Refactoring

This commit is contained in:
Changhua 2024-07-02 22:03:59 +08:00
parent 4294d81c62
commit e66b61aa67
11 changed files with 31 additions and 266 deletions

View File

@ -237,7 +237,6 @@ xcopy /y $(OutDir)$(TargetFileName) $(SolutionDir)..\clients\python\wcferry</Com
<ClInclude Include="exec_sql.h" />
<ClInclude Include="framework.h" />
<ClInclude Include="contact_mgmt.h" />
<ClInclude Include="load_calls.h" />
<ClInclude Include="receive_msg.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="rpc_server.h" />
@ -260,7 +259,6 @@ xcopy /y $(OutDir)$(TargetFileName) $(SolutionDir)..\clients\python\wcferry</Com
<ClCompile Include="dllmain.cpp" />
<ClCompile Include="exec_sql.cpp" />
<ClCompile Include="contact_mgmt.cpp" />
<ClCompile Include="load_calls.cpp" />
<ClCompile Include="receive_msg.cpp" />
<ClCompile Include="rpc_server.cpp" />
<ClCompile Include="send_msg.cpp" />

View File

@ -30,9 +30,6 @@
<ClInclude Include="contact_mgmt.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="load_calls.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="receive_msg.h">
<Filter>头文件</Filter>
</ClInclude>
@ -104,9 +101,6 @@
<ClCompile Include="contact_mgmt.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="load_calls.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="receive_msg.cpp">
<Filter>源文件</Filter>
</ClCompile>

View File

@ -1,7 +1,6 @@
#include <iterator>
#include "exec_sql.h"
#include "load_calls.h"
#include "log.h"
#include "sqlite3.h"
#include "util.h"

View File

