Refactoring

This commit is contained in:
Changhua 2025-02-04 17:27:35 +08:00
parent c96d85db30
commit dc51b7b5a7
11 changed files with 152 additions and 127 deletions

View File

@ -2,14 +2,13 @@
#include <codecvt> #include <codecvt>
#include <locale> #include <locale>
#include <memory> #include <optional>
#include <string.h>
#include <strsafe.h> #include <strsafe.h>
#include <tlhelp32.h>
#include <vector>
#include <wchar.h> #include <wchar.h>
#include "framework.h" #include "framework.h"
#include <Shlwapi.h>
#include <tlhelp32.h>
#include "log.hpp" #include "log.hpp"
@ -61,7 +60,7 @@ DWORD get_wechat_pid()
PROCESSENTRY32 pe32 = { sizeof(PROCESSENTRY32) }; PROCESSENTRY32 pe32 = { sizeof(PROCESSENTRY32) };
while (Process32Next(hSnapshot, &pe32)) { while (Process32Next(hSnapshot, &pe32)) {
if (std::wstring(pe32.szExeFile) == WECHATEXE) { if (w2s(pe32.szExeFile) == WECHATEXE) {
pid = pe32.th32ProcessID; pid = pe32.th32ProcessID;
break; break;
} }
@ -70,100 +69,125 @@ DWORD get_wechat_pid()
return pid; return pid;
} }
int open_wechat(DWORD *pid) int open_wechat(DWORD &pid)
{ {
*pid = get_wechat_pid(); pid = get_wechat_pid();
if (*pid) return ERROR_SUCCESS; if (pid != 0) {
return ERROR_SUCCESS;
}
WCHAR path[MAX_PATH] = { 0 }; auto wechat_path = util::get_wechat_path();
if (GetModuleFileNameW(nullptr, path, MAX_PATH) == 0) { if (!wechat_path) {
return GetLastError(); LOG_ERROR("获取 WeChat 安装路径失败");
return ERROR_FILE_NOT_FOUND;
} }
STARTUPINFO si = { sizeof(si) }; STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION pi = { 0 }; PROCESS_INFORMATION pi = {};
if (!CreateProcessA(wechat_path->c_str(), nullptr, nullptr, nullptr, FALSE, CREATE_NEW_CONSOLE, nullptr, nullptr,
if (!CreateProcessW(nullptr, path, nullptr, nullptr, FALSE, CREATE_NEW_CONSOLE, nullptr, nullptr, &si, &pi)) { &si, &pi)) {
return GetLastError(); return GetLastError();
} }
CloseHandle(pi.hThread); CloseHandle(pi.hThread);
CloseHandle(pi.hProcess); CloseHandle(pi.hProcess);
*pid = pi.dwProcessId; pid = pi.dwProcessId;
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
static std::optional<std::string> get_wechat_win_dll_path() std::optional<std::string> get_wechat_path()
{ {
char path[MAX_PATH] = { 0 }; HKEY hKey;
if (GetWeChatPath(path) != ERROR_SUCCESS) { if (RegOpenKeyExA(HKEY_CURRENT_USER, "Software\\Tencent\\WeChat", 0, KEY_READ, &hKey) != ERROR_SUCCESS) {
LOG_ERROR("无法打开注册表项");
return std::nullopt; return std::nullopt;
} }
PathRemoveFileSpecA(path); char path[MAX_PATH] = { 0 };
PathAppendA(path, WECHATWINDLL); DWORD type = REG_SZ;
DWORD size = sizeof(path);
if (!PathFileExistsA(path)) { if (RegQueryValueExA(hKey, "InstallPath", nullptr, &type, reinterpret_cast<LPBYTE>(path), &size) != ERROR_SUCCESS) {
// 微信 3.7+ 版本增加了一层目录 RegCloseKey(hKey);
PathRemoveFileSpecA(path); LOG_ERROR("无法读取注册表中的 InstallPath");
_finddata_t findData; return std::nullopt;
std::string dir = std::string(path) + "\\[*.*";
intptr_t handle = _findfirst(dir.c_str(), &findData);
if (handle == -1) {
return std::nullopt;
}
_findclose(handle);
std::string dllPath = std::string(path) + "\\" + findData.name + "\\" + WECHATWINDLL;
return dllPath;
} }
RegCloseKey(hKey);
PathAppendA(path, WECHATEXE);
return std::string(path); return std::string(path);
} }
static std::optional<std::string> get_file_version(const std::string &filePath) std::optional<std::string> get_wechat_win_dll_path()
{ {
if (filePath.empty() || !PathFileExistsA(filePath.c_str())) { auto wechat_path = get_wechat_path();
if (!wechat_path) {
return std::nullopt; return std::nullopt;
} }
DWORD handle = 0; std::string dll_path = *wechat_path;
DWORD size = GetFileVersionInfoSizeA(filePath.c_str(), &handle); PathRemoveFileSpecA(dll_path.data());
PathAppendA(dll_path.data(), WECHATWINDLL);
if (PathFileExistsA(dll_path.c_str())) {
return dll_path;
}
// 微信从大约3.7开始,增加了一层版本目录: [3.7.0.29]
PathRemoveFileSpecA(dll_path.data());
WIN32_FIND_DATAA find_data;
HANDLE hFind = FindFirstFileA((dll_path + "\\*.*").c_str(), &find_data);
if (hFind == INVALID_HANDLE_VALUE) {
return std::nullopt;
}
FindClose(hFind);
std::string versioned_path = dll_path + "\\" + find_data.cFileName + WECHATWINDLL;
return PathFileExistsA(versioned_path.c_str()) ? std::optional<std::string>(versioned_path) : std::nullopt;
}
std::optional<std::string> get_file_version(const std::string &file_path)
{
if (!PathFileExistsA(file_path.c_str())) {
return std::nullopt;
}
DWORD dummy = 0;
DWORD size = GetFileVersionInfoSizeA(file_path.c_str(), &dummy);
if (size == 0) { if (size == 0) {
return std::nullopt; return std::nullopt;
} }
std::vector<BYTE> data(size); std::vector<BYTE> buffer(size);
if (!GetFileVersionInfoA(filePath.c_str(), 0, size, data.data())) { if (!GetFileVersionInfoA(file_path.c_str(), 0, size, buffer.data())) {
return std::nullopt; return std::nullopt;
} }
VS_FIXEDFILEINFO *verInfo = nullptr; VS_FIXEDFILEINFO *ver_info = nullptr;
UINT len = 0; UINT ver_size = 0;
if (!VerQueryValueA(data.data(), "\\", reinterpret_cast<void **>(&verInfo), &len) || len == 0) { if (!VerQueryValueA(buffer.data(), "\\", reinterpret_cast<LPVOID *>(&ver_info), &ver_size)) {
return std::nullopt; return std::nullopt;
} }
char version[32]; return fmt::format("{}.{}.{}.{}", HIWORD(ver_info->dwFileVersionMS), LOWORD(ver_info->dwFileVersionMS),
StringCbPrintfA(version, sizeof(version), "%d.%d.%d.%d", HIWORD(verInfo->dwFileVersionMS), HIWORD(ver_info->dwFileVersionLS), LOWORD(ver_info->dwFileVersionLS));
LOWORD(verInfo->dwFileVersionMS), HIWORD(verInfo->dwFileVersionLS),
LOWORD(verInfo->dwFileVersionLS));
return std::string(version);
} }
std::string get_wechat_version() std::string get_wechat_version()
{ {
std::string version = ""; auto dll_path = get_wechat_win_dll_path();
if (!dll_path) {
auto dllPath = get_wechat_win_dll_path(); LOG_ERROR("无法获取 WeChatWin.dll 路径");
if (!dllPath) { return "";
return version;
} }
version = get_file_version(*dllPath); auto version = get_file_version(*dll_path);
return version ? version : ""; if (!version) {
LOG_ERROR("无法获取 WeChat 版本信息");
return "";
}
return *version;
} }
uint32_t get_memory_int_by_address(HANDLE hProcess, uint64_t addr) uint32_t get_memory_int_by_address(HANDLE hProcess, uint64_t addr)
@ -171,10 +195,7 @@ uint32_t get_memory_int_by_address(HANDLE hProcess, uint64_t addr)
uint32_t value = 0; uint32_t value = 0;
if (!addr || !hProcess) return value; if (!addr || !hProcess) return value;
unsigned char data[4] = { 0 }; ReadProcessMemory(hProcess, reinterpret_cast<LPCVOID>(addr), &value, sizeof(value), nullptr);
if (ReadProcessMemory(hProcess, reinterpret_cast<LPCVOID>(addr), data, sizeof(data), nullptr)) {
value = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);
}
return value; return value;
} }

