diff --git a/CWeChatRobot/GetA8Key.cpp b/CWeChatRobot/GetA8Key.cpp new file mode 100644 index 0000000000000000000000000000000000000000..23f0393ddb0a32f930b0af32a7ebfb493d0f27f6 --- /dev/null +++ b/CWeChatRobot/GetA8Key.cpp @@ -0,0 +1,35 @@ +#include "pch.h" + +struct GetA8KeyRespStruct +{ + DWORD message; + DWORD length; +}; + +wstring GetA8Key(DWORD pid, wchar_t *url) +{ + WeChatProcess hp(pid); + if (!hp.m_init) + return L""; + DWORD GetA8KeyReomteAddr = hp.GetProcAddr(GetA8KeyRemote); + if (GetA8KeyReomteAddr == 0) + { + return L""; + } + WeChatData r_url(hp.GetHandle(), url, TEXTLENGTH(url)); + if (!r_url.GetAddr()) + { + return L""; + } + DWORD dwRet = CallRemoteFunction(hp.GetHandle(), GetA8KeyReomteAddr, r_url.GetAddr()); + DWORD dwReadSize; + GetA8KeyRespStruct ret_info = {0}; + ReadProcessMemory(hp.GetHandle(), (LPCVOID)dwRet, &ret_info, sizeof(ret_info), &dwReadSize); + if (ret_info.message == 0) + return L""; + unique_ptr buffer(new char[ret_info.length + 1]()); + ReadProcessMemory(hp.GetHandle(), (LPCVOID)ret_info.message, buffer.get(), ret_info.length, &dwReadSize); + string result(buffer.get(), ret_info.length); + wstring wresult = gb2312_to_unicode(result.c_str()); + return wresult; +} diff --git a/CWeChatRobot/GetA8Key.h b/CWeChatRobot/GetA8Key.h new file mode 100644 index 0000000000000000000000000000000000000000..23ed109ba3740156b936de366652ef079e80116c --- /dev/null +++ b/CWeChatRobot/GetA8Key.h @@ -0,0 +1,5 @@ +#pragma once +#include +#include +using namespace std; +wstring GetA8Key(DWORD pid, wchar_t *url); diff --git a/CWeChatRobot/WeChatRobot.cpp b/CWeChatRobot/WeChatRobot.cpp index e9d91c54a9d217ad74c7db3ad3ab72bbb5e6dae2..1cd1d379db396bfdb06ff0b770d9c65c9b1389e1 100644 --- a/CWeChatRobot/WeChatRobot.cpp +++ b/CWeChatRobot/WeChatRobot.cpp @@ -579,3 +579,14 @@ STDMETHODIMP CWeChatRobot::CGetQrcodeImage(DWORD pid, VARIANT *__result) *__result = GetQrcodeImage(pid); return S_OK; } + +/* + * 参数0:目标进程pid + * 参数1:公众号文章链接 + * 参数2:预返回的值,调用时无需提供 + */ +STDMETHODIMP CWeChatRobot::CGetA8Key(DWORD pid, BSTR url, BSTR *__result) +{ + *__result = (_bstr_t)GetA8Key(pid, url).c_str(); + return S_OK; +} diff --git a/CWeChatRobot/WeChatRobot.h b/CWeChatRobot/WeChatRobot.h index 45d7b15b9c3b9f13d6298f1219649a49ba68197a..ebe2fa3e0732b93eba322a8827d1297632a18670 100644 --- a/CWeChatRobot/WeChatRobot.h +++ b/CWeChatRobot/WeChatRobot.h @@ -87,6 +87,7 @@ public: STDMETHODIMP CGetHistoryPublicMsg(DWORD pid, BSTR PublicId, BSTR Offset, VARIANT *__result); STDMETHODIMP CForwardMessage(DWORD pid, BSTR wxid, ULONG64 msgid, int *__result); STDMETHODIMP CGetQrcodeImage(DWORD pid, VARIANT *__result); + STDMETHODIMP CGetA8Key(DWORD pid, BSTR url, BSTR *__result); }; OBJECT_ENTRY_AUTO(__uuidof(WeChatRobot), CWeChatRobot) diff --git a/CWeChatRobot/WeChatRobotCOM.idl b/CWeChatRobot/WeChatRobotCOM.idl index 7ab41878f0e8a6d6accaa4f72767c3081d02fe05..6964d6cb75cad7b27d130b8e46996d176f4f9cd5 100644 --- a/CWeChatRobot/WeChatRobotCOM.idl +++ b/CWeChatRobot/WeChatRobotCOM.idl @@ -62,6 +62,7 @@ interface IWeChatRobot : IDispatch [id(47), helpstring("获取公众号历史消息")] HRESULT CGetHistoryPublicMsg([in] DWORD pid, [in] BSTR PublicId, [in] BSTR Offset, [out, retval] VARIANT * __result); [id(48), helpstring("转发消息") ] HRESULT CForwardMessage([in] DWORD pid, [in] BSTR wxid, [in] unsigned long long localId, [out, retval] int * __result); [id(49), helpstring("获取二维码")] HRESULT CGetQrcodeImage([in] DWORD pid, [out, retval] VARIANT * __result); + [id(50), helpstring("获取二维码")] HRESULT CGetA8Key([in] DWORD pid, [in] BSTR url, [ out, retval ] BSTR * __result); }; [ object, diff --git a/CWeChatRobot/WeChatRobotCOM.vcxproj b/CWeChatRobot/WeChatRobotCOM.vcxproj index fb12f5f246dd395517bd0c05864ccfb73ad197b0..c3327dd7a99bc362e8acf2426db2c2ef467f2737 100644 --- a/CWeChatRobot/WeChatRobotCOM.vcxproj +++ b/CWeChatRobot/WeChatRobotCOM.vcxproj @@ -232,6 +232,7 @@ + @@ -280,6 +281,7 @@ + diff --git a/CWeChatRobot/WeChatRobotCOM.vcxproj.filters b/CWeChatRobot/WeChatRobotCOM.vcxproj.filters index 017328ee656422619662d0630b9aa6f6a196ac66..e441df689640dce6b292a81a263040a2560aa81f 100644 --- a/CWeChatRobot/WeChatRobotCOM.vcxproj.filters +++ b/CWeChatRobot/WeChatRobotCOM.vcxproj.filters @@ -131,6 +131,9 @@ {fb5a07d9-648d-4e1c-aed3-158f872c3d3e} + + {caeac105-0e3b-497e-a73e-f1233b3888aa} + @@ -268,6 +271,9 @@ 二维码 + + 浏览器相关\获取A8Key + @@ -405,6 +411,9 @@ 二维码 + + 浏览器相关\获取A8Key + diff --git a/CWeChatRobot/WeChatRobotCOM_i.h b/CWeChatRobot/WeChatRobotCOM_i.h index 55e05776ceb3e0d4ec65d5dd1f3797ffc42beebe..4fe98cf679944331154be5491cc448c7bb3e3545 100644 --- a/CWeChatRobot/WeChatRobotCOM_i.h +++ b/CWeChatRobot/WeChatRobotCOM_i.h @@ -355,6 +355,11 @@ EXTERN_C const IID IID_IWeChatRobot; /* [in] */ DWORD pid, /* [retval][out] */ VARIANT *__result) = 0; + virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE CGetA8Key( + /* [in] */ DWORD pid, + /* [in] */ BSTR url, + /* [retval][out] */ BSTR *__result) = 0; + }; @@ -700,6 +705,12 @@ EXTERN_C const IID IID_IWeChatRobot; /* [in] */ DWORD pid, /* [retval][out] */ VARIANT *__result); + /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *CGetA8Key )( + IWeChatRobot * This, + /* [in] */ DWORD pid, + /* [in] */ BSTR url, + /* [retval][out] */ BSTR *__result); + END_INTERFACE } IWeChatRobotVtbl; @@ -874,6 +885,9 @@ EXTERN_C const IID IID_IWeChatRobot; #define IWeChatRobot_CGetQrcodeImage(This,pid,__result) \ ( (This)->lpVtbl -> CGetQrcodeImage(This,pid,__result) ) +#define IWeChatRobot_CGetA8Key(This,pid,url,__result) \ + ( (This)->lpVtbl -> CGetA8Key(This,pid,url,__result) ) + #endif /* COBJMACROS */ diff --git a/CWeChatRobot/WeChatRobotCOM_p.c b/CWeChatRobot/WeChatRobotCOM_p.c index 4c5bae7d96d038295dae3f7eeb0a45dd5fa4273b..23db8b994de07200f25fcb168d7c063e8442c634 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 2383 +#define PROC_FORMAT_STRING_SIZE 2431 #define EXPR_FORMAT_STRING_SIZE 1 #define TRANSMIT_AS_TABLE_SIZE 0 #define WIRE_MARSHAL_TABLE_SIZE 2 @@ -2194,20 +2194,20 @@ static const WeChatRobotCOM_MIDL_PROC_FORMAT_STRING WeChatRobotCOM__MIDL_ProcFor /* 2272 */ 0x8, /* FC_LONG */ 0x0, /* 0 */ - /* Procedure CPostMessage */ + /* Procedure CGetA8Key */ /* 2274 */ 0x33, /* FC_AUTO_HANDLE */ 0x6c, /* Old Flags: object, Oi2 */ /* 2276 */ NdrFcLong( 0x0 ), /* 0 */ -/* 2280 */ NdrFcShort( 0x7 ), /* 7 */ -/* 2282 */ NdrFcShort( 0x20 ), /* x86 Stack size/offset = 32 */ -/* 2284 */ NdrFcShort( 0x20 ), /* 32 */ -/* 2286 */ NdrFcShort( 0x24 ), /* 36 */ -/* 2288 */ 0x46, /* Oi2 Flags: clt must size, has return, has ext, */ - 0x6, /* 6 */ +/* 2280 */ NdrFcShort( 0x35 ), /* 53 */ +/* 2282 */ NdrFcShort( 0x14 ), /* x86 Stack size/offset = 20 */ +/* 2284 */ NdrFcShort( 0x8 ), /* 8 */ +/* 2286 */ NdrFcShort( 0x8 ), /* 8 */ +/* 2288 */ 0x47, /* Oi2 Flags: srv must size, clt must size, has return, has ext, */ + 0x4, /* 4 */ /* 2290 */ 0x8, /* 8 */ - 0x45, /* Ext Flags: new corr desc, srv corr check, has range on conformance */ -/* 2292 */ NdrFcShort( 0x0 ), /* 0 */ + 0x47, /* Ext Flags: new corr desc, clt corr check, srv corr check, has range on conformance */ +/* 2292 */ NdrFcShort( 0x1 ), /* 1 */ /* 2294 */ NdrFcShort( 0x1 ), /* 1 */ /* 2296 */ NdrFcShort( 0x0 ), /* 0 */ @@ -2218,83 +2218,126 @@ static const WeChatRobotCOM_MIDL_PROC_FORMAT_STRING WeChatRobotCOM__MIDL_ProcFor /* 2302 */ 0x8, /* FC_LONG */ 0x0, /* 0 */ - /* Parameter msgtype */ + /* Parameter url */ -/* 2304 */ NdrFcShort( 0x48 ), /* Flags: in, base type, */ +/* 2304 */ NdrFcShort( 0x8b ), /* Flags: must size, must free, in, by val, */ /* 2306 */ NdrFcShort( 0x8 ), /* x86 Stack size/offset = 8 */ -/* 2308 */ 0x8, /* FC_LONG */ +/* 2308 */ NdrFcShort( 0x2a ), /* Type Offset=42 */ + + /* Parameter __result */ + +/* 2310 */ NdrFcShort( 0x2113 ), /* Flags: must size, must free, out, simple ref, srv alloc size=8 */ +/* 2312 */ NdrFcShort( 0xc ), /* x86 Stack size/offset = 12 */ +/* 2314 */ NdrFcShort( 0x4ba ), /* Type Offset=1210 */ + + /* Return value */ + +/* 2316 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */ +/* 2318 */ NdrFcShort( 0x10 ), /* x86 Stack size/offset = 16 */ +/* 2320 */ 0x8, /* FC_LONG */ + 0x0, /* 0 */ + + /* Procedure CPostMessage */ + +/* 2322 */ 0x33, /* FC_AUTO_HANDLE */ + 0x6c, /* Old Flags: object, Oi2 */ +/* 2324 */ NdrFcLong( 0x0 ), /* 0 */ +/* 2328 */ NdrFcShort( 0x7 ), /* 7 */ +/* 2330 */ NdrFcShort( 0x20 ), /* x86 Stack size/offset = 32 */ +/* 2332 */ NdrFcShort( 0x20 ), /* 32 */ +/* 2334 */ NdrFcShort( 0x24 ), /* 36 */ +/* 2336 */ 0x46, /* Oi2 Flags: clt must size, has return, has ext, */ + 0x6, /* 6 */ +/* 2338 */ 0x8, /* 8 */ + 0x45, /* Ext Flags: new corr desc, srv corr check, has range on conformance */ +/* 2340 */ NdrFcShort( 0x0 ), /* 0 */ +/* 2342 */ NdrFcShort( 0x1 ), /* 1 */ +/* 2344 */ NdrFcShort( 0x0 ), /* 0 */ + + /* Parameter pid */ + +/* 2346 */ NdrFcShort( 0x48 ), /* Flags: in, base type, */ +/* 2348 */ NdrFcShort( 0x4 ), /* x86 Stack size/offset = 4 */ +/* 2350 */ 0x8, /* FC_LONG */ + 0x0, /* 0 */ + + /* Parameter msgtype */ + +/* 2352 */ NdrFcShort( 0x48 ), /* Flags: in, base type, */ +/* 2354 */ NdrFcShort( 0x8 ), /* x86 Stack size/offset = 8 */ +/* 2356 */ 0x8, /* FC_LONG */ 0x0, /* 0 */ /* Parameter msgid */ -/* 2310 */ NdrFcShort( 0x48 ), /* Flags: in, base type, */ -/* 2312 */ NdrFcShort( 0xc ), /* x86 Stack size/offset = 12 */ -/* 2314 */ 0xb, /* FC_HYPER */ +/* 2358 */ NdrFcShort( 0x48 ), /* Flags: in, base type, */ +/* 2360 */ NdrFcShort( 0xc ), /* x86 Stack size/offset = 12 */ +/* 2362 */ 0xb, /* FC_HYPER */ 0x0, /* 0 */ /* Parameter msg */ -/* 2316 */ NdrFcShort( 0x10b ), /* Flags: must size, must free, in, simple ref, */ -/* 2318 */ NdrFcShort( 0x14 ), /* x86 Stack size/offset = 20 */ -/* 2320 */ NdrFcShort( 0x4cc ), /* Type Offset=1228 */ +/* 2364 */ NdrFcShort( 0x10b ), /* Flags: must size, must free, in, simple ref, */ +/* 2366 */ NdrFcShort( 0x14 ), /* x86 Stack size/offset = 20 */ +/* 2368 */ NdrFcShort( 0x4cc ), /* Type Offset=1228 */ /* Parameter __result */ -/* 2322 */ NdrFcShort( 0x2150 ), /* Flags: out, base type, simple ref, srv alloc size=8 */ -/* 2324 */ NdrFcShort( 0x18 ), /* x86 Stack size/offset = 24 */ -/* 2326 */ 0x8, /* FC_LONG */ +/* 2370 */ NdrFcShort( 0x2150 ), /* Flags: out, base type, simple ref, srv alloc size=8 */ +/* 2372 */ NdrFcShort( 0x18 ), /* x86 Stack size/offset = 24 */ +/* 2374 */ 0x8, /* FC_LONG */ 0x0, /* 0 */ /* Return value */ -/* 2328 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */ -/* 2330 */ NdrFcShort( 0x1c ), /* x86 Stack size/offset = 28 */ -/* 2332 */ 0x8, /* FC_LONG */ +/* 2376 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */ +/* 2378 */ NdrFcShort( 0x1c ), /* x86 Stack size/offset = 28 */ +/* 2380 */ 0x8, /* FC_LONG */ 0x0, /* 0 */ /* Procedure CRegisterWxPidWithCookie */ -/* 2334 */ 0x33, /* FC_AUTO_HANDLE */ +/* 2382 */ 0x33, /* FC_AUTO_HANDLE */ 0x6c, /* Old Flags: object, Oi2 */ -/* 2336 */ NdrFcLong( 0x0 ), /* 0 */ -/* 2340 */ NdrFcShort( 0x8 ), /* 8 */ -/* 2342 */ NdrFcShort( 0x14 ), /* x86 Stack size/offset = 20 */ -/* 2344 */ NdrFcShort( 0x10 ), /* 16 */ -/* 2346 */ NdrFcShort( 0x24 ), /* 36 */ -/* 2348 */ 0x44, /* Oi2 Flags: has return, has ext, */ +/* 2384 */ NdrFcLong( 0x0 ), /* 0 */ +/* 2388 */ NdrFcShort( 0x8 ), /* 8 */ +/* 2390 */ NdrFcShort( 0x14 ), /* x86 Stack size/offset = 20 */ +/* 2392 */ NdrFcShort( 0x10 ), /* 16 */ +/* 2394 */ NdrFcShort( 0x24 ), /* 36 */ +/* 2396 */ 0x44, /* Oi2 Flags: has return, has ext, */ 0x4, /* 4 */ -/* 2350 */ 0x8, /* 8 */ +/* 2398 */ 0x8, /* 8 */ 0x41, /* Ext Flags: new corr desc, has range on conformance */ -/* 2352 */ NdrFcShort( 0x0 ), /* 0 */ -/* 2354 */ NdrFcShort( 0x0 ), /* 0 */ -/* 2356 */ NdrFcShort( 0x0 ), /* 0 */ +/* 2400 */ NdrFcShort( 0x0 ), /* 0 */ +/* 2402 */ NdrFcShort( 0x0 ), /* 0 */ +/* 2404 */ NdrFcShort( 0x0 ), /* 0 */ /* Parameter pid */ -/* 2358 */ NdrFcShort( 0x48 ), /* Flags: in, base type, */ -/* 2360 */ NdrFcShort( 0x4 ), /* x86 Stack size/offset = 4 */ -/* 2362 */ 0x8, /* FC_LONG */ +/* 2406 */ NdrFcShort( 0x48 ), /* Flags: in, base type, */ +/* 2408 */ NdrFcShort( 0x4 ), /* x86 Stack size/offset = 4 */ +/* 2410 */ 0x8, /* FC_LONG */ 0x0, /* 0 */ /* Parameter cookie */ -/* 2364 */ NdrFcShort( 0x48 ), /* Flags: in, base type, */ -/* 2366 */ NdrFcShort( 0x8 ), /* x86 Stack size/offset = 8 */ -/* 2368 */ 0x8, /* FC_LONG */ +/* 2412 */ NdrFcShort( 0x48 ), /* Flags: in, base type, */ +/* 2414 */ NdrFcShort( 0x8 ), /* x86 Stack size/offset = 8 */ +/* 2416 */ 0x8, /* FC_LONG */ 0x0, /* 0 */ /* Parameter __result */ -/* 2370 */ NdrFcShort( 0x2150 ), /* Flags: out, base type, simple ref, srv alloc size=8 */ -/* 2372 */ NdrFcShort( 0xc ), /* x86 Stack size/offset = 12 */ -/* 2374 */ 0x8, /* FC_LONG */ +/* 2418 */ NdrFcShort( 0x2150 ), /* Flags: out, base type, simple ref, srv alloc size=8 */ +/* 2420 */ NdrFcShort( 0xc ), /* x86 Stack size/offset = 12 */ +/* 2422 */ 0x8, /* FC_LONG */ 0x0, /* 0 */ /* Return value */ -/* 2376 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */ -/* 2378 */ NdrFcShort( 0x10 ), /* x86 Stack size/offset = 16 */ -/* 2380 */ 0x8, /* FC_LONG */ +/* 2424 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */ +/* 2426 */ NdrFcShort( 0x10 ), /* x86 Stack size/offset = 16 */ +/* 2428 */ 0x8, /* FC_LONG */ 0x0, /* 0 */ 0x0 @@ -3187,7 +3230,8 @@ static const unsigned short IWeChatRobot_FormatStringOffsetTable[] = 2076, 2124, 2178, - 2232 + 2232, + 2274 }; static const MIDL_STUBLESS_PROXY_INFO IWeChatRobot_ProxyInfo = @@ -3211,7 +3255,7 @@ static const MIDL_SERVER_INFO IWeChatRobot_ServerInfo = 0, 0, 0}; -CINTERFACE_PROXY_VTABLE(53) _IWeChatRobotProxyVtbl = +CINTERFACE_PROXY_VTABLE(54) _IWeChatRobotProxyVtbl = { &IWeChatRobot_ProxyInfo, &IID_IWeChatRobot, @@ -3267,7 +3311,8 @@ CINTERFACE_PROXY_VTABLE(53) _IWeChatRobotProxyVtbl = (void *) (INT_PTR) -1 /* IWeChatRobot::COpenBrowser */ , (void *) (INT_PTR) -1 /* IWeChatRobot::CGetHistoryPublicMsg */ , (void *) (INT_PTR) -1 /* IWeChatRobot::CForwardMessage */ , - (void *) (INT_PTR) -1 /* IWeChatRobot::CGetQrcodeImage */ + (void *) (INT_PTR) -1 /* IWeChatRobot::CGetQrcodeImage */ , + (void *) (INT_PTR) -1 /* IWeChatRobot::CGetA8Key */ }; @@ -3322,6 +3367,7 @@ static const PRPC_STUB_FUNCTION IWeChatRobot_table[] = NdrStubCall2, NdrStubCall2, NdrStubCall2, + NdrStubCall2, NdrStubCall2 }; @@ -3329,7 +3375,7 @@ CInterfaceStubVtbl _IWeChatRobotStubVtbl = { &IID_IWeChatRobot, &IWeChatRobot_ServerInfo, - 53, + 54, &IWeChatRobot_table[-3], CStdStubBuffer_DELEGATING_METHODS }; @@ -3345,8 +3391,8 @@ static const unsigned short IRobotEvent_FormatStringOffsetTable[] = (unsigned short) -1, (unsigned short) -1, (unsigned short) -1, - 2274, - 2334 + 2322, + 2382 }; static const MIDL_STUBLESS_PROXY_INFO IRobotEvent_ProxyInfo = diff --git a/CWeChatRobot/robotdata.h b/CWeChatRobot/robotdata.h index 86c0ee9030f1df70087c70ac9a8f487b4c32d292..b9b7f4a79dd3187ba349e88416b2dabdac808733 100644 --- a/CWeChatRobot/robotdata.h +++ b/CWeChatRobot/robotdata.h @@ -31,6 +31,7 @@ #include "GetHistoryPublicMsg.h" #include "ForwardMessage.h" #include "GetQrcodeImage.h" +#include "GetA8Key.h" #define DLLNAME L"DWeChatRobot.dll" @@ -91,3 +92,4 @@ #define OpenBrowserRemote "OpenBrowserRemote" #define GetHistoryPublicMsgRemote "GetHistoryPublicMsgRemote" #define GetQrcodeImageRemote "GetQrcodeImageRemote" +#define GetA8KeyRemote "GetA8KeyRemote" diff --git a/DWeChatRobot/DWeChatRobot.vcxproj b/DWeChatRobot/DWeChatRobot.vcxproj index 9bc8f32eb0247e63dc5c15b2c3e5acec76b88b53..a400ccabcace7d2c8af2bbb5a02c41d830ee8a26 100644 --- a/DWeChatRobot/DWeChatRobot.vcxproj +++ b/DWeChatRobot/DWeChatRobot.vcxproj @@ -320,6 +320,7 @@ xcopy /y /d "$(OutDir)..\..\Python\http\wxDriver.py" "$(SolutionDir)build\http + @@ -366,6 +367,7 @@ xcopy /y /d "$(OutDir)..\..\Python\http\wxDriver.py" "$(SolutionDir)build\http + diff --git a/DWeChatRobot/DWeChatRobot.vcxproj.filters b/DWeChatRobot/DWeChatRobot.vcxproj.filters index 23738ec48ff921e6e7ded8b22a7ea3e79a961a40..dd0761f334bfbf9523c60773668d4dcfb62aa922 100644 --- a/DWeChatRobot/DWeChatRobot.vcxproj.filters +++ b/DWeChatRobot/DWeChatRobot.vcxproj.filters @@ -130,6 +130,9 @@ {a0a64bc2-f48e-41a0-838a-45b9985f8d68} + + {10054e30-1115-49df-b387-07c207f6cac4} + @@ -255,6 +258,9 @@ 通用标头 + + 浏览器相关\获取A8Key + @@ -383,5 +389,8 @@ 二维码 + + 浏览器相关\获取A8Key + diff --git a/DWeChatRobot/GetA8Key.cpp b/DWeChatRobot/GetA8Key.cpp new file mode 100644 index 0000000000000000000000000000000000000000..92c92a83bc06211e236c889f6de4ad41c3adbd5b --- /dev/null +++ b/DWeChatRobot/GetA8Key.cpp @@ -0,0 +1,218 @@ +#include "pch.h" +#include "json/json.hpp" +using namespace nlohmann; + +#define GetBufferCallOffset 0x79C2F9FD - 0x78220000 + +#define GetA8KeyCall1Offset 0x78991980 - 0x78220000 +#define GetA8KeyCall2Offset 0x78801650 - 0x78220000 +#define GetA8KeyCall3Offset 0x784B98F0 - 0x78220000 +#define GetA8KeyCall4Offset 0x783441F0 - 0x78220000 +#define GetA8KeyCall5Offset 0x787B9490 - 0x78220000 +#define DelNetSceneA8KeyCallOffset 0x105E1B40 - 0x10000000 + +#define HookA8KeyAddrOffset 0x78BD368E - 0x785F0000 +#define HookA8KeyJmpBackAddrOffset 0x78BD3704 - 0x785F0000 + +static BOOL A8KeyBufHooked = FALSE; +static char A8KeyBufOldAsmCode[5] = {0}; +static DWORD HookAddr = 0; +static DWORD JmpBackAddr = 0; +static string response = ""; +static DWORD SignalThreadId = 0; + +void GetA8KeyBuf(DWORD addr) +{ + json jData; + DWORD p_url = *(DWORD *)(addr + 0x8); + int length = *(int *)(p_url + 0x10); + string full_url; + if (length == 0) + { + full_url = ""; + } + else + { + char *buffer = (length <= 0xF) ? (char *)p_url : (char *)(*(DWORD *)p_url); + full_url = string(buffer, length); + } + jData["full_url"] = full_url; + vector arr_1 = split(full_url, '?'); + if (arr_1.size() > 1) + { + vector params = split(arr_1[1], '&'); + for (auto param : params) + { + vector temp = split(param, '='); + if (temp.size() > 1) + { + string key = temp[0], value = temp[1]; + if (key == "__biz") + { + value += "=="; + } + else if (key == "uin") + { + value = value.substr(0, value.length() - 6) + "=="; + jData["wxuin"] = base64_decode(value.c_str()); + } + jData[key] = value; + } + } + } +#ifndef USE_SOCKET + response = utf8_to_gb2312(jData.dump().c_str()); +#else + response = jData.dump(); +#endif + SIGNAL(SignalThreadId, WM_WAIT_HOOK_DATA); +} + +_declspec(naked) void dealA8KeyBuf() +{ + __asm { + pushad; + pushfd; + mov eax,dword ptr ds:[ebp - 0x4C]; + push eax; + call GetA8KeyBuf; + add esp,0x4; + popfd; + popad; + mov edi,dword ptr ds:[ebp - 0x5C]; + jmp JmpBackAddr; + } +} + +void HookA8KeyBuf() +{ + if (A8KeyBufHooked) + return; + DWORD WeChatWinBase = GetWeChatWinBase(); + HookAddr = WeChatWinBase + HookA8KeyAddrOffset; + JmpBackAddr = WeChatWinBase + HookA8KeyJmpBackAddrOffset; + HookAnyAddress(HookAddr, (LPVOID)dealA8KeyBuf, A8KeyBufOldAsmCode); + A8KeyBufHooked = TRUE; +} + +void UnHookA8KeyBuf() +{ + if (!A8KeyBufHooked) + return; + UnHookAnyAddress(HookAddr, A8KeyBufOldAsmCode); + A8KeyBufHooked = FALSE; +} + +BOOL __stdcall GetA8Key(wchar_t *url) +{ + HookA8KeyBuf(); + response = ""; + DWORD WeChatWinBase = GetWeChatWinBase(); + DWORD GetBufferCall = WeChatWinBase + GetBufferCallOffset; + + DWORD GetA8KeyCall1 = WeChatWinBase + GetA8KeyCall1Offset; + DWORD GetA8KeyCall2 = WeChatWinBase + GetA8KeyCall2Offset; + DWORD GetA8KeyCall3 = WeChatWinBase + GetA8KeyCall3Offset; + DWORD GetA8KeyCall4 = WeChatWinBase + GetA8KeyCall4Offset; + DWORD GetA8KeyCall5 = WeChatWinBase + GetA8KeyCall5Offset; + + DWORD DelNetSceneA8KeyCall = WeChatWinBase + DelNetSceneA8KeyCallOffset; + DWORD NetSceneA8Key = 0; + DWORD param[2] = {0}; + WxString p_url(url); + WxString p_null(NULL); + WxSignal sg(WM_WAIT_HOOK_DATA, SignalThreadId); + int isSuccess = 0; + __asm { + pushad; + pushfd; + mov ebx,0x7; + push 0x238; + call GetBufferCall; + mov edi,eax; + add esp,0x4; + mov NetSceneA8Key,edi; + push 0; + sub esp,0x14; + mov esi,0x1; + lea eax,p_null; + mov ecx,esp; + push eax; + call GetA8KeyCall1; + push 0x2; + push esi; + push 0; + lea eax,p_url; + push ebx; + sub esp,0x14; + mov ecx,esp; + push eax; + call GetA8KeyCall1; + mov ecx,edi; + call GetA8KeyCall2; + push eax; + lea ecx,param; + call GetA8KeyCall3; + call GetA8KeyCall4; + lea esi,param; + mov esi,dword ptr [esi + 0x4]; + sub esp,0x8; + mov ecx,esp; + mov edx,eax; + mov dword ptr [ecx],0x0; + mov dword ptr [ecx + 0x4],0x0; + inc dword ptr [esi + 0x4]; + mov eax,dword ptr [param]; + mov dword ptr [ecx],eax; + mov dword ptr [ecx + 0x4],esi; + mov ecx,edx; + call GetA8KeyCall5; + movzx eax,al; + mov isSuccess,eax; + popfd; + popad; + } + sg.wait(5000); + // ȴһʱſȻָ + Sleep(100); + __asm { + pushad; + pushfd; + push 0x1; + mov ecx, dword ptr [NetSceneA8Key]; + call DelNetSceneA8KeyCall; + popfd; + popad; + } + return isSuccess == 1; +} + +#ifndef USE_SOCKET +struct GetA8KeyStruct +{ + DWORD response; + DWORD length; +} static ret = {0}; + +DWORD GetA8KeyRemote(wchar_t *url) +{ + if (url == NULL || wcslen(url) == 0) + return 0; + BOOL isSuccess = GetA8Key(url); + if (!isSuccess || response.length() == 0) + return 0; + ret.response = (DWORD)response.c_str(); + ret.length = response.length(); + return (DWORD)&ret; +} +#else +string __stdcall GetA8Key(wstring url) +{ + if (url.length() == 0) + return ""; + BOOL isSuccess = GetA8Key((wchar_t *)url.c_str()); + if (!isSuccess) + return ""; + return response; +} +#endif diff --git a/DWeChatRobot/GetA8Key.h b/DWeChatRobot/GetA8Key.h new file mode 100644 index 0000000000000000000000000000000000000000..bc8a93e1698c7cb19d34d422bdbae83101b98fe3 --- /dev/null +++ b/DWeChatRobot/GetA8Key.h @@ -0,0 +1,12 @@ +#pragma once +#include + +BOOL __stdcall GetA8Key(wchar_t *url); +void UnHookA8KeyBuf(); +void HookA8KeyBuf(); + +#ifndef USE_SOCKET +extern "C" __declspec(dllexport) DWORD GetA8KeyRemote(wchar_t *url); +#else +string __stdcall GetA8Key(wstring url); +#endif diff --git a/DWeChatRobot/GetHistoryPublicMsg.cpp b/DWeChatRobot/GetHistoryPublicMsg.cpp index 5bf2aeba849d840926359edf78f6388aa9b6e674..80fb2c88596477cd1aed45949ad2ed069f9a7396 100644 --- a/DWeChatRobot/GetHistoryPublicMsg.cpp +++ b/DWeChatRobot/GetHistoryPublicMsg.cpp @@ -11,7 +11,7 @@ static BOOL H5ExtBufHooked = FALSE; static char H5ExtBufOldAsmCode[5] = {0}; static DWORD HookAddr = 0; -static DWORD JmpBackAdrr = 0; +static DWORD JmpBackAddr = 0; static string response = ""; static unsigned long long systemtime() @@ -64,7 +64,7 @@ _declspec(naked) void dealH5ExtBuf() popfd; popad; mov edi,dword ptr ds:[ebp - 0x5C]; - jmp JmpBackAdrr; + jmp JmpBackAddr; } } @@ -74,7 +74,7 @@ void HookH5ExtBuf() return; DWORD WeChatWinBase = GetWeChatWinBase(); HookAddr = WeChatWinBase + GetHistoryPublicHookAddrOffset; - JmpBackAdrr = WeChatWinBase + GetHistoryPublicJmpBackAddrOffset; + JmpBackAddr = WeChatWinBase + GetHistoryPublicJmpBackAddrOffset; HookAnyAddress(HookAddr, (LPVOID)dealH5ExtBuf, H5ExtBufOldAsmCode); H5ExtBufHooked = TRUE; } diff --git a/DWeChatRobot/GetQrcodeImage.cpp b/DWeChatRobot/GetQrcodeImage.cpp index 7d81522c8388700f937a286f96a01a72b82b09a7..9702b4a5d86a9c0b64b6650f896722a967654d81 100644 --- a/DWeChatRobot/GetQrcodeImage.cpp +++ b/DWeChatRobot/GetQrcodeImage.cpp @@ -45,7 +45,7 @@ static unique_ptr qc(new QrcodeStruct); void SaveQrcodeImage(unsigned char *src, int size) { qc->update(src, size); - SIGNAL(SignalThreadId, WM_WAIT_QRCODE); + SIGNAL(SignalThreadId, WM_WAIT_HOOK_DATA); } _declspec(naked) void dealQrcodeImage() @@ -112,8 +112,7 @@ DWORD GetQrcodeImageRemote() return 0; if (!SaveQrcodeImageHooked) HookQrcodeImage(); - WxSignal sg(WM_WAIT_QRCODE); - SignalThreadId = sg.GetThreadId(); + WxSignal sg(WM_WAIT_HOOK_DATA, SignalThreadId); SwitchToQrcodeLogin(); sg.wait(5000); return (DWORD)qc.get(); @@ -125,7 +124,7 @@ BYTE *__stdcall GetQrcodeImage(int &size) return NULL; if (!SaveQrcodeImageHooked) HookQrcodeImage(); - WxSignal sg(WM_WAIT_QRCODE); + WxSignal sg(WM_WAIT_HOOK_DATA, SignalThreadId); SignalThreadId = sg.GetThreadId(); SwitchToQrcodeLogin(); sg.wait(5000); diff --git a/DWeChatRobot/SelfInfo.cpp b/DWeChatRobot/SelfInfo.cpp index 996ffdb10c9052750959b2bee23ddb6ccf263388..0a1f2e1311cd9dfdfdf0f583419d34899775bc4e 100644 --- a/DWeChatRobot/SelfInfo.cpp +++ b/DWeChatRobot/SelfInfo.cpp @@ -73,6 +73,7 @@ wstring GetSelfInfo() self_info_addr["wxCity"] = WeChatWinBase + 0x2366214; self_info_addr["PhoneNumber"] = WeChatWinBase + 0x2366128; self_info_addr["wxFilePath"] = *(DWORD *)(WeChatWinBase + 0x2385020); + self_info_addr["uin"] = WeChatWinBase + 0x23661C8; for (auto it = self_info_addr.begin(); it != self_info_addr.end(); it++) { string key = it->first; @@ -87,6 +88,11 @@ wstring GetSelfInfo() { utf8_str = unicode_to_utf8((wchar_t *)addr); } + else if (key == "uin") + { + jData[key] = *(unsigned int *)addr; + continue; + } else { if (*(DWORD *)addr == 0) diff --git a/DWeChatRobot/pch.cpp b/DWeChatRobot/pch.cpp index 9e8c520154b0fa02045cdfa4c086cfdc08036d76..4c3d51eaec4ed672ead5107cfa88ddf754796f20 100644 --- a/DWeChatRobot/pch.cpp +++ b/DWeChatRobot/pch.cpp @@ -189,6 +189,7 @@ void UnHookAll() UnHookImageMsg(); UnHookH5ExtBuf(); UnHookQrcodeImage(); + UnHookA8KeyBuf(); return; } @@ -269,34 +270,24 @@ void PrintProcAddr() BOOL(__stdcall * get_history_public_msg) (wchar_t *, wchar_t *) = GetHistoryPublicMsg; printf("GetHistoryPublicMsg 0x%08X\n", (DWORD)get_history_public_msg); + BOOL(__stdcall * get_a8_key) + (wchar_t *) = GetA8Key; + printf("GetA8Key 0x%08X\n", (DWORD)get_a8_key); } BOOL ProcessIsWeChat() { - char szFileFullPath[MAX_PATH] = {0}, szProcessName[MAX_PATH] = {0}; + char szFileFullPath[MAX_PATH] = {0}; GetModuleFileNameA(NULL, szFileFullPath, MAX_PATH); int length = ::strlen(szFileFullPath); - for (int i = length - 1; i >= 0; i--) - { - if (szFileFullPath[i] == '\\') - { - i++; - for (int j = 0; i <= length; j++) - { - szProcessName[j] = szFileFullPath[i++]; - } - break; - } - } - - if (::strcmp(szProcessName, "WeChat.exe") != 0) - { - return FALSE; - } - else + string szFile(szFileFullPath); + size_t pos = szFile.find_last_of('\\'); + string szProcessName = szFile.substr(pos + 1, szFile.length() - pos - 1); + if (szProcessName == "WeChat.exe") { return TRUE; } + return FALSE; } DWORD OffsetFromIdaAddr(DWORD idaAddr) diff --git a/DWeChatRobot/wxapi.h b/DWeChatRobot/wxapi.h index aea35744db4da098745bc22d7abbaf84e431a117..cee99d0d9bf34c9747907dc240bea1a0b7f9baa0 100644 --- a/DWeChatRobot/wxapi.h +++ b/DWeChatRobot/wxapi.h @@ -33,6 +33,7 @@ #include "GetHistoryPublicMsg.h" #include "ForwardMessage.h" #include "GetQrcodeImage.h" +#include "GetA8Key.h" using namespace std; #pragma comment(lib, "version.lib") diff --git a/DWeChatRobot/wxdata.h b/DWeChatRobot/wxdata.h index e2645f59ca3a98f1e4cd9c204e77e2a50db34f9d..9f2516df6b9f1b356016f2bb8518111a88d3bd0a 100644 --- a/DWeChatRobot/wxdata.h +++ b/DWeChatRobot/wxdata.h @@ -3,7 +3,7 @@ using namespace std; // Hookݺ󣬸̷߳ź -#define WM_WAIT_QRCODE WM_USER + 0x1 +#define WM_WAIT_HOOK_DATA WM_USER + 0x1 /* * ΢еĻݽṹ diff --git a/DWeChatRobot/wxsignal.h b/DWeChatRobot/wxsignal.h index 9b550b98898567651da0c72ec252d874d2482305..2792be3a0c075681df392a13bf12c7736d8c122c 100644 --- a/DWeChatRobot/wxsignal.h +++ b/DWeChatRobot/wxsignal.h @@ -6,9 +6,10 @@ class WxSignal { public: - WxSignal(UINT uMsg) + WxSignal(UINT uMsg, DWORD &dwThread) { this->hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)this->Pump, (LPVOID)uMsg, 0, &this->threadId); + dwThread = this->threadId; } ~WxSignal() { diff --git a/DWeChatRobot/wxsocket.cpp b/DWeChatRobot/wxsocket.cpp index e3a271481cf22c127c4a07658913898b33cac866..6ed72e389df15342c453a393b1052fdfa211780e 100644 --- a/DWeChatRobot/wxsocket.cpp +++ b/DWeChatRobot/wxsocket.cpp @@ -576,7 +576,6 @@ void request_event(mg_http_message *hm, string &ret, struct mg_connection *c) { int size = 0; BYTE *image = GetQrcodeImage(size); - // string b64data = base64_encode(image, size,false); if (image != NULL) { mg_printf(c, "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\nContent-Type: image/png\r\n\r\n"); @@ -596,6 +595,14 @@ void request_event(mg_http_message *hm, string &ret, struct mg_connection *c) } break; } + case WECHAT_GET_A8KEY: + { + wstring url = get_http_param_str(hm, jData, "url", method); + string response = GetA8Key(url); + json ret_data = {{"msg", response}, {"result", "OK"}}; + ret = ret_data.dump(); + break; + } default: // char* wxid = mg_json_get_str(hm->body, "$.wxid"); break; diff --git a/DWeChatRobot/wxsocketapi.h b/DWeChatRobot/wxsocketapi.h index 1c0acddc90e36ca947906bd83d7612c2bacea346..17ab8b0b9c7010421ac99792236d19602a3416ac 100644 --- a/DWeChatRobot/wxsocketapi.h +++ b/DWeChatRobot/wxsocketapi.h @@ -73,6 +73,7 @@ typedef enum WECHAT_HTTP_APISTag // IJ WECHAT_MSG_FORWARD_MESSAGE, WECHAT_GET_QRCODE_IMAGE, + WECHAT_GET_A8KEY, } WECHAT_HTTP_APIS, *PWECHAT_HTTP_APIS; #endif diff --git a/Python/com/wxRobot.py b/Python/com/wxRobot.py index 186911621dfb2c80a6462f0ce370387402188433..0e2da46d160c050110d8c4ce6a4375532b1246d5 100644 --- a/Python/com/wxRobot.py +++ b/Python/com/wxRobot.py @@ -1079,6 +1079,28 @@ class WeChatRobot: data = self.robot.CGetQrcodeImage(self.pid) return bytes(data) + def GetA8Key(self,url:str) -> dict or str: + """ + 获取A8Key + + Parameters + ---------- + url : str + 公众号文章链接. + + Returns + ------- + dict + 成功返回A8Key信息,失败返回空字符串. + + """ + ret = self.robot.CGetA8Key(self.pid,url) + try: + ret = json.loads(ret) + except json.JSONDecodeError: + pass + return ret + def get_wechat_pid_list() -> list: """ diff --git a/Python/http/wxDriver.py b/Python/http/wxDriver.py index 450a94731a09d638794ba71546c17196a5053f0f..ba35617fdfbf9feb8ddabbe3be9a1099789110e7 100644 --- a/Python/http/wxDriver.py +++ b/Python/http/wxDriver.py @@ -85,6 +85,7 @@ class WECHAT_HTTP_APIS: WECHAT_MSG_FORWARD_MESSAGE = 40 # 转发消息 WECHAT_GET_QRCODE_IMAGE = 41 # 获取二维码 + WECHAT_GET_A8KEY = 42 APIS = WECHAT_HTTP_APIS @@ -189,7 +190,8 @@ class WECHAT_HTTP_API_PARAM_TEMPLATES: APIS.WECHAT_GET_PUBLIC_MSG: {"public_id": "","offset": ""}, APIS.WECHAT_MSG_FORWARD_MESSAGE: {"wxid": "filehelper","msgid": 2 ** 64 - 1}, - APIS.WECHAT_GET_QRCODE_IMAGE: {} + APIS.WECHAT_GET_QRCODE_IMAGE: {}, + APIS.WECHAT_GET_A8KEY: {"url":""} } def get_http_template(self, api_number): @@ -309,6 +311,10 @@ def test_get_public_msg(test_port,public_id): Title = info['Title'] Digest = info['Digest'] ContentUrl = info['ContentUrl'] + a8key_dict = post_wechat_http_api(APIS.WECHAT_GET_A8KEY, + port = test_port, + data = {"url":ContentUrl}) + print(a8key_dict) post_wechat_http_api(APIS.WECHAT_BROWSER_OPEN_WITH_URL, test_port, {"url":ContentUrl} diff --git a/Release/CWeChatRobot.exe b/Release/CWeChatRobot.exe index c25dfdc946c20220f52fd49affe835d70a6fd760..e49e9fab518a450b8736bb8ab131a67c9d50f0ad 100644 Binary files a/Release/CWeChatRobot.exe and b/Release/CWeChatRobot.exe differ diff --git a/Release/DWeChatRobot.dll b/Release/DWeChatRobot.dll index 41048464302165ce8b23d055c41c1548ceddbe55..44ffedf11b11c1cbbfc27e65527aa7f0bde94a14 100644 Binary files a/Release/DWeChatRobot.dll and b/Release/DWeChatRobot.dll differ diff --git a/Release/socket/SWeChatRobot.dll b/Release/socket/SWeChatRobot.dll index 7329757ad7ad7da80502a86bedc1919c2833825a..590240cf9c718693481056dc4e91cdff8bbcc842 100644 Binary files a/Release/socket/SWeChatRobot.dll and b/Release/socket/SWeChatRobot.dll differ diff --git a/Release/socket/wxDriver.dll b/Release/socket/wxDriver.dll index 8ab6e07904cc1b54700c2f22f7ed96499071f98d..fd918a0eb3b9ec2d9965e243373959968e46037a 100644 Binary files a/Release/socket/wxDriver.dll and b/Release/socket/wxDriver.dll differ diff --git a/Release/socket/wxDriver64.dll b/Release/socket/wxDriver64.dll index b1f04f673fd3fdb74c86b59180b903072c631e38..895e6e90a3dde16bc3adb344959becf1a57f3194 100644 Binary files a/Release/socket/wxDriver64.dll and b/Release/socket/wxDriver64.dll differ