diff --git a/CWeChatRobot/SendArticle.cpp b/CWeChatRobot/SendArticle.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fa7140f3698b8944b7e52a5f6ca99b6307dc5352 --- /dev/null +++ b/CWeChatRobot/SendArticle.cpp @@ -0,0 +1,56 @@ +#include "pch.h" + +struct SendArticleStruct { + DWORD wxid; + DWORD title; + DWORD abstract; + DWORD url; +}; + +BOOL SendArticle(wchar_t* wxid, wchar_t* title, wchar_t* abstract, wchar_t* url) { + if (!hProcess) + return 0; + DWORD WeChatRobotBase = GetWeChatRobotBase(); + DWORD dwId = 0; + DWORD dwWriteSize = 0; + SendArticleStruct params; + ZeroMemory(¶ms, sizeof(params)); + DWORD SendArticleProcAddr = WeChatRobotBase + SendArticleOffset; + LPVOID wxidaddr = VirtualAllocEx(hProcess, NULL, 1, MEM_COMMIT, PAGE_READWRITE); + LPVOID titleaddr = VirtualAllocEx(hProcess, NULL, 1, MEM_COMMIT, PAGE_READWRITE); + LPVOID abstractaddr = VirtualAllocEx(hProcess, NULL, 1, MEM_COMMIT, PAGE_READWRITE); + LPVOID urladdr = VirtualAllocEx(hProcess, NULL, 1, MEM_COMMIT, PAGE_READWRITE); + SendArticleStruct* paramAndFunc = (SendArticleStruct*)::VirtualAllocEx(hProcess, 0, sizeof(SendArticleStruct), MEM_COMMIT, PAGE_READWRITE); + if (!wxidaddr || !titleaddr || !abstractaddr || !urladdr || + !paramAndFunc || !WeChatRobotBase) + { + return 0; + } + + if (wxidaddr) + WriteProcessMemory(hProcess, wxidaddr, wxid, wcslen(wxid) * 2 + 2, &dwWriteSize); + if (titleaddr) + WriteProcessMemory(hProcess, titleaddr, title, wcslen(title) * 2 + 2, &dwWriteSize); + if (abstractaddr) + WriteProcessMemory(hProcess, abstractaddr, abstract, wcslen(abstract) * 2 + 2, &dwWriteSize); + if (urladdr) + WriteProcessMemory(hProcess, urladdr, url, wcslen(url) * 2 + 2, &dwWriteSize); + params.wxid = (DWORD)wxidaddr; + params.title = (DWORD)titleaddr; + params.abstract = (DWORD)abstractaddr; + params.url = (DWORD)urladdr; + + if (paramAndFunc) + WriteProcessMemory(hProcess, paramAndFunc, ¶ms, sizeof(params), &dwId); + HANDLE hThread = ::CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)SendArticleProcAddr, (LPVOID)paramAndFunc, 0, &dwId); + if (hThread) { + WaitForSingleObject(hThread, INFINITE); + CloseHandle(hThread); + } + VirtualFreeEx(hProcess, wxidaddr, 0, MEM_RELEASE); + VirtualFreeEx(hProcess, titleaddr, 0, MEM_RELEASE); + VirtualFreeEx(hProcess, abstractaddr, 0, MEM_RELEASE); + VirtualFreeEx(hProcess, urladdr, 0, MEM_RELEASE); + VirtualFreeEx(hProcess, paramAndFunc, 0, MEM_RELEASE); + return 1; +} \ No newline at end of file diff --git a/CWeChatRobot/SendArticle.h b/CWeChatRobot/SendArticle.h new file mode 100644 index 0000000000000000000000000000000000000000..bc965adc0ca718bc7b8936c84ee460b86dc1ed94 --- /dev/null +++ b/CWeChatRobot/SendArticle.h @@ -0,0 +1,3 @@ +#pragma once +#include +BOOL SendArticle(wchar_t* wxid, wchar_t* title, wchar_t* abstract, wchar_t* url); \ No newline at end of file diff --git a/CWeChatRobot/WeChatRobot.cpp b/CWeChatRobot/WeChatRobot.cpp index efc2e0ea31f7ee8650c397c30ee2db22264b18a7..305870494f61b44db14b3ee7e1131508653f18a5 100644 --- a/CWeChatRobot/WeChatRobot.cpp +++ b/CWeChatRobot/WeChatRobot.cpp @@ -52,6 +52,18 @@ STDMETHODIMP CWeChatRobot::CSendFile(BSTR wxid, BSTR filepath, int* __result) { return S_OK; } +/* +* 参数1:接收人wxid +* 参数2:文章标题 +* 参数3:文章摘要 +* 参数4:文章链接 +* 参数5:预返回的值,调用时无需提供 +*/ +STDMETHODIMP CWeChatRobot::CSendArticle(BSTR wxid, BSTR title,BSTR abstract,BSTR url, int* __result) { + *__result = SendArticle(wxid, title,abstract,url); + return S_OK; +} + /* * 参数1:预返回的值,调用时无需提供 */ diff --git a/CWeChatRobot/WeChatRobot.h b/CWeChatRobot/WeChatRobot.h index 9d11cabac2b47a2358591f28d35e284e9fff410f..ba1e1a1b11786ea314dc7607755b88855301356b 100644 --- a/CWeChatRobot/WeChatRobot.h +++ b/CWeChatRobot/WeChatRobot.h @@ -56,6 +56,7 @@ public: STDMETHODIMP CSendImage(BSTR wxid, BSTR imagepath, int* __result); STDMETHODIMP CSendText(BSTR wxid, BSTR wxmsg, int* __result); STDMETHODIMP CSendFile(BSTR wxid, BSTR filepath, int* __result); + STDMETHODIMP CSendArticle(BSTR wxid, BSTR title, BSTR abstract, BSTR url, int* __result); STDMETHODIMP CGetFriendList(BSTR* __result); STDMETHODIMP CGetWxUserInfo(BSTR wxid, BSTR* __result); STDMETHODIMP CGetSelfInfo(BSTR* __result); diff --git a/CWeChatRobot/WeChatRobotCOM.idl b/CWeChatRobot/WeChatRobotCOM.idl index eebcb447cdb7a2f4b6927c0b16e57961b4f2d884..73fe3eb6c9de900807d7491d238adf36d4c02c00 100644 --- a/CWeChatRobot/WeChatRobotCOM.idl +++ b/CWeChatRobot/WeChatRobotCOM.idl @@ -21,9 +21,10 @@ interface IWeChatRobot : IDispatch [id(3)] HRESULT CSendText([in] BSTR wxid, [in] BSTR wxmsg, [out, retval] int* __result); [id(4)] HRESULT CSendImage([in] BSTR wxid, [in] BSTR imagepath, [out, retval] int* __result); [id(5)] HRESULT CSendFile([in] BSTR wxid, [in] BSTR filepath, [out, retval] int* __result); - [id(6)] HRESULT CGetFriendList([out, retval] BSTR* __result); - [id(7)] HRESULT CGetWxUserInfo([in] BSTR wxid, [out, retval] BSTR* __result); - [id(8)] HRESULT CGetSelfInfo([out, retval] BSTR* __result); + [id(6)] HRESULT CSendArticle([in] BSTR wxid, [in] BSTR title, [in] BSTR abstract, [in] BSTR url, [out, retval] int* __result); + [id(7)] HRESULT CGetFriendList([out, retval] BSTR* __result); + [id(8)] HRESULT CGetWxUserInfo([in] BSTR wxid, [out, retval] BSTR* __result); + [id(9)] HRESULT CGetSelfInfo([out, retval] BSTR* __result); }; [ uuid(721abb35-141a-4aa2-94f2-762e2833fa6c), diff --git a/CWeChatRobot/WeChatRobotCOM.vcxproj b/CWeChatRobot/WeChatRobotCOM.vcxproj index ae0704205da4687154ccb934c2f4b7b464695691..74ff8c272a9a6f88cce426b577115aca950c046a 100644 --- a/CWeChatRobot/WeChatRobotCOM.vcxproj +++ b/CWeChatRobot/WeChatRobotCOM.vcxproj @@ -218,6 +218,7 @@ + @@ -237,6 +238,7 @@ Create + diff --git a/CWeChatRobot/WeChatRobotCOM.vcxproj.filters b/CWeChatRobot/WeChatRobotCOM.vcxproj.filters index 0aa07d8976d6df6457e830ce22b68d100fc038d9..99e62bc7fbf1ed59e468e009d8422e2566a9d056 100644 --- a/CWeChatRobot/WeChatRobotCOM.vcxproj.filters +++ b/CWeChatRobot/WeChatRobotCOM.vcxproj.filters @@ -44,6 +44,9 @@ {82fef7e4-e819-4cb2-9087-40ae1f426e73} + + {1986e9ed-7cd3-4ad3-b333-a1d74cc53c28} + @@ -91,6 +94,9 @@ 个人信息 + + 发送消息\发送文章 + @@ -129,6 +135,9 @@ 个人信息 + + 发送消息\发送文章 + diff --git a/CWeChatRobot/WeChatRobotCOM_i.h b/CWeChatRobot/WeChatRobotCOM_i.h index 4dcb9cd52473fd917f182a7f1d83de7f4e6f6dcf..62430ff7df3c9b411a8a9e2d354991972dd45d94 100644 --- a/CWeChatRobot/WeChatRobotCOM_i.h +++ b/CWeChatRobot/WeChatRobotCOM_i.h @@ -110,6 +110,13 @@ EXTERN_C const IID IID_IWeChatRobot; /* [in] */ BSTR filepath, /* [retval][out] */ int *__result) = 0; + virtual /* [id] */ HRESULT STDMETHODCALLTYPE CSendArticle( + /* [in] */ BSTR wxid, + /* [in] */ BSTR title, + /* [in] */ BSTR abstract, + /* [in] */ BSTR url, + /* [retval][out] */ int *__result) = 0; + virtual /* [id] */ HRESULT STDMETHODCALLTYPE CGetFriendList( /* [retval][out] */ BSTR *__result) = 0; @@ -205,6 +212,14 @@ EXTERN_C const IID IID_IWeChatRobot; /* [in] */ BSTR filepath, /* [retval][out] */ int *__result); + /* [id] */ HRESULT ( STDMETHODCALLTYPE *CSendArticle )( + IWeChatRobot * This, + /* [in] */ BSTR wxid, + /* [in] */ BSTR title, + /* [in] */ BSTR abstract, + /* [in] */ BSTR url, + /* [retval][out] */ int *__result); + /* [id] */ HRESULT ( STDMETHODCALLTYPE *CGetFriendList )( IWeChatRobot * This, /* [retval][out] */ BSTR *__result); @@ -269,6 +284,9 @@ EXTERN_C const IID IID_IWeChatRobot; #define IWeChatRobot_CSendFile(This,wxid,filepath,__result) \ ( (This)->lpVtbl -> CSendFile(This,wxid,filepath,__result) ) +#define IWeChatRobot_CSendArticle(This,wxid,title,abstract,url,__result) \ + ( (This)->lpVtbl -> CSendArticle(This,wxid,title,abstract,url,__result) ) + #define IWeChatRobot_CGetFriendList(This,__result) \ ( (This)->lpVtbl -> CGetFriendList(This,__result) ) diff --git a/CWeChatRobot/WeChatRobotCOM_p.c b/CWeChatRobot/WeChatRobotCOM_p.c index 9021cfe5b4dd552fd85b35bdeb769060db877d3c..f691d52d5c8265d65b096cfb2eaf8dc5f0ebde22 100644 --- a/CWeChatRobot/WeChatRobotCOM_p.c +++ b/CWeChatRobot/WeChatRobotCOM_p.c @@ -49,7 +49,7 @@ #include "WeChatRobotCOM_i.h" #define TYPE_FORMAT_STRING_SIZE 71 -#define PROC_FORMAT_STRING_SIZE 337 +#define PROC_FORMAT_STRING_SIZE 397 #define EXPR_FORMAT_STRING_SIZE 1 #define TRANSMIT_AS_TABLE_SIZE 0 #define WIRE_MARSHAL_TABLE_SIZE 1 @@ -304,100 +304,155 @@ static const WeChatRobotCOM_MIDL_PROC_FORMAT_STRING WeChatRobotCOM__MIDL_ProcFor /* 220 */ 0x8, /* FC_LONG */ 0x0, /* 0 */ - /* Procedure CGetFriendList */ + /* Procedure CSendArticle */ /* 222 */ 0x33, /* FC_AUTO_HANDLE */ 0x6c, /* Old Flags: object, Oi2 */ /* 224 */ NdrFcLong( 0x0 ), /* 0 */ /* 228 */ NdrFcShort( 0xc ), /* 12 */ -/* 230 */ NdrFcShort( 0xc ), /* x86 Stack size/offset = 12 */ +/* 230 */ NdrFcShort( 0x1c ), /* x86 Stack size/offset = 28 */ /* 232 */ NdrFcShort( 0x0 ), /* 0 */ -/* 234 */ NdrFcShort( 0x8 ), /* 8 */ -/* 236 */ 0x45, /* Oi2 Flags: srv must size, has return, has ext, */ - 0x2, /* 2 */ +/* 234 */ NdrFcShort( 0x24 ), /* 36 */ +/* 236 */ 0x46, /* Oi2 Flags: clt must size, has return, has ext, */ + 0x6, /* 6 */ /* 238 */ 0x8, /* 8 */ - 0x43, /* Ext Flags: new corr desc, clt corr check, has range on conformance */ -/* 240 */ NdrFcShort( 0x1 ), /* 1 */ -/* 242 */ NdrFcShort( 0x0 ), /* 0 */ + 0x45, /* Ext Flags: new corr desc, srv corr check, has range on conformance */ +/* 240 */ NdrFcShort( 0x0 ), /* 0 */ +/* 242 */ NdrFcShort( 0x1 ), /* 1 */ /* 244 */ NdrFcShort( 0x0 ), /* 0 */ - /* Parameter __result */ + /* Parameter wxid */ -/* 246 */ NdrFcShort( 0x2113 ), /* Flags: must size, must free, out, simple ref, srv alloc size=8 */ +/* 246 */ NdrFcShort( 0x8b ), /* Flags: must size, must free, in, by val, */ /* 248 */ NdrFcShort( 0x4 ), /* x86 Stack size/offset = 4 */ -/* 250 */ NdrFcShort( 0x3c ), /* Type Offset=60 */ +/* 250 */ NdrFcShort( 0x26 ), /* Type Offset=38 */ - /* Return value */ + /* Parameter title */ -/* 252 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */ +/* 252 */ NdrFcShort( 0x8b ), /* Flags: must size, must free, in, by val, */ /* 254 */ NdrFcShort( 0x8 ), /* x86 Stack size/offset = 8 */ -/* 256 */ 0x8, /* FC_LONG */ +/* 256 */ NdrFcShort( 0x26 ), /* Type Offset=38 */ + + /* Parameter abstract */ + +/* 258 */ NdrFcShort( 0x8b ), /* Flags: must size, must free, in, by val, */ +/* 260 */ NdrFcShort( 0xc ), /* x86 Stack size/offset = 12 */ +/* 262 */ NdrFcShort( 0x26 ), /* Type Offset=38 */ + + /* Parameter url */ + +/* 264 */ NdrFcShort( 0x8b ), /* Flags: must size, must free, in, by val, */ +/* 266 */ NdrFcShort( 0x10 ), /* x86 Stack size/offset = 16 */ +/* 268 */ NdrFcShort( 0x26 ), /* Type Offset=38 */ + + /* Parameter __result */ + +/* 270 */ NdrFcShort( 0x2150 ), /* Flags: out, base type, simple ref, srv alloc size=8 */ +/* 272 */ NdrFcShort( 0x14 ), /* x86 Stack size/offset = 20 */ +/* 274 */ 0x8, /* FC_LONG */ + 0x0, /* 0 */ + + /* Return value */ + +/* 276 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */ +/* 278 */ NdrFcShort( 0x18 ), /* x86 Stack size/offset = 24 */ +/* 280 */ 0x8, /* FC_LONG */ + 0x0, /* 0 */ + + /* Procedure CGetFriendList */ + +/* 282 */ 0x33, /* FC_AUTO_HANDLE */ + 0x6c, /* Old Flags: object, Oi2 */ +/* 284 */ NdrFcLong( 0x0 ), /* 0 */ +/* 288 */ NdrFcShort( 0xd ), /* 13 */ +/* 290 */ NdrFcShort( 0xc ), /* x86 Stack size/offset = 12 */ +/* 292 */ NdrFcShort( 0x0 ), /* 0 */ +/* 294 */ NdrFcShort( 0x8 ), /* 8 */ +/* 296 */ 0x45, /* Oi2 Flags: srv must size, has return, has ext, */ + 0x2, /* 2 */ +/* 298 */ 0x8, /* 8 */ + 0x43, /* Ext Flags: new corr desc, clt corr check, has range on conformance */ +/* 300 */ NdrFcShort( 0x1 ), /* 1 */ +/* 302 */ NdrFcShort( 0x0 ), /* 0 */ +/* 304 */ NdrFcShort( 0x0 ), /* 0 */ + + /* Parameter __result */ + +/* 306 */ NdrFcShort( 0x2113 ), /* Flags: must size, must free, out, simple ref, srv alloc size=8 */ +/* 308 */ NdrFcShort( 0x4 ), /* x86 Stack size/offset = 4 */ +/* 310 */ NdrFcShort( 0x3c ), /* Type Offset=60 */ + + /* Return value */ + +/* 312 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */ +/* 314 */ NdrFcShort( 0x8 ), /* x86 Stack size/offset = 8 */ +/* 316 */ 0x8, /* FC_LONG */ 0x0, /* 0 */ /* Procedure CGetWxUserInfo */ -/* 258 */ 0x33, /* FC_AUTO_HANDLE */ +/* 318 */ 0x33, /* FC_AUTO_HANDLE */ 0x6c, /* Old Flags: object, Oi2 */ -/* 260 */ NdrFcLong( 0x0 ), /* 0 */ -/* 264 */ NdrFcShort( 0xd ), /* 13 */ -/* 266 */ NdrFcShort( 0x10 ), /* x86 Stack size/offset = 16 */ -/* 268 */ NdrFcShort( 0x0 ), /* 0 */ -/* 270 */ NdrFcShort( 0x8 ), /* 8 */ -/* 272 */ 0x47, /* Oi2 Flags: srv must size, clt must size, has return, has ext, */ +/* 320 */ NdrFcLong( 0x0 ), /* 0 */ +/* 324 */ NdrFcShort( 0xe ), /* 14 */ +/* 326 */ NdrFcShort( 0x10 ), /* x86 Stack size/offset = 16 */ +/* 328 */ NdrFcShort( 0x0 ), /* 0 */ +/* 330 */ NdrFcShort( 0x8 ), /* 8 */ +/* 332 */ 0x47, /* Oi2 Flags: srv must size, clt must size, has return, has ext, */ 0x3, /* 3 */ -/* 274 */ 0x8, /* 8 */ +/* 334 */ 0x8, /* 8 */ 0x47, /* Ext Flags: new corr desc, clt corr check, srv corr check, has range on conformance */ -/* 276 */ NdrFcShort( 0x1 ), /* 1 */ -/* 278 */ NdrFcShort( 0x1 ), /* 1 */ -/* 280 */ NdrFcShort( 0x0 ), /* 0 */ +/* 336 */ NdrFcShort( 0x1 ), /* 1 */ +/* 338 */ NdrFcShort( 0x1 ), /* 1 */ +/* 340 */ NdrFcShort( 0x0 ), /* 0 */ /* Parameter wxid */ -/* 282 */ NdrFcShort( 0x8b ), /* Flags: must size, must free, in, by val, */ -/* 284 */ NdrFcShort( 0x4 ), /* x86 Stack size/offset = 4 */ -/* 286 */ NdrFcShort( 0x26 ), /* Type Offset=38 */ +/* 342 */ NdrFcShort( 0x8b ), /* Flags: must size, must free, in, by val, */ +/* 344 */ NdrFcShort( 0x4 ), /* x86 Stack size/offset = 4 */ +/* 346 */ NdrFcShort( 0x26 ), /* Type Offset=38 */ /* Parameter __result */ -/* 288 */ NdrFcShort( 0x2113 ), /* Flags: must size, must free, out, simple ref, srv alloc size=8 */ -/* 290 */ NdrFcShort( 0x8 ), /* x86 Stack size/offset = 8 */ -/* 292 */ NdrFcShort( 0x3c ), /* Type Offset=60 */ +/* 348 */ NdrFcShort( 0x2113 ), /* Flags: must size, must free, out, simple ref, srv alloc size=8 */ +/* 350 */ NdrFcShort( 0x8 ), /* x86 Stack size/offset = 8 */ +/* 352 */ NdrFcShort( 0x3c ), /* Type Offset=60 */ /* Return value */ -/* 294 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */ -/* 296 */ NdrFcShort( 0xc ), /* x86 Stack size/offset = 12 */ -/* 298 */ 0x8, /* FC_LONG */ +/* 354 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */ +/* 356 */ NdrFcShort( 0xc ), /* x86 Stack size/offset = 12 */ +/* 358 */ 0x8, /* FC_LONG */ 0x0, /* 0 */ /* Procedure CGetSelfInfo */ -/* 300 */ 0x33, /* FC_AUTO_HANDLE */ +/* 360 */ 0x33, /* FC_AUTO_HANDLE */ 0x6c, /* Old Flags: object, Oi2 */ -/* 302 */ NdrFcLong( 0x0 ), /* 0 */ -/* 306 */ NdrFcShort( 0xe ), /* 14 */ -/* 308 */ NdrFcShort( 0xc ), /* x86 Stack size/offset = 12 */ -/* 310 */ NdrFcShort( 0x0 ), /* 0 */ -/* 312 */ NdrFcShort( 0x8 ), /* 8 */ -/* 314 */ 0x45, /* Oi2 Flags: srv must size, has return, has ext, */ +/* 362 */ NdrFcLong( 0x0 ), /* 0 */ +/* 366 */ NdrFcShort( 0xf ), /* 15 */ +/* 368 */ NdrFcShort( 0xc ), /* x86 Stack size/offset = 12 */ +/* 370 */ NdrFcShort( 0x0 ), /* 0 */ +/* 372 */ NdrFcShort( 0x8 ), /* 8 */ +/* 374 */ 0x45, /* Oi2 Flags: srv must size, has return, has ext, */ 0x2, /* 2 */ -/* 316 */ 0x8, /* 8 */ +/* 376 */ 0x8, /* 8 */ 0x43, /* Ext Flags: new corr desc, clt corr check, has range on conformance */ -/* 318 */ NdrFcShort( 0x1 ), /* 1 */ -/* 320 */ NdrFcShort( 0x0 ), /* 0 */ -/* 322 */ NdrFcShort( 0x0 ), /* 0 */ +/* 378 */ NdrFcShort( 0x1 ), /* 1 */ +/* 380 */ NdrFcShort( 0x0 ), /* 0 */ +/* 382 */ NdrFcShort( 0x0 ), /* 0 */ /* Parameter __result */ -/* 324 */ NdrFcShort( 0x2113 ), /* Flags: must size, must free, out, simple ref, srv alloc size=8 */ -/* 326 */ NdrFcShort( 0x4 ), /* x86 Stack size/offset = 4 */ -/* 328 */ NdrFcShort( 0x3c ), /* Type Offset=60 */ +/* 384 */ NdrFcShort( 0x2113 ), /* Flags: must size, must free, out, simple ref, srv alloc size=8 */ +/* 386 */ NdrFcShort( 0x4 ), /* x86 Stack size/offset = 4 */ +/* 388 */ NdrFcShort( 0x3c ), /* Type Offset=60 */ /* Return value */ -/* 330 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */ -/* 332 */ NdrFcShort( 0x8 ), /* x86 Stack size/offset = 8 */ -/* 334 */ 0x8, /* FC_LONG */ +/* 390 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */ +/* 392 */ NdrFcShort( 0x8 ), /* x86 Stack size/offset = 8 */ +/* 394 */ 0x8, /* FC_LONG */ 0x0, /* 0 */ 0x0 @@ -500,8 +555,9 @@ static const unsigned short IWeChatRobot_FormatStringOffsetTable[] = 126, 174, 222, - 258, - 300 + 282, + 318, + 360 }; static const MIDL_STUBLESS_PROXY_INFO IWeChatRobot_ProxyInfo = @@ -525,7 +581,7 @@ static const MIDL_SERVER_INFO IWeChatRobot_ServerInfo = 0, 0, 0}; -CINTERFACE_PROXY_VTABLE(15) _IWeChatRobotProxyVtbl = +CINTERFACE_PROXY_VTABLE(16) _IWeChatRobotProxyVtbl = { &IWeChatRobot_ProxyInfo, &IID_IWeChatRobot, @@ -541,6 +597,7 @@ CINTERFACE_PROXY_VTABLE(15) _IWeChatRobotProxyVtbl = (void *) (INT_PTR) -1 /* IWeChatRobot::CSendText */ , (void *) (INT_PTR) -1 /* IWeChatRobot::CSendImage */ , (void *) (INT_PTR) -1 /* IWeChatRobot::CSendFile */ , + (void *) (INT_PTR) -1 /* IWeChatRobot::CSendArticle */ , (void *) (INT_PTR) -1 /* IWeChatRobot::CGetFriendList */ , (void *) (INT_PTR) -1 /* IWeChatRobot::CGetWxUserInfo */ , (void *) (INT_PTR) -1 /* IWeChatRobot::CGetSelfInfo */ @@ -560,6 +617,7 @@ static const PRPC_STUB_FUNCTION IWeChatRobot_table[] = NdrStubCall2, NdrStubCall2, NdrStubCall2, + NdrStubCall2, NdrStubCall2 }; @@ -567,7 +625,7 @@ CInterfaceStubVtbl _IWeChatRobotStubVtbl = { &IID_IWeChatRobot, &IWeChatRobot_ServerInfo, - 15, + 16, &IWeChatRobot_table[-3], CStdStubBuffer_DELEGATING_METHODS }; diff --git a/CWeChatRobot/pch.cpp b/CWeChatRobot/pch.cpp index c9ec7259604082f9405040e4c9bd3d17cefcf1db..9a22028a16149da16292c4ea48b6d3a25104583e 100644 --- a/CWeChatRobot/pch.cpp +++ b/CWeChatRobot/pch.cpp @@ -6,6 +6,7 @@ DWORD SendImageOffset = 0x0; DWORD SendTextOffset = 0x0; DWORD SendFileOffset = 0x0; +DWORD SendArticleOffset = 0x0; DWORD GetFriendListInitOffset = 0x0; DWORD GetFriendListRemoteOffset = 0x0; @@ -81,6 +82,8 @@ void GetProcOffset(wchar_t* workPath) { SendTextOffset = SendTextProcAddr - WeChatBase; DWORD SendFileProcAddr = (DWORD)GetProcAddress(hd, SendFileRemote); SendFileOffset = SendFileProcAddr - WeChatBase; + DWORD SendArticleProcAddr = (DWORD)GetProcAddress(hd, SendArticleRemote); + SendArticleOffset = SendArticleProcAddr - WeChatBase; DWORD GetFriendListInitProcAddr = (DWORD)GetProcAddress(hd, GetFriendListInit); GetFriendListInitOffset = GetFriendListInitProcAddr - WeChatBase; diff --git a/CWeChatRobot/robotdata.h b/CWeChatRobot/robotdata.h index c0e59934442aed11038d232a85459e4a3eafdeec..0637691f71718da42996c9bb3f0a2cac321d097e 100644 --- a/CWeChatRobot/robotdata.h +++ b/CWeChatRobot/robotdata.h @@ -3,6 +3,7 @@ #include "SendImage.h" #include "SendText.h" #include "SendFile.h" +#include "SendArticle.h" #include "FriendList.h" #include "UserInfo.h" #include "SelfInfo.h" @@ -11,6 +12,7 @@ extern HANDLE hProcess; extern DWORD SendImageOffset; extern DWORD SendTextOffset; extern DWORD SendFileOffset; +extern DWORD SendArticleOffset; extern DWORD GetFriendListInitOffset; extern DWORD GetFriendListRemoteOffset; @@ -28,6 +30,7 @@ extern wstring SelfInfoString; #define SendTextRemote "SendTextRemote" #define SendImageRemote "SendImageRemote" #define SendFileRemote "SendFileRemote" +#define SendArticleRemote "SendArticleRemote" #define GetFriendListInit "GetFriendListInit" #define GetFriendListRemote "GetFriendListRemote" diff --git a/DWeChatRobot/SelfInfo.cpp b/DWeChatRobot/SelfInfo.cpp index 1e10596deecad2eaaff34fafcd3c10610db6a411..fd18c6724bcd6098d88d33fd324ac19db3c7a421 100644 --- a/DWeChatRobot/SelfInfo.cpp +++ b/DWeChatRobot/SelfInfo.cpp @@ -8,6 +8,7 @@ struct SelfInfoStruct { DWORD length; } ret; +// дBUG DWORD GetSelfInfoRemote() { DWORD WeChatWinBase = GetWeChatWinBase(); vector SelfInfoAddr = { @@ -35,14 +36,24 @@ DWORD GetSelfInfoRemote() { L"\"wxCity\"", L"\"PhoneNumber\"" }; - +#ifdef _DEBUG + wcout.imbue(locale("chs")); +#endif selfinfo = selfinfo + L"{"; for (unsigned int i = 0; i < SelfInfoAddr.size(); i++) { selfinfo = selfinfo + SelfInfoKey[i] + L":"; selfinfo = selfinfo + L"\""; char* temp = (*((DWORD*)SelfInfoAddr[i]) != 0) ? (char*)SelfInfoAddr[i] : (char*)"null"; +#ifdef _DEBUG + cout << temp << endl; +#endif + continue; wchar_t* wtemp = new wchar_t[strlen(temp) + 1]; + ZeroMemory(wtemp, (strlen(temp) + 1) * 2); MultiByteToWideChar(CP_UTF8, MB_COMPOSITE, temp, -1, wtemp, strlen(temp) + 1); +#ifdef _DEBUG + wcout << wtemp << endl; +#endif selfinfo = selfinfo + wtemp; selfinfo = selfinfo + L"\""; if(i!= SelfInfoAddr.size() - 1) @@ -54,7 +65,6 @@ DWORD GetSelfInfoRemote() { ret.message = (DWORD)selfinfo.c_str(); ret.length = selfinfo.length(); #ifdef _DEBUG - wcout.imbue(locale("chs")); wcout << selfinfo << endl; DeleteSelfInfoCacheRemote(); #endif diff --git a/DWeChatRobot/SendArticle.cpp b/DWeChatRobot/SendArticle.cpp index 4da9cb2020449d5eb98e6c8bc21fe2b886073d58..869b41e936523df3776113b04dcaf5f732ba6656 100644 --- a/DWeChatRobot/SendArticle.cpp +++ b/DWeChatRobot/SendArticle.cpp @@ -1,70 +1,56 @@ #include "pch.h" struct SendArticleStruct { + DWORD wxid; DWORD title; DWORD abstract; - DWORD wxid; DWORD url; }; -struct WxSendXmlStruct -{ - wchar_t* buffer; - DWORD length; - DWORD maxLength; - DWORD fill1; - DWORD fill2; - char nullbuffer[0x3C] = { 0 }; - - WxSendXmlStruct(wchar_t* pStr) { - buffer = pStr; - length = wcslen(pStr); - maxLength = wcslen(pStr) * 2; - fill1 = 0x0; - fill2 = 0x0; - } -}; +VOID SendArticleRemote(LPVOID lparameter) { + SendArticleStruct* sas = (SendArticleStruct*)lparameter; + wchar_t* wxid = (wchar_t*)sas->wxid; + wchar_t* title = (wchar_t*)sas->title; + wchar_t* abstract = (wchar_t*)sas->abstract; + wchar_t* url = (wchar_t*)sas->url; + SendArticle(wxid,title,abstract,url); +} -struct WxSenderStruct -{ - wchar_t* buffer; - DWORD length; - DWORD maxLength; - DWORD fill1; - DWORD fill2; - char nullbuffer[0x64] = { 0 }; +BOOL __stdcall SendArticle(wchar_t* wxid,wchar_t* title, wchar_t* abstract, wchar_t* url) { + DWORD WeChatWinBase = GetWeChatWinBase(); + DWORD SendArticleCall1 = WeChatWinBase + 0x5BC68E80 - 0x5BBE0000; + DWORD SendArticleCall2 = WeChatWinBase + 0x03297840 - 0x02F20000; + DWORD SendArticleCall3 = WeChatWinBase + 0x5BC9C570 - 0x5BBE0000; + DWORD SendArticleCall4 = WeChatWinBase + 0x5BF57A10 - 0x5BBE0000; - WxSenderStruct(wchar_t* pStr) { - buffer = pStr; - length = wcslen(pStr); - maxLength = wcslen(pStr) * 2; - fill1 = 0x0; - fill2 = 0x0; - } -}; + DWORD SendArticleParam = WeChatWinBase + 0x5DDCCD1C - 0x5BBE0000; -BOOL SendArticle(wchar_t* wxid,wchar_t* title, wchar_t* abstract, wchar_t* url) { - DWORD WeChatWinBase = GetWeChatWinBase(); - DWORD SendArticleCall = WeChatWinBase + 0x03297840 - 0x02F20000; + DWORD SendArticleClearCacheCall1 = WeChatWinBase + 0x5C1F40D0 - 0x5BBE0000; + DWORD SendArticleClearCacheCall2 = WeChatWinBase + 0x59637BA0 - 0x595B0000; + // Լwxid char* sselfwxid = (char*)(*(DWORD*)(WeChatWinBase + 0x21DC9C4)); wchar_t* wselfwxid = new wchar_t[strlen(sselfwxid) + 1]; MultiByteToWideChar(CP_ACP, MB_COMPOSITE, sselfwxid, -1, wselfwxid, strlen(sselfwxid) + 1); - + // xml wchar_t* xmlbuffer = new wchar_t[0x2000]; ZeroMemory(xmlbuffer, 0x2000 * 2); swprintf_s(xmlbuffer,0x2000, (wchar_t*)L"\n %ws\n 0\n \n \n %ws\n %ws\n view\n 5\n 0\n \n %ws\n \n \n \n \n \n \n \n \n \n \n \n \n \n 0\n \n \n \n \n \n \n \n \n \n 0\n \n \n \n \n 1\n Window wechat\n \n", wselfwxid,title,abstract,url); + DWORD sendtype = 0x5; - WxSenderStruct pSender(wselfwxid); + WxBaseStruct pSender(wselfwxid); char nullbuffer[0x1C] = { 0 }; - char imgbuffer[0x3C] = { 0 }; - WxSendXmlStruct pXml(xmlbuffer); - WxSenderStruct pReceiver(wxid); + WxBaseStruct pXml(xmlbuffer); + WxBaseStruct pReceiver(wxid); + WxString imgbuffer = { 0 }; + WxString nullStruct = { 0 }; char buffer[0xF70] = { 0 }; DWORD isSuccess = 0x0; __asm { pushad; pushfd; + lea ecx, buffer; + call SendArticleCall1; mov eax, [sendtype]; push eax; lea eax, nullbuffer; @@ -77,9 +63,23 @@ BOOL SendArticle(wchar_t* wxid,wchar_t* title, wchar_t* abstract, wchar_t* url) lea edi, pReceiver; push edi; lea ecx, buffer; - call SendArticleCall; + call SendArticleCall2; add esp, 0x14; + lea eax, nullStruct; + push eax; + lea ecx, buffer; + call SendArticleCall3; + mov dl, 0x0; + lea ecx, buffer; + push SendArticleParam; + push SendArticleParam; + call SendArticleCall4; mov isSuccess, eax; + add esp, 0x8; + lea ecx, buffer; + call SendArticleClearCacheCall1; + lea ecx, buffer; + call SendArticleClearCacheCall2; popfd; popad; } @@ -87,5 +87,5 @@ BOOL SendArticle(wchar_t* wxid,wchar_t* title, wchar_t* abstract, wchar_t* url) xmlbuffer = NULL; delete[] wselfwxid; wselfwxid = NULL; - return isSuccess; + return (isSuccess == 0x1); } \ No newline at end of file diff --git a/DWeChatRobot/SendArticle.h b/DWeChatRobot/SendArticle.h index 30ef9490e6d5d0f0aac9b1df4d84be0a7c969522..5ce08585361e42d6c9f57af62256b9ef231fb826 100644 --- a/DWeChatRobot/SendArticle.h +++ b/DWeChatRobot/SendArticle.h @@ -1,3 +1,4 @@ #pragma once #include -BOOL SendArticle(wchar_t* wxid, wchar_t* title, wchar_t* abstract, wchar_t* url); \ No newline at end of file +extern "C" __declspec(dllexport) VOID SendArticleRemote(LPVOID lparameter); +BOOL __stdcall SendArticle(wchar_t* wxid, wchar_t* title, wchar_t* abstract, wchar_t* url); \ No newline at end of file diff --git a/DWeChatRobot/UserInfo.cpp b/DWeChatRobot/UserInfo.cpp index 525053e651fe7bf2d2e3242620ac9a5fb885158a..9dc7a7c4bde5383555c932da2fdfa3b2654bd093 100644 --- a/DWeChatRobot/UserInfo.cpp +++ b/DWeChatRobot/UserInfo.cpp @@ -101,7 +101,7 @@ VOID DeleteUserInfoCacheRemote() { } } -BOOL GetUserInfoByWxId(wchar_t* wxid,DWORD &address) { +BOOL __stdcall GetUserInfoByWxId(wchar_t* wxid,DWORD &address) { DWORD WeChatWinBase = GetWeChatWinBase(); DWORD GetUserDetailInfoCall1 = WeChatWinBase + GetUserInfoCall1Offset; DWORD GetUserDetailInfoCall2 = WeChatWinBase + GetUserInfoCall2Offset; @@ -157,7 +157,7 @@ BOOL GetUserInfoByWxId(wchar_t* wxid,DWORD &address) { } // һѯϢĵط -BOOL GetWxUserInfoByWxid2(wchar_t* wxid, DWORD& address) { +BOOL __stdcall GetWxUserInfoByWxid2(wchar_t* wxid, DWORD& address) { DWORD WeChatWinBase = GetWeChatWinBase(); DWORD WxUserDataCall1 = WeChatWinBase + 0x645BD9A0 - 0x64530000; DWORD WxUserDataCall2 = WeChatWinBase + 0x64C08420 - 0x64530000; diff --git a/DWeChatRobot/UserInfo.h b/DWeChatRobot/UserInfo.h index cbb6a5cc700108628b1b92f5fa909c4f543595fd..760517fc5c34818d5409e4188eccba9c96303d57 100644 --- a/DWeChatRobot/UserInfo.h +++ b/DWeChatRobot/UserInfo.h @@ -1,6 +1,6 @@ #pragma once #include -BOOL GetWxUserInfoByWxid2(wchar_t* wxid, DWORD& address); -BOOL GetUserInfoByWxId(wchar_t* wxid, DWORD& address); +BOOL __stdcall GetWxUserInfoByWxid2(wchar_t* wxid, DWORD& address); +BOOL __stdcall GetUserInfoByWxId(wchar_t* wxid, DWORD& address); extern "C" __declspec(dllexport) DWORD GetWxUserInfoRemote(LPVOID lparamter); extern "C" __declspec(dllexport) VOID DeleteUserInfoCacheRemote(); \ No newline at end of file diff --git a/DWeChatRobot/dllmain.cpp b/DWeChatRobot/dllmain.cpp index 33580e46222e819ac20ac3b44f6737140469c8e6..1ea4204a90d864dc392a0bb18bd28e7285094f44 100644 --- a/DWeChatRobot/dllmain.cpp +++ b/DWeChatRobot/dllmain.cpp @@ -25,8 +25,8 @@ BOOL APIENTRY DllMain( HMODULE hModule, printf("HookExtractExpression 0x%08X\n", (DWORD)HookExtractExpression); printf("GetUserInfoByWxId 0x%08X\n", (DWORD)GetUserInfoByWxId); printf("SendArticle 0x%08X\n", (DWORD)SendArticle); - system("pause"); - SendArticle((WCHAR*)L"filehelper",(WCHAR*)L"这是标题",(WCHAR*)L"这是摘要",(WCHAR*)L"https://www.ljczero.top/article/2022/3/13/133.html"); + + // GetSelfInfoRemote(); #endif break; } @@ -36,7 +36,7 @@ BOOL APIENTRY DllMain( HMODULE hModule, #ifdef _DEBUG detach_count++; if (detach_count != 1) { - FreeConsole(); + // FreeConsole(); // UnHookAll(); } #endif diff --git a/Release/CWeChatRobot.exe b/Release/CWeChatRobot.exe index 1ef23246623a198446d53c8b751d08b82eb15172..25d4058e8b37ae0314ab0726a2fc73f1cfdde9f4 100644 Binary files a/Release/CWeChatRobot.exe and b/Release/CWeChatRobot.exe differ diff --git a/Release/DWeChatRobot.dll b/Release/DWeChatRobot.dll index c96508b1c9560551a3384772c7da1e9b14def0fd..ee18153c8e344499191d85a832e3390295e0bc22 100644 Binary files a/Release/DWeChatRobot.dll and b/Release/DWeChatRobot.dll differ diff --git a/wxRobot.py b/wxRobot.py index c393dced50ab66d86434fb44c257f71b436f6cc1..2de41e4281f470193d8d6a4a3b74b95379324c09 100644 --- a/wxRobot.py +++ b/wxRobot.py @@ -27,6 +27,9 @@ class ChatSession(): def SendMp4(self,mp4path): return self.robot.CSendImage(self.chatwith,mp4path) + def SendArticle(self,title,abstract,url): + return self.robot.CSendArticle(self.chatwith,title,abstract,url) + class WeChatRobot(): @@ -39,9 +42,10 @@ class WeChatRobot(): def StartService(self): status = self.robot.CStartRobotService(self.dllpath) if status == 0: - self.myinfo = self.GetSelfInfo() + pass return status - + + # 有bug待修复,需要判断某项信息是否是指针 def GetSelfInfo(self): myinfo = self.robot.CGetSelfInfo().replace('\n','\\n') myinfo = ast.literal_eval(myinfo) @@ -124,7 +128,7 @@ def test(): mp4path = r"C:\Users\Administrator\Desktop\快捷\wechat\wxsend.mp4" me = wx.GetFriendByWxNickName("文件传送助手") session = wx.GetChatSession(me.get('wxid')) - + print(wx.GetWxUserInfo(me.get('wxid'))) session.SendText('来自python的消息') session.SendImage(imgpath) session.SendFile(filepath) @@ -133,12 +137,12 @@ def test(): if __name__ == '__main__': # DWeChatRobot.dll path - dllpath = r'D:\C++\ComWeChatRobot\Release' + dllpath = r'D:\VS2019C++\MyWeChatRobot\Release' wx = WeChatRobot(dllpath) wx.StartService() wxid = wx.GetFriendByWxNickName("文件传输助手").get('wxid') - print(wx.myinfo) - print(wx.GetWxUserInfo(wxid)) + session = wx.GetChatSession(wxid) + session.SendArticle("PC微信逆向--获取通讯录","确定不来看看么?","https://www.ljczero.top/article/2022/3/13/133.html") wx.StopService() \ No newline at end of file