View File

@ -1,15 +1,17 @@
#pragma once #pragma once
#include <cstdint> #include <cstdint>
#include <memory>
#include <string> #include <string>
#include <vector>
#include "spy_types.h" #include "spy_types.h"
namespace util namespace util
{ {
inline constexpr wchar_t WECHATEXE[] = L"WeChat.exe"; inline constexpr char WECHATEXE[] = "WeChat.exe";
inline constexpr wchar_t WECHATWINDLL[] = L"WeChatWin.dll"; inline constexpr char WECHATWINDLL[] = "WeChatWin.dll";
inline constexpr wchar_t WCFSDKDLL[] = L"sdk.dll"; inline constexpr wchar_t WCFSDKDLL[] = L"sdk.dll";
inline constexpr wchar_t WCFSPYDLL[] = L"spy.dll"; inline constexpr wchar_t WCFSPYDLL[] = L"spy.dll";
inline constexpr wchar_t WCFSPYDLL_DEBUG[] = L"spy_debug.dll"; inline constexpr wchar_t WCFSPYDLL_DEBUG[] = L"spy_debug.dll";
@ -19,6 +21,16 @@ struct PortPath {
char path[MAX_PATH]; char path[MAX_PATH];
}; };
DWORD get_wechat_pid();
int open_wechat(DWORD *pid);
std::string get_wechat_version();
uint32_t get_memory_int_by_address(HANDLE hProcess, uint64_t addr);
std::wstring get_unicode_info_by_address(HANDLE hProcess, uint64_t addr);
std::wstring s2w(const std::string &s);
std::string w2s(const std::wstring &ws);
std::string gb2312_to_utf8(const char *gb2312);
void dbg_msg(const char *format, ...);
inline DWORD get_dword(uint64_t addr) { return addr ? *reinterpret_cast<DWORD *>(addr) : 0; } inline DWORD get_dword(uint64_t addr) { return addr ? *reinterpret_cast<DWORD *>(addr) : 0; }
inline QWORD get_qword(uint64_t addr) { return addr ? *reinterpret_cast<QWORD *>(addr) : 0; } inline QWORD get_qword(uint64_t addr) { return addr ? *reinterpret_cast<QWORD *>(addr) : 0; }
inline uint64_t get_uint64(uint64_t addr) { return addr ? *reinterpret_cast<uint64_t *>(addr) : 0; } inline uint64_t get_uint64(uint64_t addr) { return addr ? *reinterpret_cast<uint64_t *>(addr) : 0; }
@ -47,12 +59,12 @@ inline std::wstring get_pp_wstring(uint64_t addr)
if (!addr) return L""; if (!addr) return L"";
const wchar_t *ptr = *reinterpret_cast<const wchar_t **>(addr); const wchar_t *ptr = *reinterpret_cast<const wchar_t **>(addr);
return (ptr && *ptr) ? std::wstring(ptr) : ""; return (ptr && *ptr) ? std::wstring(ptr) : L"";
} }
inline std::string get_pp_len_string(uint64_t addr) inline std::string get_pp_len_string(uint64_t addr)
{ {
size_t len = get_dword(addr + 8); size_t len = get_dword(addr + 8);
return (addr && len) ? std::string(*reinterpret_cast<const char **>(addr), len) : L""; return (addr && len) ? std::string(*reinterpret_cast<const char **>(addr), len) : "";
} }
inline std::wstring get_pp_len_wstring(uint64_t addr) inline std::wstring get_pp_len_wstring(uint64_t addr)
{ {
@ -61,16 +73,6 @@ inline std::wstring get_pp_len_wstring(uint64_t addr)
} }
inline std::string get_str_by_wstr_addr(uint64_t addr) { return w2s(get_pp_len_wstring(addr)); } inline std::string get_str_by_wstr_addr(uint64_t addr) { return w2s(get_pp_len_wstring(addr)); }
DWORD get_wechat_pid();
int open_wechat(DWORD *pid);
std::string get_wechat_version();
uint32_t get_memory_int_by_address(HANDLE hProcess, uint64_t addr);
std::wstring get_unicode_info_by_address(HANDLE hProcess, uint64_t addr);
std::wstring s2w(const std::string &s);
std::string w2s(const std::wstring &ws);
std::string gb2312_to_utf8(const char *gb2312);
void dbg_msg(const char *format, ...);
std::unique_ptr<WxString> new_wx_string(const char *str); std::unique_ptr<WxString> new_wx_string(const char *str);
std::unique_ptr<WxString> new_wx_string(const wchar_t *wstr); std::unique_ptr<WxString> new_wx_string(const wchar_t *wstr);
std::unique_ptr<WxString> new_wx_string(const std::string &str); std::unique_ptr<WxString> new_wx_string(const std::string &str);

