提交 ab0e69a3 编写于 作者: L ljc545w

优化与新增功能

上级 ff76f80c
#include "pch.h"
struct GetPublicMsgStruct
{
DWORD public_id;
DWORD offset;
};
struct GetPublicMsgRespStruct
{
DWORD message;
DWORD length;
};
wstring GetHistoryPublicMsg(DWORD pid, wchar_t *public_id, wchar_t *offset)
{
WeChatProcess hp(pid);
if (!hp.m_init)
return L"";
DWORD GetHistoryPublicMsgReomteAddr = hp.GetProcAddr(GetHistoryPublicMsgRemote);
if (GetHistoryPublicMsgReomteAddr == 0)
{
return L"";
}
GetPublicMsgStruct params = {0};
WeChatData<wchar_t *> r_public_id(hp.GetHandle(), public_id, TEXTLENGTH(public_id));
WeChatData<wchar_t *> r_offset(hp.GetHandle(), offset, TEXTLENGTH(offset));
params.public_id = (DWORD)r_public_id.GetAddr();
params.offset = (DWORD)r_offset.GetAddr();
WeChatData<GetPublicMsgStruct *> r_params(hp.GetHandle(), &params, sizeof(params));
if (!params.public_id || !params.offset || !r_params.GetAddr())
{
return L"";
}
DWORD dwRet = CallRemoteFunction(hp.GetHandle(), GetHistoryPublicMsgReomteAddr, r_params.GetAddr());
DWORD dwReadSize;
GetPublicMsgRespStruct ret_info = {0};
ReadProcessMemory(hp.GetHandle(), (LPCVOID)dwRet, &ret_info, sizeof(ret_info), &dwReadSize);
if (ret_info.message == 0)
return L"";
char *buffer = new char[ret_info.length + 1];
ReadProcessMemory(hp.GetHandle(), (LPCVOID)ret_info.message, buffer, ret_info.length, &dwReadSize);
string result(buffer, ret_info.length);
wstring wresult = gb2312_to_unicode(result.c_str());
delete[] buffer;
return wresult;
}
#pragma once
#include <windows.h>
#include <iostream>
using namespace std;
wstring GetHistoryPublicMsg(DWORD pid, wchar_t *public_id, wchar_t *offset);
#include "pch.h"
BOOL OpenBrowser(DWORD pid, wchar_t *url)
{
WeChatProcess hp(pid);
if (!hp.m_init)
return 1;
DWORD OpenBrowserRemoteAddr = hp.GetProcAddr(OpenBrowserRemote);
if (OpenBrowserRemoteAddr == 0)
{
return 1;
}
WeChatData<wchar_t *> r_url(hp.GetHandle(), url, TEXTLENGTH(url));
if (!r_url.GetAddr())
{
return 1;
}
DWORD dwRet = CallRemoteFunction(hp.GetHandle(), OpenBrowserRemoteAddr, r_url.GetAddr());
return dwRet == 0;
}
#pragma once
#include <windows.h>
BOOL OpenBrowser(DWORD pid, wchar_t *url);
此差异已折叠。
// WeChatRobot.h: CWeChatRobot 的声明
#pragma once
#include "resource.h" // 主符号
#include "resource.h" // 主符号
#include "WeChatRobotCOM_i.h"
#if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)
#error "Windows CE 平台(如不提供完全 DCOM 支持的 Windows Mobile 平台)上无法正确支持单线程 COM 对象。定义 _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA 可强制 ATL 支持创建单线程 COM 对象实现并允许使用其单线程 COM 对象实现。rgs 文件中的线程模型已被设置为“Free”,原因是该模型是非 DCOM Windows CE 平台支持的唯一线程模型。"
#endif
using namespace ATL;
// CWeChatRobot
class ATL_NO_VTABLE CWeChatRobot :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CWeChatRobot, &CLSID_WeChatRobot>,
public IDispatchImpl<IWeChatRobot, &IID_IWeChatRobot, &LIBID_WeChatRobotCOMLib, /*wMajor =*/ 1, /*wMinor =*/ 0>
class ATL_NO_VTABLE CWeChatRobot : public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CWeChatRobot, &CLSID_WeChatRobot>,
public IDispatchImpl<IWeChatRobot, &IID_IWeChatRobot, &LIBID_WeChatRobotCOMLib, /*wMajor =*/1, /*wMinor =*/0>
{
public:
CWeChatRobot()
{
}
CWeChatRobot()
{
}
DECLARE_REGISTRY_RESOURCEID(106)
DECLARE_REGISTRY_RESOURCEID(106)
BEGIN_COM_MAP(CWeChatRobot)
COM_INTERFACE_ENTRY(IWeChatRobot)
COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()
BEGIN_COM_MAP(CWeChatRobot)
COM_INTERFACE_ENTRY(IWeChatRobot)
COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()
DECLARE_PROTECT_FINAL_CONSTRUCT()
HRESULT FinalConstruct()
{
return S_OK;
}
DECLARE_PROTECT_FINAL_CONSTRUCT()
HRESULT FinalConstruct()
{
return S_OK;
}
void FinalRelease()
{
}
void FinalRelease()
{
}
public:
STDMETHODIMP CStartRobotService(DWORD pid, int* __result);
STDMETHODIMP CStopRobotService(DWORD pid, int* __result);
STDMETHODIMP CSendImage(DWORD pid, BSTR wxid, BSTR imagepath, int* __result);
STDMETHODIMP CSendText(DWORD pid, BSTR wxid, BSTR wxmsg, int* __result);
STDMETHODIMP CSendFile(DWORD pid, BSTR wxid, BSTR filepath, int* __result);
STDMETHODIMP CSendArticle(DWORD pid, BSTR wxid, BSTR title, BSTR abstract, BSTR url, BSTR imgpath, int* __result);
STDMETHODIMP CSendCard(DWORD pid, BSTR receiver, BSTR sharedwxid, BSTR nickname, int* __result);
STDMETHODIMP CSendAtText(DWORD pid, BSTR chatroomid, VARIANT* wxid, BSTR wxmsg, BOOL AutoNickName, int* __result);
STDMETHODIMP CGetFriendList(DWORD pid, VARIANT* __result);
STDMETHODIMP CGetFriendListString(DWORD pid, BSTR* __result);
STDMETHODIMP CGetWxUserInfo(DWORD pid, BSTR wxid, BSTR* __result);
STDMETHODIMP CGetSelfInfo(DWORD pid, BSTR* __result);
STDMETHODIMP CCheckFriendStatus(DWORD pid, BSTR wxid, int* __result);
STDMETHODIMP CGetComWorkPath(BSTR* __result);
STDMETHODIMP CStartReceiveMessage(DWORD pid, int port, int* __result);
STDMETHODIMP CStopReceiveMessage(DWORD pid, int* __result);
STDMETHODIMP CGetChatRoomMembers(DWORD pid, BSTR chatroomid, VARIANT* __result);
STDMETHODIMP CGetDbHandles(DWORD pid, VARIANT* __result);
STDMETHODIMP CExecuteSQL(DWORD pid, DWORD DbHandle, BSTR sql, VARIANT* __result);
STDMETHODIMP CBackupSQLiteDB(DWORD pid, DWORD DbHandle, BSTR savepath, int* __result);
STDMETHODIMP CVerifyFriendApply(DWORD pid, BSTR v3, BSTR v4, int* __result);
STDMETHODIMP CAddFriendByWxid(DWORD pid, BSTR wxid, BSTR message, int* __result);
STDMETHODIMP CAddFriendByV3(DWORD pid, BSTR v3, BSTR message, int AddType, int* __result);
STDMETHODIMP CGetWeChatVer(BSTR* __result);
STDMETHODIMP CStartWeChat(int* __result);
STDMETHODIMP CSearchContactByNet(DWORD pid, BSTR keyword, VARIANT* __result);
STDMETHODIMP CAddBrandContact(DWORD pid, BSTR PublicId, int* __result);
STDMETHODIMP CHookVoiceMsg(DWORD pid, BSTR savepath, int* __result);
STDMETHODIMP CUnHookVoiceMsg(DWORD pid, int* __result);
STDMETHODIMP CHookImageMsg(DWORD pid, BSTR savepath, int* __result);
STDMETHODIMP CUnHookImageMsg(DWORD pid, int* __result);
STDMETHODIMP CChangeWeChatVer(DWORD pid, BSTR verStr, int* __result);
STDMETHODIMP CSendAppMsg(DWORD pid, BSTR wxid, BSTR appid, int* __result);
STDMETHODIMP CDeleteUser(DWORD pid, BSTR wxid, int* __result);
STDMETHODIMP CIsWxLogin(DWORD pid, int* __result);
STDMETHODIMP CEditRemark(DWORD pid, BSTR wxid,BSTR remark,int* __result);
STDMETHODIMP CSetChatRoomName(DWORD pid, BSTR chatroomid, BSTR name, int* __result);
STDMETHODIMP CSetChatRoomAnnouncement(DWORD pid, BSTR chatroomid, BSTR announcement, int* __result);
STDMETHODIMP CSetChatRoomSelfNickname(DWORD pid, BSTR chatroomid, BSTR nickname, int* __result);
STDMETHODIMP CGetChatRoomMemberNickname(DWORD pid, BSTR chatroomid, BSTR wxid, BSTR* __result);
STDMETHODIMP CDelChatRoomMember(DWORD pid, BSTR chatroomid, VARIANT* wxids, int* __result);
STDMETHODIMP CAddChatRoomMember(DWORD pid, BSTR chatroomid, VARIANT* wxids, int* __result);
STDMETHODIMP CStartRobotService(DWORD pid, int *__result);
STDMETHODIMP CStopRobotService(DWORD pid, int *__result);
STDMETHODIMP CSendImage(DWORD pid, BSTR wxid, BSTR imagepath, int *__result);
STDMETHODIMP CSendText(DWORD pid, BSTR wxid, BSTR wxmsg, int *__result);
STDMETHODIMP CSendFile(DWORD pid, BSTR wxid, BSTR filepath, int *__result);
STDMETHODIMP CSendArticle(DWORD pid, BSTR wxid, BSTR title, BSTR abstract, BSTR url, BSTR imgpath, int *__result);
STDMETHODIMP CSendCard(DWORD pid, BSTR receiver, BSTR sharedwxid, BSTR nickname, int *__result);
STDMETHODIMP CSendAtText(DWORD pid, BSTR chatroomid, VARIANT *wxid, BSTR wxmsg, BOOL AutoNickName, int *__result);
STDMETHODIMP CGetFriendList(DWORD pid, VARIANT *__result);
STDMETHODIMP CGetFriendListString(DWORD pid, BSTR *__result);
STDMETHODIMP CGetWxUserInfo(DWORD pid, BSTR wxid, BSTR *__result);
STDMETHODIMP CGetSelfInfo(DWORD pid, BSTR *__result);
STDMETHODIMP CCheckFriendStatus(DWORD pid, BSTR wxid, int *__result);
STDMETHODIMP CGetComWorkPath(BSTR *__result);
STDMETHODIMP CStartReceiveMessage(DWORD pid, int port, int *__result);
STDMETHODIMP CStopReceiveMessage(DWORD pid, int *__result);
STDMETHODIMP CGetChatRoomMembers(DWORD pid, BSTR chatroomid, VARIANT *__result);
STDMETHODIMP CGetDbHandles(DWORD pid, VARIANT *__result);
STDMETHODIMP CExecuteSQL(DWORD pid, DWORD DbHandle, BSTR sql, VARIANT *__result);
STDMETHODIMP CBackupSQLiteDB(DWORD pid, DWORD DbHandle, BSTR savepath, int *__result);
STDMETHODIMP CVerifyFriendApply(DWORD pid, BSTR v3, BSTR v4, int *__result);
STDMETHODIMP CAddFriendByWxid(DWORD pid, BSTR wxid, BSTR message, int *__result);
STDMETHODIMP CAddFriendByV3(DWORD pid, BSTR v3, BSTR message, int AddType, int *__result);
STDMETHODIMP CGetWeChatVer(BSTR *__result);
STDMETHODIMP CStartWeChat(int *__result);
STDMETHODIMP CSearchContactByNet(DWORD pid, BSTR keyword, VARIANT *__result);
STDMETHODIMP CAddBrandContact(DWORD pid, BSTR PublicId, int *__result);
STDMETHODIMP CHookVoiceMsg(DWORD pid, BSTR savepath, int *__result);
STDMETHODIMP CUnHookVoiceMsg(DWORD pid, int *__result);
STDMETHODIMP CHookImageMsg(DWORD pid, BSTR savepath, int *__result);
STDMETHODIMP CUnHookImageMsg(DWORD pid, int *__result);
STDMETHODIMP CChangeWeChatVer(DWORD pid, BSTR verStr, int *__result);
STDMETHODIMP CSendAppMsg(DWORD pid, BSTR wxid, BSTR appid, int *__result);
STDMETHODIMP CDeleteUser(DWORD pid, BSTR wxid, int *__result);
STDMETHODIMP CIsWxLogin(DWORD pid, int *__result);
STDMETHODIMP CEditRemark(DWORD pid, BSTR wxid, BSTR remark, int *__result);
STDMETHODIMP CSetChatRoomName(DWORD pid, BSTR chatroomid, BSTR name, int *__result);
STDMETHODIMP CSetChatRoomAnnouncement(DWORD pid, BSTR chatroomid, BSTR announcement, int *__result);
STDMETHODIMP CSetChatRoomSelfNickname(DWORD pid, BSTR chatroomid, BSTR nickname, int *__result);
STDMETHODIMP CGetChatRoomMemberNickname(DWORD pid, BSTR chatroomid, BSTR wxid, BSTR *__result);
STDMETHODIMP CDelChatRoomMember(DWORD pid, BSTR chatroomid, VARIANT *wxids, int *__result);
STDMETHODIMP CAddChatRoomMember(DWORD pid, BSTR chatroomid, VARIANT *wxids, int *__result);
STDMETHODIMP COpenBrowser(DWORD pid, BSTR url, int *__result);
STDMETHODIMP CGetHistoryPublicMsg(DWORD pid, BSTR PublicId, BSTR Offset, VARIANT *__result);
};
OBJECT_ENTRY_AUTO(__uuidof(WeChatRobot), CWeChatRobot)
......@@ -58,6 +58,8 @@ interface IWeChatRobot : IDispatch
[id(43), helpstring("获取指定群成员昵称")] HRESULT CGetChatRoomMemberNickname([in] DWORD pid, [in] BSTR chatroomid, [in] BSTR wxid, [out, retval] BSTR* __result);
[id(44), helpstring("删除群成员")] HRESULT CDelChatRoomMember([in] DWORD pid, [in] BSTR chatroomid, [in] VARIANT* wxids, [out, retval] int* __result);
[id(45), helpstring("添加群成员")] HRESULT CAddChatRoomMember([in] DWORD pid, [in] BSTR chatroomid, [in] VARIANT* wxids, [out, retval] int* __result);
[id(46), helpstring("打开微信内置浏览器")] HRESULT COpenBrowser([in] DWORD pid, [in] BSTR url, [ out, retval ] int *__result);
[id(47), helpstring("获取公众号历史消息")] HRESULT CGetHistoryPublicMsg([in] DWORD pid, [in] BSTR PublicId, [in] BSTR Offset, [ out, retval ] VARIANT * __result);
};
[
object,
......
......@@ -234,8 +234,10 @@
<ClInclude Include="GetChatRoomMemberNickname.h" />
<ClInclude Include="GetChatRoomMembers.h" />
<ClInclude Include="GetDbHandles.h" />
<ClInclude Include="GetHistoryPublicMsg.h" />
<ClInclude Include="InjectDll.h" />
<ClInclude Include="ntapi.h" />
<ClInclude Include="OpenBrowser.h" />
<ClInclude Include="pch.h" />
<ClInclude Include="ReceiveMessage.h" />
<ClInclude Include="Resource.h" />
......@@ -278,10 +280,12 @@
<ClCompile Include="GetChatRoomMemberNickname.cpp" />
<ClCompile Include="GetChatRoomMembers.cpp" />
<ClCompile Include="GetDbHandles.cpp" />
<ClCompile Include="GetHistoryPublicMsg.cpp" />
<ClCompile Include="HookImageMessage.cpp" />
<ClCompile Include="HookVoiceMessage.cpp" />
<ClCompile Include="InjectDll.cpp" />
<ClCompile Include="ntapi.cpp" />
<ClCompile Include="OpenBrowser.cpp" />
<ClCompile Include="pch.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
......
......@@ -116,6 +116,15 @@
<Filter Include="template">
<UniqueIdentifier>{fdd967bf-e9c0-4793-80a1-dcb87b061fc6}</UniqueIdentifier>
</Filter>
<Filter Include="浏览器相关">
<UniqueIdentifier>{12952462-2a85-4d25-9361-e6bbf47079e9}</UniqueIdentifier>
</Filter>
<Filter Include="浏览器相关\打开浏览器">
<UniqueIdentifier>{2f7581a1-536b-426a-af04-00fa2c356a73}</UniqueIdentifier>
</Filter>
<Filter Include="浏览器相关\获取公众号历史消息">
<UniqueIdentifier>{e54ac438-bc4e-46cf-9450-502e35daf385}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="framework.h">
......@@ -241,6 +250,12 @@
<ClInclude Include="utils.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="OpenBrowser.h">
<Filter>浏览器相关\打开浏览器</Filter>
</ClInclude>
<ClInclude Include="GetHistoryPublicMsg.h">
<Filter>浏览器相关\获取公众号历史消息</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="WeChatRobotCOM.cpp">
......@@ -366,6 +381,12 @@
<ClCompile Include="templatefunc.cpp">
<Filter>template</Filter>
</ClCompile>
<ClCompile Include="OpenBrowser.cpp">
<Filter>浏览器相关\打开浏览器</Filter>
</ClCompile>
<ClCompile Include="GetHistoryPublicMsg.cpp">
<Filter>浏览器相关\获取公众号历史消息</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="WeChatRobotCOM.rc">
......@@ -388,4 +409,4 @@
<Filter>源文件</Filter>
</Midl>
</ItemGroup>
</Project>
\ No newline at end of file
</Project>
......@@ -334,6 +334,17 @@ EXTERN_C const IID IID_IWeChatRobot;
/* [in] */ VARIANT *wxids,
/* [retval][out] */ int *__result) = 0;
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE COpenBrowser(
/* [in] */ DWORD pid,
/* [in] */ BSTR url,
/* [retval][out] */ int *__result) = 0;
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE CGetHistoryPublicMsg(
/* [in] */ DWORD pid,
/* [in] */ BSTR PublicId,
/* [in] */ BSTR Offset,
/* [retval][out] */ VARIANT *__result) = 0;
};
......@@ -654,6 +665,19 @@ EXTERN_C const IID IID_IWeChatRobot;
/* [in] */ VARIANT *wxids,
/* [retval][out] */ int *__result);
/* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *COpenBrowser )(
IWeChatRobot * This,
/* [in] */ DWORD pid,
/* [in] */ BSTR url,
/* [retval][out] */ int *__result);
/* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *CGetHistoryPublicMsg )(
IWeChatRobot * This,
/* [in] */ DWORD pid,
/* [in] */ BSTR PublicId,
/* [in] */ BSTR Offset,
/* [retval][out] */ VARIANT *__result);
END_INTERFACE
} IWeChatRobotVtbl;
......@@ -816,6 +840,12 @@ EXTERN_C const IID IID_IWeChatRobot;
#define IWeChatRobot_CAddChatRoomMember(This,pid,chatroomid,wxids,__result) \
( (This)->lpVtbl -> CAddChatRoomMember(This,pid,chatroomid,wxids,__result) )
#define IWeChatRobot_COpenBrowser(This,pid,url,__result) \
( (This)->lpVtbl -> COpenBrowser(This,pid,url,__result) )
#define IWeChatRobot_CGetHistoryPublicMsg(This,pid,PublicId,Offset,__result) \
( (This)->lpVtbl -> CGetHistoryPublicMsg(This,pid,PublicId,Offset,__result) )
#endif /* COBJMACROS */
......
......@@ -49,7 +49,7 @@
#include "WeChatRobotCOM_i.h"
#define TYPE_FORMAT_STRING_SIZE 1239
#define PROC_FORMAT_STRING_SIZE 2185
#define PROC_FORMAT_STRING_SIZE 2287
#define EXPR_FORMAT_STRING_SIZE 1
#define TRANSMIT_AS_TABLE_SIZE 0
#define WIRE_MARSHAL_TABLE_SIZE 2
......@@ -2013,17 +2013,17 @@ static const WeChatRobotCOM_MIDL_PROC_FORMAT_STRING WeChatRobotCOM__MIDL_ProcFor
/* 2074 */ 0x8, /* FC_LONG */
0x0, /* 0 */
/* Procedure CPostMessage */
/* Procedure COpenBrowser */
/* 2076 */ 0x33, /* FC_AUTO_HANDLE */
0x6c, /* Old Flags: object, Oi2 */
/* 2078 */ NdrFcLong( 0x0 ), /* 0 */
/* 2082 */ NdrFcShort( 0x7 ), /* 7 */
/* 2084 */ NdrFcShort( 0x20 ), /* x86 Stack size/offset = 32 */
/* 2086 */ NdrFcShort( 0x20 ), /* 32 */
/* 2082 */ NdrFcShort( 0x31 ), /* 49 */
/* 2084 */ NdrFcShort( 0x14 ), /* x86 Stack size/offset = 20 */
/* 2086 */ NdrFcShort( 0x8 ), /* 8 */
/* 2088 */ NdrFcShort( 0x24 ), /* 36 */
/* 2090 */ 0x46, /* Oi2 Flags: clt must size, has return, has ext, */
0x6, /* 6 */
0x4, /* 4 */
/* 2092 */ 0x8, /* 8 */
0x45, /* Ext Flags: new corr desc, srv corr check, has range on conformance */
/* 2094 */ NdrFcShort( 0x0 ), /* 0 */
......@@ -2037,83 +2037,176 @@ static const WeChatRobotCOM_MIDL_PROC_FORMAT_STRING WeChatRobotCOM__MIDL_ProcFor
/* 2104 */ 0x8, /* FC_LONG */
0x0, /* 0 */
/* Parameter msgtype */
/* Parameter url */
/* 2106 */ NdrFcShort( 0x48 ), /* Flags: in, base type, */
/* 2106 */ NdrFcShort( 0x8b ), /* Flags: must size, must free, in, by val, */
/* 2108 */ NdrFcShort( 0x8 ), /* x86 Stack size/offset = 8 */
/* 2110 */ 0x8, /* FC_LONG */
/* 2110 */ NdrFcShort( 0x2a ), /* Type Offset=42 */
/* Parameter __result */
/* 2112 */ NdrFcShort( 0x2150 ), /* Flags: out, base type, simple ref, srv alloc size=8 */
/* 2114 */ NdrFcShort( 0xc ), /* x86 Stack size/offset = 12 */
/* 2116 */ 0x8, /* FC_LONG */
0x0, /* 0 */
/* Return value */
/* 2118 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */
/* 2120 */ NdrFcShort( 0x10 ), /* x86 Stack size/offset = 16 */
/* 2122 */ 0x8, /* FC_LONG */
0x0, /* 0 */
/* Procedure CGetHistoryPublicMsg */
/* 2124 */ 0x33, /* FC_AUTO_HANDLE */
0x6c, /* Old Flags: object, Oi2 */
/* 2126 */ NdrFcLong( 0x0 ), /* 0 */
/* 2130 */ NdrFcShort( 0x32 ), /* 50 */
/* 2132 */ NdrFcShort( 0x18 ), /* x86 Stack size/offset = 24 */
/* 2134 */ NdrFcShort( 0x8 ), /* 8 */
/* 2136 */ NdrFcShort( 0x8 ), /* 8 */
/* 2138 */ 0x47, /* Oi2 Flags: srv must size, clt must size, has return, has ext, */
0x5, /* 5 */
/* 2140 */ 0x8, /* 8 */
0x47, /* Ext Flags: new corr desc, clt corr check, srv corr check, has range on conformance */
/* 2142 */ NdrFcShort( 0x1 ), /* 1 */
/* 2144 */ NdrFcShort( 0x1 ), /* 1 */
/* 2146 */ NdrFcShort( 0x0 ), /* 0 */
/* Parameter pid */
/* 2148 */ NdrFcShort( 0x48 ), /* Flags: in, base type, */
/* 2150 */ NdrFcShort( 0x4 ), /* x86 Stack size/offset = 4 */
/* 2152 */ 0x8, /* FC_LONG */
0x0, /* 0 */
/* Parameter PublicId */
/* 2154 */ NdrFcShort( 0x8b ), /* Flags: must size, must free, in, by val, */
/* 2156 */ NdrFcShort( 0x8 ), /* x86 Stack size/offset = 8 */
/* 2158 */ NdrFcShort( 0x2a ), /* Type Offset=42 */
/* Parameter Offset */
/* 2160 */ NdrFcShort( 0x8b ), /* Flags: must size, must free, in, by val, */
/* 2162 */ NdrFcShort( 0xc ), /* x86 Stack size/offset = 12 */
/* 2164 */ NdrFcShort( 0x2a ), /* Type Offset=42 */
/* Parameter __result */
/* 2166 */ NdrFcShort( 0x4113 ), /* Flags: must size, must free, out, simple ref, srv alloc size=16 */
/* 2168 */ NdrFcShort( 0x10 ), /* x86 Stack size/offset = 16 */
/* 2170 */ NdrFcShort( 0x4ac ), /* Type Offset=1196 */
/* Return value */
/* 2172 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */
/* 2174 */ NdrFcShort( 0x14 ), /* x86 Stack size/offset = 20 */
/* 2176 */ 0x8, /* FC_LONG */
0x0, /* 0 */
/* Procedure CPostMessage */
/* 2178 */ 0x33, /* FC_AUTO_HANDLE */
0x6c, /* Old Flags: object, Oi2 */
/* 2180 */ NdrFcLong( 0x0 ), /* 0 */
/* 2184 */ NdrFcShort( 0x7 ), /* 7 */
/* 2186 */ NdrFcShort( 0x20 ), /* x86 Stack size/offset = 32 */
/* 2188 */ NdrFcShort( 0x20 ), /* 32 */
/* 2190 */ NdrFcShort( 0x24 ), /* 36 */
/* 2192 */ 0x46, /* Oi2 Flags: clt must size, has return, has ext, */
0x6, /* 6 */
/* 2194 */ 0x8, /* 8 */
0x45, /* Ext Flags: new corr desc, srv corr check, has range on conformance */
/* 2196 */ NdrFcShort( 0x0 ), /* 0 */
/* 2198 */ NdrFcShort( 0x1 ), /* 1 */
/* 2200 */ NdrFcShort( 0x0 ), /* 0 */
/* Parameter pid */
/* 2202 */ NdrFcShort( 0x48 ), /* Flags: in, base type, */
/* 2204 */ NdrFcShort( 0x4 ), /* x86 Stack size/offset = 4 */
/* 2206 */ 0x8, /* FC_LONG */
0x0, /* 0 */
/* Parameter msgtype */
/* 2208 */ NdrFcShort( 0x48 ), /* Flags: in, base type, */
/* 2210 */ NdrFcShort( 0x8 ), /* x86 Stack size/offset = 8 */
/* 2212 */ 0x8, /* FC_LONG */
0x0, /* 0 */
/* Parameter msgid */
/* 2112 */ NdrFcShort( 0x48 ), /* Flags: in, base type, */
/* 2114 */ NdrFcShort( 0xc ), /* x86 Stack size/offset = 12 */
/* 2116 */ 0xb, /* FC_HYPER */
/* 2214 */ NdrFcShort( 0x48 ), /* Flags: in, base type, */
/* 2216 */ NdrFcShort( 0xc ), /* x86 Stack size/offset = 12 */
/* 2218 */ 0xb, /* FC_HYPER */
0x0, /* 0 */
/* Parameter msg */
/* 2118 */ NdrFcShort( 0x10b ), /* Flags: must size, must free, in, simple ref, */
/* 2120 */ NdrFcShort( 0x14 ), /* x86 Stack size/offset = 20 */
/* 2122 */ NdrFcShort( 0x4cc ), /* Type Offset=1228 */
/* 2220 */ NdrFcShort( 0x10b ), /* Flags: must size, must free, in, simple ref, */
/* 2222 */ NdrFcShort( 0x14 ), /* x86 Stack size/offset = 20 */
/* 2224 */ NdrFcShort( 0x4cc ), /* Type Offset=1228 */
/* Parameter __result */
/* 2124 */ NdrFcShort( 0x2150 ), /* Flags: out, base type, simple ref, srv alloc size=8 */
/* 2126 */ NdrFcShort( 0x18 ), /* x86 Stack size/offset = 24 */
/* 2128 */ 0x8, /* FC_LONG */
/* 2226 */ NdrFcShort( 0x2150 ), /* Flags: out, base type, simple ref, srv alloc size=8 */
/* 2228 */ NdrFcShort( 0x18 ), /* x86 Stack size/offset = 24 */
/* 2230 */ 0x8, /* FC_LONG */
0x0, /* 0 */
/* Return value */
/* 2130 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */
/* 2132 */ NdrFcShort( 0x1c ), /* x86 Stack size/offset = 28 */
/* 2134 */ 0x8, /* FC_LONG */
/* 2232 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */
/* 2234 */ NdrFcShort( 0x1c ), /* x86 Stack size/offset = 28 */
/* 2236 */ 0x8, /* FC_LONG */
0x0, /* 0 */
/* Procedure CRegisterWxPidWithCookie */
/* 2136 */ 0x33, /* FC_AUTO_HANDLE */
/* 2238 */ 0x33, /* FC_AUTO_HANDLE */
0x6c, /* Old Flags: object, Oi2 */
/* 2138 */ NdrFcLong( 0x0 ), /* 0 */
/* 2142 */ NdrFcShort( 0x8 ), /* 8 */
/* 2144 */ NdrFcShort( 0x14 ), /* x86 Stack size/offset = 20 */
/* 2146 */ NdrFcShort( 0x10 ), /* 16 */
/* 2148 */ NdrFcShort( 0x24 ), /* 36 */
/* 2150 */ 0x44, /* Oi2 Flags: has return, has ext, */
/* 2240 */ NdrFcLong( 0x0 ), /* 0 */
/* 2244 */ NdrFcShort( 0x8 ), /* 8 */
/* 2246 */ NdrFcShort( 0x14 ), /* x86 Stack size/offset = 20 */
/* 2248 */ NdrFcShort( 0x10 ), /* 16 */
/* 2250 */ NdrFcShort( 0x24 ), /* 36 */
/* 2252 */ 0x44, /* Oi2 Flags: has return, has ext, */
0x4, /* 4 */
/* 2152 */ 0x8, /* 8 */
/* 2254 */ 0x8, /* 8 */
0x41, /* Ext Flags: new corr desc, has range on conformance */
/* 2154 */ NdrFcShort( 0x0 ), /* 0 */
/* 2156 */ NdrFcShort( 0x0 ), /* 0 */
/* 2158 */ NdrFcShort( 0x0 ), /* 0 */
/* 2256 */ NdrFcShort( 0x0 ), /* 0 */
/* 2258 */ NdrFcShort( 0x0 ), /* 0 */
/* 2260 */ NdrFcShort( 0x0 ), /* 0 */
/* Parameter pid */
/* 2160 */ NdrFcShort( 0x48 ), /* Flags: in, base type, */
/* 2162 */ NdrFcShort( 0x4 ), /* x86 Stack size/offset = 4 */
/* 2164 */ 0x8, /* FC_LONG */
/* 2262 */ NdrFcShort( 0x48 ), /* Flags: in, base type, */
/* 2264 */ NdrFcShort( 0x4 ), /* x86 Stack size/offset = 4 */
/* 2266 */ 0x8, /* FC_LONG */
0x0, /* 0 */
/* Parameter cookie */
/* 2166 */ NdrFcShort( 0x48 ), /* Flags: in, base type, */
/* 2168 */ NdrFcShort( 0x8 ), /* x86 Stack size/offset = 8 */
/* 2170 */ 0x8, /* FC_LONG */
/* 2268 */ NdrFcShort( 0x48 ), /* Flags: in, base type, */
/* 2270 */ NdrFcShort( 0x8 ), /* x86 Stack size/offset = 8 */
/* 2272 */ 0x8, /* FC_LONG */
0x0, /* 0 */
/* Parameter __result */
/* 2172 */ NdrFcShort( 0x2150 ), /* Flags: out, base type, simple ref, srv alloc size=8 */
/* 2174 */ NdrFcShort( 0xc ), /* x86 Stack size/offset = 12 */
/* 2176 */ 0x8, /* FC_LONG */
/* 2274 */ NdrFcShort( 0x2150 ), /* Flags: out, base type, simple ref, srv alloc size=8 */
/* 2276 */ NdrFcShort( 0xc ), /* x86 Stack size/offset = 12 */
/* 2278 */ 0x8, /* FC_LONG */
0x0, /* 0 */
/* Return value */
/* 2178 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */
/* 2180 */ NdrFcShort( 0x10 ), /* x86 Stack size/offset = 16 */
/* 2182 */ 0x8, /* FC_LONG */
/* 2280 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */
/* 2282 */ NdrFcShort( 0x10 ), /* x86 Stack size/offset = 16 */
/* 2284 */ 0x8, /* FC_LONG */
0x0, /* 0 */
0x0
......@@ -3002,7 +3095,9 @@ static const unsigned short IWeChatRobot_FormatStringOffsetTable[] =
1860,
1914,
1968,
2022
2022,
2076,
2124
};
static const MIDL_STUBLESS_PROXY_INFO IWeChatRobot_ProxyInfo =
......@@ -3026,7 +3121,7 @@ static const MIDL_SERVER_INFO IWeChatRobot_ServerInfo =
0,
0,
0};
CINTERFACE_PROXY_VTABLE(49) _IWeChatRobotProxyVtbl =
CINTERFACE_PROXY_VTABLE(51) _IWeChatRobotProxyVtbl =
{
&IWeChatRobot_ProxyInfo,
&IID_IWeChatRobot,
......@@ -3078,7 +3173,9 @@ CINTERFACE_PROXY_VTABLE(49) _IWeChatRobotProxyVtbl =
(void *) (INT_PTR) -1 /* IWeChatRobot::CSetChatRoomSelfNickname */ ,
(void *) (INT_PTR) -1 /* IWeChatRobot::CGetChatRoomMemberNickname */ ,
(void *) (INT_PTR) -1 /* IWeChatRobot::CDelChatRoomMember */ ,
(void *) (INT_PTR) -1 /* IWeChatRobot::CAddChatRoomMember */
(void *) (INT_PTR) -1 /* IWeChatRobot::CAddChatRoomMember */ ,
(void *) (INT_PTR) -1 /* IWeChatRobot::COpenBrowser */ ,
(void *) (INT_PTR) -1 /* IWeChatRobot::CGetHistoryPublicMsg */
};
......@@ -3129,6 +3226,8 @@ static const PRPC_STUB_FUNCTION IWeChatRobot_table[] =
NdrStubCall2,
NdrStubCall2,
NdrStubCall2,
NdrStubCall2,
NdrStubCall2,
NdrStubCall2
};
......@@ -3136,7 +3235,7 @@ CInterfaceStubVtbl _IWeChatRobotStubVtbl =
{
&IID_IWeChatRobot,
&IWeChatRobot_ServerInfo,
49,
51,
&IWeChatRobot_table[-3],
CStdStubBuffer_DELEGATING_METHODS
};
......@@ -3152,8 +3251,8 @@ static const unsigned short IRobotEvent_FormatStringOffsetTable[] =
(unsigned short) -1,
(unsigned short) -1,
(unsigned short) -1,
2076,
2136
2178,
2238
};
static const MIDL_STUBLESS_PROXY_INFO IRobotEvent_ProxyInfo =
......
......@@ -23,6 +23,21 @@ string unicode_to_utf8(wchar_t *wstr)
return str;
}
/*
* 将GB2312编码数据转换为GBK编码
*/
wstring gb2312_to_unicode(const char *buffer)
{
int c_size = MultiByteToWideChar(CP_ACP, 0, buffer, -1, 0, 0);
wchar_t *temp = new wchar_t[c_size + 1];
MultiByteToWideChar(CP_ACP, 0, buffer, -1, temp, c_size);
temp[c_size] = L'\0';
wstring ret(temp);
delete[] temp;
temp = NULL;
return ret;
}
BOOL isFileExists_stat(string &name)
{
struct stat buffer;
......
......@@ -50,6 +50,7 @@ DWORD GetWeChatPid();
DWORD StartRobotService(DWORD pid);
DWORD StopRobotService(DWORD pid);
string unicode_to_utf8(wchar_t *wstr);
wstring gb2312_to_unicode(const char *buffer);
BOOL CreateConsole();
wstring GetComWorkPath();
......
......@@ -27,6 +27,8 @@
#include "GetChatRoomMemberNickname.h"
#include "DelChatRoomMember.h"
#include "AddChatRoomMember.h"
#include "OpenBrowser.h"
#include "GetHistoryPublicMsg.h"
#define DLLNAME L"DWeChatRobot.dll"
......@@ -82,3 +84,6 @@
#define UnHookVoiceMsgRemote "UnHookVoiceMsg"
#define ChangeWeChatVerRemote "ChangeWeChatVerRemote"
#define OpenBrowserRemote "OpenBrowserRemote"
#define GetHistoryPublicMsgRemote "GetHistoryPublicMsgRemote"
......@@ -322,8 +322,10 @@ xcopy /y /d "$(OutDir)..\..\Python\http\wxDriver.py" "$(SolutionDir)build\http
<ClInclude Include="GetChatRoomMemberNickname.h" />
<ClInclude Include="GetChatRoomMembers.h" />
<ClInclude Include="GetDbHandles.h" />
<ClInclude Include="GetHistoryPublicMsg.h" />
<ClInclude Include="LogMsgInfo.h" />
<ClInclude Include="http_overload.hpp" />
<ClInclude Include="OpenBrowser.h" />
<ClInclude Include="pch.h" />
<ClInclude Include="ReceiveMessage.h" />
<ClInclude Include="SelfInfo.h" />
......@@ -363,8 +365,10 @@ xcopy /y /d "$(OutDir)..\..\Python\http\wxDriver.py" "$(SolutionDir)build\http
<ClCompile Include="GetChatRoomMemberNickname.cpp" />
<ClCompile Include="GetChatRoomMemebers.cpp" />
<ClCompile Include="GetDbHandles.cpp" />
<ClCompile Include="GetHistoryPublicMsg.cpp" />
<ClCompile Include="HookImageMessage.cpp" />
<ClCompile Include="HookVoiceMessage.cpp" />
<ClCompile Include="OpenBrowser.cpp" />
<ClCompile Include="pch.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='SOCKET_Debug|Win32'">Create</PrecompiledHeader>
......
......@@ -115,6 +115,15 @@
<Filter Include="群相关\获取群成员昵称">
<UniqueIdentifier>{cb62e2bc-3505-49dd-9b35-def28c95ff8c}</UniqueIdentifier>
</Filter>
<Filter Include="浏览器相关">
<UniqueIdentifier>{84e424af-652f-41ff-8899-eca889227424}</UniqueIdentifier>
</Filter>
<Filter Include="浏览器相关\打开浏览器">
<UniqueIdentifier>{e308ad8c-60c5-4043-a30b-ee7acaf47f36}</UniqueIdentifier>
</Filter>
<Filter Include="浏览器相关\获取公众号历史信息">
<UniqueIdentifier>{05d4d999-8961-4c1a-82fb-a36e3a4965f8}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="framework.h">
......@@ -225,6 +234,12 @@
<ClInclude Include="http_overload.hpp">
<Filter>wxsocket</Filter>
</ClInclude>
<ClInclude Include="OpenBrowser.h">
<Filter>浏览器相关\打开浏览器</Filter>
</ClInclude>
<ClInclude Include="GetHistoryPublicMsg.h">
<Filter>浏览器相关\获取公众号历史信息</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="dllmain.cpp">
......@@ -341,5 +356,11 @@
<ClCompile Include="base64\base64.cpp">
<Filter>wxsocket</Filter>
</ClCompile>
<ClCompile Include="OpenBrowser.cpp">
<Filter>浏览器相关\打开浏览器</Filter>
</ClCompile>
<ClCompile Include="GetHistoryPublicMsg.cpp">
<Filter>浏览器相关\获取公众号历史信息</Filter>
</ClCompile>
</ItemGroup>
</Project>
#include "pch.h"
#include <sys/timeb.h>
#define GetHistoryPublicMsgCall1Offset 0x5B3F5CA0 - 0x5B050000
#define GetHistoryPublicMsgCall2Offset 0x65555C80 - 0x650A0000
#define GetHistoryPublicMsgHandleOffset 0x66C78701 - 0x650A0000
#define GetHistoryPublicHookAddrOffset 0x794EFC9E - 0x78ED0000
#define GetHistoryPublicJmpBackAddrOffset 0x794EFD14 - 0x78ED0000
static BOOL H5ExtBufHooked = FALSE;
static char H5ExtBufOldAsmCode[5] = {0};
static DWORD HookAddr = 0;
static DWORD JmpBackAdrr = 0;
static string response = "";
static unsigned long long systemtime()
{
timeb t;
ftime(&t);
return t.time * 1000 + t.millitm;
}
void GetResponseData(DWORD addr1, DWORD addr2)
{
char *buffer = (char *)(*(DWORD *)addr1);
int length = *(int *)(addr1 + 0x10);
if (length != 0)
{
string json_data(buffer, length);
response = json_data;
}
else
{
int err_msg_len = *(int *)(addr2 + 0x10);
char *err_buffer = (err_msg_len <= 0xF) ? (char *)addr2 : (char *)(*(DWORD *)addr2);
string err_msg(err_buffer, err_msg_len);
response = err_msg;
}
#ifndef USE_SOCKET
response = utf8_to_gb2312(response.c_str());
#endif
}
_declspec(naked) void dealH5ExtBuf()
{
__asm {
pushad;
pushfd;
mov ecx,dword ptr ds:[ebp - 0x5C];
sub ecx,0x40;
add ecx,0x1D4;
mov ecx,dword ptr ds:[ecx];
add ecx,0x8;
mov eax,dword ptr ds:[ecx];
add eax,0x8;
mov ecx,dword ptr ds:[eax];
sub eax,0x4;
mov eax,dword ptr ds:[eax];
push eax;
push ecx;
call GetResponseData;
add esp,0x8;
popfd;
popad;
mov edi,dword ptr ds:[ebp - 0x5C];
jmp JmpBackAdrr;
}
}
void HookH5ExtBuf()
{
if (H5ExtBufHooked)
return;
DWORD WeChatWinBase = GetWeChatWinBase();
HookAddr = WeChatWinBase + GetHistoryPublicHookAddrOffset;
JmpBackAdrr = WeChatWinBase + GetHistoryPublicJmpBackAddrOffset;
HookAnyAddress(HookAddr, (LPVOID)dealH5ExtBuf, H5ExtBufOldAsmCode);
H5ExtBufHooked = TRUE;
}
void UnHookH5ExtBuf()
{
if (!H5ExtBufHooked)
return;
UnHookAnyAddress(HookAddr, H5ExtBufOldAsmCode);
H5ExtBufHooked = FALSE;
}
BOOL __stdcall GetHistoryPublicMsg(wchar_t *PublicId, wchar_t *Offset)
{
response = "";
HookH5ExtBuf();
DWORD WeChatWinBase = GetWeChatWinBase();
DWORD GetHistoryPublicMsgCall1 = WeChatWinBase + GetHistoryPublicMsgCall1Offset;
DWORD GetHistoryPublicMsgCall2 = WeChatWinBase + GetHistoryPublicMsgCall2Offset;
DWORD GetHistoryPublicMsgHandle = WeChatWinBase + GetHistoryPublicMsgHandleOffset;
wstring format_str1 = L"weixin://resourceid/Subscription/profile.html?userName=%ws&subscribed=1&from=217&localOpenTime=%llu&wechatVersion=%d";
int version = GetWeChatVerInt();
unsigned long long timestamp = systemtime();
wchar_t buffer[0x400] = {0};
swprintf_s(buffer, format_str1.c_str(), PublicId, timestamp, version);
wstring page_uri(buffer);
wstring cgi_uri = L"/cgi-bin/mmbiz-bin/bizattr/bizprofilev2h5";
ZeroMemory(buffer, 800);
if (Offset != NULL)
{
wstring format_str2 = L"{\"BizUserName\":\"%ws\",\"Offset\":\"%ws\",\"ActionType\":1,\"PageSize\":10,\"BizSessionID\":1662700879,\"Scene\":207,\"PreLoad\":0}";
swprintf_s(buffer, format_str2.c_str(), PublicId, Offset);
}
else
{
wstring format_str2 = L"{\"BizUserName\":\"%ws\",\"ActionType\":0,\"PageSize\":10,\"BizSessionID\":1662700879,\"Scene\":207,\"PreLoad\":0}";
swprintf_s(buffer, format_str2.c_str(), PublicId);
}
wstring json_data(buffer);
int h5ExtType = 0x16B6;
wstring subscriptions = L"subscriptions";
wstring index = L"3_1011_7";
WxString p_page_uri(page_uri);
WxString p_cgi_uri(cgi_uri);
WxString p_json_data(json_data);
WxString p_subscriptions(subscriptions);
WxString p_index(index);
int isSuccess = 0;
__asm {
pushad;
pushfd;
call GetHistoryPublicMsgCall1;
push dword ptr ds:[GetHistoryPublicMsgHandle];
lea ecx,p_subscriptions;
push ecx;
push dword ptr ds:[h5ExtType];
lea ecx,p_json_data;
push ecx;
lea ecx,p_cgi_uri;
push ecx;
lea ecx,p_page_uri;
push ecx;
lea ecx,p_index;
push ecx;
mov ecx,eax;
call GetHistoryPublicMsgCall2;
mov isSuccess,eax;
popfd;
popad;
}
if (!H5ExtBufHooked || isSuccess == 0) return FALSE;
return TRUE;
}
#ifndef USE_SOCKET
struct PublicMsgResponseStruct
{
DWORD buffer = 0;
DWORD length = 0;
} static resp;
DWORD GetHistoryPublicMsgRemote(LPVOID param)
{
GetPublicMsgStruct *gpms = (GetPublicMsgStruct *)param;
BOOL ret = GetHistoryPublicMsg(gpms->PublicId, gpms->Offset);
while (ret && response.length() == 0)
Sleep(200);
resp.buffer = (DWORD)response.c_str();
resp.length = response.length();
return (DWORD)&resp;
}
#else
string __stdcall GetHistoryPublicMsg(wstring PublicId, wstring Offset)
{
wchar_t *pOffset = Offset.length() == 0 ? NULL : (wchar_t *)Offset.c_str();
BOOL ret = GetHistoryPublicMsg((wchar_t *)PublicId.c_str(), pOffset);
while (ret && response.length() == 0)
Sleep(200);
return response;
}
#endif
#pragma once
#include <windows.h>
#include <iostream>
using namespace std;
void HookH5ExtBuf();
void UnHookH5ExtBuf();
BOOL __stdcall GetHistoryPublicMsg(wchar_t *PublicId, wchar_t *Offset);
#ifndef USE_SOCKET
extern "C" __declspec(dllexport) DWORD GetHistoryPublicMsgRemote(LPVOID param);
#else
string __stdcall GetHistoryPublicMsg(wstring PublicId, wstring Offset);
#endif
......@@ -10,10 +10,15 @@ static DWORD HookImageMsgAddr = WeChatWinBase + HookImageMsgAddrOffset;
static DWORD HookImageMsgNextCall = WeChatWinBase + HookImageMsgNextCallOffset;
static DWORD HookImageMsgJmpBackAddr = HookImageMsgAddr + 0x5;
static char ImageMsgOldAsm[5] = {0};
static wstring savepath = L"";
static wstring global_save_path = L"";
void SaveImageMsg(unsigned char *buffer, int length, DWORD msgHandle)
{
wstring save_path = global_save_path + GetSelfWxid();
if (!FindOrCreateDirectory(save_path.c_str()))
{
return;
}
int l_datpath = *(int *)(msgHandle + 0x4) + 1;
wchar_t *datpath = new wchar_t[l_datpath];
memcpy(datpath, (void *)(*(DWORD *)msgHandle), l_datpath * 2);
......@@ -26,7 +31,7 @@ void SaveImageMsg(unsigned char *buffer, int length, DWORD msgHandle)
}
int pos_begin = wdatpath.find_last_of(L"\\") + 1;
int pos_end = wdatpath.find_last_of(L".");
wstring filename = wdatpath.substr(pos_begin, pos_end - pos_begin);
wstring file_name = wdatpath.substr(pos_begin, pos_end - pos_begin);
unsigned char magic_head[4] = {0};
wchar_t postfix[5] = {0};
......@@ -47,8 +52,8 @@ void SaveImageMsg(unsigned char *buffer, int length, DWORD msgHandle)
{
lstrcpy(postfix, L"");
}
wstring filepath = savepath + filename + postfix;
HANDLE hFile = CreateFile(filepath.c_str(), GENERIC_ALL, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
wstring file_path = save_path + L"\\" + file_name + postfix;
HANDLE hFile = CreateFile(file_path.c_str(), GENERIC_ALL, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
return;
......@@ -101,12 +106,12 @@ void UnHookImageMsg()
#ifndef USE_SOCKET
BOOL HookImageMsgRemote(LPVOID lpParameter)
{
savepath = (wstring)(wchar_t *)lpParameter;
if (savepath.back() != '\\')
global_save_path = (wstring)(wchar_t *)lpParameter;
if (global_save_path.back() != '\\')
{
savepath += L"\\";
global_save_path += L"\\";
}
wstring createpath = savepath.substr(0, savepath.length() - 1);
wstring createpath = global_save_path.substr(0, global_save_path.length() - 1);
if (!FindOrCreateDirectory(createpath.c_str()))
{
return false;
......@@ -115,13 +120,14 @@ BOOL HookImageMsgRemote(LPVOID lpParameter)
return true;
}
#else
BOOL __stdcall HookImageMsg(wstring savepath)
BOOL __stdcall HookImageMsg(wstring save_path)
{
if (savepath.back() != '\\')
global_save_path = save_path;
if (global_save_path.back() != '\\')
{
savepath += L"\\";
global_save_path += L"\\";
}
wstring createpath = savepath.substr(0, savepath.length() - 1);
wstring createpath = global_save_path.substr(0, global_save_path.length() - 1);
if (!FindOrCreateDirectory(createpath.c_str()))
{
return false;
......
......@@ -9,14 +9,17 @@ static DWORD HookVoiceMsgAddr = WeChatWinBase + HookVoiceMsgAddrOffset;
static DWORD HookVoiceMsgNextCall = WeChatWinBase + HookVoiceMsgNextCallOffset;
static DWORD HookVoiceMsgJmpBackAddr = HookVoiceMsgAddr + 0x5;
static char VoiceMsgOldAsm[5] = {0};
static wstring savepath = L"";
static wstring global_save_path = L"";
void SaveVoiceMsg(unsigned char *buffer, int length, DWORD msgHandle)
{
/*time_t curtime = time(0);
wchar_t timestamp[32] = { 0 };
_itow_s((int)curtime, timestamp, 10);*/
wstring save_path = global_save_path + GetSelfWxid();
if (!FindOrCreateDirectory(save_path.c_str()))
{
return;
}
wchar_t *temp;
int wxid_length = *(DWORD *)(msgHandle + 0x174);
temp = new wchar_t[wxid_length + 1];
memcpy(temp, (void *)(*(DWORD *)(msgHandle + 0x170)), (wxid_length + 1) * 2);
......@@ -30,8 +33,8 @@ void SaveVoiceMsg(unsigned char *buffer, int length, DWORD msgHandle)
wstring clientmsgid(temp);
delete[] temp;
temp = NULL;
wstring filename = savepath + sender + L"-" + clientmsgid + L".amr";
HANDLE hFile = CreateFile(filename.c_str(), GENERIC_ALL, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
wstring file_path = save_path + L"\\" + clientmsgid + L".amr";
HANDLE hFile = CreateFile(file_path.c_str(), GENERIC_ALL, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
return;
......@@ -81,12 +84,12 @@ void UnHookVoiceMsg()
#ifndef USE_SOCKET
BOOL HookVoiceMsgRemote(LPVOID lpParameter)
{
savepath = (wstring)(wchar_t *)lpParameter;
if (savepath.back() != '\\')
global_save_path = (wstring)(wchar_t *)lpParameter;
if (global_save_path.back() != '\\')
{
savepath += L"\\";
global_save_path += L"\\";
}
wstring createpath = savepath.substr(0, savepath.length() - 1);
wstring createpath = global_save_path.substr(0, global_save_path.length() - 1);
if (!FindOrCreateDirectory(createpath.c_str()))
{
return false;
......@@ -95,13 +98,14 @@ BOOL HookVoiceMsgRemote(LPVOID lpParameter)
return true;
}
#else
BOOL __stdcall HookVoiceMsg(wstring savepath)
BOOL __stdcall HookVoiceMsg(wstring save_path)
{
if (savepath.back() != '\\')
global_save_path = save_path;
if (global_save_path.back() != '\\')
{
savepath += L"\\";
global_save_path += L"\\";
}
wstring createpath = savepath.substr(0, savepath.length() - 1);
wstring createpath = global_save_path.substr(0, global_save_path.length() - 1);
if (!FindOrCreateDirectory(createpath.c_str()))
{
return false;
......
#include "pch.h"
#define OpenBrowserCall1Offset 0x050E1980 - 0x04970000
#define OpenBrowserCall2Offset 0x05699450 - 0x04970000
#define OpenBrowserHandle1Offset 0x05000300 - 0x04970000
#ifndef USE_SOCKET
BOOL OpenBrowserRemote(LPVOID url)
{
return OpenBrowser((wchar_t *)url);
}
#endif
BOOL OpenBrowser(wchar_t *url)
{
WxString p_url(url);
WxString p_null(NULL);
DWORD WeChatWin = GetWeChatWinBase();
DWORD OpenBrowserCall1 = WeChatWin + OpenBrowserCall1Offset;
DWORD OpenBrowserCall2 = WeChatWin + OpenBrowserCall2Offset;
DWORD OpenBrowserHandle1 = WeChatWin + OpenBrowserHandle1Offset;
int isSuccess = 0;
__asm {
pushad;
pushfd;
sub esp,0x14;
mov edi,0x2CA9;
mov ecx,esp;
mov esi,dword ptr[OpenBrowserHandle1];
mov eax,0x1;
lea eax,p_null;
push eax;
call OpenBrowserCall1;
push 0x1;
push 0x1;
push 0x0;
push esi;
push edi;
push 0x15;
lea eax,p_url;
sub esp,0x14;
mov ecx,esp;
push eax;
call OpenBrowserCall1;
mov edx,0x1;
mov cl,0x0;
call OpenBrowserCall2;
mov isSuccess,eax;
add esp,0x40;
popfd;
popad;
}
return isSuccess == 0;
}
#pragma once
#include <windows.h>
BOOL OpenBrowser(wchar_t *url);
#ifndef USE_SOCKET
extern "C" __declspec(dllexport) BOOL OpenBrowserRemote(LPVOID url);
#endif
......@@ -139,6 +139,7 @@ static void dealMessage(DWORD messageAddr)
string extrabuf = base64_encode((BYTE *)(*(DWORD *)(messageAddr + 0x8C)), *(DWORD *)(messageAddr + 0x8C + 0x4));
jMsg["extrainfo"] = extrabuf;
jMsg["time"] = unicode_to_utf8((wchar_t *)GetTimeW(*(DWORD *)(messageAddr + 0x44)).c_str());
jMsg["self"] = unicode_to_utf8((wchar_t *)GetSelfWxid().c_str());
string jstr = jMsg.dump() + '\n';
#ifdef USE_COM
// 通过连接点,将消息广播给客户端
......
......@@ -12,8 +12,8 @@ VOID HookReceiveMessage(int port);
VOID UnHookReceiveMessage();
void UnHookImageMsg();
void UnHookVoiceMsg();
BOOL __stdcall HookVoiceMsg(wstring savepath);
BOOL __stdcall HookImageMsg(wstring savepath);
BOOL __stdcall HookVoiceMsg(wstring save_path);
BOOL __stdcall HookImageMsg(wstring save_path);
#endif
void __stdcall HookVoiceMsg();
......
......@@ -128,4 +128,9 @@ BOOL __stdcall BackupSQLiteDB(DWORD DbHandle, wstring BackupFile)
string filepath = unicode_to_utf8(WS2LW(BackupFile));
return BackupSQLiteDB(DbHandle, filepath.c_str()) == SQLITE_OK;
}
BOOL __stdcall OpenBrowser(wstring url)
{
return OpenBrowser(WS2LW(url));
}
#endif
......@@ -187,6 +187,7 @@ void UnHookAll()
UnHookSearchContact();
UnHookVoiceMsg();
UnHookImageMsg();
UnHookH5ExtBuf();
return;
}
......@@ -263,6 +264,10 @@ void PrintProcAddr()
printf("SetChatRoomAnnouncement 0x%08X\n", (DWORD)SetChatRoomAnnouncement);
printf("SetChatRoomSelfNickname 0x%08X\n", (DWORD)SetChatRoomSelfNickname);
printf("SetChatRoomName 0x%08X\n", (DWORD)SetChatRoomName);
printf("OpenBrowser 0x%08X\n", (DWORD)OpenBrowser);
BOOL(__stdcall * get_history_public_msg)
(wchar_t *, wchar_t *) = GetHistoryPublicMsg;
printf("GetHistoryPublicMsg 0x%08X\n", (DWORD)get_history_public_msg);
}
BOOL ProcessIsWeChat()
......
......@@ -28,6 +28,8 @@
#include "SetChatRoomSelfNickname.h"
#include "SetChatRoomName.h"
#include "GetChatRoomMemberNickname.h"
#include "OpenBrowser.h"
#include "GetHistoryPublicMsg.h"
using namespace std;
#pragma comment(lib, "version.lib")
......
......@@ -22,7 +22,7 @@ struct WxString
{
WxString(NULL);
}
WxString(wstring str)
WxString(wstring &str)
{
buffer = (wchar_t *)str.c_str();
length = str.length();
......@@ -167,3 +167,9 @@ struct WxFriendStruct
this->wxRemarkAddr = wxRemarkAddr;
}
};
struct GetPublicMsgStruct
{
wchar_t *PublicId;
wchar_t *Offset;
};
......@@ -516,6 +516,21 @@ void request_event(mg_http_message *hm, string &ret)
UnHookLogMsgInfo();
break;
}
case WECHAT_BROWSER_OPEN_WITH_URL:
{
wstring url = get_http_param_str(hm, jData, "url", method);
OpenBrowser(url);
break;
}
case WECHAT_GET_PUBLIC_MSG:
{
wstring public_id = get_http_param_str(hm, jData, "public_id", method);
wstring offset = get_http_param_str(hm, jData, "offset", method);
string resp = GetHistoryPublicMsg(public_id, offset);
json ret_data = {{"msg", resp}, {"result", "OK"}};
ret = ret_data.dump();
break;
}
default:
// char* wxid = mg_json_get_str(hm->body, "$.wxid");
break;
......
......@@ -67,6 +67,9 @@ typedef enum WECHAT_HTTP_APISTag
// log
WECHAT_LOG_START_HOOK,
WECHAT_LOG_STOP_HOOK,
// browser
WECHAT_BROWSER_OPEN_WITH_URL,
WECHAT_GET_PUBLIC_MSG,
} WECHAT_HTTP_APIS,
*PWECHAT_HTTP_APIS;
#endif
......@@ -965,7 +965,7 @@ class WeChatRobot:
"""
return self.robot.CGetChatRoomMemberNickname(self.pid, chatroom_id, wxid)
def DelChatRoomMember(self, chatroom_id: str, wxid_list: str or list or tuple) -> str:
def DelChatRoomMember(self, chatroom_id: str, wxid_list: str or list or tuple) -> int:
"""
删除群成员.请确认具有相关权限再调用。
......@@ -984,7 +984,7 @@ class WeChatRobot:
"""
return self.robot.CDelChatRoomMember(self.pid, chatroom_id, wxid_list)
def AddChatRoomMember(self, chatroom_id: str, wxid_list: str or list or tuple) -> str:
def AddChatRoomMember(self, chatroom_id: str, wxid_list: str or list or tuple) -> int:
"""
添加群成员.请确认具有相关权限再调用。
......@@ -1003,6 +1003,47 @@ class WeChatRobot:
"""
return self.robot.CAddChatRoomMember(self.pid, chatroom_id, wxid_list)
def OpenBrowser(self,url: str) -> int:
"""
打开微信内置浏览器
Parameters
----------
url : str
目标网页url.
Returns
-------
int
成功返回0,失败返回非0值.
"""
return self.robot.COpenBrowser(self.pid,url)
def GetHistoryPublicMsg(self,public_id:str,offset:str = "") -> str:
"""
获取公众号历史消息,一次获取十条推送记录
Parameters
----------
public_id : str
公众号id.
offset : str, optional
起始偏移,为空的话则从新到久获取十条,该值可从返回数据中取得. The default is "".
Returns
-------
str
成功返回json数据,失败返回错误信息或空字符串.
"""
ret = self.robot.CGetHistoryPublicMsg(self.pid,public_id,offset)[0]
try:
ret = json.loads(ret)
except json.JSONDecodeError:
pass
return ret
def get_wechat_pid_list() -> list:
"""
......
......@@ -80,6 +80,10 @@ class WECHAT_HTTP_APIS:
WECHAT_LOG_START_HOOK = 36 # 开启日志信息HOOK
WECHAT_LOG_STOP_HOOK = 37 # 关闭日志信息HOOK
# browser
WECHAT_BROWSER_OPEN_WITH_URL = 38 # 打开微信内置浏览器
WECHAT_GET_PUBLIC_MSG = 39 # 获取公众号历史消息
APIS = WECHAT_HTTP_APIS
# http api 参数模板
......@@ -177,6 +181,10 @@ class WECHAT_HTTP_API_PARAM_TEMPLATES:
# log
APIS.WECHAT_LOG_START_HOOK: {},
APIS.WECHAT_LOG_STOP_HOOK: {},
# browser
APIS.WECHAT_BROWSER_OPEN_WITH_URL: {"url": "https://www.baidu.com/"},
APIS.WECHAT_GET_PUBLIC_MSG: {"public_id": "","offset": ""}
}
def get_http_template(self, api_number):
......@@ -259,7 +267,7 @@ def start_socket_server(port: int = 10808,
print(e)
return None
def test(test_port):
def test_send_msg(test_port):
post_wechat_http_api(APIS.WECHAT_LOG_START_HOOK,port = test_port)
if post_wechat_http_api(APIS.WECHAT_IS_LOGIN,port = test_port)["is_login"] == 1:
print(post_wechat_http_api(APIS.WECHAT_GET_SELF_INFO,port = test_port))
......@@ -282,18 +290,39 @@ def test(test_port):
"url":"https://www.baidu.com/",
"img_path":""}
post_wechat_http_api(APIS.WECHAT_MSG_SEND_ARTICLE,data = data,port = test_port)
print(post_wechat_http_api(APIS.WECHAT_CONTACT_GET_LIST,port = test_port))
data = {"wxid":"filehelper"}
print(post_wechat_http_api(APIS.WECHAT_CONTACT_CHECK_STATUS,data = data,port = test_port))
dbs = post_wechat_http_api(APIS.WECHAT_DATABASE_GET_HANDLES,port = test_port)
db_handle = dbs['data'][0]['handle']
sql = "select * from Contact limit 1;"
data = {"db_handle":db_handle,"sql":sql}
res = post_wechat_http_api(APIS.WECHAT_DATABASE_QUERY,data = data,port = test_port)
print(res)
post_wechat_http_api(APIS.WECHAT_LOG_STOP_HOOK,port = test_port)
def test_get_public_msg(test_port,public_id):
import time
param = {"public_id": public_id,"offset": ""}
data = post_wechat_http_api(APIS.WECHAT_GET_PUBLIC_MSG,test_port,param)
msg_list = json.loads(data['msg'])['MsgList']
next_offset = msg_list['PagingInfo']['Offset']
for msg in msg_list['Msg']:
detail_info = msg['AppMsg']['DetailInfo']
for info in detail_info:
Title = info['Title']
Digest = info['Digest']
ContentUrl = info['ContentUrl']
post_wechat_http_api(APIS.WECHAT_BROWSER_OPEN_WITH_URL,
test_port,
{"url":ContentUrl}
)
time.sleep(3)
break
break
def test_get_chatroom_list_from_db(test_port):
dbs = post_wechat_http_api(APIS.WECHAT_DATABASE_GET_HANDLES,port = test_port)
db_handle = [i for i in dbs['data'] if i['db_name'] == 'MicroMsg.db'][0]['handle']
sql = "select UserName,Alias,EncryptUserName,Type,VerifyFlag,Remark,NickName,ChatRoomType,ExtraBuf from Contact where Type=2;"
data = {"db_handle":db_handle,"sql":sql}
res = post_wechat_http_api(APIS.WECHAT_DATABASE_QUERY,data = data,port = test_port)
return res['data']
if __name__ == '__main__':
port = 8000
pids = get_wechat_pid_list()
......
......@@ -126,6 +126,12 @@ CWeChatRobot.exe /unregserver
## 2022.08.25
1. 接收消息格式修改为json,现在也可以获取到扩展信息,可从扩展信息中获取到文件保存路径或被艾特人wxid
2. 优化获取个人信息,获取好友信息接口
## 2022.09.09
1. 新增打开微信内置浏览器的功能
2. 新增获取公众号历史消息功能(具体能获取多少未测试,请谨慎使用,以防封号)
3. 修复了一个bug,该bug会导致图片和语音保存到微信安装目录而非指定的目录
4. 优化实时消息接口,现在会带上自己的wxid
5. 优化图片和语音保存路径,方便区分来自不同账号的消息
# 打赏作者
请给作者一个star,感谢感谢
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册