@ -24,6 +24,7 @@ extern QWORD g_WeChatWinDllAddr;
#define HEADER_GIF1 0x47
#define HEADER_GIF2 0x49
#define OS_LOGIN_STATUS 0x5AB86A8
#define OS_GET_SNS_DATA_MGR 0x22A91C0
#define OS_GET_SNS_FIRST_PAGE 0x2ED9080
#define OS_GET_SNS_TIMELINE_MGR 0x2E6B110
@ -48,7 +49,7 @@ typedef QWORD (*PushAttachTask_t)(QWORD, QWORD, QWORD, QWORD);
typedef QWORD (*GetOCRManager_t)();
typedef QWORD (*DoOCRTask_t)(QWORD, QWORD, QWORD, QWORD, QWORD, QWORD);
int IsLogin(void) { return (int)GET_QWORD(g_WeChatWinDllAddr + g_WxCalls.login); }
int IsLogin(void) { return (int)GET_QWORD(g_WeChatWinDllAddr + OS_LOGIN_STATUS); }
static string get_key(uint8_t header1, uint8_t header2, uint8_t *key)
{

View File

@ -1,55 +0,0 @@
#include <iostream>
#include <map>
#include "load_calls.h"
#define SUPPORT_VERSION L"3.9.10.27"
WxCalls_t wxCalls = {
0x5AB86A8, // Login Status
{ 0x5AB7FB8, 0x5AB8098, 0x5AB7FD8, 0x5A7E190 }, // User Info: wxid, nickname, mobile, home
{ 0x1C1E690, 0x238DDD0, 0x1C1FF10 }, // Send Text Message
/* Receive Message:
Hook, call, msgId, type, isSelf, ts, roomId, content, wxid, sign, thumb, extra, msgXml */
{ 0x00, 0x2205510, 0x30, 0x38, 0x3C, 0x44, 0x48, 0x88, 0x240, 0x260, 0x280, 0x2A0, 0x308 },
{ 0x1C28800, 0x1C1FF10, 0x1C1E690, 0x2383560 }, // Send Image Message
{ 0x1C28800, 0x1C1FF10, 0x1C23630, 0x21969E0 }, // Send File Message
{ 0xB8A70, 0x3ED5E0, 0x107F00, 0x3ED7B0, 0x2386FE4 }, // Send xml Message
{ 0x771980, 0x4777E0, 0x239E888 }, // Send Emotion Message
/* Get Contacts:
call1, call2, wxId, Code, Remark,Name,Gender,Country,Province,City*/
{ 0x00, 0x00, 0x10, 0x30, 0x80, 0xA0, 0x0E, 0x00, 0x00, 0x00 },
/* Exec Sql:
Exec, base, start, end, slot, name*/
{ 0x141BDF0, 0x2366934, 0x1428, 0x142C, 0x3C, 0x50 },
{ 0xA17D50, 0xF59E40, 0xA18BD0, 0xA17E70 }, // Accept New Friend application
{ 0x1C4E200, 0x221B8A0, 0x00 }, // Add chatroom members
{ 0x1C4E200, 0x221BEE0, 0x00 }, // Delete chatroom members
{ 0x7B2E60, 0x15E2C20, 0x79C250 }, // Receive transfer
/* Receive PYQ
hook, call, call1, call2, call3, start, end, ts, wxid, content, xml, step*/
{ 0x14F9E15, 0x14FA0A0, 0xC39680, 0x14E2140, 0x14E21E0, 0x20, 0x24, 0x2C, 0x18, 0x3C, 0x384, 0xB48 },
/* call1, call2, call3, call4, call5, call6*/
{ 0x76F010, 0x792700, 0xBC0370, 0x80F110, 0x82BB40, 0x756E30},
/* call1, call2, call3, call4, call5*/
{0x76F010, 0x792700, 0xBC0370, 0xBB5F70, 0x756E30},
{0x1C27D50, 0x1C27120, 0x1C23630, 0x21A09C0}, // Send Rich Text Message
{0x2D669B0}, // Send Pat Message
{0x221B280, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // Invite chatroom members
/* call1, call2, call3 */
{0x80A800, 0x80F270, 0x13DA3E0},
{0x238D350}, // Forward message
/* call1, call2, url */
{0xAE9DB0, 0xCDA6F0, 0x3040DE8}
};
int LoadCalls(const wchar_t *version, WxCalls_t *calls)
{
if (wcscmp(version, SUPPORT_VERSION) != 0) {
return -1;
}
memcpy_s(calls, sizeof(WxCalls_t), &wxCalls, sizeof(WxCalls_t));
return 0;
}

View File

@ -1,5 +0,0 @@
#pragma once
#include "spy_types.h"
int LoadCalls(const wchar_t *version, WxCalls_t *calls);

View File

@ -1,14 +1,20 @@
#include <filesystem>
#include "load_calls.h"
#include "log.h"
#include "rpc_server.h"
#include "spy.h"
#include "util.h"
WxCalls_t g_WxCalls = { 0 };
UINT64 g_WeChatWinDllAddr = 0;
static bool IsWxVersionMatched(const wchar_t *version)
{
if (wcscmp(version, SUPPORT_VERSION) != 0) {
return false;
}
return true;
}
void InitSpy(LPVOID args)
{
@ -19,7 +25,7 @@ void InitSpy(LPVOID args)
g_WeChatWinDllAddr = (UINT64)GetModuleHandle(L"WeChatWin.dll"); // 获取wechatWin模块地址
if (g_WeChatWinDllAddr == 0) {
LOG_ERROR("获取 wechatWin.dll 模块地址失败");
return;
return; // TODO: 退出进程,避免后面操作失败
}
if (!GetWeChatVersion(version)) { // 获取微信版本
@ -27,7 +33,7 @@ void InitSpy(LPVOID args)
return;
}
LOG_INFO("WeChat version: {}", Wstring2String(version).c_str());
if (LoadCalls(version, &g_WxCalls) != 0) { // 加载微信版本对应的Call地址
if (!IsWxVersionMatched(version)) {
LOG_ERROR("不支持当前版本");
MessageBox(NULL, L"不支持当前版本", L"错误", 0);
return;

View File

@ -2,5 +2,7 @@
#include "framework.h"
#define SUPPORT_VERSION L"3.9.10.27"
void InitSpy(int port);
void CleanupSpy();

View File

@ -4,186 +4,6 @@
#include <string>
typedef uint64_t QWORD;
typedef struct UserInfoCall {
DWORD wxid;
DWORD nickName;
DWORD mobile;
DWORD home;
} UserInfoCall_t;
typedef struct RecvMsg {
DWORD hook; // Hook地址
DWORD call; // Call地址
DWORD msgId; // 消息ID地址
DWORD type; // 消息类型地址
DWORD isSelf; // 是否自己发送标志地址
DWORD ts; // TimeStamp
DWORD roomId; // 群聊时为群ID私聊时为微信ID
DWORD content; // 消息内容地址
DWORD wxid; // 私聊时为空群聊时为发送者微信ID
DWORD sign; // Sign
DWORD thumb; // 缩略图
DWORD extra; // 附加数据
DWORD msgXml; // 消息xml内容地址
} RecvMsg_t;
typedef struct SendText {
DWORD call1;
DWORD call2;
DWORD call3;
} SendText_t;
typedef struct Sendfile {
DWORD call1;
DWORD call2;
DWORD call3;
DWORD call4;
} Sendfile_t;
typedef struct Contact {
DWORD base;
DWORD head;
DWORD wxId;
DWORD wxCode;
DWORD wxRemark;
DWORD wxName;
DWORD wxGender;
DWORD wxCountry;
DWORD wxProvince;
DWORD wxCity;
} Contact_t;
typedef struct Sql {
DWORD exec;
DWORD base;
DWORD start;
DWORD end;
DWORD slot;
DWORD name;
} Sql_t;
typedef struct NewFriend {
DWORD call1;
DWORD call2;
DWORD call3;
DWORD call4;
} NewFriend_t;
typedef struct RoomMember {
DWORD call1;
DWORD call2;
DWORD call3;
} RoomMember_t;
typedef struct Xml {
DWORD call1;
DWORD call2;
DWORD call3;
DWORD call4;
DWORD param;
} Xml_t;
typedef struct TF {
DWORD call1;
DWORD call2;
DWORD call3;
} TF_t;
typedef struct Pyq {
DWORD hook;
DWORD call;
DWORD call1;
DWORD call2;
DWORD call3;
DWORD start;
DWORD end;
DWORD ts;
DWORD wxid;
DWORD content;
DWORD xml;
DWORD step;
} Pyq_t;
typedef struct DlAttach {
DWORD call1;
DWORD call2;
DWORD call3;
DWORD call4;
DWORD call5;
DWORD call6;
} DlAttach_t;
typedef struct RevokeMsg {
DWORD call1;
DWORD call2;
DWORD call3;
DWORD call4;
DWORD call5;
} RevokeMsg_t;
typedef struct CallRichText {
DWORD call1;
DWORD call2;
DWORD call3;
DWORD call4;
} CallRichText_t;
typedef struct CallPatMsg {
DWORD call1;
} CallPatMsg_t;
typedef struct CallInviteCM {
DWORD call1;
DWORD call2;
DWORD call3;
DWORD call4;
DWORD call5;
DWORD call6;
DWORD call7;
DWORD call8;
} CallInviteCM_t;
typedef struct CallOcr {
DWORD call1;
DWORD call2;
DWORD call3;
} CallOcr_t;
typedef struct CallFm {
DWORD call1;
} CallFm_t;
typedef struct CallRfLoginQr {
DWORD call1;
DWORD call2;
DWORD url;
} CallRfLoginQr_t;
typedef struct WxCalls {
DWORD login; // 登录状态
UserInfoCall_t ui; // 用户信息
SendText_t sendText; // 发送消息
RecvMsg_t recvMsg; // 接收消息
Sendfile_t sendImg; // 发送图片
Sendfile_t sendFile; // 发送文件
Xml_t sendXml; // 发送XML
Sendfile_t sendEmo; // 发送表情
Contact_t contact; // 获取联系人
Sql_t sql; // 执行 SQL
NewFriend_t anf; // 通过好友申请
RoomMember_t arm; // 添加群成员
RoomMember_t drm; // 删除群成员
TF_t tf; // 接收转账
Pyq_t pyq; // 接收朋友圈消息
DlAttach_t da; // 下载资源(图片、文件、视频)
RevokeMsg_t rm; // 撤回消息
CallRichText_t rt; // 发送消息卡片
CallPatMsg_t pm; // 发送拍一拍消息
CallInviteCM_t irm; // 邀请群成员
CallOcr_t ocr; // OCR
CallFm_t fm; // 转发消息
CallRfLoginQr_t rlq; // 刷新登录二维码
} WxCalls_t;
struct WxString {
const wchar_t *wptr;

View File

@ -1,7 +1,9 @@
#pragma once
#pragma once
#include "Windows.h"
#include "spy_types.h"
#define SQLITE_OK 0 /* Successful result */
/* beginning-of-error-codes */

View File

@ -1,17 +1,20 @@
#include "user_info.h"
#include "load_calls.h"
#include "log.h"
#include "util.h"
extern WxCalls_t g_WxCalls;
extern UINT64 g_WeChatWinDllAddr;
#define OS_USER_HOME 0x5A7E190
#define OS_USER_WXID 0x5AB7FB8
#define OS_USER_NAME 0x5AB8098
#define OS_USER_MOBILE 0x5AB7FD8
static char home[MAX_PATH] = { 0 };
string GetHomePath()
{
if (home[0] == 0) {
string path = Wstring2String(GET_WSTRING(g_WeChatWinDllAddr + g_WxCalls.ui.home)) + "\\WeChat Files\\";
string path = Wstring2String(GET_WSTRING(g_WeChatWinDllAddr + OS_USER_HOME)) + "\\WeChat Files\\";
strncpy_s(home, path.c_str(), path.size());
}
@ -22,15 +25,15 @@ string GetSelfWxid()
{
UINT64 wxidType = 0;
try {
wxidType = GET_UINT64(g_WeChatWinDllAddr + g_WxCalls.ui.wxid + 0x18);
wxidType = GET_UINT64(g_WeChatWinDllAddr + OS_USER_WXID + 0x18);
if (wxidType == 0xF) {
return GET_STRING_FROM_P(g_WeChatWinDllAddr + g_WxCalls.ui.wxid);
return GET_STRING_FROM_P(g_WeChatWinDllAddr + OS_USER_WXID);
} else {
return GET_STRING(g_WeChatWinDllAddr + g_WxCalls.ui.wxid);
return GET_STRING(g_WeChatWinDllAddr + OS_USER_WXID);
}
} catch (...) {
LOG_ERROR("wxid type: {:#x}", wxidType);
LOG_BUFFER((uint8_t *)(g_WeChatWinDllAddr + g_WxCalls.ui.wxid), 20);
LOG_BUFFER((uint8_t *)(g_WeChatWinDllAddr + OS_USER_WXID), 20);
return "empty_wxid";
}
}
@ -41,14 +44,14 @@ UserInfo_t GetUserInfo()
ui.wxid = GetSelfWxid();
UINT64 nameType = GET_UINT64(g_WeChatWinDllAddr + g_WxCalls.ui.nickName + 0x18);
UINT64 nameType = GET_UINT64(g_WeChatWinDllAddr + OS_USER_NAME + 0x18);
if (nameType == 0xF) {
ui.name = GET_STRING_FROM_P(g_WeChatWinDllAddr + g_WxCalls.ui.nickName);
ui.name = GET_STRING_FROM_P(g_WeChatWinDllAddr + OS_USER_NAME);
} else { // 0x1F
ui.name = GET_STRING(g_WeChatWinDllAddr + g_WxCalls.ui.nickName);
ui.name = GET_STRING(g_WeChatWinDllAddr + OS_USER_NAME);
}
ui.mobile = GET_STRING_FROM_P(g_WeChatWinDllAddr + g_WxCalls.ui.mobile);
ui.mobile = GET_STRING_FROM_P(g_WeChatWinDllAddr + OS_USER_MOBILE);
ui.home = GetHomePath();
return ui;