View File

@ -45,10 +45,10 @@ int add_chatroom_member(const string &roomid, const string &wxids)
= reinterpret_cast<add_member_to_chatroom_t>(g_WeChatWinDllAddr + OS_ADD_MEMBERS); = reinterpret_cast<add_member_to_chatroom_t>(g_WeChatWinDllAddr + OS_ADD_MEMBERS);
vector<WxString> wx_members = parse_wxids(wxids); vector<WxString> wx_members = parse_wxids(wxids);
WxString *p_wx_roomid = NewWxStringFromStr(roomid); auto wx_roomid = util::new_wx_string(roomid);
QWORD p_members = reinterpret_cast<QWORD>(&wx_members.front()); QWORD p_members = reinterpret_cast<QWORD>(&wx_members.front());
return static_cast<int>(add_members(get_chatroom_mgr(), p_members, reinterpret_cast<QWORD>(p_wx_roomid), 0)); return static_cast<int>(add_members(get_chatroom_mgr(), p_members, reinterpret_cast<QWORD>(wx_roomid.get()), 0));
} }
int del_chatroom_member(const string &roomid, const string &wxids) int del_chatroom_member(const string &roomid, const string &wxids)
@ -64,10 +64,10 @@ int del_chatroom_member(const string &roomid, const string &wxids)
= reinterpret_cast<del_member_from_chatroom_t>(g_WeChatWinDllAddr + OS_DELETE_MEMBERS); = reinterpret_cast<del_member_from_chatroom_t>(g_WeChatWinDllAddr + OS_DELETE_MEMBERS);
vector<WxString> wx_members = parse_wxids(wxids); vector<WxString> wx_members = parse_wxids(wxids);
WxString *p_wx_roomid = NewWxStringFromStr(roomid); auto wx_roomid = util::new_wx_string(roomid);
QWORD p_members = reinterpret_cast<QWORD>(&wx_members.front()); QWORD p_members = reinterpret_cast<QWORD>(&wx_members.front());
return static_cast<int>(del_members(get_chatroom_mgr(), p_members, reinterpret_cast<QWORD>(p_wx_roomid))); return static_cast<int>(del_members(get_chatroom_mgr(), p_members, reinterpret_cast<QWORD>(wx_roomid.get())));
} }
int invite_chatroom_member(const string &roomid, const string &wxids) int invite_chatroom_member(const string &roomid, const string &wxids)
@ -81,11 +81,11 @@ int invite_chatroom_member(const string &roomid, const string &wxids)
= reinterpret_cast<invite_member_to_chatroom_t>(g_WeChatWinDllAddr + OS_INVITE_MEMBERS); = reinterpret_cast<invite_member_to_chatroom_t>(g_WeChatWinDllAddr + OS_INVITE_MEMBERS);
vector<WxString> wx_members = parse_wxids(wxids); vector<WxString> wx_members = parse_wxids(wxids);
WxString *p_wx_roomid = NewWxStringFromStr(roomid); auto wx_roomid = util::new_wx_string(roomid);
QWORD p_members = reinterpret_cast<QWORD>(&wx_members.front()); QWORD p_members = reinterpret_cast<QWORD>(&wx_members.front());
return static_cast<int>(invite_members(reinterpret_cast<QWORD>(p_wx_roomid->wptr), p_members, return static_cast<int>(invite_members(reinterpret_cast<QWORD>(wx_roomid.get()->wptr), p_members,
reinterpret_cast<QWORD>(p_wx_roomid), 0)); reinterpret_cast<QWORD>(wx_roomid.get()), 0));
} }
bool rpc_add_chatroom_member(const string &roomid, const string &wxids, uint8_t *out, size_t *len) bool rpc_add_chatroom_member(const string &roomid, const string &wxids, uint8_t *out, size_t *len)

