Refine RPC
This commit is contained in:
parent
4959b58b23
commit
19f6854b73
17
Rpc/rpc.idl
17
Rpc/rpc.idl
@ -5,13 +5,24 @@
|
|||||||
]
|
]
|
||||||
|
|
||||||
interface ISpy
|
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 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);
|
||||||
|
|
||||||
void EnableReceiveMsg();
|
void EnableReceiveMsg();
|
||||||
[callback] int ReceiveMsg([ in ] RpcMessage_t *msg);
|
[callback] int ReceiveMsg([ in ] RpcMessage_t rpcMsg);
|
||||||
};
|
};
|
||||||
|
@ -1,18 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define MSG_SIZE_MSG_ID 64
|
#define MSG_SIZE_MSG_ID 64
|
||||||
#define MSG_SIZE_MSG_XML 4096
|
#define MSG_SIZE_MSG_XML 4096
|
||||||
#define MSG_SIZE_WXID 64
|
#define MSG_SIZE_WXID 64
|
||||||
#define MSG_SIZE_ROOMID 64
|
#define MSG_SIZE_ROOMID 64
|
||||||
#define MSG_SIZE_CONTENT 16385
|
#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;
|
|
||||||
|
55
SDK/sdk.cpp
55
SDK/sdk.cpp
@ -15,8 +15,6 @@
|
|||||||
#include "sdk.h"
|
#include "sdk.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
static HANDLE hEvent;
|
|
||||||
static std::queue<RpcMessage_t> MsgQueue;
|
|
||||||
static RPC_WSTR pszStringBinding = NULL;
|
static RPC_WSTR pszStringBinding = NULL;
|
||||||
static std::function<int(WxMessage_t)> cbReceiveTextMsg;
|
static std::function<int(WxMessage_t)> cbReceiveTextMsg;
|
||||||
static const MsgTypesMap_t WxMsgTypes = MsgTypesMap_t { { 0x01, L"文字" },
|
static const MsgTypesMap_t WxMsgTypes = MsgTypesMap_t { { 0x01, L"文字" },
|
||||||
@ -121,37 +119,6 @@ int WxInitSDK()
|
|||||||
return ERROR_SUCCESS;
|
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)
|
static unsigned int __stdcall innerWxSetTextMsgCb(void *p)
|
||||||
{
|
{
|
||||||
unsigned long ulCode = 0;
|
unsigned long ulCode = 0;
|
||||||
@ -175,13 +142,6 @@ int WxSetTextMsgCb(const std::function<int(WxMessage_t)> &onMsg)
|
|||||||
if (onMsg) {
|
if (onMsg) {
|
||||||
HANDLE msgThread;
|
HANDLE msgThread;
|
||||||
cbReceiveTextMsg = onMsg;
|
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);
|
msgThread = (HANDLE)_beginthreadex(NULL, 0, innerWxSetTextMsgCb, NULL, 0, NULL);
|
||||||
if (msgThread == NULL) {
|
if (msgThread == NULL) {
|
||||||
@ -197,10 +157,17 @@ int WxSetTextMsgCb(const std::function<int(WxMessage_t)> &onMsg)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int server_ReceiveMsg(RpcMessage_t *rpcMsg)
|
int server_ReceiveMsg(RpcMessage_t rpcMsg)
|
||||||
{
|
{
|
||||||
MsgQueue.push(*rpcMsg); // 发送消息
|
WxMessage_t msg;
|
||||||
SetEvent(hEvent); // 发送消息通知
|
GetRpcMessage(&msg, rpcMsg);
|
||||||
|
try {
|
||||||
|
cbReceiveTextMsg(msg); // 调用接收消息回调
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
printf("callback error...\n");
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
39
SDK/util.cpp
39
SDK/util.cpp
@ -58,7 +58,7 @@ int GetWeChatWinDLLPath(wchar_t *path)
|
|||||||
// 微信从(大约)3.7开始,增加了一层版本目录: [3.7.0.29]
|
// 微信从(大约)3.7开始,增加了一层版本目录: [3.7.0.29]
|
||||||
PathRemoveFileSpec(path);
|
PathRemoveFileSpec(path);
|
||||||
_wfinddata_t findData;
|
_wfinddata_t findData;
|
||||||
wstring dir = wstring(path) + L"\\[*.*";
|
wstring dir = wstring(path) + L"\\[*.*";
|
||||||
intptr_t handle = _wfindfirst(dir.c_str(), &findData);
|
intptr_t handle = _wfindfirst(dir.c_str(), &findData);
|
||||||
if (handle == -1) { // 检查是否成功
|
if (handle == -1) { // 检查是否成功
|
||||||
return -1;
|
return -1;
|
||||||
@ -66,7 +66,7 @@ int GetWeChatWinDLLPath(wchar_t *path)
|
|||||||
wstring dllPath = wstring(path) + L"\\" + findData.name;
|
wstring dllPath = wstring(path) + L"\\" + findData.name;
|
||||||
wcscpy_s(path, MAX_PATH, dllPath.c_str());
|
wcscpy_s(path, MAX_PATH, dllPath.c_str());
|
||||||
PathAppend(path, WECHATWINDLL);
|
PathAppend(path, WECHATWINDLL);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -133,17 +133,16 @@ int OpenWeChat(DWORD *pid)
|
|||||||
{
|
{
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
STARTUPINFO si = { sizeof(si) };
|
STARTUPINFO si = { sizeof(si) };
|
||||||
|
WCHAR Path[MAX_PATH] = { 0 };
|
||||||
PROCESS_INFORMATION pi = { 0 };
|
PROCESS_INFORMATION pi = { 0 };
|
||||||
|
|
||||||
WCHAR Path[MAX_PATH] = { 0 };
|
ret = GetWeChatPath(Path);
|
||||||
ret = GetWeChatPath(Path);
|
|
||||||
if (ERROR_SUCCESS != ret) {
|
if (ERROR_SUCCESS != ret) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!CreateProcess(NULL, Path, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
|
if (!CreateProcess(NULL, Path, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
|
||||||
ret = GetLastError();
|
return GetLastError();
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CloseHandle(pi.hThread);
|
CloseHandle(pi.hThread);
|
||||||
@ -151,9 +150,7 @@ int OpenWeChat(DWORD *pid)
|
|||||||
|
|
||||||
*pid = pi.dwProcessId;
|
*pid = pi.dwProcessId;
|
||||||
|
|
||||||
ret = ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetWstringByAddress(DWORD address, wchar_t *buffer, DWORD buffer_size)
|
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;
|
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 GetMemoryIntByAddress(HANDLE hProcess, DWORD address)
|
||||||
{
|
{
|
||||||
DWORD value = 0;
|
DWORD value = 0;
|
||||||
|
11
SDK/util.h
11
SDK/util.h
@ -1,6 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include "sdk.h"
|
||||||
|
#include "rpc_h.h"
|
||||||
|
|
||||||
#define WECHAREXE L"WeChat.exe"
|
#define WECHAREXE L"WeChat.exe"
|
||||||
#define WECHATWINDLL L"WeChatWin.dll"
|
#define WECHATWINDLL L"WeChatWin.dll"
|
||||||
@ -16,6 +19,8 @@ int GetWeChatPath(wchar_t *path);
|
|||||||
int GetWeChatWinDLLPath(wchar_t *path);
|
int GetWeChatWinDLLPath(wchar_t *path);
|
||||||
int GetWeChatVersion(wchar_t *version);
|
int GetWeChatVersion(wchar_t *version);
|
||||||
bool GetFileVersion(const wchar_t *filePath, 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);
|
DWORD GetMemoryIntByAddress(HANDLE hProcess, DWORD address);
|
||||||
std::wstring GetUnicodeInfoByAddress(HANDLE hProcess, DWORD address);
|
std::wstring GetUnicodeInfoByAddress(HANDLE hProcess, DWORD address);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#include "framework.h"
|
#include "framework.h"
|
||||||
|
|
||||||
#include "load_calls.h"
|
#include "load_calls.h"
|
||||||
#include "receive_msg.h"
|
#include "receive_msg.h"
|
||||||
@ -14,30 +14,31 @@ MsgQueue_t g_MsgQueue;
|
|||||||
DWORD reg_buffer = 0;
|
DWORD reg_buffer = 0;
|
||||||
DWORD recvMsgCallAddr = 0;
|
DWORD recvMsgCallAddr = 0;
|
||||||
DWORD recvMsgJumpBackAddr = 0;
|
DWORD recvMsgJumpBackAddr = 0;
|
||||||
RpcMessage_t *pMsg = NULL; // Find a palce to free
|
RpcMessage_t lMsg = { 0 };
|
||||||
|
|
||||||
void DispatchMsg(DWORD reg)
|
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);
|
lMsg.type = GET_DWORD(*p + g_WxCalls.recvMsg.type);
|
||||||
pMsg->self = GET_DWORD(*p + g_WxCalls.recvMsg.isSelf);
|
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"<membercount>") == NULL) {
|
if (wcsstr(lMsg.xml, L"<membercount>") == NULL) {
|
||||||
// pMsg.roomId = {0};
|
// pMsg.roomId = {0};
|
||||||
GetWstringByAddress(*p + g_WxCalls.recvMsg.roomId, pMsg->wxId, MSG_SIZE_WXID);
|
lMsg.wxId = GetBstrByAddress(*p + g_WxCalls.recvMsg.roomId);
|
||||||
} 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);
|
|
||||||
}
|
}
|
||||||
GetWstringByAddress(*p + g_WxCalls.recvMsg.content, pMsg->content, MSG_SIZE_CONTENT);
|
else {
|
||||||
g_MsgQueue.push(*pMsg); // 发送消息
|
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); // 发送消息通知
|
SetEvent(g_hEvent); // 发送消息通知
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,7 +64,6 @@ void ListenMessage()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
pMsg = new RpcMessage_t;
|
|
||||||
DWORD hookAddress = g_WeChatWinDllAddr + g_WxCalls.recvMsg.hook;
|
DWORD hookAddress = g_WeChatWinDllAddr + g_WxCalls.recvMsg.hook;
|
||||||
recvMsgCallAddr = g_WeChatWinDllAddr + g_WxCalls.recvMsg.call;
|
recvMsgCallAddr = g_WeChatWinDllAddr + g_WxCalls.recvMsg.call;
|
||||||
recvMsgJumpBackAddr = hookAddress + 5;
|
recvMsgJumpBackAddr = hookAddress + 5;
|
||||||
|
@ -25,7 +25,7 @@ void server_EnableReceiveMsg()
|
|||||||
// 中断式,兼顾及时性和CPU使用率
|
// 中断式,兼顾及时性和CPU使用率
|
||||||
WaitForSingleObject(g_hEvent, INFINITE); // 等待消息
|
WaitForSingleObject(g_hEvent, INFINITE); // 等待消息
|
||||||
while (!g_MsgQueue.empty()) {
|
while (!g_MsgQueue.empty()) {
|
||||||
client_ReceiveMsg((RpcMessage_t *)&g_MsgQueue.front()); // 调用接收消息回调
|
client_ReceiveMsg(g_MsgQueue.front()); // 调用接收消息回调
|
||||||
g_MsgQueue.pop();
|
g_MsgQueue.pop();
|
||||||
}
|
}
|
||||||
ResetEvent(g_hEvent);
|
ResetEvent(g_hEvent);
|
||||||
@ -34,7 +34,7 @@ void server_EnableReceiveMsg()
|
|||||||
RpcExcept(1)
|
RpcExcept(1)
|
||||||
{
|
{
|
||||||
ulCode = RpcExceptionCode();
|
ulCode = RpcExceptionCode();
|
||||||
printf("Runtime reported exception 0x%lx = %ld\n", ulCode, ulCode);
|
printf("server_EnableReceiveMsg exception 0x%lx = %ld\n", ulCode, ulCode);
|
||||||
}
|
}
|
||||||
RpcEndExcept
|
RpcEndExcept
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
#include "framework.h"
|
#include "framework.h"
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
|
||||||
#include "rpc_types.h"
|
#include "rpc_h.h"
|
||||||
|
|
||||||
typedef struct UserInfoCall {
|
typedef struct UserInfoCall {
|
||||||
DWORD wxid;
|
DWORD wxid;
|
||||||
@ -19,7 +19,7 @@ typedef struct RecvMsg {
|
|||||||
DWORD msgId; // 消息ID地址
|
DWORD msgId; // 消息ID地址
|
||||||
DWORD msgXml; // 消息xml内容地址
|
DWORD msgXml; // 消息xml内容地址
|
||||||
DWORD roomId; // 群聊时,为群ID;私聊时,为微信ID
|
DWORD roomId; // 群聊时,为群ID;私聊时,为微信ID
|
||||||
DWORD wxId; // 私聊时,为空;群群时,为发送者微信ID
|
DWORD wxId; // 私聊时,为空;群聊时,为发送者微信ID
|
||||||
DWORD content; // 消息内容地址
|
DWORD content; // 消息内容地址
|
||||||
} RecvMsg_t;
|
} RecvMsg_t;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user