Impl get db names with sql

This commit is contained in:
Changhua 2022-08-07 23:32:25 +08:00
parent 99b42a2bb1
commit 1f5eae96de
16 changed files with 199 additions and 47 deletions

View File

@ -20,6 +20,14 @@ void printContacts(ContactMap_t contacts)
} }
} }
void printDbNames(vector<wstring> vDbs)
{
wprintf(L"db numbers: %ld\n", vDbs.size());
for (auto it = vDbs.begin(); it != vDbs.end(); ++it) {
wprintf(L"%s\n", (*it).c_str());
}
}
int onTextMsg(WxMessage_t msg) int onTextMsg(WxMessage_t msg)
{ {
wprintf(L"%s msgType: %d, msgSource: %d, isSelf: %d\n", msg.id.c_str(), msg.type, msg.source, msg.self); wprintf(L"%s msgType: %d, msgSource: %d, isSelf: %d\n", msg.id.c_str(), msg.type, msg.source, msg.self);
@ -71,6 +79,11 @@ int main()
// 测试获取联系人 // 测试获取联系人
auto mContact = WxGetContacts(); auto mContact = WxGetContacts();
printContacts(mContact); printContacts(mContact);
Sleep(1000); // 等待1秒
// 测试获取数据库名
auto vDbNames = WxGetDbNames();
printDbNames(vDbNames);
while (1) { while (1) {
Sleep(10000); // 休眠释放CPU Sleep(10000); // 休眠释放CPU

View File

@ -19,6 +19,7 @@ interface ISpy
BSTR content; // 消息内容MAC版最大16384即16KB BSTR content; // 消息内容MAC版最大16384即16KB
} RpcMessage_t; } RpcMessage_t;
// 模拟 map<int, wstring>
typedef struct RpcIntBstrPair { typedef struct RpcIntBstrPair {
int key; int key;
BSTR value; BSTR value;
@ -27,22 +28,24 @@ interface ISpy
typedef RpcIntBstrPair_t **PPRpcIntBstrPair; typedef RpcIntBstrPair_t **PPRpcIntBstrPair;
typedef struct RpcContact { typedef struct RpcContact {
BSTR wxId; BSTR wxId; // 微信ID
BSTR wxCode; BSTR wxCode; // 微信号
BSTR wxName; BSTR wxName; // 微信昵称
BSTR wxCountry; BSTR wxCountry; // 国家
BSTR wxProvince; BSTR wxProvince; // 省/州
BSTR wxCity; BSTR wxCity; // 城市
BSTR wxGender; BSTR wxGender; // 性别
} RpcContact_t; } RpcContact_t;
typedef RpcContact_t *PRpcContact; typedef RpcContact_t *PRpcContact;
typedef RpcContact_t **PPRpcContact; typedef RpcContact_t **PPRpcContact;
int IsLogin(); int IsLogin();
int SendTextMsg([ in, string ] const wchar_t *wxid, [ in, string ] const wchar_t *at_wxid, [ in, string ] const wchar_t *msg); 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 SendImageMsg([ in, string ] const wchar_t *wxid, [ in, string ] const wchar_t *path);
int GetMsgTypes([out] int *pNum, [ out, size_is(, *pNum) ] PPRpcIntBstrPair *msgTypes); int GetMsgTypes([out] int *pNum, [ out, size_is(, *pNum) ] PPRpcIntBstrPair *msgTypes);
int GetContacts([out] int *pNum, [ out, size_is(, *pNum) ] PPRpcContact *contacts); int GetContacts([out] int *pNum, [ out, size_is(, *pNum) ] PPRpcContact *contacts);
int GetDbNames([out] int *pNum, [ out, size_is(, *pNum) ] BSTR **dbs);
void EnableReceiveMsg(); void EnableReceiveMsg();
[callback] int ReceiveMsg([in] RpcMessage_t rpcMsg); [callback] int ReceiveMsg([in] RpcMessage_t rpcMsg);

View File

@ -153,6 +153,27 @@ PPRpcContact RpcGetContacts(int *pNum)
return ppRpcContacts; return ppRpcContacts;
} }
BSTR *RpcGetDbNames(int *pNum)
{
int ret = 0;
unsigned long ulCode = 0;
BSTR *pBstr = NULL;
RpcTryExcept { ret = client_GetDbNames(pNum, &pBstr); }
RpcExcept(1)
{
ulCode = RpcExceptionCode();
printf("RpcGetDbNames exception 0x%lx = %ld\n", ulCode, ulCode);
}
RpcEndExcept;
if (ret != 0) {
printf("RpcGetDbNames Failed: %d\n", ret);
return NULL;
}
return pBstr;
}
int server_ReceiveMsg(RpcMessage_t rpcMsg) int server_ReceiveMsg(RpcMessage_t rpcMsg)
{ {
WxMessage_t msg; WxMessage_t msg;

View File

@ -1,4 +1,4 @@
#pragma once #pragma once
#include "rpc_h.h" #include "rpc_h.h"
@ -11,3 +11,4 @@ int RpcSendTextMsg(const wchar_t *wxid, const wchar_t *at_wxid, const wchar_t *m
int RpcSendImageMsg(const wchar_t *wxid, const wchar_t *path); int RpcSendImageMsg(const wchar_t *wxid, const wchar_t *path);
PPRpcIntBstrPair RpcGetMsgTypes(int *pNum); PPRpcIntBstrPair RpcGetMsgTypes(int *pNum);
PPRpcContact RpcGetContacts(int *pNum); PPRpcContact RpcGetContacts(int *pNum);
BSTR *RpcGetDbNames(int *pNum);

View File

@ -171,3 +171,19 @@ ContactMap_t WxGetContacts()
return mContact; return mContact;
} }
std::vector<std::wstring> WxGetDbNames()
{
std::vector<std::wstring> vDbs;
int size = 0;
BSTR *pBstr = RpcGetDbNames(&size);
for (int i = 0; i < size; i++) {
vDbs.push_back(GetWstringFromBstr(pBstr[i]));
}
if (pBstr) {
midl_user_free(pBstr);
}
return vDbs;
}

View File

@ -1,7 +1,8 @@
EXPORTS EXPORTS
WxInitSDK WxInitSDK
WxSetTextMsgCb WxSetTextMsgCb
WxSendTextMsg WxSendTextMsg
WxGetMsgTypes WxGetMsgTypes
WxSendImageMsg WxSendImageMsg
WxGetContacts WxGetContacts
WxGetDbNames

View File

@ -3,6 +3,7 @@
#include <functional> #include <functional>
#include <map> #include <map>
#include <string> #include <string>
#include <vector>
using namespace std; using namespace std;
@ -18,13 +19,13 @@ typedef struct WxMessage {
} WxMessage_t; } WxMessage_t;
typedef struct WxContact { typedef struct WxContact {
wstring wxId; wstring wxId; // 微信ID
wstring wxCode; wstring wxCode; // 微信号
wstring wxName; wstring wxName; // 微信昵称
wstring wxCountry; wstring wxCountry; // 国家
wstring wxProvince; wstring wxProvince; // 省/州
wstring wxCity; wstring wxCity; // 城市
wstring wxGender; wstring wxGender; // 性别
} WxContact_t; } WxContact_t;
typedef map<int, wstring> MsgTypesMap_t; typedef map<int, wstring> MsgTypesMap_t;
@ -36,3 +37,4 @@ int WxSendTextMsg(wstring wxid, wstring at_wxid, wstring msg);
int WxSendImageMsg(wstring wxid, wstring path); int WxSendImageMsg(wstring wxid, wstring path);
ContactMap_t WxGetContacts(); ContactMap_t WxGetContacts();
MsgTypesMap_t WxGetMsgTypes(); MsgTypesMap_t WxGetMsgTypes();
vector<wstring> WxGetDbNames();

View File

@ -187,6 +187,14 @@ wstring GetWstringFromBstr(BSTR p)
return ws; return ws;
} }
BSTR GetBstrFromWstring(wstring ws)
{
if (!ws.empty()) {
return SysAllocStringLen(ws.data(), ws.size());
}
return NULL;
}
void GetRpcMessage(WxMessage_t *wxMsg, RpcMessage_t rpcMsg) void GetRpcMessage(WxMessage_t *wxMsg, RpcMessage_t rpcMsg)
{ {
wxMsg->self = rpcMsg.self; wxMsg->self = rpcMsg.self;

View File

@ -1,9 +1,9 @@
#pragma once #pragma once
#include <string> #include <string>
#include "sdk.h"
#include "rpc_h.h" #include "rpc_h.h"
#include "sdk.h"
#define WECHAREXE L"WeChat.exe" #define WECHAREXE L"WeChat.exe"
#define WECHATWINDLL L"WeChatWin.dll" #define WECHATWINDLL L"WeChatWin.dll"
@ -24,4 +24,5 @@ BSTR GetBstrByAddress(DWORD address);
void GetRpcMessage(WxMessage_t *wxMsg, RpcMessage_t rpcMsg); void GetRpcMessage(WxMessage_t *wxMsg, RpcMessage_t rpcMsg);
DWORD GetMemoryIntByAddress(HANDLE hProcess, DWORD address); DWORD GetMemoryIntByAddress(HANDLE hProcess, DWORD address);
std::wstring GetWstringFromBstr(BSTR p); std::wstring GetWstringFromBstr(BSTR p);
BSTR GetBstrFromWstring(std::wstring ws);
std::wstring GetUnicodeInfoByAddress(HANDLE hProcess, DWORD address); std::wstring GetUnicodeInfoByAddress(HANDLE hProcess, DWORD address);

View File

@ -166,6 +166,7 @@
<ItemGroup> <ItemGroup>
<ClInclude Include="..\Rpc\rpc_h.h" /> <ClInclude Include="..\Rpc\rpc_h.h" />
<ClInclude Include="..\SDK\util.h" /> <ClInclude Include="..\SDK\util.h" />
<ClInclude Include="exec_sql.h" />
<ClInclude Include="framework.h" /> <ClInclude Include="framework.h" />
<ClInclude Include="get_contacts.h" /> <ClInclude Include="get_contacts.h" />
<ClInclude Include="load_calls.h" /> <ClInclude Include="load_calls.h" />
@ -180,6 +181,7 @@
<ClCompile Include="..\Rpc\rpc_s.c" /> <ClCompile Include="..\Rpc\rpc_s.c" />
<ClCompile Include="..\SDK\util.cpp" /> <ClCompile Include="..\SDK\util.cpp" />
<ClCompile Include="dllmain.cpp" /> <ClCompile Include="dllmain.cpp" />
<ClCompile Include="exec_sql.cpp" />
<ClCompile Include="get_contacts.cpp" /> <ClCompile Include="get_contacts.cpp" />
<ClCompile Include="load_calls.cpp" /> <ClCompile Include="load_calls.cpp" />
<ClCompile Include="monitor.cpp" /> <ClCompile Include="monitor.cpp" />

View File

@ -48,6 +48,9 @@
<ClInclude Include="get_contacts.h"> <ClInclude Include="get_contacts.h">
<Filter>头文件</Filter> <Filter>头文件</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="exec_sql.h">
<Filter>头文件</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="dllmain.cpp"> <ClCompile Include="dllmain.cpp">
@ -80,6 +83,9 @@
<ClCompile Include="get_contacts.cpp"> <ClCompile Include="get_contacts.cpp">
<Filter>源文件</Filter> <Filter>源文件</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="exec_sql.cpp">
<Filter>源文件</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Midl Include="..\Rpc\rpc.idl"> <Midl Include="..\Rpc\rpc.idl">

33
Spy/exec_sql.cpp Normal file
View File

@ -0,0 +1,33 @@
#include <map>
#include <string>
#include "exec_sql.h"
#include "load_calls.h"
using namespace std;
extern WxCalls_t g_WxCalls;
extern DWORD g_WeChatWinDllAddr;
typedef map<wstring, DWORD> dbMap_t;
static dbMap_t dbMap;
vector<wstring> GetDbNames()
{
vector<wstring> vDbs;
if (dbMap.empty()) {
DWORD sqlHandleBaseAddr = *(DWORD *)(g_WeChatWinDllAddr + g_WxCalls.sql.base);
DWORD sqlHandleBeginAddr = *(DWORD *)(sqlHandleBaseAddr + g_WxCalls.sql.start);
DWORD sqlHandleEndAddr = *(DWORD *)(sqlHandleBaseAddr + g_WxCalls.sql.end);
while (sqlHandleBeginAddr < sqlHandleEndAddr) {
DWORD dwHandle = *(DWORD *)sqlHandleBeginAddr;
dbMap[wstring((wchar_t *)(*(DWORD *)(dwHandle + g_WxCalls.sql.name)))]
= *(DWORD *)(dwHandle + g_WxCalls.sql.slot);
sqlHandleBeginAddr += 0x04;
}
}
for (auto it = dbMap.begin(); it != dbMap.end(); it++) {
vDbs.push_back(it->first);
}
return vDbs;
}

8
Spy/exec_sql.h Normal file
View File

@ -0,0 +1,8 @@
#pragma once
#include <string>
#include <vector>
#include "rpc_h.h"
std::vector<std::wstring> GetDbNames();

View File

@ -1,4 +1,4 @@
#include <iostream> #include <iostream>
#include <map> #include <map>
#include "load_calls.h" #include "load_calls.h"
@ -13,7 +13,10 @@ WxCalls_t wxCalls = { 0x23631D0, // Login Status
{ 0xBD780, 0x770120, 0x521640 }, // Send Image Message { 0xBD780, 0x770120, 0x521640 }, // Send Image Message
/* Get Contacts: /* Get Contacts:
Base, head, wxId, Code, Name, Gender, Country, Province, City*/ Base, head, wxId, Code, Name, Gender, Country, Province, City*/
{ 0x23638F4, 0x4C, 0x30, 0x44, 0x8C, 0x184, 0x1D0, 0x1E4, 0x1F8 } }; { 0x23638F4, 0x4C, 0x30, 0x44, 0x8C, 0x184, 0x1D0, 0x1E4, 0x1F8 },
/* Exec Sql:
Exec, base, start, end, slot, name*/
{ 0x141A4D0, 0x2363934, 0x1428, 0x142C, 0x3C, 0x50 } };
int LoadCalls(const wchar_t *version, WxCalls_t *calls) int LoadCalls(const wchar_t *version, WxCalls_t *calls)
{ {

View File

@ -1,6 +1,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include "exec_sql.h"
#include "get_contacts.h" #include "get_contacts.h"
#include "monitor.h" #include "monitor.h"
#include "rpc_h.h" #include "rpc_h.h"
@ -8,6 +9,9 @@
#include "sdk.h" #include "sdk.h"
#include "send_msg.h" #include "send_msg.h"
#include "spy_types.h" #include "spy_types.h"
#include "util.h"
using namespace std;
extern HANDLE g_hEvent; extern HANDLE g_hEvent;
extern MsgQueue_t g_MsgQueue; extern MsgQueue_t g_MsgQueue;
@ -82,7 +86,7 @@ int server_GetMsgTypes(int *pNum, PPRpcIntBstrPair *msgTypes)
int server_GetContacts(int *pNum, PPRpcContact *contacts) int server_GetContacts(int *pNum, PPRpcContact *contacts)
{ {
std::vector<RpcContact_t> vContacts = GetContacts(); vector<RpcContact_t> vContacts = GetContacts();
*pNum = vContacts.size(); *pNum = vContacts.size();
PPRpcContact pp = (PPRpcContact)midl_user_allocate(*pNum * sizeof(RpcContact_t)); PPRpcContact pp = (PPRpcContact)midl_user_allocate(*pNum * sizeof(RpcContact_t));
@ -115,6 +119,26 @@ int server_GetContacts(int *pNum, PPRpcContact *contacts)
return 0; return 0;
} }
int server_GetDbNames(int *pNum, BSTR **dbs)
{
vector<wstring> vDbs = GetDbNames();
*pNum = vDbs.size();
BSTR *pp = (BSTR *)midl_user_allocate(*pNum * sizeof(BSTR));
if (pp == NULL) {
printf("server_GetMsgTypes midl_user_allocate Failed for pp\n");
return -2;
}
int index = 0;
for (auto it = vDbs.begin(); it != vDbs.end(); it++) {
pp[index++] = GetBstrFromWstring(*it);
}
*dbs = pp;
return 0;
}
RPC_STATUS CALLBACK SecurityCallback(RPC_IF_HANDLE /*hInterface*/, void * /*pBindingHandle*/) RPC_STATUS CALLBACK SecurityCallback(RPC_IF_HANDLE /*hInterface*/, void * /*pBindingHandle*/)
{ {
return RPC_S_OK; // Always allow anyone. return RPC_S_OK; // Always allow anyone.

View File

@ -1,4 +1,4 @@
#pragma once #pragma once
#include "framework.h" #include "framework.h"
#include <queue> #include <queue>
@ -41,6 +41,15 @@ typedef struct Contact {
DWORD wxCity; DWORD wxCity;
} Contact_t; } Contact_t;
typedef struct Sql {
DWORD exec;
DWORD base;
DWORD start;
DWORD end;
DWORD slot;
DWORD name;
} Sql_t;
typedef struct WxCalls { typedef struct WxCalls {
DWORD login; // 登录状态 DWORD login; // 登录状态
UserInfoCall_t ui; // 用户信息 UserInfoCall_t ui; // 用户信息
@ -48,6 +57,7 @@ typedef struct WxCalls {
RecvMsg_t recvMsg; // 接收消息 RecvMsg_t recvMsg; // 接收消息
SendImg_t sendImg; // 发送图片 SendImg_t sendImg; // 发送图片
Contact_t contact; // 获取联系人 Contact_t contact; // 获取联系人
Sql_t sql; // 执行 SQL
} WxCalls_t; } WxCalls_t;
typedef struct TextStruct { typedef struct TextStruct {