2022-08-06 21:44:26 +08:00
|
|
|
|
#include "Shlwapi.h"
|
2021-02-12 23:21:57 +08:00
|
|
|
|
#include "framework.h"
|
|
|
|
|
#include <process.h>
|
|
|
|
|
#include <queue>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <tlhelp32.h>
|
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
|
|
#include "injector.h"
|
2022-08-07 16:21:28 +08:00
|
|
|
|
#include "rpc_client.h"
|
2021-02-12 23:21:57 +08:00
|
|
|
|
#include "sdk.h"
|
|
|
|
|
#include "util.h"
|
|
|
|
|
|
2022-08-07 16:21:28 +08:00
|
|
|
|
std::function<int(WxMessage_t)> g_cbReceiveTextMsg;
|
2021-02-12 23:21:57 +08:00
|
|
|
|
|
2022-08-13 23:33:37 +08:00
|
|
|
|
static DWORD WeChatPID = 0;
|
|
|
|
|
static WCHAR SpyDllPath[MAX_PATH] = { 0 };
|
|
|
|
|
|
2021-02-12 23:21:57 +08:00
|
|
|
|
int WxInitSDK()
|
|
|
|
|
{
|
2022-08-20 15:15:04 +08:00
|
|
|
|
int status = 0;
|
2022-08-13 23:33:37 +08:00
|
|
|
|
unsigned long ulCode = 0;
|
2021-02-12 23:21:57 +08:00
|
|
|
|
|
2022-08-13 23:33:37 +08:00
|
|
|
|
GetModuleFileName(GetModuleHandle(WECHATSDKDLL), SpyDllPath, MAX_PATH);
|
|
|
|
|
PathRemoveFileSpec(SpyDllPath);
|
|
|
|
|
PathAppend(SpyDllPath, WECHATINJECTDLL);
|
2021-02-12 23:21:57 +08:00
|
|
|
|
|
2022-08-13 23:33:37 +08:00
|
|
|
|
if (!PathFileExists(SpyDllPath)) {
|
2021-02-12 23:21:57 +08:00
|
|
|
|
return ERROR_FILE_NOT_FOUND;
|
|
|
|
|
}
|
|
|
|
|
|
2022-08-13 23:33:37 +08:00
|
|
|
|
status = OpenWeChat(&WeChatPID);
|
2021-02-12 23:21:57 +08:00
|
|
|
|
if (status != 0) {
|
|
|
|
|
return status;
|
|
|
|
|
}
|
2022-08-20 15:15:04 +08:00
|
|
|
|
|
2022-08-06 16:49:37 +08:00
|
|
|
|
Sleep(2000); // 等待微信打开
|
2022-08-14 07:15:05 +08:00
|
|
|
|
if (InjectDll(WeChatPID, SpyDllPath)) {
|
2021-02-12 23:21:57 +08:00
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
2022-08-20 15:15:04 +08:00
|
|
|
|
Sleep(1000); // 等待SPY就绪
|
|
|
|
|
status = RpcConnectServer();
|
|
|
|
|
if (status != 0) {
|
|
|
|
|
printf("RpcConnectServer: %d\n", status);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
2021-02-12 23:21:57 +08:00
|
|
|
|
|
2022-08-20 15:15:04 +08:00
|
|
|
|
do {
|
|
|
|
|
status = RpcIsLogin();
|
|
|
|
|
if (status == -1) {
|
|
|
|
|
return status;
|
2022-08-20 17:39:21 +08:00
|
|
|
|
} else if (status == 1) {
|
2022-08-20 15:15:04 +08:00
|
|
|
|
break;
|
|
|
|
|
}
|
2022-08-07 16:21:28 +08:00
|
|
|
|
Sleep(1000);
|
2022-08-20 15:15:04 +08:00
|
|
|
|
} while (1);
|
2021-02-12 23:21:57 +08:00
|
|
|
|
|
|
|
|
|
return ERROR_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2022-08-13 23:33:37 +08:00
|
|
|
|
int WxDestroySDK()
|
|
|
|
|
{
|
2022-08-20 15:15:04 +08:00
|
|
|
|
WxDisableRecvMsg();
|
2022-08-13 23:33:37 +08:00
|
|
|
|
RpcDisconnectServer();
|
2022-08-20 15:15:04 +08:00
|
|
|
|
// 关闭 RPC,但不卸载 DLL,方便下次使用。
|
2022-08-20 17:39:21 +08:00
|
|
|
|
// EjectDll(WeChatPID, SpyDllPath);
|
|
|
|
|
|
2022-08-13 23:33:37 +08:00
|
|
|
|
return ERROR_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2022-08-20 15:15:04 +08:00
|
|
|
|
int WxEnableRecvMsg(const std::function<int(WxMessage_t)> &onMsg)
|
2021-02-12 23:21:57 +08:00
|
|
|
|
{
|
|
|
|
|
if (onMsg) {
|
|
|
|
|
HANDLE msgThread;
|
2022-08-07 16:21:28 +08:00
|
|
|
|
g_cbReceiveTextMsg = onMsg;
|
2022-08-20 17:39:21 +08:00
|
|
|
|
|
2022-08-20 15:15:04 +08:00
|
|
|
|
msgThread = (HANDLE)CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)RpcEnableReceiveMsg, NULL, 0, NULL);
|
2021-02-12 23:21:57 +08:00
|
|
|
|
if (msgThread == NULL) {
|
|
|
|
|
printf("Failed to create innerWxRecvTextMsg.\n");
|
|
|
|
|
return -2;
|
|
|
|
|
}
|
|
|
|
|
CloseHandle(msgThread);
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
printf("Empty Callback.\n");
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
2022-08-20 15:15:04 +08:00
|
|
|
|
int WxDisableRecvMsg()
|
|
|
|
|
{
|
|
|
|
|
RpcDisableReceiveMsg();
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
2022-08-20 17:39:21 +08:00
|
|
|
|
int WxSendTextMsg(wstring wxid, wstring msg, wstring atWxids)
|
2021-02-12 23:21:57 +08:00
|
|
|
|
{
|
2022-08-20 17:39:21 +08:00
|
|
|
|
return RpcSendTextMsg(wxid.c_str(), msg.c_str(), atWxids.c_str());
|
2021-08-22 21:57:16 +08:00
|
|
|
|
}
|
|
|
|
|
|
2022-08-07 16:21:28 +08:00
|
|
|
|
int WxSendImageMsg(wstring wxid, wstring path) { return RpcSendImageMsg(wxid.c_str(), path.c_str()); }
|
2021-08-22 21:57:16 +08:00
|
|
|
|
|
2021-02-12 23:21:57 +08:00
|
|
|
|
static int getAddrHandle(DWORD *addr, HANDLE *handle)
|
|
|
|
|
{
|
|
|
|
|
DWORD processID = 0;
|
|
|
|
|
wstring processName = L"WeChat.exe";
|
|
|
|
|
wstring moduleName = L"WeChatWin.dll";
|
|
|
|
|
|
|
|
|
|
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
|
|
|
|
PROCESSENTRY32 pe32 = { sizeof(PROCESSENTRY32) };
|
|
|
|
|
while (Process32Next(hSnapshot, &pe32)) {
|
|
|
|
|
wstring strProcess = pe32.szExeFile;
|
|
|
|
|
if (strProcess == processName) {
|
|
|
|
|
processID = pe32.th32ProcessID;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
CloseHandle(hSnapshot);
|
|
|
|
|
if (processID == 0) {
|
|
|
|
|
printf("Failed to get Process ID\r\n");
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HANDLE hProcessSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, processID);
|
|
|
|
|
if (hProcessSnapshot == INVALID_HANDLE_VALUE) {
|
|
|
|
|
printf("Failed to get Process Snapshot\r\n");
|
|
|
|
|
return -2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MODULEENTRY32 me32;
|
|
|
|
|
SecureZeroMemory(&me32, sizeof(MODULEENTRY32));
|
|
|
|
|
me32.dwSize = sizeof(MODULEENTRY32);
|
|
|
|
|
while (Module32Next(hProcessSnapshot, &me32)) {
|
|
|
|
|
me32.dwSize = sizeof(MODULEENTRY32);
|
|
|
|
|
|
|
|
|
|
if (!wcscmp(me32.szModule, moduleName.c_str())) {
|
|
|
|
|
*addr = (DWORD)me32.modBaseAddr;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CloseHandle(hProcessSnapshot);
|
|
|
|
|
if (*addr == 0) {
|
|
|
|
|
printf("Failed to get Module Address\r\n");
|
|
|
|
|
return -3;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*handle = OpenProcess(PROCESS_VM_READ, FALSE, processID);
|
|
|
|
|
if (*handle == 0) {
|
|
|
|
|
printf("Failed to open Process\r\n");
|
|
|
|
|
return -4;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2022-08-07 20:50:49 +08:00
|
|
|
|
MsgTypesMap_t WxGetMsgTypes()
|
2021-08-28 08:33:24 +08:00
|
|
|
|
{
|
2022-08-07 20:50:49 +08:00
|
|
|
|
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);
|
|
|
|
|
}
|
2021-08-28 08:33:24 +08:00
|
|
|
|
}
|
|
|
|
|
|
2022-08-07 20:50:49 +08:00
|
|
|
|
return WxMsgTypes;
|
2021-08-28 08:33:24 +08:00
|
|
|
|
}
|
|
|
|
|
|
2022-08-07 20:50:49 +08:00
|
|
|
|
ContactMap_t WxGetContacts()
|
2022-08-07 20:08:54 +08:00
|
|
|
|
{
|
2022-08-07 20:50:49 +08:00
|
|
|
|
ContactMap_t mContact;
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
mContact.insert(make_pair(contact.wxId, contact));
|
|
|
|
|
midl_user_free(pp[i]);
|
|
|
|
|
}
|
2022-08-07 20:08:54 +08:00
|
|
|
|
|
2022-08-07 20:50:49 +08:00
|
|
|
|
if (pp) {
|
|
|
|
|
midl_user_free(pp);
|
|
|
|
|
}
|
2022-08-07 20:08:54 +08:00
|
|
|
|
|
2022-08-07 20:50:49 +08:00
|
|
|
|
return mContact;
|
|
|
|
|
}
|
2022-08-07 23:32:25 +08:00
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
2022-08-07 23:49:37 +08:00
|
|
|
|
|
|
|
|
|
DbTableVector_t WxGetDbTables(wstring db)
|
|
|
|
|
{
|
|
|
|
|
DbTableVector_t vTables;
|
|
|
|
|
int size = 0;
|
|
|
|
|
PPRpcTables pp = RpcGetDbTables(db.c_str(), &size);
|
|
|
|
|
for (int i = 0; i < size; i++) {
|
|
|
|
|
WxDbTable_t tbl;
|
|
|
|
|
tbl.table = GetWstringFromBstr(pp[i]->table);
|
|
|
|
|
tbl.sql = GetWstringFromBstr(pp[i]->sql);
|
|
|
|
|
|
|
|
|
|
vTables.push_back(tbl);
|
|
|
|
|
midl_user_free(pp[i]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (pp) {
|
|
|
|
|
midl_user_free(pp);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return vTables;
|
|
|
|
|
}
|
2022-08-20 22:10:11 +08:00
|
|
|
|
|
|
|
|
|
SqlRetVector_t WxExecDbQuery(wstring db, wstring sql)
|
|
|
|
|
{
|
|
|
|
|
int row, col = 0;
|
|
|
|
|
PPPRpcSqlResult ppp = RpcExecDbQuery(db.c_str(), sql.c_str(), &row, &col);
|
|
|
|
|
vector<vector<WxSqlResult_t>> vvResults;
|
|
|
|
|
for (int r = 0; r < row; r++) {
|
|
|
|
|
vector<WxSqlResult_t> vResult;
|
|
|
|
|
for (int c = 0; c < col; c++) {
|
|
|
|
|
WxSqlResult_t result = { 0 };
|
|
|
|
|
result.type = ppp[r][c]->type;
|
|
|
|
|
result.column = GetWstringFromBstr(ppp[r][c]->column);
|
|
|
|
|
result.content = GetBytesFromBstr(ppp[r][c]->content);
|
|
|
|
|
vResult.push_back(result);
|
|
|
|
|
midl_user_free(ppp[r][c]);
|
|
|
|
|
}
|
|
|
|
|
vvResults.push_back(vResult);
|
|
|
|
|
midl_user_free(ppp[r]);
|
|
|
|
|
}
|
|
|
|
|
if (ppp) {
|
|
|
|
|
midl_user_free(ppp);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return vvResults;
|
|
|
|
|
}
|
2022-08-21 08:45:16 +08:00
|
|
|
|
|
|
|
|
|
BOOL WxAcceptNewFriend(wstring v3, wstring v4) { return AcceptNewFriend(v3.c_str(), v4.c_str()); }
|