Impl SendXmlMessage
This commit is contained in:
parent
902d7caa76
commit
2af5ad0253
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
import logging
|
import logging
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
|
from time import sleep
|
||||||
|
|
||||||
from wcferry import Wcf
|
from wcferry import Wcf
|
||||||
|
|
||||||
@ -26,6 +27,7 @@ def main():
|
|||||||
wcf = Wcf(debug=True) # 默认连接本地服务
|
wcf = Wcf(debug=True) # 默认连接本地服务
|
||||||
# wcf = Wcf("tcp://127.0.0.1:10086") # 连接远端服务
|
# wcf = Wcf("tcp://127.0.0.1:10086") # 连接远端服务
|
||||||
|
|
||||||
|
sleep(5) # 等微信加载好,以免信息显示异常
|
||||||
LOG.info(f"已经登录: {True if wcf.is_login() else False}")
|
LOG.info(f"已经登录: {True if wcf.is_login() else False}")
|
||||||
LOG.info(f"wxid: {wcf.get_self_wxid()}")
|
LOG.info(f"wxid: {wcf.get_self_wxid()}")
|
||||||
|
|
||||||
@ -58,6 +60,10 @@ def main():
|
|||||||
# ret = wcf.add_chatroom_members("chatroom id", "wxid1,wxid2,wxid3,...")
|
# ret = wcf.add_chatroom_members("chatroom id", "wxid1,wxid2,wxid3,...")
|
||||||
# LOG.info(f"add_chatroom_members: {ret}")
|
# LOG.info(f"add_chatroom_members: {ret}")
|
||||||
|
|
||||||
|
xml = '<?xml version="1.0"?><msg><appmsg appid="" sdkver="0"><title>叮当药房,24小时服务,28分钟送药到家!</title><des>叮当快药首家承诺范围内28分钟送药到家!叮当快药核心区域内7*24小时全天候服务,送药上门!叮当快药官网为您提供快捷便利,正品低价,安全放心的购药、送药服务体验。</des><action>view</action><type>33</type><showtype>0</showtype><content /><url>https://mp.weixin.qq.com/mp/waerrpage?appid=wxc2edadc87077fa2a&type=upgrade&upgradetype=3#wechat_redirect</url><dataurl /><lowurl /><lowdataurl /><recorditem /><thumburl /><messageaction /><md5>7f6f49d301ebf47100199b8a4fcf4de4</md5><extinfo /><sourceusername>gh_c2b88a38c424@app</sourceusername><sourcedisplayname>叮当快药 药店送药到家夜间买药</sourcedisplayname><commenturl /><appattach><totallen>0</totallen><attachid /><emoticonmd5></emoticonmd5><fileext>jpg</fileext><filekey>da0e08f5c7259d03da150d5e7ca6d950</filekey><cdnthumburl>3057020100044b30490201000204e4c0232702032f4ef20204a6bace6f02046401f62d042430326337303430352d333734332d343362652d623335322d6233333566623266376334620204012400030201000405004c537600</cdnthumburl><aeskey>0db26456caf243fbd4efb99058a01d66</aeskey><cdnthumbaeskey>0db26456caf243fbd4efb99058a01d66</cdnthumbaeskey><encryver>1</encryver><cdnthumblength>61558</cdnthumblength><cdnthumbheight>100</cdnthumbheight><cdnthumbwidth>100</cdnthumbwidth></appattach><weappinfo><pagepath>pages/index/index.html</pagepath><username>gh_c2b88a38c424@app</username><appid>wxc2edadc87077fa2a</appid><version>197</version><type>2</type><weappiconurl>http://wx.qlogo.cn/mmhead/Q3auHgzwzM4727n0NQ0ZIPQPlfp15m1WLsnrXbo1kLhFGcolgLyc0A/96</weappiconurl><appservicetype>0</appservicetype><shareId>1_wxc2edadc87077fa2a_29177e9a9b918cb9e75964f80bb8f32e_1677849476_0</shareId></weappinfo><websearch /></appmsg><fromusername>wxid_eob5qfcrv4zd22</fromusername><scene>0</scene><appinfo><version>1</version><appname /></appinfo><commenturl /></msg>'
|
||||||
|
ret = wcf.send_xml("filehelper", xml, 0x21)
|
||||||
|
LOG.info(f"send_xml: {ret}")
|
||||||
|
|
||||||
# 一直运行
|
# 一直运行
|
||||||
wcf.keep_running()
|
wcf.keep_running()
|
||||||
|
|
||||||
|
@ -227,6 +227,18 @@ class Wcf():
|
|||||||
rsp = self._send_request(req)
|
rsp = self._send_request(req)
|
||||||
return rsp.status
|
return rsp.status
|
||||||
|
|
||||||
|
def send_xml(self, receiver: str, xml: str, type: int, path: str = None) -> int:
|
||||||
|
"""发送文件"""
|
||||||
|
req = wcf_pb2.Request()
|
||||||
|
req.func = wcf_pb2.FUNC_SEND_XML # FUNC_SEND_XML
|
||||||
|
req.xml.receiver = receiver
|
||||||
|
req.xml.content = xml
|
||||||
|
req.xml.type = type
|
||||||
|
if path:
|
||||||
|
req.xml.path = path
|
||||||
|
rsp = self._send_request(req)
|
||||||
|
return rsp.status
|
||||||
|
|
||||||
def get_msg(self, block=True) -> WxMsg:
|
def get_msg(self, block=True) -> WxMsg:
|
||||||
return self.msgQ.get(block, timeout=1)
|
return self.msgQ.get(block, timeout=1)
|
||||||
|
|
||||||
@ -351,8 +363,8 @@ class Wcf():
|
|||||||
friends = []
|
friends = []
|
||||||
for cnt in self.get_contacts():
|
for cnt in self.get_contacts():
|
||||||
if (cnt.wxid.endswith("@chatroom") # 群聊
|
if (cnt.wxid.endswith("@chatroom") # 群聊
|
||||||
or cnt.wxid.startswith("gh_") # 公众号
|
or cnt.wxid.startswith("gh_") # 公众号
|
||||||
or cnt.wxid in not_friends.keys() # 其他杂号
|
or cnt.wxid in not_friends.keys() # 其他杂号
|
||||||
):
|
):
|
||||||
continue
|
continue
|
||||||
friends.append(cnt)
|
friends.append(cnt)
|
||||||
|
@ -31,6 +31,7 @@ enum Functions {
|
|||||||
FUNC_SEND_TXT = 0x20;
|
FUNC_SEND_TXT = 0x20;
|
||||||
FUNC_SEND_IMG = 0x21;
|
FUNC_SEND_IMG = 0x21;
|
||||||
FUNC_SEND_FILE = 0x22;
|
FUNC_SEND_FILE = 0x22;
|
||||||
|
FUNC_SEND_XML = 0x23;
|
||||||
FUNC_ENABLE_RECV_TXT = 0x30;
|
FUNC_ENABLE_RECV_TXT = 0x30;
|
||||||
FUNC_DISABLE_RECV_TXT = 0x40;
|
FUNC_DISABLE_RECV_TXT = 0x40;
|
||||||
FUNC_EXEC_DB_QUERY = 0x50;
|
FUNC_EXEC_DB_QUERY = 0x50;
|
||||||
@ -50,6 +51,7 @@ message Request
|
|||||||
DbQuery query = 6;
|
DbQuery query = 6;
|
||||||
Verification v = 7;
|
Verification v = 7;
|
||||||
AddMembers m = 8;
|
AddMembers m = 8;
|
||||||
|
XmlMsg xml = 9;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,6 +98,14 @@ message PathMsg
|
|||||||
string receiver = 2; // 消息接收人
|
string receiver = 2; // 消息接收人
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message XmlMsg
|
||||||
|
{
|
||||||
|
string receiver = 1; // 消息接收人
|
||||||
|
string content = 2; // xml 内容
|
||||||
|
string path = 3; // 图片路径
|
||||||
|
int32 type = 4; // 消息类型
|
||||||
|
}
|
||||||
|
|
||||||
message MsgTypes { map<int32, string> types = 1; }
|
message MsgTypes { map<int32, string> types = 1; }
|
||||||
|
|
||||||
message RpcContact
|
message RpcContact
|
||||||
|
@ -11,8 +11,9 @@ WxCalls_t wxCalls = {
|
|||||||
/* Receive Message:
|
/* Receive Message:
|
||||||
Hook, call, type, self, id, msgXml, roomId, wxId, content */
|
Hook, call, type, self, id, msgXml, roomId, wxId, content */
|
||||||
{ 0x550F4C, 0xA96350, 0x38, 0x3C, 0x184, 0x1EC, 0x48, 0x170, 0x70 },
|
{ 0x550F4C, 0xA96350, 0x38, 0x3C, 0x184, 0x1EC, 0x48, 0x170, 0x70 },
|
||||||
{ 0xBD780, 0x771980, 0x521640 }, // Send Image Message
|
{ 0xBD780, 0x771980, 0x521640 }, // Send Image Message
|
||||||
{ 0xC3B70, 0x771980, 0x3ED8C0 }, // Send File Message
|
{ 0xC3B70, 0x771980, 0x3ED8C0 }, // Send File Message
|
||||||
|
{ 0xB8A70, 0x3ED5E0, 0x107F00, 0x3ED7B0, 0x2386FE4 }, // Send xml message
|
||||||
/* Get Contacts:
|
/* Get Contacts:
|
||||||
Base, head, wxId, Code, Name, Gender, Country, Province, City*/
|
Base, head, wxId, Code, Name, Gender, Country, Province, City*/
|
||||||
{ 0x23668F4, 0x4C, 0x30, 0x44, 0x8C, 0x184, 0x1D0, 0x1E4, 0x1F8 },
|
{ 0x23668F4, 0x4C, 0x30, 0x44, 0x8C, 0x184, 0x1D0, 0x1E4, 0x1F8 },
|
||||||
|
@ -234,6 +234,33 @@ bool func_send_file(char *path, char *receiver, uint8_t *out, size_t *len)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool func_send_xml(XmlMsg xml, uint8_t *out, size_t *len)
|
||||||
|
{
|
||||||
|
Response rsp = Response_init_default;
|
||||||
|
rsp.func = Functions_FUNC_SEND_XML;
|
||||||
|
rsp.which_msg = Response_status_tag;
|
||||||
|
rsp.msg.status = 0;
|
||||||
|
|
||||||
|
if ((xml.content == NULL) || (xml.receiver == NULL)) {
|
||||||
|
rsp.msg.status = -1;
|
||||||
|
} else {
|
||||||
|
string receiver(xml.receiver);
|
||||||
|
string content(xml.content);
|
||||||
|
string path(xml.path ? xml.path : "");
|
||||||
|
uint32_t type = (uint32_t)xml.type;
|
||||||
|
SendXmlMessage(receiver, content, path, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
pb_ostream_t stream = pb_ostream_from_buffer(out, *len);
|
||||||
|
if (!pb_encode(&stream, Response_fields, &rsp)) {
|
||||||
|
LOG_ERROR("Encoding failed: {}", PB_GET_ERROR(&stream));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*len = stream.bytes_written;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static void PushMessage()
|
static void PushMessage()
|
||||||
{
|
{
|
||||||
static nng_socket msg_sock;
|
static nng_socket msg_sock;
|
||||||
@ -417,7 +444,7 @@ static bool dispatcher(uint8_t *in, size_t in_len, uint8_t *out, size_t *out_len
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_DEBUG("Func: {}", (uint8_t)req.func);
|
LOG_DEBUG("Func: {:#x} Data: {}", (uint8_t)req.func, in_len);
|
||||||
switch (req.func) {
|
switch (req.func) {
|
||||||
case Functions_FUNC_IS_LOGIN: {
|
case Functions_FUNC_IS_LOGIN: {
|
||||||
LOG_DEBUG("[Functions_FUNC_IS_LOGIN]");
|
LOG_DEBUG("[Functions_FUNC_IS_LOGIN]");
|
||||||
@ -464,6 +491,11 @@ static bool dispatcher(uint8_t *in, size_t in_len, uint8_t *out, size_t *out_len
|
|||||||
ret = func_send_file(req.msg.file.path, req.msg.file.receiver, out, out_len);
|
ret = func_send_file(req.msg.file.path, req.msg.file.receiver, out, out_len);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case Functions_FUNC_SEND_XML: {
|
||||||
|
LOG_DEBUG("[Functions_FUNC_SEND_XML]");
|
||||||
|
ret = func_send_xml(req.msg.xml, out, out_len);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case Functions_FUNC_ENABLE_RECV_TXT: {
|
case Functions_FUNC_ENABLE_RECV_TXT: {
|
||||||
LOG_DEBUG("[Functions_FUNC_ENABLE_RECV_TXT]");
|
LOG_DEBUG("[Functions_FUNC_ENABLE_RECV_TXT]");
|
||||||
ret = func_enable_recv_txt(out, out_len);
|
ret = func_enable_recv_txt(out, out_len);
|
||||||
@ -527,7 +559,7 @@ static int RunServer()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_BUFFER(in, in_len);
|
// LOG_BUFFER(in, in_len);
|
||||||
if (dispatcher(in, in_len, gBuffer, &out_len)) {
|
if (dispatcher(in, in_len, gBuffer, &out_len)) {
|
||||||
LOG_DEBUG("Send data length {}", out_len);
|
LOG_DEBUG("Send data length {}", out_len);
|
||||||
// LOG_BUFFER(gBuffer, out_len);
|
// LOG_BUFFER(gBuffer, out_len);
|
||||||
|
100
spy/send_msg.cpp
100
spy/send_msg.cpp
@ -9,12 +9,13 @@
|
|||||||
extern HANDLE g_hEvent;
|
extern HANDLE g_hEvent;
|
||||||
extern WxCalls_t g_WxCalls;
|
extern WxCalls_t g_WxCalls;
|
||||||
extern DWORD g_WeChatWinDllAddr;
|
extern DWORD g_WeChatWinDllAddr;
|
||||||
|
extern string GetSelfWxid(); // Defined in spy.cpp
|
||||||
|
|
||||||
void SendTextMessage(string wxid, string msg, string atWxids)
|
void SendTextMessage(string wxid, string msg, string atWxids)
|
||||||
{
|
{
|
||||||
char buffer[0x3B0] = { 0 };
|
char buffer[0x3B0] = { 0 };
|
||||||
WxString_t txtMsg = { 0 };
|
WxString_t wxMsg = { 0 };
|
||||||
WxString_t txtWxid = { 0 };
|
WxString_t wxWxid = { 0 };
|
||||||
|
|
||||||
// 发送消息Call地址 = 微信基址 + 偏移
|
// 发送消息Call地址 = 微信基址 + 偏移
|
||||||
DWORD sendCallAddress = g_WeChatWinDllAddr + g_WxCalls.sendTextMsg;
|
DWORD sendCallAddress = g_WeChatWinDllAddr + g_WxCalls.sendTextMsg;
|
||||||
@ -22,13 +23,13 @@ void SendTextMessage(string wxid, string msg, string atWxids)
|
|||||||
wstring wsWxid = String2Wstring(wxid);
|
wstring wsWxid = String2Wstring(wxid);
|
||||||
wstring wsMsg = String2Wstring(msg);
|
wstring wsMsg = String2Wstring(msg);
|
||||||
|
|
||||||
txtMsg.text = (wchar_t *)wsMsg.c_str();
|
wxMsg.text = (wchar_t *)wsMsg.c_str();
|
||||||
txtMsg.size = wsMsg.size();
|
wxMsg.size = wsMsg.size();
|
||||||
txtMsg.capacity = wsMsg.capacity();
|
wxMsg.capacity = wsMsg.capacity();
|
||||||
|
|
||||||
txtWxid.text = (wchar_t *)wsWxid.c_str();
|
wxWxid.text = (wchar_t *)wsWxid.c_str();
|
||||||
txtWxid.size = wsWxid.size();
|
wxWxid.size = wsWxid.size();
|
||||||
txtWxid.capacity = wsWxid.capacity();
|
wxWxid.capacity = wsWxid.capacity();
|
||||||
|
|
||||||
vector<WxString_t> vTxtAtWxids;
|
vector<WxString_t> vTxtAtWxids;
|
||||||
if (!atWxids.empty()) {
|
if (!atWxids.empty()) {
|
||||||
@ -51,9 +52,9 @@ void SendTextMessage(string wxid, string msg, string atWxids)
|
|||||||
lea eax, vTxtAtWxids;
|
lea eax, vTxtAtWxids;
|
||||||
push 0x01;
|
push 0x01;
|
||||||
push eax;
|
push eax;
|
||||||
lea edi, txtMsg;
|
lea edi, wxMsg;
|
||||||
push edi;
|
push edi;
|
||||||
lea edx, txtWxid;
|
lea edx, wxWxid;
|
||||||
lea ecx, buffer;
|
lea ecx, buffer;
|
||||||
call sendCallAddress;
|
call sendCallAddress;
|
||||||
add esp, 0xC;
|
add esp, 0xC;
|
||||||
@ -173,3 +174,82 @@ void SendFileMessage(string wxid, string path)
|
|||||||
popad;
|
popad;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SendXmlMessage(string receiver, string xml, string path, int type)
|
||||||
|
{
|
||||||
|
if (g_WeChatWinDllAddr == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 发送消息Call地址 = 微信基址 + 偏移
|
||||||
|
DWORD sendXmlCall1 = g_WeChatWinDllAddr + g_WxCalls.sendXml.call1;
|
||||||
|
DWORD sendXmlCall2 = g_WeChatWinDllAddr + g_WxCalls.sendXml.call2;
|
||||||
|
DWORD sendXmlCall3 = g_WeChatWinDllAddr + g_WxCalls.sendXml.call3;
|
||||||
|
DWORD sendXmlCall4 = g_WeChatWinDllAddr + g_WxCalls.sendXml.call4;
|
||||||
|
DWORD sendXmlParam = g_WeChatWinDllAddr + g_WxCalls.sendXml.param;
|
||||||
|
|
||||||
|
char buffer[0xFF0] = { 0 };
|
||||||
|
char nullBuf[0x1C] = { 0 };
|
||||||
|
WxString_t wxReceiver = { 0 };
|
||||||
|
WxString_t wxXml = { 0 };
|
||||||
|
WxString_t wxPath = { 0 };
|
||||||
|
WxString_t wxNull = { 0 };
|
||||||
|
WxString_t wxSender = { 0 };
|
||||||
|
|
||||||
|
wstring wsSender = String2Wstring(GetSelfWxid());
|
||||||
|
wstring wsReceiver = String2Wstring(receiver);
|
||||||
|
wstring wsXml = String2Wstring(xml);
|
||||||
|
|
||||||
|
wxReceiver.text = (wchar_t *)wsReceiver.c_str();
|
||||||
|
wxReceiver.size = wsReceiver.size();
|
||||||
|
wxReceiver.capacity = wsReceiver.capacity();
|
||||||
|
|
||||||
|
wxXml.text = (wchar_t *)wsXml.c_str();
|
||||||
|
wxXml.size = wsXml.size();
|
||||||
|
wxXml.capacity = wsXml.capacity();
|
||||||
|
|
||||||
|
wxSender.text = (wchar_t *)wsSender.c_str();
|
||||||
|
wxSender.size = wsSender.size();
|
||||||
|
wxSender.capacity = wsSender.capacity();
|
||||||
|
|
||||||
|
if (!path.empty()) {
|
||||||
|
wstring wsPath = String2Wstring(path);
|
||||||
|
wxPath.text = (wchar_t *)wsPath.c_str();
|
||||||
|
wxPath.size = wsPath.size();
|
||||||
|
wxPath.capacity = wsPath.capacity();
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD sendtype = type;
|
||||||
|
__asm {
|
||||||
|
pushad;
|
||||||
|
pushfd;
|
||||||
|
lea ecx, buffer;
|
||||||
|
call sendXmlCall1;
|
||||||
|
mov eax, [sendtype];
|
||||||
|
push eax;
|
||||||
|
lea eax, nullBuf;
|
||||||
|
lea edx, wxSender;
|
||||||
|
push eax;
|
||||||
|
lea eax, wxPath;
|
||||||
|
push eax;
|
||||||
|
lea eax, wxXml;
|
||||||
|
push eax;
|
||||||
|
lea edi, wxReceiver;
|
||||||
|
push edi;
|
||||||
|
lea ecx, buffer;
|
||||||
|
call sendXmlCall2;
|
||||||
|
add esp, 0x14;
|
||||||
|
lea eax, wxNull;
|
||||||
|
push eax;
|
||||||
|
lea ecx, buffer;
|
||||||
|
call sendXmlCall3;
|
||||||
|
mov dl, 0x0;
|
||||||
|
lea ecx, buffer;
|
||||||
|
push sendXmlParam;
|
||||||
|
push sendXmlParam;
|
||||||
|
call sendXmlCall4;
|
||||||
|
add esp, 0x8;
|
||||||
|
popfd;
|
||||||
|
popad;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -7,3 +7,4 @@ using namespace std;
|
|||||||
void SendTextMessage(string wxid, string msg, string atWxids);
|
void SendTextMessage(string wxid, string msg, string atWxids);
|
||||||
void SendImageMessage(string wxid, string path);
|
void SendImageMessage(string wxid, string path);
|
||||||
void SendFileMessage(string wxid, string path);
|
void SendFileMessage(string wxid, string path);
|
||||||
|
void SendXmlMessage(string receiver, string xml, string path, int type);
|
||||||
|
@ -59,6 +59,14 @@ typedef struct RoomMember {
|
|||||||
DWORD call3;
|
DWORD call3;
|
||||||
} RoomMember_t;
|
} RoomMember_t;
|
||||||
|
|
||||||
|
typedef struct Xml {
|
||||||
|
DWORD call1;
|
||||||
|
DWORD call2;
|
||||||
|
DWORD call3;
|
||||||
|
DWORD call4;
|
||||||
|
DWORD param;
|
||||||
|
} Xml_t;
|
||||||
|
|
||||||
typedef struct WxCalls {
|
typedef struct WxCalls {
|
||||||
DWORD login; // 登录状态
|
DWORD login; // 登录状态
|
||||||
UserInfoCall_t ui; // 用户信息
|
UserInfoCall_t ui; // 用户信息
|
||||||
@ -66,6 +74,7 @@ typedef struct WxCalls {
|
|||||||
RecvMsg_t recvMsg; // 接收消息
|
RecvMsg_t recvMsg; // 接收消息
|
||||||
Sendfile_t sendImg; // 发送图片
|
Sendfile_t sendImg; // 发送图片
|
||||||
Sendfile_t sendFile; // 发送文件
|
Sendfile_t sendFile; // 发送文件
|
||||||
|
Xml_t sendXml; // 发送XML
|
||||||
Contact_t contact; // 获取联系人
|
Contact_t contact; // 获取联系人
|
||||||
Sql_t sql; // 执行 SQL
|
Sql_t sql; // 执行 SQL
|
||||||
NewFriend_t anf; // 通过好友申请
|
NewFriend_t anf; // 通过好友申请
|
||||||
|
Loading…
Reference in New Issue
Block a user