refactor(spy): refactoring

This commit is contained in:
Changhua 2025-03-07 00:07:12 +08:00
parent e00958cf33
commit 19a34d45bd
10 changed files with 90 additions and 89 deletions

View File

@ -5,10 +5,9 @@
#include "log.hpp"
#include "offsets.h"
#include "rpc_helper.h"
#include "spy.h"
#include "util.h"
extern UINT64 g_WeChatWinDllAddr;
namespace account
{
@ -28,7 +27,7 @@ static void clear_cached_home_path() { cachedHomePath.reset(); }
static uint64_t get_account_service()
{
static auto GetService = reinterpret_cast<get_account_service_t>(g_WeChatWinDllAddr + OsAcc::SERVICE);
static auto GetService = Spy::getFunction<get_account_service_t>(OsAcc::SERVICE);
return GetService ? GetService() : 0;
}
@ -52,7 +51,7 @@ fs::path get_home_path()
return *cachedHomePath;
}
WxString home;
auto GetDataPath = reinterpret_cast<get_data_path_t>(g_WeChatWinDllAddr + OsAcc::PATH);
auto GetDataPath = Spy::getFunction<get_data_path_t>(OsAcc::PATH);
int64_t service_addr = get_account_service();
GetDataPath((QWORD)&home);
if (home.wptr) {

View File

@ -5,10 +5,9 @@
#include "offsets.h"
#include "pb_util.h"
#include "rpc_helper.h"
#include "spy.h"
#include "util.h"
extern QWORD g_WeChatWinDllAddr;
namespace chatroom
{
namespace OsRoom = Offsets::Chatroom;
@ -32,8 +31,8 @@ bool rpc_chatroom_common(const MemberMgmt &m, uint8_t *out, size_t *len, Func fu
int add_chatroom_member(const string &roomid, const string &wxids)
{
auto get_chatroom_mgr = reinterpret_cast<get_mgr_t>(g_WeChatWinDllAddr + OsRoom::MGR);
auto add_members = reinterpret_cast<add_member_t>(g_WeChatWinDllAddr + OsRoom::ADD);
auto get_chatroom_mgr = Spy::getFunction<get_mgr_t>(OsRoom::MGR);
auto add_members = Spy::getFunction<add_member_t>(OsRoom::ADD);
WxString *wx_roomid = util::CreateWxString(roomid);
@ -46,8 +45,8 @@ int add_chatroom_member(const string &roomid, const string &wxids)
int del_chatroom_member(const string &roomid, const string &wxids)
{
auto get_chatroom_mgr = reinterpret_cast<get_mgr_t>(g_WeChatWinDllAddr + OsRoom::MGR);
auto del_members = reinterpret_cast<delete_member_t>(g_WeChatWinDllAddr + OsRoom::DEL);
auto get_chatroom_mgr = Spy::getFunction<get_mgr_t>(OsRoom::MGR);
auto del_members = Spy::getFunction<delete_member_t>(OsRoom::DEL);
WxString *wx_roomid = util::CreateWxString(roomid);
auto wx_members = util::parse_wxids(wxids).wxWxids;
@ -58,7 +57,7 @@ int del_chatroom_member(const string &roomid, const string &wxids)
int invite_chatroom_member(const string &roomid, const string &wxids)
{
auto invite_members = reinterpret_cast<invite_members_t>(g_WeChatWinDllAddr + OsRoom::INV);
auto invite_members = Spy::getFunction<invite_members_t>(OsRoom::INV);
wstring ws_roomid = util::s2w(roomid);
WxString *wx_roomid = util::CreateWxString(roomid);

View File

@ -6,12 +6,11 @@
#include "offsets.h"
#include "pb_util.h"
#include "rpc_helper.h"
#include "spy.h"
#include "util.h"
using namespace std;
extern QWORD g_WeChatWinDllAddr;
namespace contact
{
namespace OsCon = Offsets::Contact;
@ -54,8 +53,8 @@ static string get_cnt_string(QWORD start, QWORD end, const uint8_t *feat, size_t
vector<RpcContact_t> get_contacts()
{
vector<RpcContact_t> contacts;
get_contact_mgr_t func_get_contact_mgr = reinterpret_cast<get_contact_mgr_t>(g_WeChatWinDllAddr + OsCon::MGR);
get_contact_list_t func_get_contact_list = reinterpret_cast<get_contact_list_t>(g_WeChatWinDllAddr + OsCon::LIST);
auto func_get_contact_mgr = Spy::getFunction<get_contact_mgr_t>(OsCon::MGR);
auto func_get_contact_list = Spy::getFunction<get_contact_list_t>(OsCon::LIST);
QWORD mgr = func_get_contact_mgr();
QWORD addr[3] = { 0 };

View File

@ -7,11 +7,10 @@
#include "offsets.h"
#include "pb_util.h"
#include "rpc_helper.h"
#include "spy.h"
#include "sqlite3.h"
#include "util.h"
extern UINT64 g_WeChatWinDllAddr;
namespace db
{
namespace OsDb = Offsets::Db;
@ -48,7 +47,7 @@ static void get_msg_db_handle(QWORD msg_mgr_addr)
db_map_t get_db_handles()
{
db_map.clear();
QWORD db_instance_addr = util::get_qword(g_WeChatWinDllAddr + OsDb::INSTANCE);
QWORD db_instance_addr = util::get_qword(Spy::WeChatDll.load() + OsDb::INSTANCE);
get_db_handle(db_instance_addr, OsDb::MICROMSG); // MicroMsg.db
get_db_handle(db_instance_addr, OsDb::CHAT_MSG); // ChatMsg.db
@ -57,7 +56,7 @@ db_map_t get_db_handles()
get_db_handle(db_instance_addr, OsDb::MEDIA); // Media.db
get_db_handle(db_instance_addr, OsDb::FUNCTION_MSG); // Function.db
get_msg_db_handle(util::get_qword(g_WeChatWinDllAddr + OsDb::MSG_I)); // MSGi.db & MediaMsgi.db
get_msg_db_handle(util::get_qword(Spy::WeChatDll.load() + OsDb::MSG_I)); // MSGi.db & MediaMsgi.db
return db_map;
}
@ -103,8 +102,8 @@ DbTables_t get_db_tables(const std::string &db)
return tables;
}
constexpr const char *sql = "SELECT name FROM sqlite_master WHERE type='table';";
Sqlite3_exec p_sqlite3_exec = reinterpret_cast<Sqlite3_exec>(g_WeChatWinDllAddr + OsDb::EXEC);
constexpr const char *sql = "SELECT name FROM sqlite_master WHERE type='table';";
auto p_sqlite3_exec = Spy::getFunction<Sqlite3_exec>(OsDb::EXEC);
p_sqlite3_exec(it->second, sql, (Sqlite3_callback)cb_get_tables, (void *)&tables, nullptr);
return tables;
@ -114,19 +113,14 @@ DbRows_t exec_db_query(const std::string &db, const std::string &sql)
{
DbRows_t rows;
Sqlite3_prepare func_prepare = reinterpret_cast<Sqlite3_prepare>(g_WeChatWinDllAddr + OsDb::PREPARE);
Sqlite3_step func_step = reinterpret_cast<Sqlite3_step>(g_WeChatWinDllAddr + OsDb::STEP);
Sqlite3_column_count func_column_count
= reinterpret_cast<Sqlite3_column_count>(g_WeChatWinDllAddr + OsDb::COLUMN_COUNT);
Sqlite3_column_name func_column_name
= reinterpret_cast<Sqlite3_column_name>(g_WeChatWinDllAddr + OsDb::COLUMN_NAME);
Sqlite3_column_type func_column_type
= reinterpret_cast<Sqlite3_column_type>(g_WeChatWinDllAddr + OsDb::COLUMN_TYPE);
Sqlite3_column_blob func_column_blob
= reinterpret_cast<Sqlite3_column_blob>(g_WeChatWinDllAddr + OsDb::COLUMN_BLOB);
Sqlite3_column_bytes func_column_bytes
= reinterpret_cast<Sqlite3_column_bytes>(g_WeChatWinDllAddr + OsDb::COLUMN_BYTES);
Sqlite3_finalize func_finalize = reinterpret_cast<Sqlite3_finalize>(g_WeChatWinDllAddr + OsDb::FINALIZE);
auto func_prepare = Spy::getFunction<Sqlite3_prepare>(OsDb::PREPARE);
auto func_step = Spy::getFunction<Sqlite3_step>(OsDb::STEP);
auto func_column_count = Spy::getFunction<Sqlite3_column_count>(OsDb::COLUMN_COUNT);
auto func_column_name = Spy::getFunction<Sqlite3_column_name>(OsDb::COLUMN_NAME);
auto func_column_type = Spy::getFunction<Sqlite3_column_type>(OsDb::COLUMN_TYPE);
auto func_column_blob = Spy::getFunction<Sqlite3_column_blob>(OsDb::COLUMN_BLOB);
auto func_column_bytes = Spy::getFunction<Sqlite3_column_bytes>(OsDb::COLUMN_BYTES);
auto func_finalize = Spy::getFunction<Sqlite3_finalize>(OsDb::FINALIZE);
if (db_map.empty()) {
db_map = get_db_handles();
@ -180,7 +174,7 @@ int get_local_id_and_dbidx(uint64_t id, uint64_t *local_id, uint32_t *db_idx)
return -1;
}
QWORD msg_mgr_addr = util::get_qword(g_WeChatWinDllAddr + OsDb::MSG_I);
QWORD msg_mgr_addr = util::get_qword(Spy::WeChatDll.load() + OsDb::MSG_I);
int db_index = static_cast<int>(util::get_qword(msg_mgr_addr + 0x68)); // 总不能 int 还不够吧?
QWORD p_start = util::get_qword(msg_mgr_addr + 0x50);
@ -223,7 +217,7 @@ int get_local_id_and_dbidx(uint64_t id, uint64_t *local_id, uint32_t *db_idx)
std::vector<uint8_t> get_audio_data(uint64_t id)
{
QWORD msg_mgr_addr = util::get_qword(g_WeChatWinDllAddr + OsDb::MSG_I);
QWORD msg_mgr_addr = util::get_qword(Spy::WeChatDll.load() + OsDb::MSG_I);
int db_index = static_cast<int>(util::get_qword(msg_mgr_addr + 0x68));
std::string sql = "SELECT Buf FROM Media WHERE Reserved0=" + std::to_string(id) + ";";

View File

@ -1,9 +1,5 @@
// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "framework.h"
#include <iostream>
#include <sstream>
#include "spy.h"
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{

View File

@ -12,10 +12,9 @@
#include "offsets.h"
#include "pb_util.h"
#include "rpc_helper.h"
#include "spy.h"
#include "util.h"
extern QWORD g_WeChatWinDllAddr;
namespace message
{
@ -189,8 +188,8 @@ int Handler::EnableLog()
{
if (isLogging) return 1;
pLogLevel = reinterpret_cast<uint32_t *>(g_WeChatWinDllAddr + OsLog::LEVEL);
funcWxLog = reinterpret_cast<funcWxLog_t>(g_WeChatWinDllAddr + OsLog::CALL);
pLogLevel = reinterpret_cast<uint32_t *>(Spy::WeChatDll.load() + OsLog::LEVEL);
funcWxLog = Spy::getFunction<funcWxLog_t>(OsLog::CALL);
if (InitializeHook() != MH_OK) return -1;
if (MH_CreateHook(funcWxLog, &PrintWxLog, reinterpret_cast<LPVOID *>(&realWxLog)) != MH_OK) return -2;
@ -215,7 +214,7 @@ int Handler::ListenMsg()
{
if (isListeningMsg) return 1;
funcRecvMsg = reinterpret_cast<funcRecvMsg_t>(g_WeChatWinDllAddr + OsRecv::CALL);
funcRecvMsg = Spy::getFunction<funcRecvMsg_t>(OsRecv::CALL);
if (InitializeHook() != MH_OK) return -1;
if (MH_CreateHook(funcRecvMsg, &DispatchMsg, reinterpret_cast<LPVOID *>(&realRecvMsg)) != MH_OK) return -1;
if (MH_EnableHook(funcRecvMsg) != MH_OK) return -1;
@ -237,7 +236,7 @@ int Handler::ListenPyq()
{
if (isListeningPyq) return 1;
funcRecvPyq = reinterpret_cast<funcRecvPyq_t>(g_WeChatWinDllAddr + OsRecv::PYQ_CALL);
funcRecvPyq = Spy::getFunction<funcRecvPyq_t>(OsRecv::PYQ_CALL);
if (InitializeHook() != MH_OK) return -1;
if (MH_CreateHook(funcRecvPyq, &DispatchPyq, reinterpret_cast<LPVOID *>(&realRecvPyq)) != MH_OK) return -1;
if (MH_EnableHook(funcRecvPyq) != MH_OK) return -1;

View File

@ -8,11 +8,10 @@
#include "log.hpp"
#include "offsets.h"
#include "rpc_helper.h"
#include "spy.h"
#include "spy_types.h"
#include "util.h"
extern QWORD g_WeChatWinDllAddr;
namespace message
{
@ -26,22 +25,22 @@ Sender &Sender::get_instance()
Sender::Sender()
{
func_new_chat_msg = reinterpret_cast<New_t>(g_WeChatWinDllAddr + OsSend::INSTANCE);
func_free_chat_msg = reinterpret_cast<Free_t>(g_WeChatWinDllAddr + OsSend::FREE);
func_send_msg_mgr = reinterpret_cast<SendMsgMgr_t>(g_WeChatWinDllAddr + OsSend::MGR);
func_send_text = reinterpret_cast<SendText_t>(g_WeChatWinDllAddr + OsSend::TEXT);
func_send_image = reinterpret_cast<SendImage_t>(g_WeChatWinDllAddr + OsSend::IMAGE);
func_get_app_mgr = reinterpret_cast<GetAppMgr_t>(g_WeChatWinDllAddr + OsSend::APP_MGR);
func_send_file = reinterpret_cast<SendFile_t>(g_WeChatWinDllAddr + OsSend::FILE);
func_new_mmreader = reinterpret_cast<New_t>(g_WeChatWinDllAddr + OsSend::NEW_MM_READER);
func_free_mmreader = reinterpret_cast<Free_t>(g_WeChatWinDllAddr + OsSend::FREE_MM_READER);
func_send_rich_text = reinterpret_cast<SendRichText_t>(g_WeChatWinDllAddr + OsSend::RICH_TEXT);
func_send_pat = reinterpret_cast<SendPat_t>(g_WeChatWinDllAddr + OsSend::PAT);
func_forward = reinterpret_cast<Forward_t>(g_WeChatWinDllAddr + OsSend::FORWARD);
func_get_emotion_mgr = reinterpret_cast<GetEmotionMgr_t>(g_WeChatWinDllAddr + OsSend::EMOTION_MGR);
func_send_emotion = reinterpret_cast<SendEmotion_t>(g_WeChatWinDllAddr + OsSend::EMOTION);
func_send_xml = reinterpret_cast<SendXml_t>(g_WeChatWinDllAddr + OsSend::XML);
func_xml_buf_sign = reinterpret_cast<XmlBufSign_t>(g_WeChatWinDllAddr + OsSend::XML_BUF_SIGN);
func_new_chat_msg = Spy::getFunction<New_t>(OsSend::INSTANCE);
func_free_chat_msg = Spy::getFunction<Free_t>(OsSend::FREE);
func_send_msg_mgr = Spy::getFunction<SendMsgMgr_t>(OsSend::MGR);
func_send_text = Spy::getFunction<SendText_t>(OsSend::TEXT);
func_send_image = Spy::getFunction<SendImage_t>(OsSend::IMAGE);
func_get_app_mgr = Spy::getFunction<GetAppMgr_t>(OsSend::APP_MGR);
func_send_file = Spy::getFunction<SendFile_t>(OsSend::FILE);
func_new_mmreader = Spy::getFunction<New_t>(OsSend::NEW_MM_READER);
func_free_mmreader = Spy::getFunction<Free_t>(OsSend::FREE_MM_READER);
func_send_rich_text = Spy::getFunction<SendRichText_t>(OsSend::RICH_TEXT);
func_send_pat = Spy::getFunction<SendPat_t>(OsSend::PAT);
func_forward = Spy::getFunction<Forward_t>(OsSend::FORWARD);
func_get_emotion_mgr = Spy::getFunction<GetEmotionMgr_t>(OsSend::EMOTION_MGR);
func_send_emotion = Spy::getFunction<SendEmotion_t>(OsSend::EMOTION);
func_send_xml = Spy::getFunction<SendXml_t>(OsSend::XML);
func_xml_buf_sign = Spy::getFunction<XmlBufSign_t>(OsSend::XML_BUF_SIGN);
}
void Sender::send_text(const std::string &wxid, const std::string &msg, const std::string &at_wxids)

View File

@ -12,11 +12,10 @@
#include "message_handler.h"
#include "offsets.h"
#include "rpc_helper.h"
#include "spy.h"
#include "spy_types.h"
#include "util.h"
extern QWORD g_WeChatWinDllAddr;
namespace misc
{
using namespace std;
@ -105,8 +104,8 @@ static int get_first_page()
{
int status = -1;
get_sns_data_mgr_t GetSNSDataMgr = (get_sns_data_mgr_t)(g_WeChatWinDllAddr + OsSns::DATA_MGR);
get_sns_first_page_t GetSNSFirstPage = (get_sns_first_page_t)(g_WeChatWinDllAddr + OsSns::FIRST);
auto GetSNSDataMgr = Spy::getFunction<get_sns_data_mgr_t>(OsSns::DATA_MGR);
auto GetSNSFirstPage = Spy::getFunction<get_sns_first_page_t>(OsSns::FIRST);
QWORD buff[16] = { 0 };
QWORD mgr = GetSNSDataMgr();
@ -119,8 +118,8 @@ static int get_next_page(QWORD id)
{
int status = -1;
get_sns_timeline_mgr_t GetSnsTimeLineMgr = (get_sns_timeline_mgr_t)(g_WeChatWinDllAddr + OsSns::TIMELINE);
get_sns_next_page_scene_t GetSNSNextPageScene = (get_sns_next_page_scene_t)(g_WeChatWinDllAddr + OsSns::NEXT);
auto GetSnsTimeLineMgr = Spy::getFunction<get_sns_timeline_mgr_t>(OsSns::TIMELINE);
auto GetSNSNextPageScene = Spy::getFunction<get_sns_next_page_scene_t>(OsSns::NEXT);
QWORD mgr = GetSnsTimeLineMgr();
status = (int)GetSNSNextPageScene(mgr, id);
@ -167,13 +166,12 @@ int download_attachment(uint64_t id, const fs::path &thumb, const fs::path &extr
return status;
}
new_chat_msg_t NewChatMsg = (new_chat_msg_t)(g_WeChatWinDllAddr + OsMisc::INSATNCE);
free_chat_msg_t FreeChatMsg = (free_chat_msg_t)(g_WeChatWinDllAddr + OsMisc::FREE);
get_chat_mgr_t GetChatMgr = (get_chat_mgr_t)(g_WeChatWinDllAddr + OsMisc::CHAT_MGR);
get_pre_download_mgr_t GetPreDownLoadMgr = (get_pre_download_mgr_t)(g_WeChatWinDllAddr + OsMisc::PRE_DOWNLOAD_MGR);
push_attach_task_t PushAttachTask = (push_attach_task_t)(g_WeChatWinDllAddr + OsMisc::PUSH_ATTACH_TASK);
get_mgr_by_prefix_localid_t GetMgrByPrefixLocalId
= (get_mgr_by_prefix_localid_t)(g_WeChatWinDllAddr + OsMisc::PRE_LOCAL_ID_MGR);
auto NewChatMsg = Spy::getFunction<new_chat_msg_t>(OsMisc::INSATNCE);
auto FreeChatMsg = Spy::getFunction<free_chat_msg_t>(OsMisc::FREE);
auto GetChatMgr = Spy::getFunction<get_chat_mgr_t>(OsMisc::CHAT_MGR);
auto GetPreDownLoadMgr = Spy::getFunction<get_pre_download_mgr_t>(OsMisc::PRE_DOWNLOAD_MGR);
auto PushAttachTask = Spy::getFunction<push_attach_task_t>(OsMisc::PUSH_ATTACH_TASK);
auto GetMgrByPrefixLocalId = Spy::getFunction<get_mgr_by_prefix_localid_t>(OsMisc::PRE_LOCAL_ID_MGR);
LARGE_INTEGER l;
l.HighPart = dbIdx;
@ -336,7 +334,7 @@ int revoke_message(uint64_t id)
std::string get_login_url()
{
std::string uri;
get_qr_code_mgr_t get_qr_code_mgr = (get_qr_code_mgr_t)(g_WeChatWinDllAddr + OsMisc::QR_CODE);
auto get_qr_code_mgr = Spy::getFunction<get_qr_code_mgr_t>(OsMisc::QR_CODE);
uint64_t addr = get_qr_code_mgr() + 0x68;
uint64_t len = *(uint64_t *)(addr + 0x10);

View File

@ -1,23 +1,21 @@
#include "spy.h"
#include <filesystem>
#include <string_view>
#include "log.hpp"
#include "rpc_server.h"
#include "spy.h"
#include "util.h"
constexpr std::string_view SUPPORT_VERSION = "3.9.12.17";
UINT64 g_WeChatWinDllAddr = 0;
int InitSpy(LPVOID args)
namespace Spy
{
int Init(void *args)
{
auto *pp = static_cast<util::PortPath *>(args);
Log::InitLogger(pp->path);
if (auto dll_addr = GetModuleHandle(L"WeChatWin.dll")) {
g_WeChatWinDllAddr = reinterpret_cast<UINT64>(dll_addr);
WeChatDll.store(reinterpret_cast<uint64_t>(dll_addr));
} else {
LOG_ERROR("获取 WeChatWin.dll 模块地址失败");
return -1;
@ -37,8 +35,14 @@ int InitSpy(LPVOID args)
return 0;
}
void CleanupSpy()
void Cleanup()
{
LOG_DEBUG("CleanupSpy");
RpcServer::destroyInstance();
}
}
extern "C" {
__declspec(dllexport) int InitSpy(void *args) { return Spy::Init(args); }
__declspec(dllexport) void CleanupSpy() { Spy::Cleanup(); }
}

View File

@ -1,6 +1,20 @@
#pragma once
#include "framework.h"
#include <atomic>
#include <cstdint>
#include <string_view>
int InitSpy(int port);
void CleanupSpy();
namespace Spy
{
constexpr std::string_view SUPPORT_VERSION = "3.9.12.17";
inline std::atomic<std::uintptr_t> WeChatDll { 0 };
template <typename T> inline T getFunction(std::uintptr_t offset) { return reinterpret_cast<T>(WeChatDll + offset); }
template <typename T> inline T getFunction(std::uintptr_t base, std::uintptr_t offset)
{
return reinterpret_cast<T>(base + offset);
}
int Init(void *args);
void Cleanup();
}