From 19f6854b738f9fb669738a155529706c6ad6e7bf Mon Sep 17 00:00:00 2001 From: Changhua Date: Sun, 7 Aug 2022 15:03:17 +0800 Subject: [PATCH] Refine RPC --- Rpc/rpc.idl | 17 +++++++++++--- Rpc/rpc_types.h | 13 +---------- SDK/sdk.cpp | 55 +++++++++------------------------------------ SDK/util.cpp | 39 ++++++++++++++++++++++++-------- SDK/util.h | 11 ++++++--- Spy/receive_msg.cpp | 34 ++++++++++++++-------------- Spy/rpc_server.cpp | 4 ++-- Spy/spy_types.h | 4 ++-- 8 files changed, 85 insertions(+), 92 deletions(-) diff --git a/Rpc/rpc.idl b/Rpc/rpc.idl index 50d0893..0cd4ef8 100644 --- a/Rpc/rpc.idl +++ b/Rpc/rpc.idl @@ -5,13 +5,24 @@ ] interface ISpy -{ - import "rpc_types.h"; +{ + import "oaidl.idl"; + + typedef struct RpcMessage { + int self; // 是否自己发的消息:0=否,1=是 + int type; // 消息类型 + int source; // 消息来源:0=好友消息,1=群消息 + BSTR id; // 消息ID + BSTR xml; // 群其他消息 + BSTR wxId; // 发送人微信ID + BSTR roomId; // 群ID + BSTR content; // 消息内容,MAC版最大:16384,即16KB + } RpcMessage_t; int IsLogin(); int SendTextMsg([ in, string ] const wchar_t *wxid, [ in, string ] const wchar_t *at_wxid, [ in, string ] const wchar_t *msg); int SendImageMsg([ in, string ] const wchar_t *wxid, [ in, string ] const wchar_t *path); void EnableReceiveMsg(); - [callback] int ReceiveMsg([ in ] RpcMessage_t *msg); + [callback] int ReceiveMsg([ in ] RpcMessage_t rpcMsg); }; diff --git a/Rpc/rpc_types.h b/Rpc/rpc_types.h index b897a96..d4ad805 100644 --- a/Rpc/rpc_types.h +++ b/Rpc/rpc_types.h @@ -1,18 +1,7 @@ -#pragma once +#pragma once #define MSG_SIZE_MSG_ID 64 #define MSG_SIZE_MSG_XML 4096 #define MSG_SIZE_WXID 64 #define MSG_SIZE_ROOMID 64 #define MSG_SIZE_CONTENT 16385 - -typedef struct RpcMessage { - int self; // 是否自己发的消息:0=否,1=是 - int type; // 消息类型 - int source; // 消息来源:0=好友消息,1=群消息 - wchar_t id[MSG_SIZE_MSG_ID]; // 消息ID - wchar_t xml[MSG_SIZE_MSG_XML]; // 群其他消息 - wchar_t wxId[MSG_SIZE_WXID]; // 发送人微信ID - wchar_t roomId[MSG_SIZE_ROOMID]; // 群ID - wchar_t content[MSG_SIZE_CONTENT]; // 消息内容,MAC版最大:16384,即16KB -} RpcMessage_t; diff --git a/SDK/sdk.cpp b/SDK/sdk.cpp index 9d45954..2c7d1cb 100644 --- a/SDK/sdk.cpp +++ b/SDK/sdk.cpp @@ -15,8 +15,6 @@ #include "sdk.h" #include "util.h" -static HANDLE hEvent; -static std::queue MsgQueue; static RPC_WSTR pszStringBinding = NULL; static std::function cbReceiveTextMsg; static const MsgTypesMap_t WxMsgTypes = MsgTypesMap_t { { 0x01, L"文字" }, @@ -121,37 +119,6 @@ int WxInitSDK() return ERROR_SUCCESS; } -static unsigned int __stdcall waitForMsg(void *p) -{ - RpcMessage_t *rpcMsg; - while (true) { - // 中断式,兼顾及时性和CPU使用率 - WaitForSingleObject(hEvent, INFINITE); // 等待消息 - while (!MsgQueue.empty()) { - rpcMsg = (RpcMessage_t *)&MsgQueue.front(); - WxMessage_t msg; - msg.id = wstring(rpcMsg->id); - msg.self = rpcMsg->self; - msg.type = rpcMsg->type; - msg.source = rpcMsg->source; - msg.xml = wstring(rpcMsg->xml); - msg.wxId = wstring(rpcMsg->wxId); - msg.roomId = wstring(rpcMsg->roomId); - msg.content = wstring(rpcMsg->content); - - try { - cbReceiveTextMsg(msg); // 调用接收消息回调 - } catch (...) { - printf("callback error...\n"); - } - MsgQueue.pop(); - } - ResetEvent(hEvent); - } - - return 0; -} - static unsigned int __stdcall innerWxSetTextMsgCb(void *p) { unsigned long ulCode = 0; @@ -175,13 +142,6 @@ int WxSetTextMsgCb(const std::function &onMsg) if (onMsg) { HANDLE msgThread; cbReceiveTextMsg = onMsg; - hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - msgThread = (HANDLE)_beginthreadex(NULL, 0, waitForMsg, NULL, 0, NULL); - if (msgThread == NULL) { - printf("Failed to create message listening thread.\n"); - return -2; - } - CloseHandle(msgThread); msgThread = (HANDLE)_beginthreadex(NULL, 0, innerWxSetTextMsgCb, NULL, 0, NULL); if (msgThread == NULL) { @@ -197,10 +157,17 @@ int WxSetTextMsgCb(const std::function &onMsg) return -1; } -int server_ReceiveMsg(RpcMessage_t *rpcMsg) -{ - MsgQueue.push(*rpcMsg); // 发送消息 - SetEvent(hEvent); // 发送消息通知 +int server_ReceiveMsg(RpcMessage_t rpcMsg) +{ + WxMessage_t msg; + GetRpcMessage(&msg, rpcMsg); + try { + cbReceiveTextMsg(msg); // 调用接收消息回调 + } + catch (...) { + printf("callback error...\n"); + } + return 0; } diff --git a/SDK/util.cpp b/SDK/util.cpp index 0d8a96e..2445bb0 100644 --- a/SDK/util.cpp +++ b/SDK/util.cpp @@ -58,7 +58,7 @@ int GetWeChatWinDLLPath(wchar_t *path) // 微信从(大约)3.7开始,增加了一层版本目录: [3.7.0.29] PathRemoveFileSpec(path); _wfinddata_t findData; - wstring dir = wstring(path) + L"\\[*.*"; + wstring dir = wstring(path) + L"\\[*.*"; intptr_t handle = _wfindfirst(dir.c_str(), &findData); if (handle == -1) { // 检查是否成功 return -1; @@ -66,7 +66,7 @@ int GetWeChatWinDLLPath(wchar_t *path) wstring dllPath = wstring(path) + L"\\" + findData.name; wcscpy_s(path, MAX_PATH, dllPath.c_str()); PathAppend(path, WECHATWINDLL); - } + } return ret; } @@ -133,17 +133,16 @@ int OpenWeChat(DWORD *pid) { int ret = -1; STARTUPINFO si = { sizeof(si) }; + WCHAR Path[MAX_PATH] = { 0 }; PROCESS_INFORMATION pi = { 0 }; - WCHAR Path[MAX_PATH] = { 0 }; - ret = GetWeChatPath(Path); + ret = GetWeChatPath(Path); if (ERROR_SUCCESS != ret) { return ret; } if (!CreateProcess(NULL, Path, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) { - ret = GetLastError(); - return ret; + return GetLastError(); } CloseHandle(pi.hThread); @@ -151,9 +150,7 @@ int OpenWeChat(DWORD *pid) *pid = pi.dwProcessId; - ret = ERROR_SUCCESS; - - return ret; + return ERROR_SUCCESS; } int GetWstringByAddress(DWORD address, wchar_t *buffer, DWORD buffer_size) @@ -170,6 +167,30 @@ int GetWstringByAddress(DWORD address, wchar_t *buffer, DWORD buffer_size) return strLength; } +BSTR GetBstrByAddress(DWORD address) { return SysAllocStringLen(GET_WSTRING(address), GET_DWORD(address + 4)); } + +static wstring GetWstringFromBstr(BSTR p) +{ + wstring ret = L""; + if (p != nullptr) { + ret = wstring(p); + SysFreeString(p); + } + return ret; +} + +void GetRpcMessage(WxMessage_t *wxMsg, RpcMessage_t rpcMsg) +{ + wxMsg->self = rpcMsg.self; + wxMsg->type = rpcMsg.type; + wxMsg->source = rpcMsg.source; + wxMsg->id = GetWstringFromBstr(rpcMsg.id); + wxMsg->xml = GetWstringFromBstr(rpcMsg.xml); + wxMsg->wxId = GetWstringFromBstr(rpcMsg.wxId); + wxMsg->roomId = GetWstringFromBstr(rpcMsg.roomId); + wxMsg->content = GetWstringFromBstr(rpcMsg.content); +} + DWORD GetMemoryIntByAddress(HANDLE hProcess, DWORD address) { DWORD value = 0; diff --git a/SDK/util.h b/SDK/util.h index 19084e1..c61a6b1 100644 --- a/SDK/util.h +++ b/SDK/util.h @@ -1,6 +1,9 @@ -#pragma once +#pragma once -#include +#include + +#include "sdk.h" +#include "rpc_h.h" #define WECHAREXE L"WeChat.exe" #define WECHATWINDLL L"WeChatWin.dll" @@ -16,6 +19,8 @@ int GetWeChatPath(wchar_t *path); int GetWeChatWinDLLPath(wchar_t *path); int GetWeChatVersion(wchar_t *version); bool GetFileVersion(const wchar_t *filePath, wchar_t *version); -int GetWstringByAddress(DWORD address, wchar_t *buffer, DWORD buffer_size); +int GetWstringByAddress(DWORD address, wchar_t *buffer, DWORD buffer_size); +BSTR GetBstrByAddress(DWORD address); +void GetRpcMessage(WxMessage_t *wxMsg, RpcMessage_t rpcMsg); DWORD GetMemoryIntByAddress(HANDLE hProcess, DWORD address); std::wstring GetUnicodeInfoByAddress(HANDLE hProcess, DWORD address); diff --git a/Spy/receive_msg.cpp b/Spy/receive_msg.cpp index ce21af1..714b09d 100644 --- a/Spy/receive_msg.cpp +++ b/Spy/receive_msg.cpp @@ -1,4 +1,4 @@ -#include "framework.h" +#include "framework.h" #include "load_calls.h" #include "receive_msg.h" @@ -14,30 +14,31 @@ MsgQueue_t g_MsgQueue; DWORD reg_buffer = 0; DWORD recvMsgCallAddr = 0; DWORD recvMsgJumpBackAddr = 0; -RpcMessage_t *pMsg = NULL; // Find a palce to free +RpcMessage_t lMsg = { 0 }; void DispatchMsg(DWORD reg) { - DWORD *p = (DWORD *)reg; //消息结构基址 + DWORD* p = (DWORD*)reg; //消息结构基址 - memset(pMsg, 0, sizeof(RpcMessage_t)); + memset(&lMsg, 0, sizeof(RpcMessage_t)); - pMsg->type = GET_DWORD(*p + g_WxCalls.recvMsg.type); - pMsg->self = GET_DWORD(*p + g_WxCalls.recvMsg.isSelf); + lMsg.type = GET_DWORD(*p + g_WxCalls.recvMsg.type); + lMsg.self = GET_DWORD(*p + g_WxCalls.recvMsg.isSelf); + lMsg.id = GetBstrByAddress(*p + g_WxCalls.recvMsg.msgId); + lMsg.xml = GetBstrByAddress(*p + g_WxCalls.recvMsg.msgXml); - GetWstringByAddress(*p + g_WxCalls.recvMsg.msgId, pMsg->id, MSG_SIZE_MSG_ID); - GetWstringByAddress(*p + g_WxCalls.recvMsg.msgXml, pMsg->xml, MSG_SIZE_MSG_XML); - if (wcsstr(pMsg->xml, L"") == NULL) { + if (wcsstr(lMsg.xml, L"") == NULL) { // pMsg.roomId = {0}; - GetWstringByAddress(*p + g_WxCalls.recvMsg.roomId, pMsg->wxId, MSG_SIZE_WXID); - } else { - pMsg->source = 1; - GetWstringByAddress(*p + g_WxCalls.recvMsg.roomId, pMsg->roomId, MSG_SIZE_ROOMID); - GetWstringByAddress(*p + g_WxCalls.recvMsg.wxId, pMsg->wxId, MSG_SIZE_WXID); + lMsg.wxId = GetBstrByAddress(*p + g_WxCalls.recvMsg.roomId); } - GetWstringByAddress(*p + g_WxCalls.recvMsg.content, pMsg->content, MSG_SIZE_CONTENT); - g_MsgQueue.push(*pMsg); // 发送消息 + else { + lMsg.source = 1; + lMsg.wxId = GetBstrByAddress(*p + g_WxCalls.recvMsg.wxId); + lMsg.roomId = GetBstrByAddress(*p + g_WxCalls.recvMsg.roomId); + } + lMsg.content = GetBstrByAddress(*p + g_WxCalls.recvMsg.content); + g_MsgQueue.push(lMsg); // 发送消息 SetEvent(g_hEvent); // 发送消息通知 } @@ -63,7 +64,6 @@ void ListenMessage() return; } - pMsg = new RpcMessage_t; DWORD hookAddress = g_WeChatWinDllAddr + g_WxCalls.recvMsg.hook; recvMsgCallAddr = g_WeChatWinDllAddr + g_WxCalls.recvMsg.call; recvMsgJumpBackAddr = hookAddress + 5; diff --git a/Spy/rpc_server.cpp b/Spy/rpc_server.cpp index 932a155..daeed03 100644 --- a/Spy/rpc_server.cpp +++ b/Spy/rpc_server.cpp @@ -25,7 +25,7 @@ void server_EnableReceiveMsg() // 中断式,兼顾及时性和CPU使用率 WaitForSingleObject(g_hEvent, INFINITE); // 等待消息 while (!g_MsgQueue.empty()) { - client_ReceiveMsg((RpcMessage_t *)&g_MsgQueue.front()); // 调用接收消息回调 + client_ReceiveMsg(g_MsgQueue.front()); // 调用接收消息回调 g_MsgQueue.pop(); } ResetEvent(g_hEvent); @@ -34,7 +34,7 @@ void server_EnableReceiveMsg() RpcExcept(1) { ulCode = RpcExceptionCode(); - printf("Runtime reported exception 0x%lx = %ld\n", ulCode, ulCode); + printf("server_EnableReceiveMsg exception 0x%lx = %ld\n", ulCode, ulCode); } RpcEndExcept } diff --git a/Spy/spy_types.h b/Spy/spy_types.h index 3b2ee29..6c98504 100644 --- a/Spy/spy_types.h +++ b/Spy/spy_types.h @@ -3,7 +3,7 @@ #include "framework.h" #include -#include "rpc_types.h" +#include "rpc_h.h" typedef struct UserInfoCall { DWORD wxid; @@ -19,7 +19,7 @@ typedef struct RecvMsg { DWORD msgId; // 消息ID地址 DWORD msgXml; // 消息xml内容地址 DWORD roomId; // 群聊时,为群ID;私聊时,为微信ID - DWORD wxId; // 私聊时,为空;群群时,为发送者微信ID + DWORD wxId; // 私聊时,为空;群聊时,为发送者微信ID DWORD content; // 消息内容地址 } RecvMsg_t;