View File

@ -51,7 +51,7 @@ static string get_cnt_string(QWORD start, QWORD end, const uint8_t *feat, size_t
return ""; return "";
} }
DWORD lfeat = GET_DWORD(pfeat + len); DWORD lfeat = util::get_dword(pfeat + len);
if (lfeat <= 2) { if (lfeat <= 2) {
return ""; return "";
} }
@ -78,8 +78,8 @@ vector<RpcContact_t> get_contacts()
QWORD pend = addr[2]; QWORD pend = addr[2];
while (pstart < pend) { while (pstart < pend) {
RpcContact_t cnt; RpcContact_t cnt;
QWORD pbin = GET_QWORD(pstart + OS_CONTACT_BIN); QWORD pbin = util::get_qword(pstart + OS_CONTACT_BIN);
QWORD lenbin = GET_DWORD(pstart + OS_CONTACT_BIN_LEN); QWORD lenbin = util::get_dword(pstart + OS_CONTACT_BIN_LEN);
cnt.wxid = util::get_str_by_wstr_addr(pstart + OS_CONTACT_WXID); cnt.wxid = util::get_str_by_wstr_addr(pstart + OS_CONTACT_WXID);
cnt.code = util::get_str_by_wstr_addr(pstart + OS_CONTACT_CODE); cnt.code = util::get_str_by_wstr_addr(pstart + OS_CONTACT_CODE);
@ -180,7 +180,7 @@ RpcContact_t get_contact_by_wxid(const string &wxid)
contact.code = util::get_str_by_wstr_addr(reinterpret_cast<DWORD>(buff) + g_WxCalls.contact.wxCode); contact.code = util::get_str_by_wstr_addr(reinterpret_cast<DWORD>(buff) + g_WxCalls.contact.wxCode);
contact.remark = util::get_str_by_wstr_addr(reinterpret_cast<DWORD>(buff) + g_WxCalls.contact.wxRemark); contact.remark = util::get_str_by_wstr_addr(reinterpret_cast<DWORD>(buff) + g_WxCalls.contact.wxRemark);
contact.name = util::get_str_by_wstr_addr(reinterpret_cast<DWORD>(buff) + g_WxCalls.contact.wxName); contact.name = util::get_str_by_wstr_addr(reinterpret_cast<DWORD>(buff) + g_WxCalls.contact.wxName);
contact.gender = GET_DWORD(reinterpret_cast<DWORD>(buff) + 0x148); contact.gender = util::get_dword(reinterpret_cast<DWORD>(buff) + 0x148);
__asm { __asm {
PUSHAD PUSHAD

View File

@ -31,24 +31,24 @@ static void get_db_handle(QWORD base, QWORD offset)
{ {
auto *wsp = reinterpret_cast<wchar_t *>(*(QWORD *)(base + offset + OFFSET_DB_NAME)); auto *wsp = reinterpret_cast<wchar_t *>(*(QWORD *)(base + offset + OFFSET_DB_NAME));
std::string dbname = util::w2s(std::wstring(wsp)); std::string dbname = util::w2s(std::wstring(wsp));
db_map[dbname] = GET_QWORD(base + offset); db_map[dbname] = util::get_qword(base + offset);
} }
static void get_msg_db_handle(QWORD msg_mgr_addr) static void get_msg_db_handle(QWORD msg_mgr_addr)
{ {
QWORD db_index = GET_QWORD(msg_mgr_addr + 0x68); QWORD db_index = util::get_qword(msg_mgr_addr + 0x68);
QWORD p_start = GET_QWORD(msg_mgr_addr + 0x50); QWORD p_start = util::get_qword(msg_mgr_addr + 0x50);
for (uint32_t i = 0; i < db_index; i++) { for (uint32_t i = 0; i < db_index; i++) {
QWORD db_addr = GET_QWORD(p_start + i * 0x08); QWORD db_addr = util::get_qword(p_start + i * 0x08);
if (db_addr) { if (db_addr) {
// MSGi.db // MSGi.db
std::string dbname = util::w2s(get_pp_wstring(db_addr)); std::string dbname = util::w2s(util::get_pp_wstring(db_addr));
db_map[dbname] = GET_QWORD(db_addr + 0x78); db_map[dbname] = util::get_qword(db_addr + 0x78);
// MediaMsgi.db // MediaMsgi.db
QWORD mmdb_addr = GET_QWORD(db_addr + 0x20); QWORD mmdb_addr = util::get_qword(db_addr + 0x20);
std::string mmdbname = util::w2s(get_pp_wstring(mmdb_addr + 0x78)); std::string mmdbname = util::w2s(util::get_pp_wstring(mmdb_addr + 0x78));
db_map[mmdbname] = GET_QWORD(mmdb_addr + 0x50); db_map[mmdbname] = util::get_qword(mmdb_addr + 0x50);
} }
} }
} }
@ -56,7 +56,7 @@ static void get_msg_db_handle(QWORD msg_mgr_addr)
db_map_t get_db_handles() db_map_t get_db_handles()
{ {
db_map.clear(); db_map.clear();
QWORD db_instance_addr = GET_QWORD(g_WeChatWinDllAddr + OFFSET_DB_INSTANCE); QWORD db_instance_addr = util::get_qword(g_WeChatWinDllAddr + OFFSET_DB_INSTANCE);
get_db_handle(db_instance_addr, OFFSET_DB_MICROMSG); // MicroMsg.db get_db_handle(db_instance_addr, OFFSET_DB_MICROMSG); // MicroMsg.db
get_db_handle(db_instance_addr, OFFSET_DB_CHAT_MSG); // ChatMsg.db get_db_handle(db_instance_addr, OFFSET_DB_CHAT_MSG); // ChatMsg.db
@ -65,7 +65,7 @@ db_map_t get_db_handles()
get_db_handle(db_instance_addr, OFFSET_DB_MEDIA); // Media.db get_db_handle(db_instance_addr, OFFSET_DB_MEDIA); // Media.db
get_db_handle(db_instance_addr, OFFSET_DB_FUNCTION_MSG); // Function.db get_db_handle(db_instance_addr, OFFSET_DB_FUNCTION_MSG); // Function.db
get_msg_db_handle(GET_QWORD(g_WeChatWinDllAddr + OFFSET_DB_MSG_MGR)); // MSGi.db & MediaMsgi.db get_msg_db_handle(util::get_qword(g_WeChatWinDllAddr + OFFSET_DB_MSG_MGR)); // MSGi.db & MediaMsgi.db
return db_map; return db_map;
} }
@ -189,19 +189,19 @@ int get_local_id_and_dbidx(uint64_t id, uint64_t *local_id, uint32_t *db_idx)
return -1; return -1;
} }
QWORD msg_mgr_addr = GET_QWORD(g_WeChatWinDllAddr + OFFSET_DB_MSG_MGR); QWORD msg_mgr_addr = util::get_qword(g_WeChatWinDllAddr + OFFSET_DB_MSG_MGR);
int db_index = static_cast<int>(GET_QWORD(msg_mgr_addr + 0x68)); // 总不能 int 还不够吧? int db_index = static_cast<int>(util::get_qword(msg_mgr_addr + 0x68)); // 总不能 int 还不够吧?
QWORD p_start = GET_QWORD(msg_mgr_addr + 0x50); QWORD p_start = util::get_qword(msg_mgr_addr + 0x50);
*db_idx = 0; *db_idx = 0;
for (int i = db_index - 1; i >= 0; i--) { // 从后往前遍历 for (int i = db_index - 1; i >= 0; i--) { // 从后往前遍历
QWORD db_addr = GET_QWORD(p_start + i * 0x08); QWORD db_addr = util::get_qword(p_start + i * 0x08);
if (!db_addr) { if (!db_addr) {
continue; continue;
} }
std::string dbname = util::w2s(get_pp_wstring(db_addr)); std::string dbname = util::w2s(util::get_pp_wstring(db_addr));
db_map[dbname] = GET_QWORD(db_addr + 0x78); db_map[dbname] = util::get_qword(db_addr + 0x78);
std::string sql = "SELECT localId FROM MSG WHERE MsgSvrID=" + std::to_string(id) + ";"; std::string sql = "SELECT localId FROM MSG WHERE MsgSvrID=" + std::to_string(id) + ";";
DbRows_t rows = exec_db_query(dbname, sql); DbRows_t rows = exec_db_query(dbname, sql);
@ -223,7 +223,7 @@ int get_local_id_and_dbidx(uint64_t id, uint64_t *local_id, uint32_t *db_idx)
continue; continue;
} }
*db_idx = static_cast<uint32_t>(GET_QWORD(GET_QWORD(db_addr + 0x28) + 0x1E8) >> 32); *db_idx = static_cast<uint32_t>(util::get_qword(util::get_qword(db_addr + 0x28) + 0x1E8) >> 32);
return 0; return 0;
} }
@ -232,8 +232,8 @@ 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) std::vector<uint8_t> get_audio_data(uint64_t id)
{ {
QWORD msg_mgr_addr = GET_QWORD(g_WeChatWinDllAddr + OFFSET_DB_MSG_MGR); QWORD msg_mgr_addr = util::get_qword(g_WeChatWinDllAddr + OFFSET_DB_MSG_MGR);
int db_index = static_cast<int>(GET_QWORD(msg_mgr_addr + 0x68)); 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) + ";"; std::string sql = "SELECT Buf FROM Media WHERE Reserved0=" + std::to_string(id) + ";";
for (int i = db_index - 1; i >= 0; i--) { for (int i = db_index - 1; i >= 0; i--) {

View File

@ -51,7 +51,7 @@ typedef QWORD (*PushAttachTask_t)(QWORD, QWORD, QWORD, QWORD);
typedef QWORD (*GetOCRManager_t)(); typedef QWORD (*GetOCRManager_t)();
typedef QWORD (*DoOCRTask_t)(QWORD, QWORD, QWORD, QWORD, QWORD, QWORD); typedef QWORD (*DoOCRTask_t)(QWORD, QWORD, QWORD, QWORD, QWORD, QWORD);
int IsLogin(void) { return (int)GET_QWORD(g_WeChatWinDllAddr + OS_LOGIN_STATUS); } int IsLogin(void) { return (int)util::get_qword(g_WeChatWinDllAddr + OS_LOGIN_STATUS); }
static string get_key(uint8_t header1, uint8_t header2, uint8_t *key) static string get_key(uint8_t header1, uint8_t header2, uint8_t *key)
{ {
@ -230,7 +230,7 @@ int DownloadAttach(QWORD id, string thumb, string extra)
GetChatMgr(); GetChatMgr();
GetMgrByPrefixLocalId(l.QuadPart, pChatMsg); GetMgrByPrefixLocalId(l.QuadPart, pChatMsg);
QWORD type = GET_QWORD(buff + 0x38); QWORD type = util::get_qword(reinterpret_cast<QWORD>(buff) + 0x38);
string save_path = ""; string save_path = "";
string thumb_path = ""; string thumb_path = "";
@ -262,12 +262,12 @@ int DownloadAttach(QWORD id, string thumb, string extra)
// 创建父目录,由于路径来源于微信,不做检查 // 创建父目录,由于路径来源于微信,不做检查
fs::create_directory(fs::path(save_path).parent_path().string()); fs::create_directory(fs::path(save_path).parent_path().string());
int temp = 1; int temp = 1;
WxString *pSavePath = NewWxStringFromStr(save_path); auto wx_save_path = util::new_wx_string(save_path);
WxString *pThumbPath = NewWxStringFromStr(thumb_path); auto wx_thumb_path = util::new_wx_string(thumb_path);
memcpy(&buff[0x280], pThumbPath, sizeof(WxString)); memcpy(&buff[0x280], wx_thumb_path.get(), sizeof(WxString));
memcpy(&buff[0x2A0], pSavePath, sizeof(WxString)); memcpy(&buff[0x2A0], wx_save_path.get(), sizeof(WxString));
memcpy(&buff[0x40C], &temp, sizeof(temp)); memcpy(&buff[0x40C], &temp, sizeof(temp));
QWORD mgr = GetPreDownLoadMgr(); QWORD mgr = GetPreDownLoadMgr();
@ -354,11 +354,11 @@ OcrResult_t GetOcrResult(string path)
QWORD mgr = GetOCRManager(); QWORD mgr = GetOCRManager();
ret.status = (int)DoOCRTask(mgr, (QWORD)&wxPath, unused, (QWORD)buff, (QWORD)&pUnk1, (QWORD)&pUnk2); ret.status = (int)DoOCRTask(mgr, (QWORD)&wxPath, unused, (QWORD)buff, (QWORD)&pUnk1, (QWORD)&pUnk2);
QWORD count = GET_QWORD(buff + 0x8); QWORD count = util::get_qword(buff + 0x8);
if (count > 0) { if (count > 0) {
QWORD header = GET_QWORD(buff); QWORD header = util::get_qword(buff);
for (QWORD i = 0; i < count; i++) { for (QWORD i = 0; i < count; i++) {
QWORD content = GET_QWORD(header); QWORD content = util::get_qword(header);
ret.result += util::w2s(get_pp_wstring(content + 0x28)); ret.result += util::w2s(get_pp_wstring(content + 0x28));
ret.result += "\n"; ret.result += "\n";
header = content; header = content;

View File

@ -3,6 +3,8 @@
#include "stdint.h" #include "stdint.h"
#include <string> #include <string>
#include "pb_types.h"
int IsLogin(void); int IsLogin(void);
std::string GetAudio(uint64_t id, std::string dir); std::string GetAudio(uint64_t id, std::string dir);
std::string GetPCMAudio(uint64_t id, std::string dir, int32_t sr); std::string GetPCMAudio(uint64_t id, std::string dir, int32_t sr);
@ -11,5 +13,5 @@ int RefreshPyq(uint64_t id);
int DownloadAttach(uint64_t id, std::string thumb, std::string extra); int DownloadAttach(uint64_t id, std::string thumb, std::string extra);
int RevokeMsg(uint64_t id); int RevokeMsg(uint64_t id);
OcrResult_t GetOcrResult(std::string path); OcrResult_t GetOcrResult(std::string path);
string GetLoginUrl(); std::string GetLoginUrl();
int ReceiveTransfer(std::string wxid, std::string transferid, std::string transactionid); int ReceiveTransfer(std::string wxid, std::string transferid, std::string transactionid);

View File

@ -38,10 +38,10 @@ QWORD MessageHandler::DispatchMsg(QWORD arg1, QWORD arg2)
auto &handler = getInstance(); auto &handler = getInstance();
WxMsg_t wxMsg = {}; WxMsg_t wxMsg = {};
try { try {
wxMsg.id = GET_QWORD(arg2 + OS_RECV_MSG_ID); wxMsg.id = util::get_qword(arg2 + OS_RECV_MSG_ID);
wxMsg.type = GET_DWORD(arg2 + OS_RECV_MSG_TYPE); wxMsg.type = util::get_dword(arg2 + OS_RECV_MSG_TYPE);
wxMsg.is_self = GET_DWORD(arg2 + OS_RECV_MSG_SELF); wxMsg.is_self = util::get_dword(arg2 + OS_RECV_MSG_SELF);
wxMsg.ts = GET_DWORD(arg2 + OS_RECV_MSG_TS); wxMsg.ts = util::get_dword(arg2 + OS_RECV_MSG_TS);
wxMsg.content = util::get_str_by_wstr_addr(arg2 + OS_RECV_MSG_CONTENT); wxMsg.content = util::get_str_by_wstr_addr(arg2 + OS_RECV_MSG_CONTENT);
wxMsg.sign = util::get_str_by_wstr_addr(arg2 + OS_RECV_MSG_SIGN); wxMsg.sign = util::get_str_by_wstr_addr(arg2 + OS_RECV_MSG_SIGN);
wxMsg.xml = util::get_str_by_wstr_addr(arg2 + OS_RECV_MSG_XML); wxMsg.xml = util::get_str_by_wstr_addr(arg2 + OS_RECV_MSG_XML);
@ -98,8 +98,8 @@ void MessageHandler::DispatchPyq(QWORD arg1, QWORD arg2, QWORD arg3)
wxMsg.type = 0x00; wxMsg.type = 0x00;
wxMsg.is_self = false; wxMsg.is_self = false;
wxMsg.is_group = false; wxMsg.is_group = false;
wxMsg.id = GET_QWORD(startAddr); wxMsg.id = util::get_qword(startAddr);
wxMsg.ts = GET_DWORD(startAddr + OS_PYQ_MSG_TS); wxMsg.ts = util::get_dword(startAddr + OS_PYQ_MSG_TS);
wxMsg.xml = util::get_str_by_wstr_addr(startAddr + OS_PYQ_MSG_XML); wxMsg.xml = util::get_str_by_wstr_addr(startAddr + OS_PYQ_MSG_XML);
wxMsg.sender = util::get_str_by_wstr_addr(startAddr + OS_PYQ_MSG_SENDER); wxMsg.sender = util::get_str_by_wstr_addr(startAddr + OS_PYQ_MSG_SENDER);
wxMsg.content = util::get_str_by_wstr_addr(startAddr + OS_PYQ_MSG_CONTENT); wxMsg.content = util::get_str_by_wstr_addr(startAddr + OS_PYQ_MSG_CONTENT);

View File

@ -5,11 +5,11 @@
#include <mutex> #include <mutex>
#include <optional> #include <optional>
#include <queue> #include <queue>
#include <windows.h>
#include "MinHook.h" #include "MinHook.h"
#include "pb_types.h" #include "pb_types.h"
#include "spy_types.h"
class MessageHandler class MessageHandler
{ {

View File

@ -13,7 +13,7 @@ UINT64 g_WeChatWinDllAddr = 0;
void InitSpy(LPVOID args) void InitSpy(LPVOID args)
{ {
auto *pp = static_cast<PortPath_t *>(args); auto *pp = static_cast<util::PortPath *>(args);
Log::InitLogger(pp->path); Log::InitLogger(pp->path);
if (auto dll_addr = GetModuleHandle(L"WeChatWin.dll")) { if (auto dll_addr = GetModuleHandle(L"WeChatWin.dll")) {

View File

@ -22,7 +22,7 @@ std::string get_home_path()
static std::string home_path; static std::string home_path;
std::call_once(flag, [] { std::call_once(flag, [] {
std::string path = util::w2s(get_pp_wstring(g_WeChatWinDllAddr + OS_USER_HOME)) + "\\WeChat Files\\"; std::string path = util::w2s(util::get_pp_wstring(g_WeChatWinDllAddr + OS_USER_HOME)) + "\\WeChat Files\\";
home_path = std::filesystem::absolute(path).string(); home_path = std::filesystem::absolute(path).string();
}); });
@ -37,7 +37,7 @@ std::string get_self_wxid()
std::call_once(flag, [] { std::call_once(flag, [] {
UINT64 wxid_type = 0; UINT64 wxid_type = 0;
try { try {
wxid_type = GET_UINT64(g_WeChatWinDllAddr + OS_USER_WXID + 0x18); wxid_type = util::get_qword(g_WeChatWinDllAddr + OS_USER_WXID + 0x18);
if (wxid_type == 0xF) { if (wxid_type == 0xF) {
wxid = util::get_p_string(g_WeChatWinDllAddr + OS_USER_WXID); wxid = util::get_p_string(g_WeChatWinDllAddr + OS_USER_WXID);
} else { } else {
@ -58,7 +58,7 @@ UserInfo_t get_user_info()
UserInfo_t ui; UserInfo_t ui;
ui.wxid = get_self_wxid(); ui.wxid = get_self_wxid();
UINT64 name_type = GET_UINT64(g_WeChatWinDllAddr + OS_USER_NAME + 0x18); UINT64 name_type = util::get_qword(g_WeChatWinDllAddr + OS_USER_NAME + 0x18);
ui.name = (name_type == 0xF) ? util::get_p_string(g_WeChatWinDllAddr + OS_USER_NAME) ui.name = (name_type == 0xF) ? util::get_p_string(g_WeChatWinDllAddr + OS_USER_NAME)
: util::get_pp_string(g_WeChatWinDllAddr + OS_USER_NAME); : util::get_pp_string(g_WeChatWinDllAddr + OS_USER_NAME);