未验证 提交 6c63780c 编写于 作者: J Jack Li 提交者: GitHub

Merge pull request #159 from ljc545w/add_new_support

添加新的支持
#include "pch.h"
wstring GetMsgCND(DWORD pid, ULONG64 msgid)
{
WeChatProcess hp(pid);
if (!hp.m_init)
return L"";
DWORD GetMsgCDNRemoteAddr = hp.GetProcAddr(GetMsgCDNRemote);
if (GetMsgCDNRemoteAddr == 0)
{
return L"";
}
WeChatData<ULONG64 *> r_msgid(hp.GetHandle(), &msgid, sizeof(ULONG64));
if (!r_msgid.GetAddr())
{
return L"";
}
DWORD dwRet = CallRemoteFunction(hp.GetHandle(), GetMsgCDNRemoteAddr, r_msgid.GetAddr());
if (dwRet == 0)
return L"";
DWORD get_cdn_resp[2] = {0};
ReadProcessMemory(hp.GetHandle(), (LPVOID)dwRet, &get_cdn_resp, sizeof(get_cdn_resp), 0);
if (!get_cdn_resp[0] || !get_cdn_resp[1])
return L"";
unique_ptr<wchar_t[]> path_buf = make_unique<wchar_t[]>(get_cdn_resp[1] + 1);
ReadProcessMemory(hp.GetHandle(), (LPVOID)get_cdn_resp[0], path_buf.get(), get_cdn_resp[1] * 2, 0);
return wstring(path_buf.get(), get_cdn_resp[1]);
}
#pragma once
#include<windows.h>
BOOL StartReceiveMessage(DWORD pid,int port);
#include <windows.h>
#include <iostream>
using namespace std;
BOOL StartReceiveMessage(DWORD pid, int port);
BOOL StopReceiveMessage(DWORD pid);
BOOL HookImageMsg(DWORD pid,wchar_t* savepath);
BOOL HookVoiceMsg(DWORD pid,wchar_t* savepath);
BOOL HookImageMsg(DWORD pid, wchar_t *savepath);
BOOL HookVoiceMsg(DWORD pid, wchar_t *savepath);
void UnHookImageMsg(DWORD pid);
void UnHookVoiceMsg(DWORD pid);
\ No newline at end of file
void UnHookVoiceMsg(DWORD pid);
wstring GetMsgCND(DWORD pid, ULONG64 msgid);
#include "pch.h"
struct SendEmotionStruct
{
DWORD wxid;
DWORD img_path;
};
int SendEmotion(DWORD pid, wchar_t *wxid, wchar_t *img_path)
{
WeChatProcess hp(pid);
if (!hp.m_init)
return 1;
DWORD SendEmitonRemoteAddr = hp.GetProcAddr(SendEmotionRemote);
if (SendEmitonRemoteAddr == 0)
{
return 1;
}
SendEmotionStruct params = {0};
WeChatData<wchar_t *> r_wxid(hp.GetHandle(), wxid, TEXTLENGTH(wxid));
WeChatData<wchar_t *> r_img_path(hp.GetHandle(), img_path, TEXTLENGTH(img_path));
params.wxid = (DWORD)r_wxid.GetAddr();
params.img_path = (DWORD)r_img_path.GetAddr();
WeChatData<SendEmotionStruct *> r_params(hp.GetHandle(), &params, sizeof(params));
if (!params.wxid || !params.img_path || !r_params.GetAddr())
{
return 1;
}
DWORD dwRet = CallRemoteFunction(hp.GetHandle(), SendEmitonRemoteAddr, r_params.GetAddr());
return (dwRet != 1);
}
#pragma once
#include <windows.h>
int SendEmotion(DWORD pid, wchar_t *wxid, wchar_t *img_path);
......@@ -626,3 +626,27 @@ STDMETHODIMP CWeChatRobot::CGetTransfer(DWORD pid, BSTR wxid, BSTR transcationid
*__result = GetTransfer(pid, wxid, transcationid, transferid);
return S_OK;
}
/*
* 参数0:目标进程pid
* 参数1:接收人wxid
* 参数2:表情绝对路径
* 参数3:预返回的值,调用时无需提供
*/
STDMETHODIMP CWeChatRobot::CSendEmotion(DWORD pid, BSTR wxid, BSTR img_path, int *__result)
{
*__result = SendEmotion(pid, wxid, img_path);
return S_OK;
}
/*
* 参数0:目标进程pid
* 参数1:消息id
* 参数2:预返回的值,调用时无需提供
*/
STDMETHODIMP CWeChatRobot::CGetMsgCDN(DWORD pid, ULONG64 msgid, BSTR *__result)
{
_bstr_t path = (_bstr_t)GetMsgCND(pid, msgid).c_str();
*__result = path;
return S_OK;
}
......@@ -91,6 +91,8 @@ public:
STDMETHODIMP CSendXmlMsg(DWORD pid, BSTR wxid, BSTR xml, BSTR imgpath, int *__result);
STDMETHODIMP CLogout(DWORD pid, int *__result);
STDMETHODIMP CGetTransfer(DWORD pid, BSTR wxid, BSTR transcationid, BSTR transferid, int *__result);
STDMETHODIMP CSendEmotion(DWORD pid, BSTR wxid, BSTR img_path, int *__result);
STDMETHODIMP CWeChatRobot::CGetMsgCDN(DWORD pid, ULONG64 msgid, BSTR *__result);
};
OBJECT_ENTRY_AUTO(__uuidof(WeChatRobot), CWeChatRobot)
......@@ -66,6 +66,8 @@ interface IWeChatRobot : IDispatch
[id(51), helpstring("发送xml消息")] HRESULT CSendXmlMsg([in] DWORD pid, [in] BSTR wxid, [in] BSTR xml, [in] BSTR imgpath,[out, retval] int *__result);
[id(52), helpstring("退出登录")] HRESULT CLogout([in] DWORD pid,[out, retval] int *__result);
[id(53), helpstring("收款")] HRESULT CGetTransfer([in] DWORD pid, [in] BSTR wxid, [in] BSTR transcationid, [in] BSTR transferid, [out, retval] int *__result);
[id(54), helpstring("发送表情")] HRESULT CSendEmotion([in] DWORD pid, [in] BSTR wxid, [in] BSTR img_path, [ out, retval ] int *__result);
[id(55), helpstring("获取CDN")] HRESULT CGetMsgCDN([in] DWORD pid, [in] ULONG64 msgid, [ out, retval ] BSTR *__result);
};
[
object,
......
......@@ -253,6 +253,7 @@
<ClInclude Include="SendArticle.h" />
<ClInclude Include="SendAtText.h" />
<ClInclude Include="SendCard.h" />
<ClInclude Include="SendEmotion.h" />
<ClInclude Include="SendFile.h" />
<ClInclude Include="SendImage.h" />
<ClInclude Include="SendText.h" />
......@@ -289,6 +290,7 @@
<ClCompile Include="GetChatRoomMembers.cpp" />
<ClCompile Include="GetDbHandles.cpp" />
<ClCompile Include="GetHistoryPublicMsg.cpp" />
<ClCompile Include="GetMsgCDN.cpp" />
<ClCompile Include="GetTransfer.cpp" />
<ClCompile Include="HookImageMessage.cpp" />
<ClCompile Include="HookVoiceMessage.cpp" />
......@@ -311,6 +313,7 @@
<ClCompile Include="SendArticle.cpp" />
<ClCompile Include="SendAtText.cpp" />
<ClCompile Include="SendCard.cpp" />
<ClCompile Include="SendEmotion.cpp" />
<ClCompile Include="SendFile.cpp" />
<ClCompile Include="SendImage.cpp" />
<ClCompile Include="SendText.cpp" />
......
......@@ -149,6 +149,9 @@
<Filter Include="未分类\收款">
<UniqueIdentifier>{79bb1058-041b-4bdc-8678-0369c294e570}</UniqueIdentifier>
</Filter>
<Filter Include="发送消息\发送表情">
<UniqueIdentifier>{75c46b26-c4df-4772-862b-839be6a2bf95}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="framework.h">
......@@ -298,6 +301,9 @@
<ClInclude Include="GetTransfer.h">
<Filter>未分类\收款</Filter>
</ClInclude>
<ClInclude Include="SendEmotion.h">
<Filter>发送消息\发送表情</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="WeChatRobotCOM.cpp">
......@@ -447,6 +453,12 @@
<ClCompile Include="GetTransfer.cpp">
<Filter>未分类\收款</Filter>
</ClCompile>
<ClCompile Include="SendEmotion.cpp">
<Filter>发送消息\发送表情</Filter>
</ClCompile>
<ClCompile Include="GetMsgCDN.cpp">
<Filter>接收消息</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="WeChatRobotCOM.rc">
......
......@@ -378,6 +378,17 @@ EXTERN_C const IID IID_IWeChatRobot;
/* [in] */ BSTR transferid,
/* [retval][out] */ int *__result) = 0;
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE CSendEmotion(
/* [in] */ DWORD pid,
/* [in] */ BSTR wxid,
/* [in] */ BSTR img_path,
/* [retval][out] */ int *__result) = 0;
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE CGetMsgCDN(
/* [in] */ DWORD pid,
/* [in] */ ULONG64 msgid,
/* [retval][out] */ BSTR *__result) = 0;
};
......@@ -750,6 +761,19 @@ EXTERN_C const IID IID_IWeChatRobot;
/* [in] */ BSTR transferid,
/* [retval][out] */ int *__result);
/* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *CSendEmotion )(
IWeChatRobot * This,
/* [in] */ DWORD pid,
/* [in] */ BSTR wxid,
/* [in] */ BSTR img_path,
/* [retval][out] */ int *__result);
/* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *CGetMsgCDN )(
IWeChatRobot * This,
/* [in] */ DWORD pid,
/* [in] */ ULONG64 msgid,
/* [retval][out] */ BSTR *__result);
END_INTERFACE
} IWeChatRobotVtbl;
......@@ -936,6 +960,12 @@ EXTERN_C const IID IID_IWeChatRobot;
#define IWeChatRobot_CGetTransfer(This,pid,wxid,transcationid,transferid,__result) \
( (This)->lpVtbl -> CGetTransfer(This,pid,wxid,transcationid,transferid,__result) )
#define IWeChatRobot_CSendEmotion(This,pid,wxid,img_path,__result) \
( (This)->lpVtbl -> CSendEmotion(This,pid,wxid,img_path,__result) )
#define IWeChatRobot_CGetMsgCDN(This,pid,msgid,__result) \
( (This)->lpVtbl -> CGetMsgCDN(This,pid,msgid,__result) )
#endif /* COBJMACROS */
......
......@@ -49,7 +49,7 @@
#include "WeChatRobotCOM_i.h"
#define TYPE_FORMAT_STRING_SIZE 1239
#define PROC_FORMAT_STRING_SIZE 2593
#define PROC_FORMAT_STRING_SIZE 2695
#define EXPR_FORMAT_STRING_SIZE 1
#define TRANSMIT_AS_TABLE_SIZE 0
#define WIRE_MARSHAL_TABLE_SIZE 2
......@@ -2387,17 +2387,17 @@ static const WeChatRobotCOM_MIDL_PROC_FORMAT_STRING WeChatRobotCOM__MIDL_ProcFor
/* 2482 */ 0x8, /* FC_LONG */
0x0, /* 0 */
/* Procedure CPostMessage */
/* Procedure CSendEmotion */
/* 2484 */ 0x33, /* FC_AUTO_HANDLE */
0x6c, /* Old Flags: object, Oi2 */
/* 2486 */ NdrFcLong( 0x0 ), /* 0 */
/* 2490 */ NdrFcShort( 0x7 ), /* 7 */
/* 2492 */ NdrFcShort( 0x20 ), /* x86 Stack size/offset = 32 */
/* 2494 */ NdrFcShort( 0x20 ), /* 32 */
/* 2490 */ NdrFcShort( 0x39 ), /* 57 */
/* 2492 */ NdrFcShort( 0x18 ), /* x86 Stack size/offset = 24 */
/* 2494 */ NdrFcShort( 0x8 ), /* 8 */
/* 2496 */ NdrFcShort( 0x24 ), /* 36 */
/* 2498 */ 0x46, /* Oi2 Flags: clt must size, has return, has ext, */
0x6, /* 6 */
0x5, /* 5 */
/* 2500 */ 0x8, /* 8 */
0x45, /* Ext Flags: new corr desc, srv corr check, has range on conformance */
/* 2502 */ NdrFcShort( 0x0 ), /* 0 */
......@@ -2411,83 +2411,177 @@ static const WeChatRobotCOM_MIDL_PROC_FORMAT_STRING WeChatRobotCOM__MIDL_ProcFor
/* 2512 */ 0x8, /* FC_LONG */
0x0, /* 0 */
/* Parameter msgtype */
/* Parameter wxid */
/* 2514 */ NdrFcShort( 0x48 ), /* Flags: in, base type, */
/* 2514 */ NdrFcShort( 0x8b ), /* Flags: must size, must free, in, by val, */
/* 2516 */ NdrFcShort( 0x8 ), /* x86 Stack size/offset = 8 */
/* 2518 */ 0x8, /* FC_LONG */
/* 2518 */ NdrFcShort( 0x2a ), /* Type Offset=42 */
/* Parameter img_path */
/* 2520 */ NdrFcShort( 0x8b ), /* Flags: must size, must free, in, by val, */
/* 2522 */ NdrFcShort( 0xc ), /* x86 Stack size/offset = 12 */
/* 2524 */ NdrFcShort( 0x2a ), /* Type Offset=42 */
/* Parameter __result */
/* 2526 */ NdrFcShort( 0x2150 ), /* Flags: out, base type, simple ref, srv alloc size=8 */
/* 2528 */ NdrFcShort( 0x10 ), /* x86 Stack size/offset = 16 */
/* 2530 */ 0x8, /* FC_LONG */
0x0, /* 0 */
/* Return value */
/* 2532 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */
/* 2534 */ NdrFcShort( 0x14 ), /* x86 Stack size/offset = 20 */
/* 2536 */ 0x8, /* FC_LONG */
0x0, /* 0 */
/* Procedure CGetMsgCDN */
/* 2538 */ 0x33, /* FC_AUTO_HANDLE */
0x6c, /* Old Flags: object, Oi2 */
/* 2540 */ NdrFcLong( 0x0 ), /* 0 */
/* 2544 */ NdrFcShort( 0x3a ), /* 58 */
/* 2546 */ NdrFcShort( 0x18 ), /* x86 Stack size/offset = 24 */
/* 2548 */ NdrFcShort( 0x18 ), /* 24 */
/* 2550 */ NdrFcShort( 0x8 ), /* 8 */
/* 2552 */ 0x45, /* Oi2 Flags: srv must size, has return, has ext, */
0x4, /* 4 */
/* 2554 */ 0x8, /* 8 */
0x43, /* Ext Flags: new corr desc, clt corr check, has range on conformance */
/* 2556 */ NdrFcShort( 0x1 ), /* 1 */
/* 2558 */ NdrFcShort( 0x0 ), /* 0 */
/* 2560 */ NdrFcShort( 0x0 ), /* 0 */
/* Parameter pid */
/* 2562 */ NdrFcShort( 0x48 ), /* Flags: in, base type, */
/* 2564 */ NdrFcShort( 0x4 ), /* x86 Stack size/offset = 4 */
/* 2566 */ 0x8, /* FC_LONG */
0x0, /* 0 */
/* Parameter msgid */
/* 2520 */ NdrFcShort( 0x48 ), /* Flags: in, base type, */
/* 2522 */ NdrFcShort( 0xc ), /* x86 Stack size/offset = 12 */
/* 2524 */ 0xb, /* FC_HYPER */
/* 2568 */ NdrFcShort( 0x48 ), /* Flags: in, base type, */
/* 2570 */ NdrFcShort( 0x8 ), /* x86 Stack size/offset = 8 */
/* 2572 */ 0xb, /* FC_HYPER */
0x0, /* 0 */
/* Parameter __result */
/* 2574 */ NdrFcShort( 0x2113 ), /* Flags: must size, must free, out, simple ref, srv alloc size=8 */
/* 2576 */ NdrFcShort( 0x10 ), /* x86 Stack size/offset = 16 */
/* 2578 */ NdrFcShort( 0x4ba ), /* Type Offset=1210 */
/* Return value */
/* 2580 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */
/* 2582 */ NdrFcShort( 0x14 ), /* x86 Stack size/offset = 20 */
/* 2584 */ 0x8, /* FC_LONG */
0x0, /* 0 */
/* Procedure CPostMessage */
/* 2586 */ 0x33, /* FC_AUTO_HANDLE */
0x6c, /* Old Flags: object, Oi2 */
/* 2588 */ NdrFcLong( 0x0 ), /* 0 */
/* 2592 */ NdrFcShort( 0x7 ), /* 7 */
/* 2594 */ NdrFcShort( 0x20 ), /* x86 Stack size/offset = 32 */
/* 2596 */ NdrFcShort( 0x20 ), /* 32 */
/* 2598 */ NdrFcShort( 0x24 ), /* 36 */
/* 2600 */ 0x46, /* Oi2 Flags: clt must size, has return, has ext, */
0x6, /* 6 */
/* 2602 */ 0x8, /* 8 */
0x45, /* Ext Flags: new corr desc, srv corr check, has range on conformance */
/* 2604 */ NdrFcShort( 0x0 ), /* 0 */
/* 2606 */ NdrFcShort( 0x1 ), /* 1 */
/* 2608 */ NdrFcShort( 0x0 ), /* 0 */
/* Parameter pid */
/* 2610 */ NdrFcShort( 0x48 ), /* Flags: in, base type, */
/* 2612 */ NdrFcShort( 0x4 ), /* x86 Stack size/offset = 4 */
/* 2614 */ 0x8, /* FC_LONG */
0x0, /* 0 */
/* Parameter msgtype */
/* 2616 */ NdrFcShort( 0x48 ), /* Flags: in, base type, */
/* 2618 */ NdrFcShort( 0x8 ), /* x86 Stack size/offset = 8 */
/* 2620 */ 0x8, /* FC_LONG */
0x0, /* 0 */
/* Parameter msgid */
/* 2622 */ NdrFcShort( 0x48 ), /* Flags: in, base type, */
/* 2624 */ NdrFcShort( 0xc ), /* x86 Stack size/offset = 12 */
/* 2626 */ 0xb, /* FC_HYPER */
0x0, /* 0 */
/* Parameter msg */
/* 2526 */ NdrFcShort( 0x10b ), /* Flags: must size, must free, in, simple ref, */
/* 2528 */ NdrFcShort( 0x14 ), /* x86 Stack size/offset = 20 */
/* 2530 */ NdrFcShort( 0x4cc ), /* Type Offset=1228 */
/* 2628 */ NdrFcShort( 0x10b ), /* Flags: must size, must free, in, simple ref, */
/* 2630 */ NdrFcShort( 0x14 ), /* x86 Stack size/offset = 20 */
/* 2632 */ NdrFcShort( 0x4cc ), /* Type Offset=1228 */
/* Parameter __result */
/* 2532 */ NdrFcShort( 0x2150 ), /* Flags: out, base type, simple ref, srv alloc size=8 */
/* 2534 */ NdrFcShort( 0x18 ), /* x86 Stack size/offset = 24 */
/* 2536 */ 0x8, /* FC_LONG */
/* 2634 */ NdrFcShort( 0x2150 ), /* Flags: out, base type, simple ref, srv alloc size=8 */
/* 2636 */ NdrFcShort( 0x18 ), /* x86 Stack size/offset = 24 */
/* 2638 */ 0x8, /* FC_LONG */
0x0, /* 0 */
/* Return value */
/* 2538 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */
/* 2540 */ NdrFcShort( 0x1c ), /* x86 Stack size/offset = 28 */
/* 2542 */ 0x8, /* FC_LONG */
/* 2640 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */
/* 2642 */ NdrFcShort( 0x1c ), /* x86 Stack size/offset = 28 */
/* 2644 */ 0x8, /* FC_LONG */
0x0, /* 0 */
/* Procedure CRegisterWxPidWithCookie */
/* 2544 */ 0x33, /* FC_AUTO_HANDLE */
/* 2646 */ 0x33, /* FC_AUTO_HANDLE */
0x6c, /* Old Flags: object, Oi2 */
/* 2546 */ NdrFcLong( 0x0 ), /* 0 */
/* 2550 */ NdrFcShort( 0x8 ), /* 8 */
/* 2552 */ NdrFcShort( 0x14 ), /* x86 Stack size/offset = 20 */
/* 2554 */ NdrFcShort( 0x10 ), /* 16 */
/* 2556 */ NdrFcShort( 0x24 ), /* 36 */
/* 2558 */ 0x44, /* Oi2 Flags: has return, has ext, */
/* 2648 */ NdrFcLong( 0x0 ), /* 0 */
/* 2652 */ NdrFcShort( 0x8 ), /* 8 */
/* 2654 */ NdrFcShort( 0x14 ), /* x86 Stack size/offset = 20 */
/* 2656 */ NdrFcShort( 0x10 ), /* 16 */
/* 2658 */ NdrFcShort( 0x24 ), /* 36 */
/* 2660 */ 0x44, /* Oi2 Flags: has return, has ext, */
0x4, /* 4 */
/* 2560 */ 0x8, /* 8 */
/* 2662 */ 0x8, /* 8 */
0x41, /* Ext Flags: new corr desc, has range on conformance */
/* 2562 */ NdrFcShort( 0x0 ), /* 0 */
/* 2564 */ NdrFcShort( 0x0 ), /* 0 */
/* 2566 */ NdrFcShort( 0x0 ), /* 0 */
/* 2664 */ NdrFcShort( 0x0 ), /* 0 */
/* 2666 */ NdrFcShort( 0x0 ), /* 0 */
/* 2668 */ NdrFcShort( 0x0 ), /* 0 */
/* Parameter pid */
/* 2568 */ NdrFcShort( 0x48 ), /* Flags: in, base type, */
/* 2570 */ NdrFcShort( 0x4 ), /* x86 Stack size/offset = 4 */
/* 2572 */ 0x8, /* FC_LONG */
/* 2670 */ NdrFcShort( 0x48 ), /* Flags: in, base type, */
/* 2672 */ NdrFcShort( 0x4 ), /* x86 Stack size/offset = 4 */
/* 2674 */ 0x8, /* FC_LONG */
0x0, /* 0 */
/* Parameter cookie */
/* 2574 */ NdrFcShort( 0x48 ), /* Flags: in, base type, */
/* 2576 */ NdrFcShort( 0x8 ), /* x86 Stack size/offset = 8 */
/* 2578 */ 0x8, /* FC_LONG */
/* 2676 */ NdrFcShort( 0x48 ), /* Flags: in, base type, */
/* 2678 */ NdrFcShort( 0x8 ), /* x86 Stack size/offset = 8 */
/* 2680 */ 0x8, /* FC_LONG */
0x0, /* 0 */
/* Parameter __result */
/* 2580 */ NdrFcShort( 0x2150 ), /* Flags: out, base type, simple ref, srv alloc size=8 */
/* 2582 */ NdrFcShort( 0xc ), /* x86 Stack size/offset = 12 */
/* 2584 */ 0x8, /* FC_LONG */
/* 2682 */ NdrFcShort( 0x2150 ), /* Flags: out, base type, simple ref, srv alloc size=8 */
/* 2684 */ NdrFcShort( 0xc ), /* x86 Stack size/offset = 12 */
/* 2686 */ 0x8, /* FC_LONG */
0x0, /* 0 */
/* Return value */
/* 2586 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */
/* 2588 */ NdrFcShort( 0x10 ), /* x86 Stack size/offset = 16 */
/* 2590 */ 0x8, /* FC_LONG */
/* 2688 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */
/* 2690 */ NdrFcShort( 0x10 ), /* x86 Stack size/offset = 16 */
/* 2692 */ 0x8, /* FC_LONG */
0x0, /* 0 */
0x0
......@@ -3384,7 +3478,9 @@ static const unsigned short IWeChatRobot_FormatStringOffsetTable[] =
2274,
2322,
2382,
2424
2424,
2484,
2538
};
static const MIDL_STUBLESS_PROXY_INFO IWeChatRobot_ProxyInfo =
......@@ -3408,7 +3504,7 @@ static const MIDL_SERVER_INFO IWeChatRobot_ServerInfo =
0,
0,
0};
CINTERFACE_PROXY_VTABLE(57) _IWeChatRobotProxyVtbl =
CINTERFACE_PROXY_VTABLE(59) _IWeChatRobotProxyVtbl =
{
&IWeChatRobot_ProxyInfo,
&IID_IWeChatRobot,
......@@ -3468,7 +3564,9 @@ CINTERFACE_PROXY_VTABLE(57) _IWeChatRobotProxyVtbl =
(void *) (INT_PTR) -1 /* IWeChatRobot::CGetA8Key */ ,
(void *) (INT_PTR) -1 /* IWeChatRobot::CSendXmlMsg */ ,
(void *) (INT_PTR) -1 /* IWeChatRobot::CLogout */ ,
(void *) (INT_PTR) -1 /* IWeChatRobot::CGetTransfer */
(void *) (INT_PTR) -1 /* IWeChatRobot::CGetTransfer */ ,
(void *) (INT_PTR) -1 /* IWeChatRobot::CSendEmotion */ ,
(void *) (INT_PTR) -1 /* IWeChatRobot::CGetMsgCDN */
};
......@@ -3527,6 +3625,8 @@ static const PRPC_STUB_FUNCTION IWeChatRobot_table[] =
NdrStubCall2,
NdrStubCall2,
NdrStubCall2,
NdrStubCall2,
NdrStubCall2,
NdrStubCall2
};
......@@ -3534,7 +3634,7 @@ CInterfaceStubVtbl _IWeChatRobotStubVtbl =
{
&IID_IWeChatRobot,
&IWeChatRobot_ServerInfo,
57,
59,
&IWeChatRobot_table[-3],
CStdStubBuffer_DELEGATING_METHODS
};
......@@ -3550,8 +3650,8 @@ static const unsigned short IRobotEvent_FormatStringOffsetTable[] =
(unsigned short) -1,
(unsigned short) -1,
(unsigned short) -1,
2484,
2544
2586,
2646
};
static const MIDL_STUBLESS_PROXY_INFO IRobotEvent_ProxyInfo =
......
......@@ -35,11 +35,13 @@
#include "SendXmlMsg.h"
#include "Logout.h"
#include "GetTransfer.h"
#include "SendEmotion.h"
#define DLLNAME L"DWeChatRobot.dll"
#define SendTextRemote "SendTextRemote"
#define SendImageRemote "SendImageRemote"
#define SendEmotionRemote "SendEmotionRemote"
#define SendFileRemote "SendFileRemote"
#define SendArticleRemote "SendArticleRemote"
#define SendCardRemote "SendCardRemote"
......@@ -100,3 +102,4 @@
#define LogoutRemote "Logout"
#define GetTransferRemote "GetTransferRemote"
#define GetMsgCDNRemote "GetMsgCDNRemote"
#include "pch.h"
#define ChatMsgHandleOffset 0x5AF6803C - 0x590F0000
#define GetChatMsgCallOffset 0x59522730 - 0x590F0000
#define ReleaseChatMsgCallOffset 0x78757780 - 0x786A0000
BOOL __stdcall GetChatMsgBySvrId(ULONG64 msgid, PCHAT_MSG p_chat_msg)
{
int dbIndex = 0;
int localId = GetLocalIdByMsgId(msgid, dbIndex);
if (localId == 0)
return FALSE;
DWORD WeChatWinBase = GetWeChatWinBase();
DWORD ChatMsgHandle = WeChatWinBase + ChatMsgHandleOffset;
DWORD GetChatMsgCall = WeChatWinBase + GetChatMsgCallOffset;
p_chat_msg->handle1 = ChatMsgHandle;
int isSuccess = 0x0;
__asm {
pushad;
pushfd;
push dword ptr [dbIndex];
mov ecx,dword ptr [p_chat_msg];
push dword ptr [localId];
call GetChatMsgCall;
add esp,0x8;
movzx eax,al;
mov isSuccess,eax;
popfd;
popad;
}
return (isSuccess == 0x1);
}
BOOL __stdcall ReleaseChatMsg(PCHAT_MSG p_chat_msg)
{
DWORD WeChatWinBase = GetWeChatWinBase();
DWORD ReleaseChatMsgCall = WeChatWinBase + ReleaseChatMsgCallOffset;
int isSuccess = 0;
__asm {
pushad;
mov ecx, dword ptr [p_chat_msg];
call ReleaseChatMsgCall;
popad;
}
return TRUE;
}
......@@ -344,6 +344,7 @@ xcopy /y /d "$(OutDir)..\..\Python\http\wxDriver.py" "$(SolutionDir)build\http
<ClInclude Include="SendArticle.h" />
<ClInclude Include="SendAtText.h" />
<ClInclude Include="SendCard.h" />
<ClInclude Include="SendEmotion.h" />
<ClInclude Include="SendFile.h" />
<ClInclude Include="SendImage.h" />
<ClInclude Include="SendText.h" />
......@@ -366,6 +367,7 @@ xcopy /y /d "$(OutDir)..\..\Python\http\wxDriver.py" "$(SolutionDir)build\http
<ClCompile Include="AddFriendByV3.cpp" />
<ClCompile Include="AddFriendByWxid.cpp" />
<ClCompile Include="AddBrandContact.cpp" />
<ClCompile Include="ChatMsg.cpp" />
<ClCompile Include="CheckFriendStatus.cpp" />
<ClCompile Include="comclient.cpp" />
<ClCompile Include="DbBackup.cpp" />
......@@ -373,6 +375,7 @@ xcopy /y /d "$(OutDir)..\..\Python\http\wxDriver.py" "$(SolutionDir)build\http
<ClCompile Include="DelChatRoomMember.cpp" />
<ClCompile Include="DeleteUser.cpp" />
<ClCompile Include="dllmain.cpp" />
<ClCompile Include="GetMsgCDN.cpp" />
<ClCompile Include="EditRemark.cpp" />
<ClCompile Include="ForwardMessage.cpp" />
<ClCompile Include="FriendList.cpp" />
......@@ -404,6 +407,7 @@ xcopy /y /d "$(OutDir)..\..\Python\http\wxDriver.py" "$(SolutionDir)build\http
<ClCompile Include="SendArticle.cpp" />
<ClCompile Include="SendAtText.cpp" />
<ClCompile Include="SendCard.cpp" />
<ClCompile Include="SendEmotion.cpp" />
<ClCompile Include="SendFile.cpp" />
<ClCompile Include="SendImage.cpp" />
<ClCompile Include="SendText.cpp" />
......
......@@ -148,6 +148,9 @@
<Filter Include="未分类\收款">
<UniqueIdentifier>{f24eb4af-96d0-41a3-ba1a-799d49f2fb4e}</UniqueIdentifier>
</Filter>
<Filter Include="发送消息\发送表情">
<UniqueIdentifier>{63a49bf5-1537-4fb1-be9a-acecc57ca98c}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="framework.h">
......@@ -285,6 +288,9 @@
<ClInclude Include="GetTransfer.h">
<Filter>未分类\收款</Filter>
</ClInclude>
<ClInclude Include="SendEmotion.h">
<Filter>发送消息\发送表情</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="dllmain.cpp">
......@@ -425,5 +431,14 @@
<ClCompile Include="GetTransfer.cpp">
<Filter>未分类\收款</Filter>
</ClCompile>
<ClCompile Include="SendEmotion.cpp">
<Filter>发送消息\发送表情</Filter>
</ClCompile>
<ClCompile Include="GetMsgCDN.cpp">
<Filter>接收消息</Filter>
</ClCompile>
<ClCompile Include="ChatMsg.cpp">
<Filter>接收消息</Filter>
</ClCompile>
</ItemGroup>
</Project>
......@@ -7,13 +7,13 @@
struct ForwardMessageStruct
{
wchar_t *wxid;
unsigned long long localId;
unsigned long long msgid;
};
BOOL ForwardMessageRemote(LPVOID lpParameter)
{
ForwardMessageStruct *fms = (ForwardMessageStruct *)lpParameter;
return ForwardMessage(fms->wxid, fms->localId);
return ForwardMessage(fms->wxid, fms->msgid);
}
#endif
......
......@@ -148,8 +148,13 @@ BOOL __stdcall GetHistoryPublicMsg(wchar_t *PublicId, wchar_t *Offset)
if (!H5ExtBufHooked || isSuccess == 0) return FALSE;
return TRUE;
}
#ifndef USE_SOCKET
struct GetPublicMsgStruct
{
wchar_t *PublicId;
wchar_t *Offset;
};
struct PublicMsgResponseStruct
{
DWORD buffer = 0;
......
#include "pch.h"
#define WeChatFilePathOffset 0x2385020
#define DownloadImageCall1Offset 0x591D4010 - 0x590F0000
#define DownloadImageCall2Offset 0x5951AAE0 - 0x590F0000
#define ParserAppXmlCall1Offset 0x588F0C70 - 0x587D0000
#define ParserAppXmlCall2Offset 0x58E51340 - 0x587D0000
#define DownloadFileCall1Offset 0x58893B70 - 0x587D0000
#define DownloadFileCall2Offset 0x58BC7330 - 0x587D0000
#define ParserVideoXmlCallOffset 0x59784620 - 0x590F0000
#define DownloadVideoThumbCallOffset 0x58D3C9B0 - 0x587D0000
#define DownloadVideoCallOffset 0x58C852F0 - 0x587D0000
#define XorKeyOffset 0x5B4569D6 - 0x590F0000
#define GetWeChatCDNCallOffset 0x58C852F0 - 0x587D0000
#define AutoDownloadImageTimeSettingOffset 0x239EC50
#define ImageAutoPatchOffset 0x48D56B
#define AutoDownloadVideoTimeSettingOffset 0x239EBD8
#define VideoAutoPatchOffset 0x48CE1B
static BOOL AutoDownloadTimeSeted = FALSE;
void __stdcall SetDownloadTime()
{
if (AutoDownloadTimeSeted)
return;
DWORD WeChatWinBase = GetWeChatWinBase();
char settime[] = "00:00-00:00";
DWORD AutoDownloadTimeSettingAddr1 = GetWeChatWinBase() + AutoDownloadImageTimeSettingOffset;
DWORD AutoDownloadTimeSettingAddr2 = GetWeChatWinBase() + AutoDownloadVideoTimeSettingOffset;
WriteProcessMemory(GetCurrentProcess(), (LPVOID)AutoDownloadTimeSettingAddr1, settime, strlen(settime) + 1, 0);
WriteProcessMemory(GetCurrentProcess(), (LPVOID)AutoDownloadTimeSettingAddr2, settime, strlen(settime) + 1, 0);
BYTE nopVideo[] = {0x90, 0x90, 0x90, 0x90, 0x90, 0x90};
DWORD nopVideoAddr = WeChatWinBase + VideoAutoPatchOffset;
WriteProcessMemory(GetCurrentProcess(), (LPVOID)nopVideoAddr, &nopVideo, sizeof(nopVideo), 0);
BYTE nopImg[] = {0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90};
DWORD nopImgAddr = WeChatWinBase + ImageAutoPatchOffset;
WriteProcessMemory(GetCurrentProcess(), (LPVOID)nopImgAddr, &nopImg, sizeof(nopImg), 0);
AutoDownloadTimeSeted = TRUE;
}
static BOOL GetWeChatCDN(CHAT_MSG *chat_msg)
{
DWORD GetWeChatCDNCall = GetWeChatWinBase() + GetWeChatCDNCallOffset;
int isSuccess = 0x0;
__asm {
pushad;
pushfd;
mov esi,dword ptr[chat_msg];
push esi;
call GetWeChatCDNCall;
movzx eax,al;
mov isSuccess,eax;
popfd;
popad;
}
return (isSuccess == 0x1);
}
BOOL ParserAppXml(wchar_t *xml, char *xml_buf)
{
DWORD WeChatWinBase = GetWeChatWinBase();
DWORD ParserAppXmlCall1 = WeChatWinBase + ParserAppXmlCall1Offset;
DWORD ParserAppXmlCall2 = WeChatWinBase + ParserAppXmlCall2Offset;
WxString p_xml(xml);
int isSuccess = 0x0;
__asm {
pushad;
pushfd;
mov ecx,dword ptr [xml_buf];
call ParserAppXmlCall1;
mov ecx,dword ptr [xml_buf];
lea eax,p_xml;
push 0x1;
push eax;
call ParserAppXmlCall2;
movzx eax,al;
mov isSuccess,eax;
popfd;
popad;
}
return (isSuccess == 0x1);
}
BOOL ParserVideoXml(wchar_t *xml, char *xml_buf)
{
DWORD WeChatWinBase = GetWeChatWinBase();
DWORD ParserVideoXmlCall = WeChatWinBase + ParserVideoXmlCallOffset;
string s_xml = unicode_to_utf8(xml).c_str();
WxStringA p_xml(s_xml);
int isSuccess = 0x0;
__asm {
pushad;
pushfd;
mov ecx,dword ptr [xml_buf];
lea eax,p_xml;
push eax;
call ParserVideoXmlCall;
movzx eax,al;
mov isSuccess,eax;
popfd;
popad;
}
return (isSuccess == 0x1);
}
wstring GetWeChatFilePath()
{
DWORD WeChatWinBase = GetWeChatWinBase();
WxString *wechat_file_path = (WxString *)(WeChatWinBase + 0x2385020);
return wstring(wechat_file_path->buffer, wechat_file_path->length);
}
wstring __stdcall GetMsgCDN(ULONG64 msgid)
{
SetDownloadTime();
wstring robot_base_dir = GetWeChatFilePath() + L"WeChatRobot\\";
CHAT_MSG chat_msg = {0};
if (!FindOrCreateDirectory(robot_base_dir.c_str()) || !GetChatMsgBySvrId(msgid, &chat_msg))
return L"";
DWORD WeChatWinBase = GetWeChatWinBase();
DWORD param[4] = {0};
param[0] = (DWORD)&param;
param[1] = (DWORD)&param;
param[2] = (DWORD)&param;
param[3] = 0x101;
chat_msg.unknown_ptr2 = &param;
int isSuccess = 0x0;
wstring abs_path(robot_base_dir);
switch (chat_msg.type)
{
case 0x3:
{
abs_path += L"Image\\";
FindOrCreateDirectory(abs_path.c_str());
abs_path = abs_path + gb2312_to_unicode(to_string(msgid).c_str()) + L".png";
if (!_waccess(abs_path.c_str(), 0))
return abs_path;
CHAT_MSG image_msg = {0};
image_msg.handle1 = chat_msg.handle1;
image_msg.content = chat_msg.content;
image_msg.unknown_ptr2 = chat_msg.unknown_ptr2;
image_msg.file_save_path.buffer = (wchar_t *)abs_path.c_str();
image_msg.file_save_path.length = abs_path.length();
image_msg.file_save_path.maxLength = abs_path.length() * 2;
DWORD DownloadImageCall1 = WeChatWinBase + DownloadImageCall1Offset;
DWORD DownloadImageCall2 = WeChatWinBase + DownloadImageCall2Offset;
__asm {
pushad;
pushfd;
call DownloadImageCall1;
push 0x0;
push 0x0;
push 0x1;
lea ecx,image_msg;
push ecx;
mov ecx,eax;
call DownloadImageCall2;
movzx eax,al;
mov isSuccess,eax;
popfd;
popad;
}
break;
}
case 0x2B:
{
abs_path += L"Video\\";
FindOrCreateDirectory(abs_path.c_str());
unique_ptr<char[]> xml_data = make_unique<char[]>(0x680);
char *xml_buf = xml_data.get();
if (!ParserVideoXml(chat_msg.content.buffer, xml_buf))
return L"";
DWORD DownloadVideoThumbCall = WeChatWinBase + DownloadVideoThumbCallOffset;
DWORD DownloadVideoCall = WeChatWinBase + DownloadVideoCallOffset;
wstring thumbnail_path = abs_path + gb2312_to_unicode(to_string(msgid).c_str()) + L".jpg";
abs_path = abs_path + gb2312_to_unicode(to_string(msgid).c_str()) + L".mp4";
if (!_waccess(abs_path.c_str(), 0))
return abs_path;
chat_msg.file_save_path.buffer = (wchar_t *)abs_path.c_str();
chat_msg.file_save_path.length = abs_path.length();
chat_msg.file_save_path.maxLength = abs_path.length() * 2;
chat_msg.thumbnail.buffer = (wchar_t *)thumbnail_path.c_str();
chat_msg.thumbnail.length = thumbnail_path.length();
chat_msg.thumbnail.maxLength = thumbnail_path.length() * 2;
DWORD param[20] = {0};
param[17] = 0x1FFF;
__asm {
pushad;
pushfd;
mov eax,dword ptr [xml_buf];
push eax;
lea eax,chat_msg;
push eax;
lea eax,param;
push eax;
call DownloadVideoThumbCall;
lea esi,chat_msg;
push esi;
call DownloadVideoCall;
movzx eax,al;
mov isSuccess,eax;
popfd;
popad;
}
break;
}
case 0x31:
{
abs_path += L"Files\\";
FindOrCreateDirectory(abs_path.c_str());
unique_ptr<char[]> xml_data = make_unique<char[]>(0xC48);
char *xml_buf = xml_data.get();
if (!ParserAppXml(chat_msg.content.buffer, xml_buf))
return L"";
DWORD DownloadFileCall1 = WeChatWinBase + DownloadFileCall1Offset;
DWORD DownloadFileCall2 = WeChatWinBase + DownloadFileCall2Offset;
WxString *filename = (WxString *)((DWORD)xml_buf + 0x44);
abs_path = abs_path + gb2312_to_unicode(to_string(msgid).c_str()) + L"_" + wstring(filename->buffer, filename->length);
if (!_waccess(abs_path.c_str(), 0))
return abs_path;
chat_msg.file_save_path.buffer = (wchar_t *)abs_path.c_str();
chat_msg.file_save_path.length = abs_path.length();
chat_msg.file_save_path.maxLength = abs_path.length() * 2;
__asm {
pushad;
pushfd;
call DownloadFileCall1;
mov ecx,dword ptr [xml_buf];
push ecx;
lea ecx,chat_msg;
push ecx;
mov ecx,eax;
call DownloadFileCall2;
xor al,0x1;
movzx eax,al;
mov isSuccess,eax;
popfd;
popad;
}
break;
}
default:
break;
}
return (isSuccess == 0x1) ? abs_path : L"";
}
#ifndef USE_SOCKET
struct GetMsgCDNRespStruct
{
wchar_t *path = NULL;
int length = 0;
} cdn_resp;
DWORD GetMsgCDNRemote(ULONG64 *p_msgid)
{
if (cdn_resp.length != 0)
{
delete[] cdn_resp.path;
cdn_resp.length = 0;
}
wstring cdn_path = GetMsgCDN(*p_msgid);
if (cdn_path.length() == 0)
return 0;
cdn_resp.path = new wchar_t[cdn_path.length() + 1]();
cdn_resp.length = cdn_path.length();
memcpy(cdn_resp.path, cdn_path.c_str(), cdn_path.length() * 2);
return (DWORD)&cdn_resp;
}
#endif
......@@ -2,13 +2,11 @@
#define HookImageMsgAddrOffset 0x10732D26 - 0x10000000
#define HookImageMsgNextCallOffset 0x10732160 - 0x10000000
#define AutoDownloadTimeSettingOffset 0x239EC50
BOOL ImageMsgHooked = false;
static DWORD WeChatWinBase = GetWeChatWinBase();
static DWORD HookImageMsgAddr = WeChatWinBase + HookImageMsgAddrOffset;
static DWORD HookImageMsgNextCall = WeChatWinBase + HookImageMsgNextCallOffset;
static DWORD HookImageMsgJmpBackAddr = HookImageMsgAddr + 0x5;
static DWORD HookImageMsgAddr = 0;
static DWORD HookImageMsgNextCall = 0;
static DWORD HookImageMsgJmpBackAddr = 0;
static char ImageMsgOldAsm[5] = {0};
static wstring global_save_path = L"";
......@@ -82,27 +80,14 @@ __declspec(naked) void dealImageMsg()
void __stdcall HookImageMsg()
{
WeChatWinBase = GetWeChatWinBase();
DWORD WeChatWinBase = GetWeChatWinBase();
if (ImageMsgHooked || !WeChatWinBase)
return;
SetDownloadTime();
HookImageMsgAddr = WeChatWinBase + HookImageMsgAddrOffset;
HookImageMsgNextCall = WeChatWinBase + HookImageMsgNextCallOffset;
HookImageMsgJmpBackAddr = HookImageMsgAddr + 0x5;
HookAnyAddress(HookImageMsgAddr, dealImageMsg, ImageMsgOldAsm);
char settime[] = "00:00-00:00";
DWORD AutoDownloadTimeSettingAddr = GetWeChatWinBase() + AutoDownloadTimeSettingOffset;
WriteProcessMemory(GetCurrentProcess(), (LPVOID)AutoDownloadTimeSettingAddr, settime, strlen(settime) + 1, 0);
// video auto
BYTE nopVideo[] = {0x90, 0x90, 0x90, 0x90, 0x90, 0x90};
DWORD nopVideoAddr = WeChatWinBase + 0x48CE1B;
WriteProcessMemory(GetCurrentProcess(), (LPVOID)nopVideoAddr, &nopVideo, sizeof(nopVideo), 0);
// image auto
BYTE nopImg[] = {0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90};
DWORD nopImgAddr = WeChatWinBase + 0x48D56B;
WriteProcessMemory(GetCurrentProcess(), (LPVOID)nopImgAddr, &nopImg, sizeof(nopImg), 0);
ImageMsgHooked = true;
}
......@@ -122,8 +107,7 @@ BOOL HookImageMsgRemote(LPVOID lpParameter)
{
global_save_path += L"\\";
}
wstring createpath = global_save_path.substr(0, global_save_path.length() - 1);
if (!FindOrCreateDirectory(createpath.c_str()))
if (!FindOrCreateDirectory(global_save_path.c_str()))
{
return false;
}
......
......@@ -66,6 +66,7 @@ void __stdcall HookVoiceMsg()
WeChatWinBase = GetWeChatWinBase();
if (VoiceMsgHooked || !WeChatWinBase)
return;
SetDownloadTime();
HookVoiceMsgAddr = WeChatWinBase + HookVoiceMsgAddrOffset;
HookVoiceMsgNextCall = WeChatWinBase + HookVoiceMsgNextCallOffset;
HookVoiceMsgJmpBackAddr = HookVoiceMsgAddr + 0x5;
......@@ -89,8 +90,7 @@ BOOL HookVoiceMsgRemote(LPVOID lpParameter)
{
global_save_path += L"\\";
}
wstring createpath = global_save_path.substr(0, global_save_path.length() - 1);
if (!FindOrCreateDirectory(createpath.c_str()))
if (!FindOrCreateDirectory(global_save_path.c_str()))
{
return false;
}
......
......@@ -335,6 +335,7 @@ VOID HookReceiveMessage(int port)
WeChatWinBase = GetWeChatWinBase();
if (ReceiveMessageHooked || !WeChatWinBase)
return;
SetDownloadTime();
ReceiveMessageHookAddress = WeChatWinBase + ReceiveMessageHookOffset;
ReceiveMessageNextCall = WeChatWinBase + ReceiveMessageNextCallOffset;
ReceiveMessageJmpBackAddress = ReceiveMessageHookAddress + 0x5;
......
#pragma once
#include <windows.h>
#include "wxdata.h"
#ifndef USE_SOCKET
extern "C" __declspec(dllexport) VOID HookReceiveMessage(int port);
extern "C" __declspec(dllexport) VOID UnHookReceiveMessage();
......@@ -7,6 +8,7 @@ extern "C" __declspec(dllexport) void UnHookVoiceMsg();
extern "C" __declspec(dllexport) BOOL HookVoiceMsgRemote(LPVOID lpParameter);
extern "C" __declspec(dllexport) void UnHookImageMsg();
extern "C" __declspec(dllexport) BOOL HookImageMsgRemote(LPVOID lpParameter);
extern "C" __declspec(dllexport) DWORD GetMsgCDNRemote(ULONG64 *p_msgid);
#else
VOID HookReceiveMessage(int port);
VOID UnHookReceiveMessage();
......@@ -18,6 +20,10 @@ BOOL __stdcall HookImageMsg(wstring save_path);
void __stdcall HookVoiceMsg();
void __stdcall HookImageMsg();
BOOL __stdcall GetChatMsgBySvrId(ULONG64 msgid, PCHAT_MSG p_chat_msg);
BOOL __stdcall ReleaseChatMsg(PCHAT_MSG p_chat_msg);
wstring __stdcall GetMsgCDN(ULONG64 msgid);
void __stdcall SetDownloadTime();
typedef enum MSG_SOURCE_TYPETag
{
......
#include "pch.h"
#define SendEmotionCall1Offset 0x5FEC1980 - 0x5F750000
#define SendEmotionCall2Offset 0x5FBC77E0 - 0x5F750000
#define SendEmotionHandleOffset 0x61AEE888 - 0x5F750000
#ifndef USE_SOCKET
struct SendEmotionStruct
{
wchar_t *wxid;
wchar_t *img_path;
};
BOOL SendEmotionRemote(LPVOID lparameter)
{
SendEmotionStruct *ses = (SendEmotionStruct *)lparameter;
BOOL status = SendEmotion(ses->wxid, ses->img_path);
return status;
}
#endif
BOOL __stdcall SendEmotion(wchar_t *wxid, wchar_t *img_path)
{
DWORD WeChatWinBase = GetWeChatWinBase();
DWORD SendEmotionCall1 = WeChatWinBase + SendEmotionCall1Offset;
DWORD SendEmotionCall2 = WeChatWinBase + SendEmotionCall2Offset;
DWORD SendEmotionHandle = WeChatWinBase + SendEmotionHandleOffset;
WxString p_wxid(wxid), p_img_path(img_path), p_null(NULL);
char buf[0x1C] = {0};
int isSuccess = 0x0;
__asm {
pushad;
pushfd;
mov ebx,dword ptr[SendEmotionHandle];
lea eax,buf;
push eax;
push 0x0;
sub esp,0x14;
mov esi,esp;
mov dword ptr [esi], 0x0;
mov dword ptr [esi+0x4], 0x0;
mov dword ptr [esi+0x8], 0x0;
mov dword ptr [esi+0xC], 0x0;
mov dword ptr [esi+0x10], 0x0;
push 0x2;
lea eax,p_wxid;
sub esp,0x14;
mov ecx,esp;
push eax;
call SendEmotionCall1;
sub esp,0x14;
mov esi,esp;
mov dword ptr [esi], 0x0;
mov dword ptr [esi+0x4], 0x0;
mov dword ptr [esi+0x8], 0x0;
mov dword ptr [esi+0xC], 0x0;
mov dword ptr [esi+0x10], 0x0;
sub esp,0x14;
mov ecx,esp;
lea eax,p_img_path;
push eax;
call SendEmotionCall1;
mov ecx,ebx;
call SendEmotionCall2;
movzx eax,al;
mov isSuccess,eax;
popfd;
popad;
}
return (isSuccess == 0x1);
}
#pragma once
#include <windows.h>
BOOL __stdcall SendEmotion(wchar_t *wxid, wchar_t *img_path);
#ifndef USE_SOCKET
extern "C" __declspec(dllexport) BOOL SendEmotionRemote(LPVOID lparameter);
#endif
......@@ -148,4 +148,9 @@ BOOL __stdcall GetTransfer(wstring wxid, wstring transcationid, wstring transfer
{
return GetTransfer(WS2LW(wxid), WS2LW(transcationid), WS2LW(transferid));
}
BOOL __stdcall SendEmotion(wstring wxid, wstring img_path)
{
return SendEmotion(WS2LW(wxid), WS2LW(img_path));
}
#endif
// pch.cpp: 与预编译标头对应的源文件
#include "pch.h"
#include "io.h"
#include <functional>
// 当使用预编译的头时,需要使用此源文件,编译才能成功。
......@@ -37,19 +38,15 @@ DWORD GetWeChatWinBase()
BOOL FindOrCreateDirectory(const wchar_t *pszPath)
{
WIN32_FIND_DATA fd;
HANDLE hFind = ::FindFirstFile(pszPath, &fd);
if (hFind != INVALID_HANDLE_VALUE)
string dir = unicode_to_gb2312((wchar_t *)pszPath);
char last_char = dir.back();
if (last_char != '\\')
{
FindClose(hFind);
return true;
dir += '\\';
}
if (!::CreateDirectory(pszPath, NULL))
{
return false;
}
return true;
if (!_access(dir.c_str(), 0))
return true;
return MakeSureDirectoryPathExists(dir.c_str());
}
/*
......
......@@ -17,6 +17,7 @@
#include <string>
#include <sstream>
#include <fstream>
#include <imagehlp.h>
#include <time.h>
#include "wxdata.h"
#include "wxapi.h"
......
......@@ -37,6 +37,7 @@
#include "GetA8Key.h"
#include "Logout.h"
#include "GetTransfer.h"
#include "SendEmotion.h"
using namespace std;
#pragma comment(lib, "version.lib")
......
......@@ -14,34 +14,33 @@ using namespace std;
* fill2:占位成员2,默认为0
* WxString:默认构造函数
*/
struct WxString
typedef struct WxStringW
{
wchar_t *buffer;
DWORD length;
DWORD maxLength;
wchar_t *buffer = NULL;
DWORD length = 0;
DWORD maxLength = 0;
DWORD fill1 = 0;
DWORD fill2 = 0;
WxString()
{
WxString(NULL);
}
WxString(wstring &str)
WxStringW() {}
WxStringW(wstring &str)
{
buffer = (wchar_t *)str.c_str();
length = str.length();
maxLength = str.length() * 2;
}
WxString(const wchar_t *pStr)
WxStringW(const wchar_t *pStr)
{
WxString((wchar_t *)pStr);
buffer = (wchar_t *)pStr;
length = wcslen(pStr);
maxLength = wcslen(pStr) * 2;
}
WxString(int tmp)
WxStringW(int tmp)
{
buffer = NULL;
length = 0x0;
maxLength = 0x0;
}
WxString(wchar_t *pStr)
WxStringW(wchar_t *pStr)
{
buffer = pStr;
length = wcslen(pStr);
......@@ -53,7 +52,7 @@ struct WxString
length = wcslen(pStr);
maxLength = wcslen(pStr) * 2;
}
};
} WxString;
/*
* 保存单条信息的结构
......@@ -184,8 +183,97 @@ struct WxFriendStruct
}
};
struct GetPublicMsgStruct
typedef struct CHAT_MSGTag
{
DWORD handle1 = 0;
DWORD null_value1 = 0;
ULONG64 sequence = 0x0;
DWORD null_value2[2] = {0};
ULONG64 msgsequence = 0x0;
DWORD localId = 0;
DWORD null_value3[3] = {0};
ULONG64 msgid = 0x0;
DWORD type = 0x1;
DWORD isSendMsg = 0x1;
DWORD unknown_value1 = 0x2;
DWORD create_time = 0x0;
WxString takler = {0};
WxString null_string1 = {0};
WxString content = {0};
DWORD null_value4[2] = {0};
DWORD extrabuf = 0;
DWORD extrabuf_len = 0;
DWORD null_value5[17] = {0};
BOOL isSyncMsg = 0x1;
DWORD null_value6[21] = {0};
DWORD handle2 = 0;
DWORD handle3 = 0;
void *unknown_ptr1 = NULL;
DWORD null_value7[13] = {0};
WxString chatroom_member = {0};
WxString md5 = {0};
WxString thumbnail = {0};
WxString file_save_path = {0};
DWORD null_value8[11] = {0};
WxString extra_info = {0};
DWORD null_value9[16] = {0};
DWORD unknown_value2 = 0x1;
DWORD unknown_value3 = 0x1;
DWORD null_value10[7] = {0};
DWORD unknown_value4 = 0x1;
DWORD null_value11 = 0;
DWORD unknown_value5 = 0xFF;
DWORD unknown_value6 = 0x1;
DWORD null_value12[6] = {0};
void *unknown_ptr2 = NULL;
DWORD null_value13[2] = {0};
} CHAT_MSG, *PCHAT_MSG;
struct WxStringA
{
wchar_t *PublicId;
wchar_t *Offset;
char buffer[0x10] = {0};
int length;
int maxLength;
WxStringA(string &str)
{
this->length = str.length();
this->maxLength = this->length - (this->length % 0x10) + 0xF;
if (this->length == 0)
{
*(DWORD *)this->buffer = 0;
}
else if (this->length < 0x10)
{
memcpy(this->buffer, str.c_str(), this->length + 1);
}
else
{
*(DWORD *)this->buffer = (DWORD)str.c_str();
}
}
WxStringA(const char *buf)
{
this->length = strlen(buf);
this->maxLength = this->length - (this->length % 0x10) + 0xF;
if (this->length == 0)
{
*(DWORD *)this->buffer = 0;
}
else if (this->length < 0x10)
{
memcpy(this->buffer, buf, this->length + 1);
}
else
{
*(DWORD *)this->buffer = (DWORD)buf;
}
}
char *get()
{
if (this->length < 0x10)
{
return this->buffer;
}
return (char *)(*(DWORD *)this->buffer);
}
};
......@@ -632,6 +632,31 @@ void request_event(mg_http_message *hm, string &ret, struct mg_connection *c)
ret = ret_data.dump();
break;
}
case WECHAT_MSG_SEND_EMOTION:
{
wstring wxid = get_http_param_str(hm, jData, "wxid", method);
wstring img_path = get_http_param_str(hm, jData, "img_path", method);
BOOL status = SendEmotion(wxid, img_path);
json ret_data = {{"msg", status}, {"result", "OK"}};
ret = ret_data.dump();
break;
}
case WECHAT_GET_CDN:
{
ULONG64 msgid = get_http_param_ulong64(hm, jData, "msgid", method);
wstring cdn_path = GetMsgCDN(msgid);
if (cdn_path == L"")
{
json ret_data = {{"msg", 0}, {"result", "OK"}};
ret = ret_data.dump();
}
else
{
json ret_data = {{"msg", 1}, {"result", "OK"}, {"path", unicode_to_utf8(WS2LW(cdn_path))}};
ret = ret_data.dump();
}
break;
}
default:
// char* wxid = mg_json_get_str(hm->body, "$.wxid");
break;
......
......@@ -77,6 +77,8 @@ typedef enum WECHAT_HTTP_APISTag
WECHAT_MSG_SEND_XML,
WECHAT_LOGOUT,
WECHAT_GET_TRANSFER,
WECHAT_MSG_SEND_EMOTION,
WECHAT_GET_CDN,
} WECHAT_HTTP_APIS,
*PWECHAT_HTTP_APIS;
#endif
......@@ -8,6 +8,7 @@ Created on Thu Feb 24 16:19:48 2022
# Before use,execute `CWeChatRobot.exe /regserver` in cmd by admin user
import os
import ctypes
import time
import json
import ctypes.wintypes
import socketserver
......@@ -1150,6 +1151,46 @@ class WeChatRobot:
"""
return self.robot.CGetTransfer(self.pid,wxid,transcationid,transferid)
def SendEmotion(self, wxid: str, img_path: str) -> int:
"""
发送图片消息
Parameters
----------
wxid : str
消息接收者wxid.
img_path : str
图片绝对路径.
Returns
-------
int
0成功,非0失败.
"""
return self.robot.CSendEmotion(self.pid, wxid, img_path)
def GetMsgCDN(self,msgid: int) -> str:
"""
下载图片、视频、文件
Parameters
----------
msgid : int
msgid.
Returns
-------
str
成功返回文件路径,失败返回空字符串.
"""
path = self.robot.CGetMsgCDN(self.pid,msgid)
if path != "":
while not os.path.exists(path):
time.sleep(0.5)
return path
def get_wechat_pid_list() -> list:
"""
......
......@@ -89,6 +89,8 @@ class WECHAT_HTTP_APIS:
WECHAT_MSG_SEND_XML = 43 # 发送xml消息
WECHAT_LOGOUT = 44 # 退出登录
WECHAT_GET_TRANSFER = 45 # 收款
WECHAT_MSG_SEND_EMOTION = 46 # 发送表情
WECHAT_GET_CDN = 47 # 下载文件、视频、图片
APIS = WECHAT_HTTP_APIS
......@@ -197,7 +199,9 @@ class WECHAT_HTTP_API_PARAM_TEMPLATES:
APIS.WECHAT_GET_A8KEY: {"url":""},
APIS.WECHAT_MSG_SEND_XML: {"wxid":"filehelper","xml":"","img_path":""},
APIS.WECHAT_LOGOUT: {},
APIS.WECHAT_GET_TRANSFER: {"wxid":"","transcationid":"","transferid":""}
APIS.WECHAT_GET_TRANSFER: {"wxid":"","transcationid":"","transferid":""},
APIS.WECHAT_MSG_SEND_EMOTION: {"wxid":"","img_path":""},
APIS.WECHAT_GET_CDN: {"msgid":2 ** 64 - 1},
}
def get_http_template(self, api_number):
......
......@@ -34,11 +34,10 @@ PC微信机器人,实现以下功能:
`./DWeChatRobot`:注入的DLL实现代码,根据平台配置可编译出socket版和COM版
`./old_projects`: 包含C#的调用示例以及3.7.0.26版本的E语言调用
`./Python`:python示例和接口测试文件
`./wxDriver`:driver的实现代码,有些函数具有一定的学习意义
`./Release/CWeChatRobot.exe`:编译的COM组件
`./Release/DWeChatRobot.dll`:编译的DLL文件
`./Release/socket`:包含wxDriver.dll和socket接口的DLL
`./Release/WeChatTools.exe`:用于调试时注入或卸载DLL程序,具体参阅相关代码
`./wxDriver`:driver的实现代码
下载二进制文件请到:[Release](https://github.com/ljc545w/ComWeChatRobot/releases)
# 快速启动
以管理员权限执行以下命令:
```shell
......@@ -159,6 +158,10 @@ CWeChatRobot.exe /unregserver
1. 新增收款接口
2. 实时消息接口优化,支持获取音视频聊天信息,支持获取手机端切换联系人时的提示信息
3. 修复部分已知问题
## 2022.11.2
1. 支持发送动态表情
2. 支持夜间自动下载视频(需开启一次实时消息监听)
3. 新增通过消息id下载消息附件功能
# 打赏作者
请给作者一个star,感谢感谢
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册