diff --git a/CWeChatRobot/ReceiveMessage.cpp b/CWeChatRobot/ReceiveMessage.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e2a8acfc78e0444b7fcee936879f0d56aec1f68a --- /dev/null +++ b/CWeChatRobot/ReceiveMessage.cpp @@ -0,0 +1,150 @@ +#include "pch.h" + +BOOL ReceiveMessageHooked = FALSE; + +struct GetRemoteMessageStruct { + DWORD type; + DWORD sender; + DWORD l_sender; + DWORD wxid; + DWORD l_wxid; + DWORD message; + DWORD l_message; +}; + +struct MessageStruct { + DWORD type; + wchar_t* sender; + wchar_t* wxid; + wchar_t* message; +}; + +BOOL StartReceiveMessage() { + if (!hProcess || ReceiveMessageHooked) + return 1; + DWORD WeChatRobotBase = GetWeChatRobotBase(); + DWORD dwId = 0; + + DWORD HookReceiveMessageAddr = WeChatRobotBase + HookReceiveMessageRemoteOffset; + HANDLE hThread = ::CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)HookReceiveMessageAddr, NULL, 0, &dwId); + if (hThread) { + WaitForSingleObject(hThread, INFINITE); + } + else { + return 1; + } + CloseHandle(hThread); + ReceiveMessageHooked = TRUE; + return 0; +} + +BOOL StopReceiveMessage() { + if (!hProcess || !ReceiveMessageHooked) + return 1; + DWORD WeChatRobotBase = GetWeChatRobotBase(); + DWORD dwId = 0; + + DWORD UnHookReceiveMessageAddr = WeChatRobotBase + UnHookReceiveMessageRemoteOffset; + HANDLE hThread = ::CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)UnHookReceiveMessageAddr, NULL, 0, &dwId); + if (hThread) { + WaitForSingleObject(hThread, INFINITE); + } + else { + return 1; + } + CloseHandle(hThread); + ReceiveMessageHooked = FALSE; + return 0; +} + +BOOL GetHeadMessage(GetRemoteMessageStruct* message) { + if (!hProcess || !ReceiveMessageHooked) + return 1; + DWORD WeChatRobotBase = GetWeChatRobotBase(); + DWORD dwId = 0; + DWORD dwHandle = 0; + DWORD GetHeadMessageAddr = WeChatRobotBase + GetHeadMessageRemoteOffset; + HANDLE hThread = ::CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)GetHeadMessageAddr, NULL, 0, &dwId); + + if (hThread) { + WaitForSingleObject(hThread, INFINITE); + GetExitCodeThread(hThread, &dwHandle); + } + else { + return 1; + } + if (!dwHandle) + return 0; + ReadProcessMemory(hProcess,(LPCVOID)dwHandle, message,sizeof(GetRemoteMessageStruct),0); + CloseHandle(hThread); + return 0; +} + +BOOL PopHeadMessage() { + if (!hProcess || !ReceiveMessageHooked) + return 1; + DWORD WeChatRobotBase = GetWeChatRobotBase(); + DWORD dwId = 0; + DWORD PopHeadMessageAddr = WeChatRobotBase + PopHeadMessageRemoteOffset; + HANDLE hThread = ::CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)PopHeadMessageAddr, NULL, 0, &dwId); + if (hThread) { + WaitForSingleObject(hThread, INFINITE); + } + else { + return 1; + } + CloseHandle(hThread); + return 0; +} + +SAFEARRAY* ReceiveMessage() { + if (!hProcess || !ReceiveMessageHooked) + return NULL; + GetRemoteMessageStruct remotemessage = { 0 }; + MessageStruct message = { 0 }; + HRESULT hr = S_OK; + GetHeadMessage(&remotemessage); + printf("0x%X,0x%08X,0x%08X,0x%08X\n", remotemessage.type, remotemessage.sender, remotemessage.wxid, remotemessage.message); + DWORD dwInfoAddr = 0; + if (remotemessage.type) { + message.type = remotemessage.type; + message.sender = new wchar_t[remotemessage.l_sender + 1]; + ReadProcessMemory(hProcess, (LPCVOID)remotemessage.sender, message.sender, (remotemessage.l_sender + 1) * sizeof(wchar_t), 0); + message.wxid = new wchar_t[remotemessage.l_wxid + 1]; + ReadProcessMemory(hProcess, (LPCVOID)remotemessage.wxid, message.wxid, (remotemessage.l_wxid + 1) * sizeof(wchar_t), 0); + message.message = new wchar_t[remotemessage.l_message + 1]; + ReadProcessMemory(hProcess, (LPCVOID)remotemessage.message, message.message, (remotemessage.l_message + 1) * sizeof(wchar_t), 0); + } + else { + return NULL; + } + printf("%ws\n", message.wxid); + PopHeadMessage(); + SAFEARRAY* psaValue; + vector MessageInfoKey = { + L"type", + L"sender", + L"wxid", + L"message", + }; + SAFEARRAYBOUND rgsaBound[2] = { {4,0},{2,0} }; + psaValue = SafeArrayCreate(VT_VARIANT, 2, rgsaBound); + long keyIndex[2] = { 0,0 }; + keyIndex[0] = 0; keyIndex[1] = 0; + hr = SafeArrayPutElement(psaValue, keyIndex, &(_variant_t)MessageInfoKey[0].c_str()); + keyIndex[0] = 0; keyIndex[1] = 1; + hr = SafeArrayPutElement(psaValue, keyIndex, &(_variant_t)message.type); + keyIndex[0] = 1; keyIndex[1] = 0; + hr = SafeArrayPutElement(psaValue, keyIndex, &(_variant_t)MessageInfoKey[1].c_str()); + keyIndex[0] = 1; keyIndex[1] = 1; + hr = SafeArrayPutElement(psaValue, keyIndex, &(_variant_t)message.sender); + keyIndex[0] = 2; keyIndex[1] = 0; + hr = SafeArrayPutElement(psaValue, keyIndex, &(_variant_t)MessageInfoKey[2].c_str()); + keyIndex[0] = 2; keyIndex[1] = 1; + hr = SafeArrayPutElement(psaValue, keyIndex, &(_variant_t)message.wxid); + keyIndex[0] = 3; keyIndex[1] = 0; + hr = SafeArrayPutElement(psaValue, keyIndex, &(_variant_t)MessageInfoKey[3].c_str()); + keyIndex[0] = 3; keyIndex[1] = 1; + hr = SafeArrayPutElement(psaValue, keyIndex, &(_variant_t)message.message); + return psaValue; +} \ No newline at end of file diff --git a/CWeChatRobot/ReceiveMessage.h b/CWeChatRobot/ReceiveMessage.h new file mode 100644 index 0000000000000000000000000000000000000000..8df94ee13c79617260a3d75b5612cb9b6427fd10 --- /dev/null +++ b/CWeChatRobot/ReceiveMessage.h @@ -0,0 +1,5 @@ +#pragma once +#include +BOOL StartReceiveMessage(); +SAFEARRAY* ReceiveMessage(); +BOOL StopReceiveMessage(); \ No newline at end of file diff --git a/CWeChatRobot/WeChatRobot.cpp b/CWeChatRobot/WeChatRobot.cpp index 70afcd095f1ebabfc9799465c19794759b271fec..0ff6702432a03be4243cf4907e68beeeed9709fe 100644 --- a/CWeChatRobot/WeChatRobot.cpp +++ b/CWeChatRobot/WeChatRobot.cpp @@ -148,4 +148,31 @@ STDMETHODIMP CWeChatRobot::CGetComWorkPath(BSTR* __result) { string path = _com_util::ConvertBSTRToString((BSTR)(GetComWorkPath().c_str())); *__result = _com_util::ConvertStringToBSTR(path.c_str()); return S_OK; +} + +/* +* 参数1:预返回的值,调用时无需提供 +*/ +STDMETHODIMP CWeChatRobot::CStartReceiveMessage(int* __result) { + *__result = StartReceiveMessage(); + return S_OK; +} + +/* +* 参数1:预返回的值,调用时无需提供 +*/ +STDMETHODIMP CWeChatRobot::CReceiveMessage(VARIANT* __result) { + VARIANT vsaValue; + vsaValue.vt = VT_ARRAY | VT_VARIANT; + V_ARRAY(&vsaValue) = ReceiveMessage(); + *__result = vsaValue; + return S_OK; +} + +/* +* 参数1:预返回的值,调用时无需提供 +*/ +STDMETHODIMP CWeChatRobot::CStopReceiveMessage(int* __result) { + *__result = StopReceiveMessage(); + return S_OK; } \ No newline at end of file diff --git a/CWeChatRobot/WeChatRobot.h b/CWeChatRobot/WeChatRobot.h index 54ebde716c5ed88ce857e13d426ba76f18b29732..6144ea253c40101ca95827f6667c019046cca78f 100644 --- a/CWeChatRobot/WeChatRobot.h +++ b/CWeChatRobot/WeChatRobot.h @@ -66,6 +66,9 @@ public: STDMETHODIMP CCheckFriendStatus(BSTR wxid, int* __result); STDMETHODIMP CCheckFriendStatusFinish(int* __result); STDMETHODIMP CGetComWorkPath(BSTR* __result); + STDMETHODIMP CStartReceiveMessage(int* __result); + STDMETHODIMP CReceiveMessage(VARIANT* __result); + STDMETHODIMP CStopReceiveMessage(int* __result); }; OBJECT_ENTRY_AUTO(__uuidof(WeChatRobot), CWeChatRobot) diff --git a/CWeChatRobot/WeChatRobotCOM.idl b/CWeChatRobot/WeChatRobotCOM.idl index 095ae9f0d6e4e6c8ac9f0a42537b93f438535f2d..ed5418d9e77bff1866f1433b36dff02ab7f30404 100644 --- a/CWeChatRobot/WeChatRobotCOM.idl +++ b/CWeChatRobot/WeChatRobotCOM.idl @@ -31,6 +31,9 @@ interface IWeChatRobot : IDispatch [id(13)] HRESULT CCheckFriendStatus([in] BSTR wxid, [out, retval] int* __result); [id(14)] HRESULT CCheckFriendStatusFinish([out, retval] int* __result); [id(15)] HRESULT CGetComWorkPath([out, retval] BSTR* __result); + [id(16)] HRESULT CStartReceiveMessage([out, retval] int* __result); + [id(17)] HRESULT CReceiveMessage([out, retval] VARIANT* __result); + [id(18)] HRESULT CStopReceiveMessage([out, retval] int* __result); }; [ uuid(721abb35-141a-4aa2-94f2-762e2833fa6c), diff --git a/CWeChatRobot/WeChatRobotCOM.vcxproj b/CWeChatRobot/WeChatRobotCOM.vcxproj index afc275748e723d026eaef57b88ac21b4f70cf843..d4aee32c1aeba99212e582595576eeeeadaad20a 100644 --- a/CWeChatRobot/WeChatRobotCOM.vcxproj +++ b/CWeChatRobot/WeChatRobotCOM.vcxproj @@ -216,6 +216,7 @@ + @@ -240,6 +241,7 @@ Create Create + diff --git a/CWeChatRobot/WeChatRobotCOM.vcxproj.filters b/CWeChatRobot/WeChatRobotCOM.vcxproj.filters index 2d97e8b3067ab95f6934d5153784a9ddaac771a2..b6b6ea0b722ecf4d5fc446980588f6b1b75d57b7 100644 --- a/CWeChatRobot/WeChatRobotCOM.vcxproj.filters +++ b/CWeChatRobot/WeChatRobotCOM.vcxproj.filters @@ -53,6 +53,9 @@ {2543fa88-031d-42ca-9dd1-ac564ee2f744} + + {9f0d63f2-46a6-4d9c-83dd-ed19792705d0} + @@ -109,6 +112,9 @@ 好友相关\好友状态 + + 接收消息 + @@ -156,6 +162,9 @@ 好友相关\好友状态 + + 接收消息 + diff --git a/CWeChatRobot/WeChatRobotCOM_i.h b/CWeChatRobot/WeChatRobotCOM_i.h index 7f6a37e548b9187d88eeeb92a273515a12c1df02..c77e9e9e2f2a0b9ee90247b76550edff52fdff58 100644 --- a/CWeChatRobot/WeChatRobotCOM_i.h +++ b/CWeChatRobot/WeChatRobotCOM_i.h @@ -148,6 +148,15 @@ EXTERN_C const IID IID_IWeChatRobot; virtual /* [id] */ HRESULT STDMETHODCALLTYPE CGetComWorkPath( /* [retval][out] */ BSTR *__result) = 0; + virtual /* [id] */ HRESULT STDMETHODCALLTYPE CStartReceiveMessage( + /* [retval][out] */ int *__result) = 0; + + virtual /* [id] */ HRESULT STDMETHODCALLTYPE CReceiveMessage( + /* [retval][out] */ VARIANT *__result) = 0; + + virtual /* [id] */ HRESULT STDMETHODCALLTYPE CStopReceiveMessage( + /* [retval][out] */ int *__result) = 0; + }; @@ -281,6 +290,18 @@ EXTERN_C const IID IID_IWeChatRobot; IWeChatRobot * This, /* [retval][out] */ BSTR *__result); + /* [id] */ HRESULT ( STDMETHODCALLTYPE *CStartReceiveMessage )( + IWeChatRobot * This, + /* [retval][out] */ int *__result); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *CReceiveMessage )( + IWeChatRobot * This, + /* [retval][out] */ VARIANT *__result); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *CStopReceiveMessage )( + IWeChatRobot * This, + /* [retval][out] */ int *__result); + END_INTERFACE } IWeChatRobotVtbl; @@ -362,6 +383,15 @@ EXTERN_C const IID IID_IWeChatRobot; #define IWeChatRobot_CGetComWorkPath(This,__result) \ ( (This)->lpVtbl -> CGetComWorkPath(This,__result) ) +#define IWeChatRobot_CStartReceiveMessage(This,__result) \ + ( (This)->lpVtbl -> CStartReceiveMessage(This,__result) ) + +#define IWeChatRobot_CReceiveMessage(This,__result) \ + ( (This)->lpVtbl -> CReceiveMessage(This,__result) ) + +#define IWeChatRobot_CStopReceiveMessage(This,__result) \ + ( (This)->lpVtbl -> CStopReceiveMessage(This,__result) ) + #endif /* COBJMACROS */ diff --git a/CWeChatRobot/WeChatRobotCOM_p.c b/CWeChatRobot/WeChatRobotCOM_p.c index 9ef89b8b2d03cdfb47dcc68fe54efa9d008e19fd..5591a4bd0bbc4024b15d9f494d1fe508b0366236 100644 --- a/CWeChatRobot/WeChatRobotCOM_p.c +++ b/CWeChatRobot/WeChatRobotCOM_p.c @@ -49,7 +49,7 @@ #include "WeChatRobotCOM_i.h" #define TYPE_FORMAT_STRING_SIZE 1221 -#define PROC_FORMAT_STRING_SIZE 631 +#define PROC_FORMAT_STRING_SIZE 739 #define EXPR_FORMAT_STRING_SIZE 1 #define TRANSMIT_AS_TABLE_SIZE 0 #define WIRE_MARSHAL_TABLE_SIZE 2 @@ -657,6 +657,98 @@ static const WeChatRobotCOM_MIDL_PROC_FORMAT_STRING WeChatRobotCOM__MIDL_ProcFor /* 628 */ 0x8, /* FC_LONG */ 0x0, /* 0 */ + /* Procedure CStartReceiveMessage */ + +/* 630 */ 0x33, /* FC_AUTO_HANDLE */ + 0x6c, /* Old Flags: object, Oi2 */ +/* 632 */ NdrFcLong( 0x0 ), /* 0 */ +/* 636 */ NdrFcShort( 0x16 ), /* 22 */ +/* 638 */ NdrFcShort( 0xc ), /* x86 Stack size/offset = 12 */ +/* 640 */ NdrFcShort( 0x0 ), /* 0 */ +/* 642 */ NdrFcShort( 0x24 ), /* 36 */ +/* 644 */ 0x44, /* Oi2 Flags: has return, has ext, */ + 0x2, /* 2 */ +/* 646 */ 0x8, /* 8 */ + 0x41, /* Ext Flags: new corr desc, has range on conformance */ +/* 648 */ NdrFcShort( 0x0 ), /* 0 */ +/* 650 */ NdrFcShort( 0x0 ), /* 0 */ +/* 652 */ NdrFcShort( 0x0 ), /* 0 */ + + /* Parameter __result */ + +/* 654 */ NdrFcShort( 0x2150 ), /* Flags: out, base type, simple ref, srv alloc size=8 */ +/* 656 */ NdrFcShort( 0x4 ), /* x86 Stack size/offset = 4 */ +/* 658 */ 0x8, /* FC_LONG */ + 0x0, /* 0 */ + + /* Return value */ + +/* 660 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */ +/* 662 */ NdrFcShort( 0x8 ), /* x86 Stack size/offset = 8 */ +/* 664 */ 0x8, /* FC_LONG */ + 0x0, /* 0 */ + + /* Procedure CReceiveMessage */ + +/* 666 */ 0x33, /* FC_AUTO_HANDLE */ + 0x6c, /* Old Flags: object, Oi2 */ +/* 668 */ NdrFcLong( 0x0 ), /* 0 */ +/* 672 */ NdrFcShort( 0x17 ), /* 23 */ +/* 674 */ NdrFcShort( 0xc ), /* x86 Stack size/offset = 12 */ +/* 676 */ NdrFcShort( 0x0 ), /* 0 */ +/* 678 */ NdrFcShort( 0x8 ), /* 8 */ +/* 680 */ 0x45, /* Oi2 Flags: srv must size, has return, has ext, */ + 0x2, /* 2 */ +/* 682 */ 0x8, /* 8 */ + 0x43, /* Ext Flags: new corr desc, clt corr check, has range on conformance */ +/* 684 */ NdrFcShort( 0x1 ), /* 1 */ +/* 686 */ NdrFcShort( 0x0 ), /* 0 */ +/* 688 */ NdrFcShort( 0x0 ), /* 0 */ + + /* Parameter __result */ + +/* 690 */ NdrFcShort( 0x4113 ), /* Flags: must size, must free, out, simple ref, srv alloc size=16 */ +/* 692 */ NdrFcShort( 0x4 ), /* x86 Stack size/offset = 4 */ +/* 694 */ NdrFcShort( 0x4ac ), /* Type Offset=1196 */ + + /* Return value */ + +/* 696 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */ +/* 698 */ NdrFcShort( 0x8 ), /* x86 Stack size/offset = 8 */ +/* 700 */ 0x8, /* FC_LONG */ + 0x0, /* 0 */ + + /* Procedure CStopReceiveMessage */ + +/* 702 */ 0x33, /* FC_AUTO_HANDLE */ + 0x6c, /* Old Flags: object, Oi2 */ +/* 704 */ NdrFcLong( 0x0 ), /* 0 */ +/* 708 */ NdrFcShort( 0x18 ), /* 24 */ +/* 710 */ NdrFcShort( 0xc ), /* x86 Stack size/offset = 12 */ +/* 712 */ NdrFcShort( 0x0 ), /* 0 */ +/* 714 */ NdrFcShort( 0x24 ), /* 36 */ +/* 716 */ 0x44, /* Oi2 Flags: has return, has ext, */ + 0x2, /* 2 */ +/* 718 */ 0x8, /* 8 */ + 0x41, /* Ext Flags: new corr desc, has range on conformance */ +/* 720 */ NdrFcShort( 0x0 ), /* 0 */ +/* 722 */ NdrFcShort( 0x0 ), /* 0 */ +/* 724 */ NdrFcShort( 0x0 ), /* 0 */ + + /* Parameter __result */ + +/* 726 */ NdrFcShort( 0x2150 ), /* Flags: out, base type, simple ref, srv alloc size=8 */ +/* 728 */ NdrFcShort( 0x4 ), /* x86 Stack size/offset = 4 */ +/* 730 */ 0x8, /* FC_LONG */ + 0x0, /* 0 */ + + /* Return value */ + +/* 732 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */ +/* 734 */ NdrFcShort( 0x8 ), /* x86 Stack size/offset = 8 */ +/* 736 */ 0x8, /* FC_LONG */ + 0x0, /* 0 */ + 0x0 } }; @@ -1504,7 +1596,10 @@ static const unsigned short IWeChatRobot_FormatStringOffsetTable[] = 480, 516, 558, - 594 + 594, + 630, + 666, + 702 }; static const MIDL_STUBLESS_PROXY_INFO IWeChatRobot_ProxyInfo = @@ -1528,7 +1623,7 @@ static const MIDL_SERVER_INFO IWeChatRobot_ServerInfo = 0, 0, 0}; -CINTERFACE_PROXY_VTABLE(22) _IWeChatRobotProxyVtbl = +CINTERFACE_PROXY_VTABLE(25) _IWeChatRobotProxyVtbl = { &IWeChatRobot_ProxyInfo, &IID_IWeChatRobot, @@ -1553,7 +1648,10 @@ CINTERFACE_PROXY_VTABLE(22) _IWeChatRobotProxyVtbl = (void *) (INT_PTR) -1 /* IWeChatRobot::CCheckFriendStatusInit */ , (void *) (INT_PTR) -1 /* IWeChatRobot::CCheckFriendStatus */ , (void *) (INT_PTR) -1 /* IWeChatRobot::CCheckFriendStatusFinish */ , - (void *) (INT_PTR) -1 /* IWeChatRobot::CGetComWorkPath */ + (void *) (INT_PTR) -1 /* IWeChatRobot::CGetComWorkPath */ , + (void *) (INT_PTR) -1 /* IWeChatRobot::CStartReceiveMessage */ , + (void *) (INT_PTR) -1 /* IWeChatRobot::CReceiveMessage */ , + (void *) (INT_PTR) -1 /* IWeChatRobot::CStopReceiveMessage */ }; @@ -1577,6 +1675,9 @@ static const PRPC_STUB_FUNCTION IWeChatRobot_table[] = NdrStubCall2, NdrStubCall2, NdrStubCall2, + NdrStubCall2, + NdrStubCall2, + NdrStubCall2, NdrStubCall2 }; @@ -1584,7 +1685,7 @@ CInterfaceStubVtbl _IWeChatRobotStubVtbl = { &IID_IWeChatRobot, &IWeChatRobot_ServerInfo, - 22, + 25, &IWeChatRobot_table[-3], CStdStubBuffer_DELEGATING_METHODS }; diff --git a/CWeChatRobot/pch.cpp b/CWeChatRobot/pch.cpp index 9de87cd8b391719fbd0da05c954fbd49310269d1..78abcf9f7e85da89d1e75134a2f83ff45a59e2da 100644 --- a/CWeChatRobot/pch.cpp +++ b/CWeChatRobot/pch.cpp @@ -23,6 +23,11 @@ DWORD CheckFriendStatusInitRemoteOffset = 0x0; DWORD CheckFriendStatusRemoteOffset = 0x0; DWORD CheckFriendStatusFinishRemoteOffset = 0x0; +DWORD HookReceiveMessageRemoteOffset = 0x0; +DWORD UnHookReceiveMessageRemoteOffset = 0x0; +DWORD GetHeadMessageRemoteOffset = 0x0; +DWORD PopHeadMessageRemoteOffset = 0x0; + wstring SelfInfoString = L""; HANDLE hProcess = NULL; @@ -117,6 +122,15 @@ void GetProcOffset(wchar_t* workPath) { DWORD CheckFriendStatusFinishRemoteAddr = (DWORD)GetProcAddress(hd, CheckFriendStatusFinishRemote); CheckFriendStatusFinishRemoteOffset = CheckFriendStatusFinishRemoteAddr - WeChatBase; + DWORD HookReceiveMessageRemoteAddr = (DWORD)GetProcAddress(hd, HookReceiveMessageRemote); + HookReceiveMessageRemoteOffset = HookReceiveMessageRemoteAddr - WeChatBase; + DWORD UnHookReceiveMessageRemoteAddr = (DWORD)GetProcAddress(hd, UnHookReceiveMessageRemote); + UnHookReceiveMessageRemoteOffset = UnHookReceiveMessageRemoteAddr - WeChatBase; + DWORD GetHeadMessageRemoteAddr = (DWORD)GetProcAddress(hd, GetHeadMessageRemote); + GetHeadMessageRemoteOffset = GetHeadMessageRemoteAddr - WeChatBase; + DWORD PopHeadMessageRemoteAddr = (DWORD)GetProcAddress(hd, PopHeadMessageRemote); + PopHeadMessageRemoteOffset = PopHeadMessageRemoteAddr - WeChatBase; + FreeLibrary(hd); delete[] dllpath; dllpath = NULL; @@ -156,6 +170,7 @@ DWORD StopRobotService() { return 1; DWORD wxPid = GetWeChatPid(); CheckFriendStatusFinish(); + StopReceiveMessage(); RemoveDll(wxPid); ZeroMemory((wchar_t*)SelfInfoString.c_str(), SelfInfoString.length() * 2 + 2); CloseHandle(hProcess); diff --git a/CWeChatRobot/robotdata.h b/CWeChatRobot/robotdata.h index 3276bbfcd6102cb171dc9b4ee9ef453809d8d2c6..a4c345b155673f72279539e7e52ece26d60ce89f 100644 --- a/CWeChatRobot/robotdata.h +++ b/CWeChatRobot/robotdata.h @@ -9,6 +9,7 @@ #include "UserInfo.h" #include "SelfInfo.h" #include "CheckFriendStatus.h" +#include "ReceiveMessage.h" extern HANDLE hProcess; extern DWORD SendImageOffset; @@ -32,6 +33,11 @@ extern DWORD CheckFriendStatusInitRemoteOffset; extern DWORD CheckFriendStatusRemoteOffset; extern DWORD CheckFriendStatusFinishRemoteOffset; +extern DWORD HookReceiveMessageRemoteOffset; +extern DWORD UnHookReceiveMessageRemoteOffset; +extern DWORD GetHeadMessageRemoteOffset; +extern DWORD PopHeadMessageRemoteOffset; + #define dllname L"DWeChatRobot.dll" @@ -53,4 +59,9 @@ extern DWORD CheckFriendStatusFinishRemoteOffset; #define CheckFriendStatusInitRemote "CheckFriendStatusInitRemote" #define CheckFriendStatusRemote "CheckFriendStatusRemote" -#define CheckFriendStatusFinishRemote "CheckFriendStatusFinishRemote" \ No newline at end of file +#define CheckFriendStatusFinishRemote "CheckFriendStatusFinishRemote" + +#define HookReceiveMessageRemote "HookReceiveMessage" +#define UnHookReceiveMessageRemote "UnHookReceiveMessage" +#define GetHeadMessageRemote "GetHeadMessage" +#define PopHeadMessageRemote "PopHeadMessage" \ No newline at end of file diff --git a/DWeChatRobot/DWeChatRobot.vcxproj b/DWeChatRobot/DWeChatRobot.vcxproj index 968993b6c16d54560a1953b5b1c325ca723bda1d..b9f6e00689aca8854ffb4e18de7b61b4ced66e4c 100644 --- a/DWeChatRobot/DWeChatRobot.vcxproj +++ b/DWeChatRobot/DWeChatRobot.vcxproj @@ -159,6 +159,7 @@ + @@ -177,6 +178,7 @@ Create Create + diff --git a/DWeChatRobot/DWeChatRobot.vcxproj.filters b/DWeChatRobot/DWeChatRobot.vcxproj.filters index d70653125d321d64851e0b3e33bc991f6f66c2e9..0632d35499547b31bacd258c0a028a96750c5a91 100644 --- a/DWeChatRobot/DWeChatRobot.vcxproj.filters +++ b/DWeChatRobot/DWeChatRobot.vcxproj.filters @@ -52,6 +52,9 @@ {54c9691e-786d-4279-874d-b1e35673a666} + + {4763248d-1490-48c0-aa63-bf3265cf8178} + @@ -90,6 +93,9 @@ 微信日志 + + 接收消息 + @@ -128,5 +134,8 @@ 微信日志 + + 接收消息 + \ No newline at end of file diff --git a/DWeChatRobot/ReceiveMessage.cpp b/DWeChatRobot/ReceiveMessage.cpp new file mode 100644 index 0000000000000000000000000000000000000000..564bafcae1231a6754d0873386c73ad7f8fc9d14 --- /dev/null +++ b/DWeChatRobot/ReceiveMessage.cpp @@ -0,0 +1,99 @@ +#include "pch.h" +#include + +#define ReceiveMessageHookOffset 0x034A4F60 - 0x02FE0000 +#define ReceiveMessageNextCallOffset 0x034A0CE0 - 0x02FE0000 + +struct messageStruct { + DWORD messagetype; + wchar_t* sender; + DWORD l_sender; + wchar_t* wxid; + DWORD l_wxid; + wchar_t* message; + DWORD l_message; +}; + +vector messageVector; + +BOOL ReceiveMessageHooked = false; +char OldReceiveMessageAsmCode[5] = { 0 }; + +DWORD ReceiveMessageHookAddress = GetWeChatWinBase() + ReceiveMessageHookOffset; +DWORD ReceiveMessageNextCall = GetWeChatWinBase() + ReceiveMessageNextCallOffset; +DWORD JmpBackAddress = ReceiveMessageHookAddress + 0x5; + +VOID ReceiveMessage(DWORD messageAddr) { + messageStruct message = { 0 }; + message.messagetype = *(DWORD*)(messageAddr + 0x38); + + DWORD length = *(DWORD*)(messageAddr + 0x48 + 0x4); + message.sender = new wchar_t[length + 1]; + ZeroMemory(message.sender, (length + 1) * 2); + memcpy(message.sender,(wchar_t*)(*(DWORD*)(messageAddr + 0x48)),length * 2); + message.l_sender = length; + + length = *(DWORD*)(messageAddr + 0x170 + 0x4); + if (length == 0) { + message.wxid = new wchar_t[message.l_sender + 1]; + ZeroMemory(message.wxid, (message.l_sender + 1) * 2); + memcpy(message.wxid, (wchar_t*)(*(DWORD*)(messageAddr + 0x48)), message.l_sender * 2); + message.l_wxid = message.l_sender; + } + else { + message.wxid = new wchar_t[length + 1]; + ZeroMemory(message.wxid, (length + 1) * 2); + memcpy(message.wxid, (wchar_t*)(*(DWORD*)(messageAddr + 0x170)), length * 2); + message.l_wxid = length; + } + + length = *(DWORD*)(messageAddr + 0x70 + 0x4); + message.message = new wchar_t[length + 1]; + ZeroMemory(message.message, (length + 1) * 2); + memcpy(message.message, (wchar_t*)(*(DWORD*)(messageAddr + 0x70)), length * 2); + message.l_message = length; + + messageVector.push_back(message); +} + +DWORD GetHeadMessage() { + if (messageVector.size() == 0) + return 0; + return (DWORD)&messageVector[0].messagetype; +} + +VOID PopHeadMessage() { + if (messageVector.size() == 0) + return; + vector::iterator k = messageVector.begin(); + messageVector.erase(k); +} + +_declspec(naked) void dealReceiveMessage() { + __asm { + pushad; + pushfd; + mov edi, [eax]; + push edi; + call ReceiveMessage; + add esp, 0x4; + popfd; + popad; + call ReceiveMessageNextCall; + jmp JmpBackAddress; + } +} + +VOID HookReceiveMessage() { + if (ReceiveMessageHooked) + return; + HookAnyAddress(ReceiveMessageHookAddress,(LPVOID)dealReceiveMessage,OldReceiveMessageAsmCode); + ReceiveMessageHooked = TRUE; +} + +VOID UnHookReceiveMessage() { + if (!ReceiveMessageHooked) + return; + UnHookAnyAddress(ReceiveMessageHookAddress,OldReceiveMessageAsmCode); + ReceiveMessageHooked = FALSE; +} \ No newline at end of file diff --git a/DWeChatRobot/ReceiveMessage.h b/DWeChatRobot/ReceiveMessage.h new file mode 100644 index 0000000000000000000000000000000000000000..8d1ac39250ebe0305158fd58c74c1c97585539f7 --- /dev/null +++ b/DWeChatRobot/ReceiveMessage.h @@ -0,0 +1,7 @@ +#pragma once +#include +extern "C" __declspec(dllexport) DWORD GetHeadMessage(); +extern "C" __declspec(dllexport) VOID PopHeadMessage(); + +extern "C" __declspec(dllexport) VOID HookReceiveMessage(); +extern "C" __declspec(dllexport) VOID UnHookReceiveMessage(); \ No newline at end of file diff --git a/DWeChatRobot/SelfInfo.cpp b/DWeChatRobot/SelfInfo.cpp index 5d0be3b0305d23a62e647b7393307dcbd9c02d9f..bc13a70f3193f901aa75218fc2f6f41f57448352 100644 --- a/DWeChatRobot/SelfInfo.cpp +++ b/DWeChatRobot/SelfInfo.cpp @@ -12,7 +12,7 @@ struct SelfInfoStruct { DWORD GetSelfInfoRemote() { DWORD WeChatWinBase = GetWeChatWinBase(); vector SelfInfoAddr = { - *(DWORD*)(WeChatWinBase + 0x222EB3C), + WeChatWinBase + 0x222EB3C, WeChatWinBase + 0x222ED30, WeChatWinBase + 0x222EBB4, *(DWORD*)(WeChatWinBase + 0x222ECEC), @@ -52,6 +52,19 @@ DWORD GetSelfInfoRemote() { temp = (*((DWORD*)SelfInfoAddr[i]) != 0) ? (char*)(*(DWORD*)SelfInfoAddr[i]) : (char*)"null"; } } + else if (!SelfInfoKey[i].compare(L"\"wxId\"")) { + char wxidbuffer[0x100] = { 0 }; + sprintf_s(wxidbuffer, "%s", (char*)SelfInfoAddr[i]); + if (strlen(wxidbuffer) < 0x6 || strlen(wxidbuffer) > 0x14) + { + //µ΢ź ΢IDõַ + temp = (char*)(*(DWORD*)SelfInfoAddr[i]); + } + else + { + temp = (char*)SelfInfoAddr[i]; + } + } else { temp = (char*)SelfInfoAddr[i]; if (strlen(temp) == 0) diff --git a/DWeChatRobot/SendArticle.cpp b/DWeChatRobot/SendArticle.cpp index b1507b800796205f8715a205443114414434e47f..54132ba9c3e6642a9be702597a12abedf1aa7d39 100644 --- a/DWeChatRobot/SendArticle.cpp +++ b/DWeChatRobot/SendArticle.cpp @@ -25,6 +25,22 @@ VOID SendArticleRemote(LPVOID lparameter) { SendArticle(wxid,title,abstract,url); } +DWORD GetSelfWxIdAddr() { + DWORD baseAddr = GetWeChatWinBase() + 0x222EB3C; + char wxidbuffer[0x100] = { 0 }; + DWORD SelfWxIdAddr = 0x0; + sprintf_s(wxidbuffer, "%s", (char*)baseAddr); + if (strlen(wxidbuffer) < 0x6 || strlen(wxidbuffer) > 0x14) + { + SelfWxIdAddr = *(DWORD*)baseAddr; + } + else + { + SelfWxIdAddr = baseAddr; + } + return SelfWxIdAddr; +} + BOOL __stdcall SendArticle(wchar_t* wxid,wchar_t* title, wchar_t* abstract, wchar_t* url) { DWORD WeChatWinBase = GetWeChatWinBase(); DWORD SendArticleCall1 = WeChatWinBase + SendArticleCall1Offset; @@ -37,7 +53,7 @@ BOOL __stdcall SendArticle(wchar_t* wxid,wchar_t* title, wchar_t* abstract, wcha DWORD SendArticleClearCacheCall1 = WeChatWinBase + SendArticleClearCacheCall1Offset; DWORD SendArticleClearCacheCall2 = WeChatWinBase + SendArticleClearCacheCall2Offset; // Լwxid - char* sselfwxid = (char*)(*(DWORD*)(WeChatWinBase + 0x222EB3C)); + char* sselfwxid = (char*)GetSelfWxIdAddr(); wchar_t* wselfwxid = new wchar_t[strlen(sselfwxid) + 1]; MultiByteToWideChar(CP_ACP, MB_COMPOSITE, sselfwxid, -1, wselfwxid, strlen(sselfwxid) + 1); // xml diff --git a/DWeChatRobot/dllmain.cpp b/DWeChatRobot/dllmain.cpp index 58eeec6e1178d60db769da6b1d182a4dc952b794..8cd56b2198782d7a47a721b06ecf1b7031073755 100644 --- a/DWeChatRobot/dllmain.cpp +++ b/DWeChatRobot/dllmain.cpp @@ -20,7 +20,6 @@ BOOL APIENTRY DllMain( HMODULE hModule, printf("SendArticle 0x%08X\n", (DWORD)SendArticle); printf("SendCard 0x%08X\n", (DWORD)SendCard); printf("CheckFriendStatus 0x%08X\n", (DWORD)CheckFriendStatus); - HookLogMsgInfo(); #endif break; } diff --git a/DWeChatRobot/pch.h b/DWeChatRobot/pch.h index d3a6383d489430a61305b918c8997b703f07d0cc..b46c8030800dcbf4a7d83c5f942465edb78ef6df 100644 --- a/DWeChatRobot/pch.h +++ b/DWeChatRobot/pch.h @@ -21,6 +21,7 @@ #include "SendCard.h" #include "CheckFriendStatus.h" #include "LogMsgInfo.h" +#include "ReceiveMessage.h" #endif //PCH_H using namespace std; diff --git a/Release/CWeChatRobot.exe b/Release/CWeChatRobot.exe index 3789330b5058df51a8f8da512088e49af8ad45ba..5dfff03e01023bb3076e378d77ef6f44d3faf916 100644 Binary files a/Release/CWeChatRobot.exe and b/Release/CWeChatRobot.exe differ diff --git a/Release/DWeChatRobot.dll b/Release/DWeChatRobot.dll index 43536dde33e1e7441a53ec169d4e6f2e401fbe86..e30983f1677c03d0dfc6a9f9a322c1a5c362214c 100644 Binary files a/Release/DWeChatRobot.dll and b/Release/DWeChatRobot.dll differ diff --git a/wxRobot.py b/wxRobot.py index 06e85749f38f05afc696091822924159c3a5cd91..ec1adc843b3d3b9c410fa4be36af79fd0be06e97 100644 --- a/wxRobot.py +++ b/wxRobot.py @@ -9,6 +9,8 @@ Created on Thu Feb 24 16:19:48 2022 # need `pip install comtypes` import comtypes.client import ast +import threading +import time class ChatSession(): def __init__(self,robot,wxid): @@ -41,6 +43,7 @@ class WeChatRobot(): self.robot = comtypes.client.CreateObject("WeChatRobot.CWeChatRobot") self.AddressBook = [] self.myinfo = {} + self.ReceiveMessageStarted = False def StartService(self): status = self.robot.CStartRobotService() @@ -57,6 +60,7 @@ class WeChatRobot(): return self.myinfo def StopService(self): + self.StopReceiveMessage() return self.robot.CStopRobotService() def GetAddressBook(self): @@ -147,6 +151,44 @@ class WeChatRobot(): except KeyError: return "未知状态:{}".format( hex(status).upper().replace('0X','0x')) + + def ReceiveMessage(self,CallBackFunc = None): + comtypes.CoInitialize() + ThreadRobot = comtypes.client.CreateObject("WeChatRobot.CWeChatRobot") + + while self.ReceiveMessageStarted: + try: + message = dict(ThreadRobot.CReceiveMessage()) + if CallBackFunc: + CallBackFunc(ThreadRobot,message) + except IndexError: + message = None + time.sleep(0.5) + comtypes.CoUninitialize() + + # 接收消息的函数,可以添加一个回调 + def StartReceiveMessage(self,CallBackFunc = None): + self.ReceiveMessageStarted = True + status = self.robot.CStartReceiveMessage() + self.ReceiveMessageThread = threading.Thread(target = self.ReceiveMessage,args= (CallBackFunc,)) + self.ReceiveMessageThread.daemon = True + self.ReceiveMessageThread.start() + return status + + def StopReceiveMessage(self): + self.ReceiveMessageStarted = False + try: + self.ReceiveMessageThread.join() + except: + pass + status = self.robot.CStopReceiveMessage() + return status + +# 一个示例回调,将收到的文本消息转发给filehelper +def ReceiveMessageCallBack(robot,message): + if message['type'] == 1 and message['sender'] != 'filehelper': + robot.CSendText('filehelper',message['message']) + if message['sender'] != 'filehelper': print(message) def test_SendText(): import os @@ -165,13 +207,12 @@ def test_SendText(): session.SendText('好友信息:{}'.format(str(filehelper.get('wxNickName')))) if os.path.exists(imgpath): session.SendImage(imgpath) if os.path.exists(filepath): session.SendFile(filepath) - session.SendArticle("PC微信逆向--获取通讯录","确定不来看看么?","https://www.ljczero.top/article/2022/3/13/133.html") + session.SendArticle("天气预报","点击查看","http://www.baidu.com") shared = wx.GetFriendByWxNickName("码农翻身") if shared: session.SendCard(shared.get('wxid'),shared.get('wxNickName')) wx.StopService() def test_FriendStatus(): - import time f = open('Friendstatus.txt','wt',encoding = 'utf-8') wx = WeChatRobot() wx.StartService() @@ -190,6 +231,13 @@ def test_FriendStatus(): break f.close() wx.StopService() + +def test_ReceiveMessage(): + wx = WeChatRobot() + wx.StartService() + wx.StartReceiveMessage(CallBackFunc = ReceiveMessageCallBack) + input('按Enter可退出') + wx.StopService() if __name__ == '__main__': - test_SendText() \ No newline at end of file + test_ReceiveMessage() \ No newline at end of file diff --git a/wxRobot/bin/Release/wxRobot.exe b/wxRobot/bin/Release/wxRobot.exe index 0cbc32b2b82f4af7651534b081f330de847637d3..fb130d9d6d1f61d153c2163644505db96be0a3b1 100644 Binary files a/wxRobot/bin/Release/wxRobot.exe and b/wxRobot/bin/Release/wxRobot.exe differ