diff --git a/Rpc/rpc.idl b/Rpc/rpc.idl index 2ec1d8d..3b55c2a 100644 --- a/Rpc/rpc.idl +++ b/Rpc/rpc.idl @@ -23,13 +23,26 @@ interface ISpy int key; BSTR value; } RpcIntBstrPair_t; - typedef RpcIntBstrPair_t* PRpcIntBstrPair_t; - typedef RpcIntBstrPair_t** PPRpcIntBstrPair_t; + typedef RpcIntBstrPair_t* PRpcIntBstrPair; + typedef RpcIntBstrPair_t** PPRpcIntBstrPair; + + typedef struct RpcContact { + BSTR wxId; + BSTR wxCode; + BSTR wxName; + BSTR wxCountry; + BSTR wxProvince; + BSTR wxCity; + BSTR wxGender; + } RpcContact_t; + typedef RpcContact_t *PRpcContact; + typedef RpcContact_t **PPRpcContact; 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); - int GetMsgTypes([ out ] int *pNum, [ out, size_is(, *pNum) ] PPRpcIntBstrPair_t *msgTypes); + int GetMsgTypes([ out ] int *pNum, [ out, size_is(, *pNum) ] PPRpcIntBstrPair *msgTypes); + int GetContacts([ out ] int *pNum, [ out, size_is(, *pNum) ] PPRpcContact *contacts); void EnableReceiveMsg(); [callback] int ReceiveMsg([ in ] RpcMessage_t rpcMsg); diff --git a/SDK/rpc_client.cpp b/SDK/rpc_client.cpp index c6d247d..06beb8f 100644 --- a/SDK/rpc_client.cpp +++ b/SDK/rpc_client.cpp @@ -1,6 +1,6 @@ -#include "sdk.h" +#include "rpc_client.h" +#include "sdk.h" #include "util.h" -#include "rpc_client.h" #pragma comment(lib, "Rpcrt4.lib") @@ -113,13 +113,13 @@ int RpcSendImageMsg(const wchar_t *wxid, const wchar_t *path) return ret; } -PPRpcIntBstrPair_t RpcGetMsgTypes(int *pNum) +PPRpcIntBstrPair RpcGetMsgTypes(int *pNum) { - int ret = 0; - unsigned long ulCode = 0; - PPRpcIntBstrPair_t ppRpcMsgTypes = NULL; + int ret = 0; + unsigned long ulCode = 0; + PPRpcIntBstrPair ppRpcMsgTypes = NULL; - RpcTryExcept{ ret = client_GetMsgTypes(pNum, &ppRpcMsgTypes); } + RpcTryExcept { ret = client_GetMsgTypes(pNum, &ppRpcMsgTypes); } RpcExcept(1) { ulCode = RpcExceptionCode(); @@ -134,6 +134,27 @@ PPRpcIntBstrPair_t RpcGetMsgTypes(int *pNum) return ppRpcMsgTypes; } +PPRpcContact RpcGetContacts(int *pNum) +{ + int ret = 0; + unsigned long ulCode = 0; + PPRpcContact ppRpcContacts = NULL; + + RpcTryExcept { ret = client_GetContacts(pNum, &ppRpcContacts); } + RpcExcept(1) + { + ulCode = RpcExceptionCode(); + printf("RpcGetContacts exception 0x%lx = %ld\n", ulCode, ulCode); + } + RpcEndExcept; + if (ret != 0) { + printf("GetContacts Failed: %d\n", ret); + return NULL; + } + + return ppRpcContacts; +} + int server_ReceiveMsg(RpcMessage_t rpcMsg) { WxMessage_t msg; diff --git a/SDK/rpc_client.h b/SDK/rpc_client.h index 5587f99..800d02c 100644 --- a/SDK/rpc_client.h +++ b/SDK/rpc_client.h @@ -9,4 +9,5 @@ unsigned int __stdcall RpcSetTextMsgCb(void *p); int RpcIsLogin(); int RpcSendTextMsg(const wchar_t *wxid, const wchar_t *at_wxid, const wchar_t *msg); int RpcSendImageMsg(const wchar_t *wxid, const wchar_t *path); -RpcIntBstrPair_t** RpcGetMsgTypes(int *pNum); +PPRpcIntBstrPair RpcGetMsgTypes(int *pNum); +PPRpcContact RpcGetContacts(int *pNum); diff --git a/SDK/sdk.cpp b/SDK/sdk.cpp index 0af3228..de7e39f 100644 --- a/SDK/sdk.cpp +++ b/SDK/sdk.cpp @@ -128,60 +128,46 @@ static int getAddrHandle(DWORD *addr, HANDLE *handle) return 0; } +MsgTypesMap_t WxGetMsgTypes() +{ + static MsgTypesMap_t WxMsgTypes; + if (WxMsgTypes.empty()) { + int size = 0; + PPRpcIntBstrPair pp = RpcGetMsgTypes(&size); + for (int i = 0; i < size; i++) { + WxMsgTypes.insert(make_pair(pp[i]->key, GetWstringFromBstr(pp[i]->value))); + midl_user_free(pp[i]); + } + if (pp) { + midl_user_free(pp); + } + } + + return WxMsgTypes; +} + ContactMap_t WxGetContacts() { ContactMap_t mContact; - DWORD moduleBaseAddress; - HANDLE hProcess; + int size = 0; + PPRpcContact pp = RpcGetContacts(&size); + for (int i = 0; i < size; i++) { + WxContact_t contact; + contact.wxId = GetWstringFromBstr(pp[i]->wxId); + contact.wxCode = GetWstringFromBstr(pp[i]->wxCode); + contact.wxName = GetWstringFromBstr(pp[i]->wxName); + contact.wxCountry = GetWstringFromBstr(pp[i]->wxCountry); + contact.wxProvince = GetWstringFromBstr(pp[i]->wxProvince); + contact.wxCity = GetWstringFromBstr(pp[i]->wxCity); + contact.wxGender = GetWstringFromBstr(pp[i]->wxGender); - if (getAddrHandle(&moduleBaseAddress, &hProcess) != 0) { - return mContact; - } - printf("WxGetContacts\n"); - DWORD baseAddr = moduleBaseAddress + 0x23638F4; - DWORD tempAddr = GetMemoryIntByAddress(hProcess, baseAddr); - DWORD head = GetMemoryIntByAddress(hProcess, tempAddr + 0x4C); - DWORD node = GetMemoryIntByAddress(hProcess, head); - - while (node != head) { - WxContact_t contactItem; - contactItem.wxId = GetUnicodeInfoByAddress(hProcess, node + 0x30); - contactItem.wxCode = GetUnicodeInfoByAddress(hProcess, node + 0x44); - contactItem.wxName = GetUnicodeInfoByAddress(hProcess, node + 0x8C); - contactItem.wxCountry = GetUnicodeInfoByAddress(hProcess, node + 0x1D0); - contactItem.wxProvince = GetUnicodeInfoByAddress(hProcess, node + 0x1E4); - contactItem.wxCity = GetUnicodeInfoByAddress(hProcess, node + 0x1F8); - DWORD gender = GetMemoryIntByAddress(hProcess, node + 0x184); - - if (gender == 1) - contactItem.wxGender = L"男"; - else if (gender == 2) - contactItem.wxGender = L"女"; - else - contactItem.wxGender = L"未知"; - - mContact.insert(make_pair(contactItem.wxId, contactItem)); - node = GetMemoryIntByAddress(hProcess, node); + mContact.insert(make_pair(contact.wxId, contact)); + midl_user_free(pp[i]); } - CloseHandle(hProcess); + if (pp) { + midl_user_free(pp); + } return mContact; } - -MsgTypesMap_t WxGetMsgTypes() -{ - static MsgTypesMap_t WxMsgTypes; - if (WxMsgTypes.empty()) { - int size = 0; - PPRpcIntBstrPair_t pp = RpcGetMsgTypes(&size); - for (int i = 0; i < size; i++) { - WxMsgTypes.insert(make_pair(pp[i]->key, GetWstringFromBstr(pp[i]->value))); - midl_user_free(pp[i]); - } - midl_user_free(pp); - } - - return WxMsgTypes; -} - diff --git a/SDK/util.cpp b/SDK/util.cpp index e153ea8..61100be 100644 --- a/SDK/util.cpp +++ b/SDK/util.cpp @@ -167,12 +167,20 @@ 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)); } +BSTR GetBstrByAddress(DWORD address) +{ + wchar_t *p = GET_WSTRING(address); + if (p == NULL) { + return NULL; + } + + return SysAllocStringLen(GET_WSTRING(address), GET_DWORD(address + 4)); +} wstring GetWstringFromBstr(BSTR p) { wstring ws = L""; - if (p != nullptr) { + if (p != NULL) { ws = wstring(p); SysFreeString(p); } diff --git a/Spy/Spy.vcxproj b/Spy/Spy.vcxproj index 28b3413..4ca44e3 100644 --- a/Spy/Spy.vcxproj +++ b/Spy/Spy.vcxproj @@ -166,6 +166,7 @@ + @@ -178,6 +179,7 @@ + diff --git a/Spy/Spy.vcxproj.filters b/Spy/Spy.vcxproj.filters index d756e4f..be1f776 100644 --- a/Spy/Spy.vcxproj.filters +++ b/Spy/Spy.vcxproj.filters @@ -45,6 +45,9 @@ 头文件 + + 头文件 + @@ -74,6 +77,9 @@ 源文件 + + 源文件 + diff --git a/Spy/get_contacts.cpp b/Spy/get_contacts.cpp new file mode 100644 index 0000000..5f43cc5 --- /dev/null +++ b/Spy/get_contacts.cpp @@ -0,0 +1,39 @@ +#include "get_contacts.h" +#include "load_calls.h" +#include "util.h" + +extern WxCalls_t g_WxCalls; +extern DWORD g_WeChatWinDllAddr; + +std::vector GetContacts() +{ + int gender = 0; + vector vContacts; + DWORD baseAddr = g_WeChatWinDllAddr + 0x23638F4; + DWORD tempAddr = GET_DWORD(baseAddr); + DWORD head = GET_DWORD(tempAddr + 0x4C); + DWORD node = GET_DWORD(head); + + while (node != head) { + RpcContact_t rpcContact = { 0 }; + rpcContact.wxId = GetBstrByAddress(node + 0x30); + rpcContact.wxCode = GetBstrByAddress(node + 0x44); + rpcContact.wxName = GetBstrByAddress(node + 0x8C); + rpcContact.wxCountry = GetBstrByAddress(node + 0x1D0); + rpcContact.wxProvince = GetBstrByAddress(node + 0x1E4); + rpcContact.wxCity = GetBstrByAddress(node + 0x1F8); + + gender = GET_DWORD(node + 0x184); + if (gender == 1) + rpcContact.wxGender = SysAllocString(L"男"); + else if (gender == 2) + rpcContact.wxGender = SysAllocString(L"女"); + else + rpcContact.wxGender = SysAllocString(L"未知"); + + vContacts.push_back(rpcContact); + node = GET_DWORD(node); + } + + return vContacts; +} diff --git a/Spy/get_contacts.h b/Spy/get_contacts.h new file mode 100644 index 0000000..5662225 --- /dev/null +++ b/Spy/get_contacts.h @@ -0,0 +1,7 @@ +#pragma once + +#include + +#include "rpc_h.h" + +std::vector GetContacts(); diff --git a/Spy/rpc_server.cpp b/Spy/rpc_server.cpp index 9c340d8..344b34d 100644 --- a/Spy/rpc_server.cpp +++ b/Spy/rpc_server.cpp @@ -1,18 +1,19 @@ -#include +#include #include +#include "get_contacts.h" #include "monitor.h" #include "rpc_server.h" -#include "send_msg.h" -#include "spy_types.h" #include "sdk.h" +#include "send_msg.h" +#include "spy_types.h" #include "rpc_h.h" -#pragma comment(lib, "Rpcrt4.lib") +#pragma comment(lib, "Rpcrt4.lib") extern HANDLE g_hEvent; extern MsgQueue_t g_MsgQueue; -extern const MsgTypesMap_t g_WxMsgTypes; +extern const MsgTypesMap_t g_WxMsgTypes; int server_IsLogin() { return IsLogin(); } @@ -54,32 +55,67 @@ int server_SendImageMsg(const wchar_t *wxid, const wchar_t *path) return 0; } - -int server_GetMsgTypes(int *pNum, PPRpcIntBstrPair_t *msgTypes) + +int server_GetMsgTypes(int *pNum, PPRpcIntBstrPair *msgTypes) { - *pNum = g_WxMsgTypes.size(); - PPRpcIntBstrPair_t pp = (PPRpcIntBstrPair_t)midl_user_allocate(*pNum * sizeof(RpcIntBstrPair_t)); + *pNum = g_WxMsgTypes.size(); + PPRpcIntBstrPair pp = (PPRpcIntBstrPair)midl_user_allocate(*pNum * sizeof(RpcIntBstrPair_t)); if (pp == NULL) { printf("server_GetMsgTypes midl_user_allocate Failed for pp\n"); return -2; - } - int index = 0; - for (auto it = g_WxMsgTypes.begin(); it != g_WxMsgTypes.end(); ++it) { - PRpcIntBstrPair_t p = (PRpcIntBstrPair_t)midl_user_allocate(sizeof(RpcIntBstrPair_t)); + } + int index = 0; + for (auto it = g_WxMsgTypes.begin(); it != g_WxMsgTypes.end(); it++) { + PRpcIntBstrPair p = (PRpcIntBstrPair)midl_user_allocate(sizeof(RpcIntBstrPair_t)); if (p == NULL) { printf("server_GetMsgTypes midl_user_allocate Failed for p\n"); return -3; - } + } - p->key = it->first; - p->value = SysAllocString(it->second.c_str()); + p->key = it->first; + p->value = SysAllocString(it->second.c_str()); pp[index++] = p; - } - - *msgTypes = pp; - + } + + *msgTypes = pp; + return 0; -} +} + +int server_GetContacts(int *pNum, PPRpcContact *contacts) +{ + std::vector vContacts = GetContacts(); + + *pNum = vContacts.size(); + PPRpcContact pp = (PPRpcContact)midl_user_allocate(*pNum * sizeof(RpcContact_t)); + if (pp == NULL) { + printf("server_GetMsgTypes midl_user_allocate Failed for pp\n"); + return -2; + } + + int index = 0; + for (auto it = vContacts.begin(); it != vContacts.end(); it++) { + PRpcContact p = (PRpcContact)midl_user_allocate(sizeof(RpcContact_t)); + if (p == NULL) { + printf("server_GetMsgTypes midl_user_allocate Failed for p\n"); + return -3; + } + + p->wxId = it->wxId; + p->wxCode = it->wxCode; + p->wxName = it->wxName; + p->wxCountry = it->wxCountry; + p->wxProvince = it->wxProvince; + p->wxCity = it->wxCity; + p->wxGender = it->wxGender; + + pp[index++] = p; + } + + *contacts = pp; + + return 0; +} RPC_STATUS CALLBACK SecurityCallback(RPC_IF_HANDLE /*hInterface*/, void * /*pBindingHandle*/) {