WeChatFerry/spy/receive_msg.cpp

175 lines
5.1 KiB
C++
Raw Normal View History

2022-10-15 20:25:42 +08:00
#pragma execution_character_set("utf-8")
2023-02-16 22:04:31 +08:00
2023-02-19 05:34:10 +08:00
#include "framework.h"
2023-02-26 23:07:04 +08:00
#include <condition_variable>
#include <mutex>
2023-02-19 05:34:10 +08:00
#include <queue>
#include "load_calls.h"
2023-02-16 22:04:31 +08:00
#include "receive_msg.h"
2023-04-10 23:39:57 +08:00
#include "user_info.h"
2023-02-19 05:34:10 +08:00
#include "util.h"
// Defined in rpc_server.cpp
extern bool gIsListening;
2023-02-26 23:07:04 +08:00
extern mutex gMutex;
extern condition_variable gCV;
2023-02-19 05:34:10 +08:00
extern queue<WxMsg_t> gMsgQueue;
// Defined in spy.cpp
extern WxCalls_t g_WxCalls;
extern DWORD g_WeChatWinDllAddr;
static DWORD reg_buffer = 0;
static DWORD recvMsgHookAddr = 0;
static DWORD recvMsgCallAddr = 0;
static DWORD recvMsgJumpBackAddr = 0;
static CHAR recvMsgBackupCode[5] = { 0 };
2023-02-16 22:04:31 +08:00
MsgTypes_t GetMsgTypes()
{
2023-05-24 22:01:31 +08:00
const MsgTypes_t m = {
{ 0x01, "文字" },
{ 0x03, "图片" },
{ 0x22, "语音" },
{ 0x25, "好友确认" },
{ 0x28, "POSSIBLEFRIEND_MSG" },
{ 0x2A, "名片" },
{ 0x2B, "视频" },
{ 0x2F, "石头剪刀布 | 表情图片" },
{ 0x30, "位置" },
{ 0x31, "共享实时位置、文件、转账、链接" },
{ 0x32, "VOIPMSG" },
{ 0x33, "微信初始化" },
{ 0x34, "VOIPNOTIFY" },
{ 0x35, "VOIPINVITE" },
{ 0x3E, "小视频" },
{ 0x42, "微信红包" },
{ 0x270F, "SYSNOTICE" },
{ 0x2710, "红包、系统消息" },
{ 0x2712, "撤回消息" },
{ 0x100031, "搜狗表情" },
{ 0x1000031, "链接" },
{ 0x1A000031, "微信红包" },
{ 0x20010031, "红包封面" },
{ 0x2D000031, "视频号视频" },
{ 0x2E000031, "视频号名片" },
{ 0x31000031, "引用消息" },
{ 0x37000031, "拍一拍" },
{ 0x3A000031, "视频号直播" },
{ 0x3A100031, "商品链接" },
{ 0x3A200031, "视频号直播" },
{ 0x3E000031, "音乐链接" },
{ 0x41000031, "文件" },
};
2023-02-16 22:04:31 +08:00
return m;
}
2022-08-13 08:13:56 +08:00
void HookAddress(DWORD hookAddr, LPVOID funcAddr, CHAR recvMsgBackupCode[5])
{
2023-02-16 22:04:31 +08:00
// 组装跳转数据
2022-08-13 08:13:56 +08:00
BYTE jmpCode[5] = { 0 };
2022-10-16 22:14:06 +08:00
jmpCode[0] = 0xE9;
2022-08-13 08:13:56 +08:00
2023-02-16 22:04:31 +08:00
// 计算偏移
2022-08-13 08:13:56 +08:00
*(DWORD *)&jmpCode[1] = (DWORD)funcAddr - hookAddr - 5;
// 备份原来的代码
ReadProcessMemory(GetCurrentProcess(), (LPVOID)hookAddr, recvMsgBackupCode, 5, 0);
// 写入新的代码
WriteProcessMemory(GetCurrentProcess(), (LPVOID)hookAddr, jmpCode, 5, 0);
}
void UnHookAddress(DWORD hookAddr, CHAR restoreCode[5])
{
WriteProcessMemory(GetCurrentProcess(), (LPVOID)hookAddr, restoreCode, 5, 0);
}
2021-02-12 23:21:57 +08:00
void DispatchMsg(DWORD reg)
{
2023-02-19 05:34:10 +08:00
WxMsg_t wxMsg;
2023-02-16 22:04:31 +08:00
DWORD *p = (DWORD *)reg; // 消息结构基址
2021-02-12 23:21:57 +08:00
2023-02-19 05:34:10 +08:00
wxMsg.type = GET_DWORD(*p + g_WxCalls.recvMsg.type);
wxMsg.is_self = GET_DWORD(*p + g_WxCalls.recvMsg.isSelf);
wxMsg.id = GetStringByAddress(*p + g_WxCalls.recvMsg.msgId);
wxMsg.xml = GetStringByAddress(*p + g_WxCalls.recvMsg.msgXml);
2021-02-12 23:21:57 +08:00
2023-04-30 11:26:09 +08:00
string roomid = GetStringByAddress(*p + g_WxCalls.recvMsg.roomId);
if (roomid.find("@chatroom") != string::npos) { // 群 ID 的格式为 xxxxxxxxxxx@chatroom
2023-02-19 05:34:10 +08:00
wxMsg.is_group = true;
2023-04-30 11:26:09 +08:00
wxMsg.roomid = roomid;
if (wxMsg.is_self) {
wxMsg.sender = GetSelfWxid();
} else {
wxMsg.sender = GetStringByAddress(*p + g_WxCalls.recvMsg.wxId);
}
2022-09-24 16:48:48 +08:00
} else {
2023-02-19 05:34:10 +08:00
wxMsg.is_group = false;
2023-04-30 11:26:09 +08:00
if (wxMsg.is_self) {
wxMsg.sender = GetSelfWxid();
} else {
wxMsg.sender = roomid;
}
2022-08-07 15:03:17 +08:00
}
2023-04-11 16:12:02 +08:00
2023-04-30 11:26:09 +08:00
wxMsg.content = GetStringByAddress(*p + g_WxCalls.recvMsg.content);
wxMsg.thumb = GetStringByAddress(*p + g_WxCalls.recvMsg.thumb);
2023-04-11 16:12:02 +08:00
if (!wxMsg.thumb.empty()) {
wxMsg.thumb = GetHomePath() + "\\WeChat Files\\" + wxMsg.thumb;
}
2023-04-11 21:53:50 +08:00
wxMsg.extra = GetStringByAddress(*p + g_WxCalls.recvMsg.extra);
2023-04-10 23:39:57 +08:00
if (!wxMsg.extra.empty()) {
2023-04-11 16:12:02 +08:00
wxMsg.extra = GetHomePath() + "\\WeChat Files\\" + wxMsg.extra;
2023-04-10 23:39:57 +08:00
}
2022-10-15 20:25:42 +08:00
2023-02-26 23:07:04 +08:00
{
unique_lock<mutex> lock(gMutex);
gMsgQueue.push(wxMsg); // 推送到队列
}
2022-10-15 20:25:42 +08:00
2023-02-26 23:07:04 +08:00
gCV.notify_all(); // 通知各方消息就绪
2021-02-12 23:21:57 +08:00
}
2022-08-13 08:13:56 +08:00
__declspec(naked) void RecieveMsgFunc()
2021-02-12 23:21:57 +08:00
{
__asm {
2023-02-16 22:04:31 +08:00
mov reg_buffer, edi // 把值复制出来
2021-02-12 23:21:57 +08:00
}
DispatchMsg(reg_buffer);
__asm
{
2022-10-16 22:14:06 +08:00
call recvMsgCallAddr // 这个为被覆盖的call
2021-02-12 23:21:57 +08:00
jmp recvMsgJumpBackAddr // 跳回被HOOK指令的下一条指令
}
}
void ListenMessage()
{
2023-02-19 05:34:10 +08:00
// OutputDebugString(L"ListenMessage\n");
2021-02-12 23:21:57 +08:00
// MessageBox(NULL, L"ListenMessage", L"ListenMessage", 0);
2022-10-15 20:25:42 +08:00
if (gIsListening || (g_WeChatWinDllAddr == 0)) {
2021-02-12 23:21:57 +08:00
return;
}
2022-10-16 22:14:06 +08:00
recvMsgHookAddr = g_WeChatWinDllAddr + g_WxCalls.recvMsg.hook;
recvMsgCallAddr = g_WeChatWinDllAddr + g_WxCalls.recvMsg.call;
2022-08-13 08:13:56 +08:00
recvMsgJumpBackAddr = recvMsgHookAddr + 5;
2021-02-12 23:21:57 +08:00
2022-08-13 08:13:56 +08:00
HookAddress(recvMsgHookAddr, RecieveMsgFunc, recvMsgBackupCode);
2022-10-15 20:25:42 +08:00
gIsListening = true;
2022-08-13 08:13:56 +08:00
}
2021-02-12 23:21:57 +08:00
2022-08-13 08:13:56 +08:00
void UnListenMessage()
{
2022-10-15 20:25:42 +08:00
if (!gIsListening) {
2022-08-13 08:13:56 +08:00
return;
}
UnHookAddress(recvMsgHookAddr, recvMsgBackupCode);
2022-10-15 20:25:42 +08:00
gIsListening = false;
2022-08-06 17:26:32 +08:00
}