diff --git a/CWeChatRobot/HookImageMessage.cpp b/CWeChatRobot/HookImageMessage.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f85b28c2b7c28df7a0faedaab82b1c36e50be997 --- /dev/null +++ b/CWeChatRobot/HookImageMessage.cpp @@ -0,0 +1,35 @@ +#include "pch.h" + +BOOL HookImageMsg(wchar_t* savepath) { + if (!hProcess) + return 1; + DWORD WeChatRobotBase = GetWeChatRobotBase(); + DWORD dwId = 0; + DWORD dwRet = 0x0; + LPVOID savepathaddr = VirtualAllocEx(hProcess, NULL, 1, MEM_COMMIT, PAGE_READWRITE); + DWORD dwWriteSize = 0; + if (!savepathaddr) + return 1; + WriteProcessMemory(hProcess, savepathaddr, savepath, wcslen(savepath) * 2 + 2, &dwWriteSize); + DWORD HookImageMsgRemoteAddr = WeChatRobotBase + HookImageMsgRemoteOffset; + HANDLE hThread = ::CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)HookImageMsgRemoteAddr, savepathaddr, 0, &dwId); + if (hThread) { + WaitForSingleObject(hThread, INFINITE); + GetExitCodeThread(hThread, &dwRet); + CloseHandle(hThread); + } + VirtualFreeEx(hProcess, savepathaddr, 0, MEM_RELEASE); + return dwRet == 0; +} + +void UnHookImageMsg() { + if (!hProcess) + return; + DWORD dwId = 0x0; + DWORD UnHookImageMsgRemoteAddr = GetWeChatRobotBase() + UnHookImageMsgRemoteOffset; + HANDLE hThread = ::CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)UnHookImageMsgRemoteAddr, NULL, 0, &dwId); + if (hThread) { + WaitForSingleObject(hThread, INFINITE); + CloseHandle(hThread); + } +} \ No newline at end of file diff --git a/CWeChatRobot/HookVoiceMessage.cpp b/CWeChatRobot/HookVoiceMessage.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b0ae623e1ad32a36346f14bda70a27d6e373a55b --- /dev/null +++ b/CWeChatRobot/HookVoiceMessage.cpp @@ -0,0 +1,35 @@ +#include "pch.h" + +BOOL HookVoiceMsg(wchar_t* savepath) { + if (!hProcess) + return 1; + DWORD WeChatRobotBase = GetWeChatRobotBase(); + DWORD dwId = 0; + DWORD dwRet = 0x0; + LPVOID savepathaddr = VirtualAllocEx(hProcess, NULL, 1, MEM_COMMIT, PAGE_READWRITE); + DWORD dwWriteSize = 0; + if (!savepathaddr) + return 1; + WriteProcessMemory(hProcess, savepathaddr, savepath, wcslen(savepath) * 2 + 2, &dwWriteSize); + DWORD HookVoiceMsgRemoteAddr = WeChatRobotBase + HookVoiceMsgRemoteOffset; + HANDLE hThread = ::CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)HookVoiceMsgRemoteAddr, savepathaddr, 0, &dwId); + if (hThread) { + WaitForSingleObject(hThread, INFINITE); + GetExitCodeThread(hThread, &dwRet); + CloseHandle(hThread); + } + VirtualFreeEx(hProcess, savepathaddr, 0, MEM_RELEASE); + return dwRet == 0; +} + +void UnHookVoiceMsg() { + if (!hProcess) + return; + DWORD dwId = 0x0; + DWORD UnHookVoiceMsgRemoteAddr = GetWeChatRobotBase() + UnHookVoiceMsgRemoteOffset; + HANDLE hThread = ::CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)UnHookVoiceMsgRemoteAddr, NULL, 0, &dwId); + if (hThread) { + WaitForSingleObject(hThread, INFINITE); + CloseHandle(hThread); + } +} \ No newline at end of file diff --git a/CWeChatRobot/ReceiveMessage.h b/CWeChatRobot/ReceiveMessage.h index 8df94ee13c79617260a3d75b5612cb9b6427fd10..423a6565d2c9b45ae91f2bc4e4250ab162f6d1ed 100644 --- a/CWeChatRobot/ReceiveMessage.h +++ b/CWeChatRobot/ReceiveMessage.h @@ -2,4 +2,9 @@ #include BOOL StartReceiveMessage(); SAFEARRAY* ReceiveMessage(); -BOOL StopReceiveMessage(); \ No newline at end of file +BOOL StopReceiveMessage(); + +BOOL HookImageMsg(wchar_t* savepath); +BOOL HookVoiceMsg(wchar_t* savepath); +void UnHookImageMsg(); +void UnHookVoiceMsg(); \ No newline at end of file diff --git a/CWeChatRobot/WeChatRobot.cpp b/CWeChatRobot/WeChatRobot.cpp index 0adb26dfcb4ebf0022cc4cde4d36d84f1eca461f..c1c53990a92b3c06e37540ffceb4f0d9a4d12e21 100644 --- a/CWeChatRobot/WeChatRobot.cpp +++ b/CWeChatRobot/WeChatRobot.cpp @@ -309,4 +309,49 @@ STDMETHODIMP CWeChatRobot::CSearchContactByNet(BSTR keyword, VARIANT* __result) STDMETHODIMP CWeChatRobot::CAddBrandContact(BSTR PublicId, int* __result) { *__result = AddBrandContact(PublicId); return S_OK; +} + +/* +* 参数1:保存路径 +* 参数2:预返回的值,调用时无需提供 +*/ +STDMETHODIMP CWeChatRobot::CHookVoiceMsg(BSTR savepath, int* __result) { + *__result = HookVoiceMsg(savepath); + return S_OK; +} + +/* +* 参数1:预返回的值,调用时无需提供 +*/ +STDMETHODIMP CWeChatRobot::CUnHookVoiceMsg(int* __result) { + UnHookVoiceMsg(); + *__result = 0; + return S_OK; +} + +/* +* 参数1:保存路径 +* 参数2:预返回的值,调用时无需提供 +*/ +STDMETHODIMP CWeChatRobot::CHookImageMsg(BSTR savepath, int* __result) { + *__result = HookImageMsg(savepath); + return S_OK; +} + +/* +* 参数1:预返回的值,调用时无需提供 +*/ +STDMETHODIMP CWeChatRobot::CUnHookImageMsg(int* __result) { + UnHookImageMsg(); + *__result = 0; + return S_OK; +} + +/* +* 参数1:版本号 +* 参数2:预返回的值,调用时无需提供 +*/ +STDMETHODIMP CWeChatRobot::CChangeWeChatVer(BSTR verStr, int* __result) { + *__result = ChangeWeChatVer(verStr); + return S_OK; } \ No newline at end of file diff --git a/CWeChatRobot/WeChatRobot.h b/CWeChatRobot/WeChatRobot.h index 83d9244ec7098ab1acef794d4a65bbc637cff299..9c049ecb1c777167465d9caa51d9a11bee0659cd 100644 --- a/CWeChatRobot/WeChatRobot.h +++ b/CWeChatRobot/WeChatRobot.h @@ -81,6 +81,11 @@ public: STDMETHODIMP CStartWeChat(int* __result); STDMETHODIMP CSearchContactByNet(BSTR keyword, VARIANT* __result); STDMETHODIMP CAddBrandContact(BSTR PublicId, int* __result); + STDMETHODIMP CHookVoiceMsg(BSTR savepath, int* __result); + STDMETHODIMP CUnHookVoiceMsg(int* __result); + STDMETHODIMP CHookImageMsg(BSTR savepath, int* __result); + STDMETHODIMP CUnHookImageMsg(int* __result); + STDMETHODIMP CChangeWeChatVer(BSTR verStr, int* __result); }; OBJECT_ENTRY_AUTO(__uuidof(WeChatRobot), CWeChatRobot) diff --git a/CWeChatRobot/WeChatRobotCOM.idl b/CWeChatRobot/WeChatRobotCOM.idl index c95bc11282b9d6ff36c6373b74165704e251fc6a..2f821564620713d609b1c45a5c71aa8abd340c5f 100644 --- a/CWeChatRobot/WeChatRobotCOM.idl +++ b/CWeChatRobot/WeChatRobotCOM.idl @@ -46,6 +46,11 @@ interface IWeChatRobot : IDispatch [id(28)] HRESULT CStartWeChat([out, retval] int* __result); [id(29)] HRESULT CSearchContactByNet([in] BSTR keyword, [out, retval] VARIANT* __result); [id(30)] HRESULT CAddBrandContact([in] BSTR PublicId, [out, retval] int* __result); + [id(31)] HRESULT CHookVoiceMsg([in] BSTR savepath, [out, retval] int* __result); + [id(32)] HRESULT CUnHookVoiceMsg([out, retval] int* __result); + [id(33)] HRESULT CHookImageMsg([in] BSTR savepath, [out, retval] int* __result); + [id(34)] HRESULT CUnHookImageMsg([out, retval] int* __result); + [id(35)] HRESULT CChangeWeChatVer([in] BSTR verStr, [out, retval] int* __result); }; [ uuid(721abb35-141a-4aa2-94f2-762e2833fa6c), diff --git a/CWeChatRobot/WeChatRobotCOM.vcxproj b/CWeChatRobot/WeChatRobotCOM.vcxproj index b5147d56c06a1a98b0912111a8715dc203ef1e76..b979bff7d7c7712f6face7700228edc36217eecf 100644 --- a/CWeChatRobot/WeChatRobotCOM.vcxproj +++ b/CWeChatRobot/WeChatRobotCOM.vcxproj @@ -236,6 +236,7 @@ + @@ -248,6 +249,8 @@ + + Create @@ -282,6 +285,7 @@ + diff --git a/CWeChatRobot/WeChatRobotCOM.vcxproj.filters b/CWeChatRobot/WeChatRobotCOM.vcxproj.filters index e16145c25ff93a58612426ec8e6bd7ad4bc937ec..3d4162de3327449d0d6aaf13885afc958d1d9a42 100644 --- a/CWeChatRobot/WeChatRobotCOM.vcxproj.filters +++ b/CWeChatRobot/WeChatRobotCOM.vcxproj.filters @@ -83,6 +83,9 @@ {cdd9e8b4-4576-499c-b20e-60e05911f6d6} + + {4214a216-3efc-48db-8fda-8a33066b2db2} + @@ -163,6 +166,9 @@ 好友相关\添加好友 + + 微信版本 + @@ -243,6 +249,15 @@ 好友相关\添加好友 + + 接收消息 + + + 接收消息 + + + 微信版本 + diff --git a/CWeChatRobot/WeChatRobotCOM_i.h b/CWeChatRobot/WeChatRobotCOM_i.h index bb0ccdf5b2eecdec57b665e1edb7ea6bf42cf660..ce4056417219991d28706209af76bd9cd3b3a5b9 100644 --- a/CWeChatRobot/WeChatRobotCOM_i.h +++ b/CWeChatRobot/WeChatRobotCOM_i.h @@ -210,6 +210,24 @@ EXTERN_C const IID IID_IWeChatRobot; /* [in] */ BSTR PublicId, /* [retval][out] */ int *__result) = 0; + virtual /* [id] */ HRESULT STDMETHODCALLTYPE CHookVoiceMsg( + /* [in] */ BSTR savepath, + /* [retval][out] */ int *__result) = 0; + + virtual /* [id] */ HRESULT STDMETHODCALLTYPE CUnHookVoiceMsg( + /* [retval][out] */ int *__result) = 0; + + virtual /* [id] */ HRESULT STDMETHODCALLTYPE CHookImageMsg( + /* [in] */ BSTR savepath, + /* [retval][out] */ int *__result) = 0; + + virtual /* [id] */ HRESULT STDMETHODCALLTYPE CUnHookImageMsg( + /* [retval][out] */ int *__result) = 0; + + virtual /* [id] */ HRESULT STDMETHODCALLTYPE CChangeWeChatVer( + /* [in] */ BSTR verStr, + /* [retval][out] */ int *__result) = 0; + }; @@ -420,6 +438,29 @@ EXTERN_C const IID IID_IWeChatRobot; /* [in] */ BSTR PublicId, /* [retval][out] */ int *__result); + /* [id] */ HRESULT ( STDMETHODCALLTYPE *CHookVoiceMsg )( + IWeChatRobot * This, + /* [in] */ BSTR savepath, + /* [retval][out] */ int *__result); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *CUnHookVoiceMsg )( + IWeChatRobot * This, + /* [retval][out] */ int *__result); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *CHookImageMsg )( + IWeChatRobot * This, + /* [in] */ BSTR savepath, + /* [retval][out] */ int *__result); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *CUnHookImageMsg )( + IWeChatRobot * This, + /* [retval][out] */ int *__result); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *CChangeWeChatVer )( + IWeChatRobot * This, + /* [in] */ BSTR verStr, + /* [retval][out] */ int *__result); + END_INTERFACE } IWeChatRobotVtbl; @@ -546,6 +587,21 @@ EXTERN_C const IID IID_IWeChatRobot; #define IWeChatRobot_CAddBrandContact(This,PublicId,__result) \ ( (This)->lpVtbl -> CAddBrandContact(This,PublicId,__result) ) +#define IWeChatRobot_CHookVoiceMsg(This,savepath,__result) \ + ( (This)->lpVtbl -> CHookVoiceMsg(This,savepath,__result) ) + +#define IWeChatRobot_CUnHookVoiceMsg(This,__result) \ + ( (This)->lpVtbl -> CUnHookVoiceMsg(This,__result) ) + +#define IWeChatRobot_CHookImageMsg(This,savepath,__result) \ + ( (This)->lpVtbl -> CHookImageMsg(This,savepath,__result) ) + +#define IWeChatRobot_CUnHookImageMsg(This,__result) \ + ( (This)->lpVtbl -> CUnHookImageMsg(This,__result) ) + +#define IWeChatRobot_CChangeWeChatVer(This,verStr,__result) \ + ( (This)->lpVtbl -> CChangeWeChatVer(This,verStr,__result) ) + #endif /* COBJMACROS */ diff --git a/CWeChatRobot/WeChatRobotCOM_p.c b/CWeChatRobot/WeChatRobotCOM_p.c index ba6a5b5e0f23d3591acb37eb867fa8e1d11aa718..e27f235c9872a9f08a1dd469e20690f61b2210d0 100644 --- a/CWeChatRobot/WeChatRobotCOM_p.c +++ b/CWeChatRobot/WeChatRobotCOM_p.c @@ -49,7 +49,7 @@ #include "WeChatRobotCOM_i.h" #define TYPE_FORMAT_STRING_SIZE 1239 -#define PROC_FORMAT_STRING_SIZE 1273 +#define PROC_FORMAT_STRING_SIZE 1471 #define EXPR_FORMAT_STRING_SIZE 1 #define TRANSMIT_AS_TABLE_SIZE 0 #define WIRE_MARSHAL_TABLE_SIZE 2 @@ -1221,6 +1221,179 @@ static const WeChatRobotCOM_MIDL_PROC_FORMAT_STRING WeChatRobotCOM__MIDL_ProcFor /* 1270 */ 0x8, /* FC_LONG */ 0x0, /* 0 */ + /* Procedure CHookVoiceMsg */ + +/* 1272 */ 0x33, /* FC_AUTO_HANDLE */ + 0x6c, /* Old Flags: object, Oi2 */ +/* 1274 */ NdrFcLong( 0x0 ), /* 0 */ +/* 1278 */ NdrFcShort( 0x25 ), /* 37 */ +/* 1280 */ NdrFcShort( 0x10 ), /* x86 Stack size/offset = 16 */ +/* 1282 */ NdrFcShort( 0x0 ), /* 0 */ +/* 1284 */ NdrFcShort( 0x24 ), /* 36 */ +/* 1286 */ 0x46, /* Oi2 Flags: clt must size, has return, has ext, */ + 0x3, /* 3 */ +/* 1288 */ 0x8, /* 8 */ + 0x45, /* Ext Flags: new corr desc, srv corr check, has range on conformance */ +/* 1290 */ NdrFcShort( 0x0 ), /* 0 */ +/* 1292 */ NdrFcShort( 0x1 ), /* 1 */ +/* 1294 */ NdrFcShort( 0x0 ), /* 0 */ + + /* Parameter savepath */ + +/* 1296 */ NdrFcShort( 0x8b ), /* Flags: must size, must free, in, by val, */ +/* 1298 */ NdrFcShort( 0x4 ), /* x86 Stack size/offset = 4 */ +/* 1300 */ NdrFcShort( 0x2a ), /* Type Offset=42 */ + + /* Parameter __result */ + +/* 1302 */ NdrFcShort( 0x2150 ), /* Flags: out, base type, simple ref, srv alloc size=8 */ +/* 1304 */ NdrFcShort( 0x8 ), /* x86 Stack size/offset = 8 */ +/* 1306 */ 0x8, /* FC_LONG */ + 0x0, /* 0 */ + + /* Return value */ + +/* 1308 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */ +/* 1310 */ NdrFcShort( 0xc ), /* x86 Stack size/offset = 12 */ +/* 1312 */ 0x8, /* FC_LONG */ + 0x0, /* 0 */ + + /* Procedure CUnHookVoiceMsg */ + +/* 1314 */ 0x33, /* FC_AUTO_HANDLE */ + 0x6c, /* Old Flags: object, Oi2 */ +/* 1316 */ NdrFcLong( 0x0 ), /* 0 */ +/* 1320 */ NdrFcShort( 0x26 ), /* 38 */ +/* 1322 */ NdrFcShort( 0xc ), /* x86 Stack size/offset = 12 */ +/* 1324 */ NdrFcShort( 0x0 ), /* 0 */ +/* 1326 */ NdrFcShort( 0x24 ), /* 36 */ +/* 1328 */ 0x44, /* Oi2 Flags: has return, has ext, */ + 0x2, /* 2 */ +/* 1330 */ 0x8, /* 8 */ + 0x41, /* Ext Flags: new corr desc, has range on conformance */ +/* 1332 */ NdrFcShort( 0x0 ), /* 0 */ +/* 1334 */ NdrFcShort( 0x0 ), /* 0 */ +/* 1336 */ NdrFcShort( 0x0 ), /* 0 */ + + /* Parameter __result */ + +/* 1338 */ NdrFcShort( 0x2150 ), /* Flags: out, base type, simple ref, srv alloc size=8 */ +/* 1340 */ NdrFcShort( 0x4 ), /* x86 Stack size/offset = 4 */ +/* 1342 */ 0x8, /* FC_LONG */ + 0x0, /* 0 */ + + /* Return value */ + +/* 1344 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */ +/* 1346 */ NdrFcShort( 0x8 ), /* x86 Stack size/offset = 8 */ +/* 1348 */ 0x8, /* FC_LONG */ + 0x0, /* 0 */ + + /* Procedure CHookImageMsg */ + +/* 1350 */ 0x33, /* FC_AUTO_HANDLE */ + 0x6c, /* Old Flags: object, Oi2 */ +/* 1352 */ NdrFcLong( 0x0 ), /* 0 */ +/* 1356 */ NdrFcShort( 0x27 ), /* 39 */ +/* 1358 */ NdrFcShort( 0x10 ), /* x86 Stack size/offset = 16 */ +/* 1360 */ NdrFcShort( 0x0 ), /* 0 */ +/* 1362 */ NdrFcShort( 0x24 ), /* 36 */ +/* 1364 */ 0x46, /* Oi2 Flags: clt must size, has return, has ext, */ + 0x3, /* 3 */ +/* 1366 */ 0x8, /* 8 */ + 0x45, /* Ext Flags: new corr desc, srv corr check, has range on conformance */ +/* 1368 */ NdrFcShort( 0x0 ), /* 0 */ +/* 1370 */ NdrFcShort( 0x1 ), /* 1 */ +/* 1372 */ NdrFcShort( 0x0 ), /* 0 */ + + /* Parameter savepath */ + +/* 1374 */ NdrFcShort( 0x8b ), /* Flags: must size, must free, in, by val, */ +/* 1376 */ NdrFcShort( 0x4 ), /* x86 Stack size/offset = 4 */ +/* 1378 */ NdrFcShort( 0x2a ), /* Type Offset=42 */ + + /* Parameter __result */ + +/* 1380 */ NdrFcShort( 0x2150 ), /* Flags: out, base type, simple ref, srv alloc size=8 */ +/* 1382 */ NdrFcShort( 0x8 ), /* x86 Stack size/offset = 8 */ +/* 1384 */ 0x8, /* FC_LONG */ + 0x0, /* 0 */ + + /* Return value */ + +/* 1386 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */ +/* 1388 */ NdrFcShort( 0xc ), /* x86 Stack size/offset = 12 */ +/* 1390 */ 0x8, /* FC_LONG */ + 0x0, /* 0 */ + + /* Procedure CUnHookImageMsg */ + +/* 1392 */ 0x33, /* FC_AUTO_HANDLE */ + 0x6c, /* Old Flags: object, Oi2 */ +/* 1394 */ NdrFcLong( 0x0 ), /* 0 */ +/* 1398 */ NdrFcShort( 0x28 ), /* 40 */ +/* 1400 */ NdrFcShort( 0xc ), /* x86 Stack size/offset = 12 */ +/* 1402 */ NdrFcShort( 0x0 ), /* 0 */ +/* 1404 */ NdrFcShort( 0x24 ), /* 36 */ +/* 1406 */ 0x44, /* Oi2 Flags: has return, has ext, */ + 0x2, /* 2 */ +/* 1408 */ 0x8, /* 8 */ + 0x41, /* Ext Flags: new corr desc, has range on conformance */ +/* 1410 */ NdrFcShort( 0x0 ), /* 0 */ +/* 1412 */ NdrFcShort( 0x0 ), /* 0 */ +/* 1414 */ NdrFcShort( 0x0 ), /* 0 */ + + /* Parameter __result */ + +/* 1416 */ NdrFcShort( 0x2150 ), /* Flags: out, base type, simple ref, srv alloc size=8 */ +/* 1418 */ NdrFcShort( 0x4 ), /* x86 Stack size/offset = 4 */ +/* 1420 */ 0x8, /* FC_LONG */ + 0x0, /* 0 */ + + /* Return value */ + +/* 1422 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */ +/* 1424 */ NdrFcShort( 0x8 ), /* x86 Stack size/offset = 8 */ +/* 1426 */ 0x8, /* FC_LONG */ + 0x0, /* 0 */ + + /* Procedure CChangeWeChatVer */ + +/* 1428 */ 0x33, /* FC_AUTO_HANDLE */ + 0x6c, /* Old Flags: object, Oi2 */ +/* 1430 */ NdrFcLong( 0x0 ), /* 0 */ +/* 1434 */ NdrFcShort( 0x29 ), /* 41 */ +/* 1436 */ NdrFcShort( 0x10 ), /* x86 Stack size/offset = 16 */ +/* 1438 */ NdrFcShort( 0x0 ), /* 0 */ +/* 1440 */ NdrFcShort( 0x24 ), /* 36 */ +/* 1442 */ 0x46, /* Oi2 Flags: clt must size, has return, has ext, */ + 0x3, /* 3 */ +/* 1444 */ 0x8, /* 8 */ + 0x45, /* Ext Flags: new corr desc, srv corr check, has range on conformance */ +/* 1446 */ NdrFcShort( 0x0 ), /* 0 */ +/* 1448 */ NdrFcShort( 0x1 ), /* 1 */ +/* 1450 */ NdrFcShort( 0x0 ), /* 0 */ + + /* Parameter verStr */ + +/* 1452 */ NdrFcShort( 0x8b ), /* Flags: must size, must free, in, by val, */ +/* 1454 */ NdrFcShort( 0x4 ), /* x86 Stack size/offset = 4 */ +/* 1456 */ NdrFcShort( 0x2a ), /* Type Offset=42 */ + + /* Parameter __result */ + +/* 1458 */ NdrFcShort( 0x2150 ), /* Flags: out, base type, simple ref, srv alloc size=8 */ +/* 1460 */ NdrFcShort( 0x8 ), /* x86 Stack size/offset = 8 */ +/* 1462 */ 0x8, /* FC_LONG */ + 0x0, /* 0 */ + + /* Return value */ + +/* 1464 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */ +/* 1466 */ NdrFcShort( 0xc ), /* x86 Stack size/offset = 12 */ +/* 1468 */ 0x8, /* FC_LONG */ + 0x0, /* 0 */ + 0x0 } }; @@ -2095,7 +2268,12 @@ static const unsigned short IWeChatRobot_FormatStringOffsetTable[] = 1116, 1152, 1188, - 1230 + 1230, + 1272, + 1314, + 1350, + 1392, + 1428 }; static const MIDL_STUBLESS_PROXY_INFO IWeChatRobot_ProxyInfo = @@ -2119,7 +2297,7 @@ static const MIDL_SERVER_INFO IWeChatRobot_ServerInfo = 0, 0, 0}; -CINTERFACE_PROXY_VTABLE(37) _IWeChatRobotProxyVtbl = +CINTERFACE_PROXY_VTABLE(42) _IWeChatRobotProxyVtbl = { &IWeChatRobot_ProxyInfo, &IID_IWeChatRobot, @@ -2159,7 +2337,12 @@ CINTERFACE_PROXY_VTABLE(37) _IWeChatRobotProxyVtbl = (void *) (INT_PTR) -1 /* IWeChatRobot::CGetWeChatVer */ , (void *) (INT_PTR) -1 /* IWeChatRobot::CStartWeChat */ , (void *) (INT_PTR) -1 /* IWeChatRobot::CSearchContactByNet */ , - (void *) (INT_PTR) -1 /* IWeChatRobot::CAddBrandContact */ + (void *) (INT_PTR) -1 /* IWeChatRobot::CAddBrandContact */ , + (void *) (INT_PTR) -1 /* IWeChatRobot::CHookVoiceMsg */ , + (void *) (INT_PTR) -1 /* IWeChatRobot::CUnHookVoiceMsg */ , + (void *) (INT_PTR) -1 /* IWeChatRobot::CHookImageMsg */ , + (void *) (INT_PTR) -1 /* IWeChatRobot::CUnHookImageMsg */ , + (void *) (INT_PTR) -1 /* IWeChatRobot::CChangeWeChatVer */ }; @@ -2198,6 +2381,11 @@ static const PRPC_STUB_FUNCTION IWeChatRobot_table[] = NdrStubCall2, NdrStubCall2, NdrStubCall2, + NdrStubCall2, + NdrStubCall2, + NdrStubCall2, + NdrStubCall2, + NdrStubCall2, NdrStubCall2 }; @@ -2205,7 +2393,7 @@ CInterfaceStubVtbl _IWeChatRobotStubVtbl = { &IID_IWeChatRobot, &IWeChatRobot_ServerInfo, - 37, + 42, &IWeChatRobot_table[-3], CStdStubBuffer_DELEGATING_METHODS }; diff --git a/CWeChatRobot/pch.cpp b/CWeChatRobot/pch.cpp index 1774ac19a8da395d05269db2a4ae49190d589744..4b5949296256ab7b1f0ec0a2f0f7c72b56fc8cc6 100644 --- a/CWeChatRobot/pch.cpp +++ b/CWeChatRobot/pch.cpp @@ -43,6 +43,13 @@ DWORD AddFriendByWxidRemoteOffset = 0x0; DWORD AddFriendByV3RemoteOffset = 0x0; DWORD AddBrandContactRemoteOffset = 0x0; +DWORD HookImageMsgRemoteOffset = 0x0; +DWORD UnHookImageMsgRemoteOffset = 0x0; +DWORD HookVoiceMsgRemoteOffset = 0x0; +DWORD UnHookVoiceMsgRemoteOffset = 0x0; + +DWORD ChangeWeChatVerRemoteOffset = 0x0; + wstring SelfInfoString = L""; HANDLE hProcess = NULL; @@ -173,6 +180,18 @@ BOOL GetProcOffset(wchar_t* workPath) { DWORD AddBrandContactRemoteAddr = (DWORD)GetProcAddress(hd, AddBrandContactRemote); AddBrandContactRemoteOffset = AddBrandContactRemoteAddr - WeChatBase; + DWORD HookImageMsgRemoteAddr = (DWORD)GetProcAddress(hd, HookImageMsgRemote); + HookImageMsgRemoteOffset = HookImageMsgRemoteAddr - WeChatBase; + DWORD UnHookImageMsgAddr = (DWORD)GetProcAddress(hd, UnHookImageMsgRemote); + UnHookImageMsgRemoteOffset = UnHookImageMsgAddr - WeChatBase; + DWORD HookVoiceMsgRemoteAddr = (DWORD)GetProcAddress(hd, HookVoiceMsgRemote); + HookVoiceMsgRemoteOffset = HookVoiceMsgRemoteAddr - WeChatBase; + DWORD UnHookVoiceMsgAddr = (DWORD)GetProcAddress(hd, UnHookVoiceMsgRemote); + UnHookVoiceMsgRemoteOffset = UnHookVoiceMsgAddr - WeChatBase; + + DWORD ChangeWeChatVerRemoteAddr = (DWORD)GetProcAddress(hd, ChangeWeChatVerRemote); + ChangeWeChatVerRemoteOffset = ChangeWeChatVerRemoteAddr - WeChatBase; + FreeLibrary(hd); delete[] dllpath; dllpath = NULL; diff --git a/CWeChatRobot/robotdata.h b/CWeChatRobot/robotdata.h index 90a664343ddb6b1fac29466d1c4d3037a5ba00f4..e70d0a4a91686477e9bcac12f68ae3e7a0c3e68b 100644 --- a/CWeChatRobot/robotdata.h +++ b/CWeChatRobot/robotdata.h @@ -17,6 +17,7 @@ #include "DbBackup.h" #include "VerifyFriendApply.h" #include "AddFriend.h" +#include "wechatver.h" extern HANDLE hProcess; extern DWORD SendImageOffset; @@ -60,6 +61,13 @@ extern DWORD AddFriendByWxidRemoteOffset; extern DWORD AddFriendByV3RemoteOffset; extern DWORD AddBrandContactRemoteOffset; +extern DWORD HookImageMsgRemoteOffset; +extern DWORD UnHookImageMsgRemoteOffset; +extern DWORD HookVoiceMsgRemoteOffset; +extern DWORD UnHookVoiceMsgRemoteOffset; + +extern DWORD ChangeWeChatVerRemoteOffset; + #define dllname L"DWeChatRobot.dll" @@ -101,4 +109,11 @@ extern DWORD AddBrandContactRemoteOffset; #define AddFriendByWxidRemote "AddFriendByWxidRemote" #define AddFriendByV3Remote "AddFriendByV3Remote" -#define AddBrandContactRemote "AddBrandContactRemote" \ No newline at end of file +#define AddBrandContactRemote "AddBrandContactRemote" + +#define HookImageMsgRemote "HookImageMsgRemote" +#define UnHookImageMsgRemote "UnHookImageMsg" +#define HookVoiceMsgRemote "HookVoiceMsgRemote" +#define UnHookVoiceMsgRemote "UnHookVoiceMsg" + +#define ChangeWeChatVerRemote "ChangeWeChatVerRemote" \ No newline at end of file diff --git a/CWeChatRobot/wechatver.cpp b/CWeChatRobot/wechatver.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8288a4aaf2c80918b104120e77c66f4173dacfd0 --- /dev/null +++ b/CWeChatRobot/wechatver.cpp @@ -0,0 +1,23 @@ +#include "pch.h" + +BOOL ChangeWeChatVer(wchar_t* verStr) { + if (!hProcess) + return 1; + DWORD WeChatRobotBase = GetWeChatRobotBase(); + DWORD dwId = 0; + DWORD dwRet = 0x0; + LPVOID verStraddr = VirtualAllocEx(hProcess, NULL, 1, MEM_COMMIT, PAGE_READWRITE); + DWORD dwWriteSize = 0; + if (!verStraddr) + return 1; + WriteProcessMemory(hProcess, verStraddr, verStr, wcslen(verStr) * 2 + 2, &dwWriteSize); + DWORD ChangeWeChatVerRemoteAddr = WeChatRobotBase + ChangeWeChatVerRemoteOffset; + HANDLE hThread = ::CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)ChangeWeChatVerRemoteAddr, verStraddr, 0, &dwId); + if (hThread) { + WaitForSingleObject(hThread, INFINITE); + GetExitCodeThread(hThread, &dwRet); + CloseHandle(hThread); + } + VirtualFreeEx(hProcess, verStraddr, 0, MEM_RELEASE); + return dwRet == 0; +} \ No newline at end of file diff --git a/CWeChatRobot/wechatver.h b/CWeChatRobot/wechatver.h new file mode 100644 index 0000000000000000000000000000000000000000..b5e0894e4a6780206ddf9126082d0f1c613c541b --- /dev/null +++ b/CWeChatRobot/wechatver.h @@ -0,0 +1,3 @@ +#pragma once +#include +BOOL ChangeWeChatVer(wchar_t* verStr); \ No newline at end of file diff --git a/DWeChatRobot/DWeChatRobot.vcxproj b/DWeChatRobot/DWeChatRobot.vcxproj index 419fc6e9b16c75a28fe9370ce68925febb30f192..83be8360614ae0544d17dfd807f4ce21357d6d69 100644 --- a/DWeChatRobot/DWeChatRobot.vcxproj +++ b/DWeChatRobot/DWeChatRobot.vcxproj @@ -175,6 +175,7 @@ + @@ -187,6 +188,8 @@ + + Create Create @@ -205,6 +208,7 @@ + diff --git a/DWeChatRobot/DWeChatRobot.vcxproj.filters b/DWeChatRobot/DWeChatRobot.vcxproj.filters index 39fbcbe707bad3ac8f252a91212a56023217ce87..45b3d80acd75378cee21d4783fe97ebf06b96dbf 100644 --- a/DWeChatRobot/DWeChatRobot.vcxproj.filters +++ b/DWeChatRobot/DWeChatRobot.vcxproj.filters @@ -82,6 +82,9 @@ {564cc9ef-a939-4bfd-a420-a08b3072d198} + + {820d8228-ee6c-43ad-87ec-4e349d7a549a} + @@ -147,6 +150,9 @@ 通用标头 + + 微信版本 + @@ -218,5 +224,14 @@ 好友相关\添加好友 + + 接收消息 + + + 接收消息 + + + 微信版本 + \ No newline at end of file diff --git a/DWeChatRobot/HookImageMessage.cpp b/DWeChatRobot/HookImageMessage.cpp new file mode 100644 index 0000000000000000000000000000000000000000..71ce3e57441ee0ec11f462a34c7a01730cb8cd62 --- /dev/null +++ b/DWeChatRobot/HookImageMessage.cpp @@ -0,0 +1,98 @@ +#include "pch.h" + +#define HookImageMsgAddrOffset 0x61211FF6 - 0x60AE0000 +#define HookImageMsgNextCallOffset 0x61211430 - 0x60AE0000 + +BOOL ImageMsgHooked = false; +static DWORD WeChatWinBase = GetWeChatWinBase(); +static DWORD HookImageMsgAddr = WeChatWinBase + HookImageMsgAddrOffset; +static DWORD HookImageMsgNextCall = WeChatWinBase + HookImageMsgNextCallOffset; +static DWORD HookImageMsgJmpBackAddr = HookImageMsgAddr + 0x5; +static char ImageMsgOldAsm[5] = { 0 }; +static wstring savepath = L""; + +void SaveImageMsg(unsigned char* buffer, int length, DWORD msgHandle) { + int l_datpath = *(int*)(msgHandle + 0x4) + 1; + wchar_t* datpath = new wchar_t[l_datpath]; + memcpy(datpath, (void*)(*(DWORD*)msgHandle), l_datpath * 2); + wstring wdatpath(datpath); + delete[] datpath; + datpath = NULL; + if (wdatpath.find(L"_t.dat") != wstring::npos) { + return; + } + int pos_begin = wdatpath.find_last_of(L"\\") + 1; + int pos_end = wdatpath.find_last_of(L"."); + wstring filename = wdatpath.substr(pos_begin, pos_end - pos_begin); + + unsigned char magic_head[4] = { 0 }; + wchar_t postfix[5] = { 0 }; + memcpy(magic_head, buffer, 3); + if (magic_head[0] == 137 && magic_head[1] == 80 && magic_head[2] == 78) + { + lstrcpy(postfix,L".png"); + } + else if (magic_head[0] == 71 && magic_head[1] == 73 && magic_head[2] == 70) + { + lstrcpy(postfix, L".gif"); + } + else if (magic_head[0] == 255 && magic_head[1] == 216 && magic_head[2] == 255) + { + lstrcpy(postfix, L".jpg"); + } + else { + lstrcpy(postfix, L""); + } + wstring filepath = savepath + filename + postfix; + HANDLE hFile = CreateFile(filepath.c_str(), GENERIC_ALL, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if (hFile == INVALID_HANDLE_VALUE) + { + return; + } + DWORD dwWrite = 0; + WriteFile(hFile, (LPCVOID)buffer, length, &dwWrite, 0); + CloseHandle(hFile); +} + +__declspec(naked) void dealImageMsg() { + __asm { + pushad; + pushfd; + push esi; + push dword ptr [ebp - 0x20]; + push edi; + call SaveImageMsg; + add esp, 0xC; + popfd; + popad; + call HookImageMsgNextCall; + jmp HookImageMsgJmpBackAddr; + } +} + +void __stdcall HookImageMsg() { + if (ImageMsgHooked) + return; + HookAnyAddress(HookImageMsgAddr, dealImageMsg, ImageMsgOldAsm); + ImageMsgHooked = true; +} + +void UnHookImageMsg() { + if (!ImageMsgHooked) + return; + UnHookAnyAddress(HookImageMsgAddr, ImageMsgOldAsm); + ImageMsgHooked = false; +} + +BOOL HookImageMsgRemote(LPVOID lpParameter) { + savepath = (wstring)(wchar_t*)lpParameter; + if (savepath.back() != '\\') { + savepath += L"\\"; + } + wstring createpath = savepath.substr(0, savepath.length() - 1); + if (!FindOrCreateDirectory(createpath.c_str())) { + return false; + } + HookImageMsg(); + return true; +} \ No newline at end of file diff --git a/DWeChatRobot/HookVoiceMessage.cpp b/DWeChatRobot/HookVoiceMessage.cpp new file mode 100644 index 0000000000000000000000000000000000000000..54d665ad57f1aea82a662bf70868f2c18821a06b --- /dev/null +++ b/DWeChatRobot/HookVoiceMessage.cpp @@ -0,0 +1,70 @@ +#include "pch.h" + +#define HookVoiceMsgAddrOffset 0x610528DA - 0x60AE0000 +#define HookVoiceMsgNextCallOffset 0x620F1040 - 0x60AE0000 + +BOOL VoiceMsgHooked = false; +static DWORD WeChatWinBase = GetWeChatWinBase(); +static DWORD HookVoiceMsgAddr = WeChatWinBase + HookVoiceMsgAddrOffset; +static DWORD HookVoiceMsgNextCall = WeChatWinBase + HookVoiceMsgNextCallOffset; +static DWORD HookVoiceMsgJmpBackAddr = HookVoiceMsgAddr + 0x5; +static char VoiceMsgOldAsm[5] = { 0 }; +static wstring savepath = L""; + +void SaveVoiceMsg(unsigned char* buffer, int length, DWORD msgHandle) { + time_t curtime = time(0); + wchar_t timestamp[32] = { 0 }; + _itow_s((int)curtime, timestamp, 10); + wstring filename = savepath + timestamp + L".amr"; + HANDLE hFile = CreateFile(filename.c_str(), GENERIC_ALL, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if (hFile == INVALID_HANDLE_VALUE) + { + return; + } + DWORD dwWrite = 0; + WriteFile(hFile, (LPCVOID)buffer, length, &dwWrite, 0); + CloseHandle(hFile); +} + +__declspec(naked) void dealVoiceMsg() { + __asm { + pushad; + pushfd; + push edi; + push esi; + push eax; + call SaveVoiceMsg; + add esp, 0xC; + popfd; + popad; + call HookVoiceMsgNextCall; + jmp HookVoiceMsgJmpBackAddr; + } +} + +void __stdcall HookVoiceMsg() { + if (VoiceMsgHooked) + return; + HookAnyAddress(HookVoiceMsgAddr, dealVoiceMsg, VoiceMsgOldAsm); + VoiceMsgHooked = true; +} + +void UnHookVoiceMsg() { + if (!VoiceMsgHooked) + return; + UnHookAnyAddress(HookVoiceMsgAddr, VoiceMsgOldAsm); + VoiceMsgHooked = false; +} + +BOOL HookVoiceMsgRemote(LPVOID lpParameter) { + savepath = (wstring)(wchar_t*)lpParameter; + if (savepath.back() != '\\') { + savepath += L"\\"; + } + wstring createpath = savepath.substr(0, savepath.length() - 1); + if (!FindOrCreateDirectory(createpath.c_str())) { + return false; + } + HookVoiceMsg(); + return true; +} \ No newline at end of file diff --git a/DWeChatRobot/ReceiveMessage.h b/DWeChatRobot/ReceiveMessage.h index 8d1ac39250ebe0305158fd58c74c1c97585539f7..f9a3aaaeda69aebd60a8c926ac82fea61e59ca1a 100644 --- a/DWeChatRobot/ReceiveMessage.h +++ b/DWeChatRobot/ReceiveMessage.h @@ -4,4 +4,12 @@ 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 +extern "C" __declspec(dllexport) VOID UnHookReceiveMessage(); + +void __stdcall HookVoiceMsg(); +extern "C" __declspec(dllexport) void UnHookVoiceMsg(); +extern "C" __declspec(dllexport) BOOL HookVoiceMsgRemote(LPVOID lpParameter); + +void __stdcall HookImageMsg(); +extern "C" __declspec(dllexport) void UnHookImageMsg(); +extern "C" __declspec(dllexport) BOOL HookImageMsgRemote(LPVOID lpParameter); \ No newline at end of file diff --git a/DWeChatRobot/pch.cpp b/DWeChatRobot/pch.cpp index 65c05edbdbe929617d27c614471fac5d920a6e7b..41dd69cd03b589cfe429901841b7a33e17af3184 100644 --- a/DWeChatRobot/pch.cpp +++ b/DWeChatRobot/pch.cpp @@ -29,6 +29,23 @@ DWORD GetWeChatWinBase() { return (DWORD)GetModuleHandleA("WeChatWin.dll"); } +BOOL FindOrCreateDirectory(const wchar_t* pszPath) +{ + WIN32_FIND_DATA fd; + HANDLE hFind = ::FindFirstFile(pszPath, &fd); + if (hFind != INVALID_HANDLE_VALUE) + { + FindClose(hFind); + return true; + } + + if (!::CreateDirectory(pszPath, NULL)) + { + return false; + } + return true; +} + /* * 将宽字节字符串转换成`std::string` */ @@ -116,6 +133,8 @@ void UnHookAll() { UnHookLogMsgInfo(); UnHookReceiveMessage(); StopSearchContactHook(); + UnHookVoiceMsg(); + UnHookImageMsg(); return; } @@ -206,45 +225,6 @@ BOOL ProcessIsWeChat() } } -DWORD GetWeChatVerInt() -{ - WCHAR VersionFilePath[MAX_PATH]; - BYTE WeChatVersion[4] = { 0 }; - if (GetModuleFileName((HMODULE)GetWeChatWinBase(), VersionFilePath, MAX_PATH) == 0) - { - return 0; - } - - VS_FIXEDFILEINFO* pVsInfo; - unsigned int iFileInfoSize = sizeof(VS_FIXEDFILEINFO); - int iVerInfoSize = GetFileVersionInfoSize(VersionFilePath, NULL); - if (iVerInfoSize != 0) { - char* pBuf = new char[iVerInfoSize]; - if (GetFileVersionInfo(VersionFilePath, 0, iVerInfoSize, pBuf)) { - if (VerQueryValue(pBuf, TEXT("\\"), (void**)&pVsInfo, &iFileInfoSize)) { - WeChatVersion[3] = (BYTE)(0x60 + (pVsInfo->dwFileVersionMS >> 16) & 0x0000FFFF); - WeChatVersion[2] = (BYTE)(pVsInfo->dwFileVersionMS & 0x0000FFFF); - WeChatVersion[1] = (BYTE)((pVsInfo->dwFileVersionLS >> 16) & 0x0000FFFF); - WeChatVersion[0] = (BYTE)(pVsInfo->dwFileVersionLS & 0x0000FFFF); - } - } - delete[] pBuf; - } - return *(DWORD*)WeChatVersion; -} - -string GetWeChatVerStr() { - DWORD WeChatVersion = GetWeChatVerInt(); - if (WeChatVersion == 0) - return "null"; - string wxver = ""; - BYTE* pWxVer = (BYTE*)&WeChatVersion; - strstream wxVer; - wxVer << (int)pWxVer[3] - 0x60 << "." << (int)pWxVer[2] << "." << (int)pWxVer[1] << "." << (int)pWxVer[0]; - wxVer >> wxver; - return wxver; -} - DWORD OffsetFromIdaAddr(DWORD idaAddr) { return idaAddr - IDA_BASE; } \ No newline at end of file diff --git a/DWeChatRobot/pch.h b/DWeChatRobot/pch.h index acfceaec157a7a95fa6b2f102d49deb2808b4c35..48de2ccefed1b7b2d0d42b44c70daddb17b0a8e8 100644 --- a/DWeChatRobot/pch.h +++ b/DWeChatRobot/pch.h @@ -30,6 +30,7 @@ #include "VerifyFriendApply.h" #include "AddFriend.h" #include "sqlite3.h" +#include "wechatver.h" #include #include #endif //PCH_H @@ -89,5 +90,4 @@ wstring wreplace(wstring source, wchar_t replaced, wstring replaceto); void PrintProcAddr(); wchar_t* GetTimeW(); BOOL ProcessIsWeChat(); -DWORD GetWeChatVerInt(); -string GetWeChatVerStr(); \ No newline at end of file +BOOL FindOrCreateDirectory(const wchar_t* pszPath); \ No newline at end of file diff --git a/DWeChatRobot/wechatver.cpp b/DWeChatRobot/wechatver.cpp new file mode 100644 index 0000000000000000000000000000000000000000..80486e8acbce6955c2192114f12d1ed0cc8c4a86 --- /dev/null +++ b/DWeChatRobot/wechatver.cpp @@ -0,0 +1,78 @@ +#include "pch.h" + +#define WeChatVersionOffset 0x2382AF0 + +DWORD GetWeChatVerInt() +{ + WCHAR VersionFilePath[MAX_PATH]; + BYTE WeChatVersion[4] = { 0 }; + if (GetModuleFileName((HMODULE)GetWeChatWinBase(), VersionFilePath, MAX_PATH) == 0) + { + return 0; + } + + VS_FIXEDFILEINFO* pVsInfo; + unsigned int iFileInfoSize = sizeof(VS_FIXEDFILEINFO); + int iVerInfoSize = GetFileVersionInfoSize(VersionFilePath, NULL); + if (iVerInfoSize != 0) { + char* pBuf = new char[iVerInfoSize]; + if (GetFileVersionInfo(VersionFilePath, 0, iVerInfoSize, pBuf)) { + if (VerQueryValue(pBuf, TEXT("\\"), (void**)&pVsInfo, &iFileInfoSize)) { + WeChatVersion[3] = (BYTE)(0x60 + (pVsInfo->dwFileVersionMS >> 16) & 0x0000FFFF); + WeChatVersion[2] = (BYTE)(pVsInfo->dwFileVersionMS & 0x0000FFFF); + WeChatVersion[1] = (BYTE)((pVsInfo->dwFileVersionLS >> 16) & 0x0000FFFF); + WeChatVersion[0] = (BYTE)(pVsInfo->dwFileVersionLS & 0x0000FFFF); + } + } + delete[] pBuf; + } + return *(DWORD*)WeChatVersion; +} + +string GetWeChatVerStr() { + DWORD WeChatVersion = GetWeChatVerInt(); + if (WeChatVersion == 0) + return "null"; + string wxver = ""; + BYTE* pWxVer = (BYTE*)&WeChatVersion; + strstream wxVer; + wxVer << (int)pWxVer[3] - 0x60 << "." << (int)pWxVer[2] << "." << (int)pWxVer[1] << "." << (int)pWxVer[0]; + wxVer >> wxver; + return wxver; +} + +vector split(const wstring& str, const wstring& delim) { + vector res; + if (L"" == str) + return res; + wchar_t* strs = new wchar_t[str.length() + 1]; + lstrcpy(strs, str.c_str()); + wchar_t* buffer = NULL; + wchar_t* d = new wchar_t[delim.length() + 1]; + lstrcpy(d, delim.c_str()); + wchar_t* p = wcstok_s(strs, d, &buffer); + while (p) { + wstring s = p; + res.push_back(s); + p = wcstok_s(NULL, d, &buffer); + } + delete[] strs; + delete[] d; + return res; +} + +BOOL ChangeWeChatVerRemote(wchar_t* verStr) { + wstring wverStr(verStr); + vector v_split = split(wverStr, L"."); + BYTE bVer[4] = { 0 }; + bVer[3] = (BYTE)0x60; + for (unsigned int i = 0; i < v_split.size(); i++) { + bVer[3 - i] += (BYTE)_wtoi(v_split[i].c_str()); + } + DWORD version = *(DWORD*)bVer; + if (version < 0x60000000) + return false; + DWORD WeChatVersionAddr = GetWeChatWinBase() + WeChatVersionOffset; + *(DWORD*)WeChatVersionAddr = version; + return true; +} \ No newline at end of file diff --git a/DWeChatRobot/wechatver.h b/DWeChatRobot/wechatver.h new file mode 100644 index 0000000000000000000000000000000000000000..5bf62c503adc3f39e93405c2d6f807b74c059896 --- /dev/null +++ b/DWeChatRobot/wechatver.h @@ -0,0 +1,7 @@ +#pragma once +#include +#include +using namespace std; +DWORD GetWeChatVerInt(); +string GetWeChatVerStr(); +extern "C" __declspec(dllexport) BOOL ChangeWeChatVerRemote(wchar_t* verStr); \ No newline at end of file diff --git a/Python/test.py b/Python/test.py index 6110fb09c297a76eb772df0c13dd99ab8c77e26a..9476379ec582339470df443110b0fe2befb0b602 100644 --- a/Python/test.py +++ b/Python/test.py @@ -102,5 +102,6 @@ def test_BackupDb(): if __name__ == '__main__': wx = WeChatRobot() + print([i for i in dir(wx.robot) if '_' not in i and i[0] == 'C']) print(wx.GetWeChatVer()) wx.StopService() \ No newline at end of file diff --git a/Python/wxRobot.py b/Python/wxRobot.py index 2ce1cf639cb2d13e2fb11cf91265dc645c495dac..e75deb2134feff12488b9109e144782dec1c8548 100644 --- a/Python/wxRobot.py +++ b/Python/wxRobot.py @@ -268,4 +268,22 @@ class WeChatRobot(): return userinfo def AddBrandContact(self,PublicId): - return self.robot.CAddBrandContact(PublicId) \ No newline at end of file + return self.robot.CAddBrandContact(PublicId) + + def ChangeWeChatVer(self,version:str): + """ + version: like `3.7.0.26` + """ + return self.robot.CChangeWeChatVer(version) + + def HookImageMsg(self,savepath): + return self.robot.CHookImageMsg(savepath) + + def UnHookImageMsg(self): + return self.robot.CUnHookImageMsg() + + def HookVoiceMsg(self,savepath): + return self.robot.CHookVoiceMsg(savepath) + + def UnHookVoiceMsg(self): + return self.robot.CUnHookVoiceMsg() \ No newline at end of file diff --git a/README.md b/README.md index 55d2c184fe5a19b1b0967803d0bc19af0aba9836..d13bf31f0edc8c6a812ec40147ad24e32e6b53be 100644 --- a/README.md +++ b/README.md @@ -20,11 +20,7 @@ PC微信机器人,实现以下功能: 微信电脑版**3.6.0.18** 微信电脑版**3.7.0.26** 主分支对应微信3.7.0.26版本,其他版本请查看对应分支。 - -## 祝大家端午安康 -今天微信更新了3.7.0.29,人已经麻了,新加的添加好友功能甚至还没做COM接口。看来更新太快也不行。 -有想继续使用3.7.0.26的,可以去找一下原来的安装包,然后修改hosts文件禁用自动更新即可。 -过段时间再适配3.7.0.29吧,以上~ + # 编译环境 **Visual Studio 2019**(平台配置:win32(x86)) # 原理 @@ -53,13 +49,8 @@ CWeChatRobot.exe /unregserver 参考[Program.cs](/wxRobot/Program.cs) # 更多功能 后续计划功能: -1. HOOK未加密图片数据 -2. HOOK语音消息(SILK_V3格式) -3. 自定义微信版本号(无法屏蔽微信启动时的检查更新,启动后可以) -4. 手机号、微信号查询信息及加好友 -5. 好友相关操作,删除好友、修改备注等 -6. 群相关操作,拉群、踢人、退群等 -7. 数据库xml消息主体解压缩 +1. 好友相关操作,删除好友、修改备注等 +2. 分享小程序接口 有空的时候会按照上述顺序进行开发,不过嘛,计划只是计划,如果未实现也请见谅 **也欢迎您提交PR** @@ -94,6 +85,9 @@ CWeChatRobot.exe /unregserver ## 2022.06.07 1. 添加获取当前微信版本(读注册表)和启动微信的接口 2. 优化数据库查询接口,现在可以正常查询BLOB类型 +## 2022.06.10 +1. 新增关注公众号、网络查询用户信息、Hook语音、未加密图片、自定义微信版本号接口 +2. Hook语音和图片的接口暂时还有瑕疵,图片收到后有可能不会自动下载;语音消息的文件名暂时是时间戳,计划替换为该条消息id。有空再做优化。 # 打赏作者 请给作者一个star,感谢感谢 # 免责声明 diff --git a/Release/CWeChatRobot.exe b/Release/CWeChatRobot.exe index e6d54ef3b588db8e696770b22545bae0b7138638..986a7e8353e149ff8467cea8bd9c425ca66f68ed 100644 Binary files a/Release/CWeChatRobot.exe and b/Release/CWeChatRobot.exe differ diff --git a/Release/DWeChatRobot.dll b/Release/DWeChatRobot.dll index ead797405aa3b5b239b66c76659d4efe6ea15b26..cb4657b6aaec83d5095a1a03f3a80cbd2f5800d7 100644 Binary files a/Release/DWeChatRobot.dll and b/Release/DWeChatRobot.dll differ