Skip to content

Commit

Permalink
Impl forward message
Browse files Browse the repository at this point in the history
  • Loading branch information
lich0821 committed Dec 17, 2023
1 parent 8044862 commit 2ae40a2
Show file tree
Hide file tree
Showing 10 changed files with 169 additions and 61 deletions.
8 changes: 8 additions & 0 deletions WeChatFerry/rpc/proto/wcf.proto
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ enum Functions {
FUNC_SEND_EMOTION = 0x24;
FUNC_SEND_RICH_TXT = 0x25;
FUNC_SEND_PAT_MSG = 0x26;
FUNC_FORWARD_MSG = 0x27;
FUNC_ENABLE_RECV_TXT = 0x30;
FUNC_DISABLE_RECV_TXT = 0x40;
FUNC_EXEC_DB_QUERY = 0x50;
Expand Down Expand Up @@ -57,6 +58,7 @@ message Request
AudioMsg am = 15;
RichText rt = 16;
PatMsg pm = 17;
ForwardMsg fm = 18;
}
}

Expand Down Expand Up @@ -225,3 +227,9 @@ message OcrMsg
int32 status = 1; // 状态
string result = 2; // 结果
}

message ForwardMsg
{
uint64 id = 1; // 待转发消息 ID
string receiver = 2; // 转发接收目标,群为 roomId,个人为 wxid
}
4 changes: 3 additions & 1 deletion WeChatFerry/spy/load_calls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ WxCalls_t wxCalls = {
/* call1, call2, call3, call4, call5, call6, call7, call8*/
{0x78CB40, 0x7F99D0, 0x78CF20, 0x78CEF0, 0xF59E40, 0xBD1A00, 0x7FA980, 0x755060},
/* call1, call2, call3 */
{0x80A800, 0x80F270, 0x13DA3E0}
{0x80A800, 0x80F270, 0x13DA3E0},
/* call1, call2 */
{0xF59E40, 0xCE6730}
};

int LoadCalls(const wchar_t *version, WxCalls_t *calls)
Expand Down
27 changes: 27 additions & 0 deletions WeChatFerry/spy/rpc_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,29 @@ bool func_send_pat_msg(char *roomid, char *wxid, uint8_t *out, size_t *len)
return true;
}

bool func_forward_msg(uint64_t id, char *receiver, uint8_t *out, size_t *len)
{
Response rsp = Response_init_default;
rsp.func = Functions_FUNC_FORWARD_MSG;
rsp.which_msg = Response_status_tag;

if (receiver == NULL) {
LOG_ERROR("Empty roomid or wxid.");
rsp.msg.status = -1;
} else {
rsp.msg.status = ForwardMessage(id, receiver);
}

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 nng_socket msg_sock;
Expand Down Expand Up @@ -850,6 +873,10 @@ 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);
break;
}
case Functions_FUNC_FORWARD_MSG: {
ret = func_forward_msg(req.msg.fm.id, req.msg.fm.receiver, out, out_len);
break;
}
#if 0
case Functions_FUNC_SEND_XML: {
ret = func_send_xml(req.msg.xml, out, out_len);
Expand Down
43 changes: 43 additions & 0 deletions WeChatFerry/spy/send_msg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
#include <sstream>
#include <vector>

#include "exec_sql.h"
#include "log.h"
#include "send_msg.h"
#include "spy_types.h"
#include "util.h"
Expand Down Expand Up @@ -395,3 +397,44 @@ int SendPatMessage(string roomid, string wxid)

return status;
}

int ForwardMessage(uint64_t msgid, string receiver)
{
int status = -1;
uint32_t dbIdx = 0;
uint64_t localId = 0;

if (GetLocalIdandDbidx(msgid, &localId, &dbIdx) != 0) {
LOG_ERROR("Failed to get localId, Please check id: {}", to_string(msgid));
return status;
}

wstring wsReceiver = String2Wstring(receiver);
WxString wxReceiver(wsReceiver);

DWORD fmCall1 = g_WeChatWinDllAddr + g_WxCalls.fm.call1;
DWORD fmCall2 = g_WeChatWinDllAddr + g_WxCalls.fm.call2;

__asm {
pushad;
pushfd;
mov edx, dword ptr [dbIdx];
push edx;
mov eax, dword ptr [localId];
push eax;
sub esp, 0x14;
mov ecx, esp;
lea esi, wxReceiver;
push esi;
call fmCall1;
xor ecx, ecx;
call fmCall2;
movzx eax, al;
mov status, eax;
add esp, 0x1c;
popfd;
popad;
}

return status;
}
1 change: 1 addition & 0 deletions WeChatFerry/spy/send_msg.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ void SendXmlMessage(string receiver, string xml, string path, int type);
void SendEmotionMessage(string wxid, string path);
int SendRichTextMessage(RichText_t &rt);
int SendPatMessage(string roomid, string wxid);
int ForwardMessage(uint64_t msgid, string receiver);
Binary file modified WeChatFerry/spy/spy.aps
Binary file not shown.
4 changes: 2 additions & 2 deletions WeChatFerry/spy/spy.rc
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ END
//

VS_VERSION_INFO VERSIONINFO
FILEVERSION 39,0,11,0
FILEVERSION 39,0,12,0
PRODUCTVERSION 3,9,2,23
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
Expand All @@ -69,7 +69,7 @@ BEGIN
BEGIN
VALUE "CompanyName", "WeChatFerry"
VALUE "FileDescription", "WeChatFerry"
VALUE "FileVersion", "39.0.11.0"
VALUE "FileVersion", "39.0.12.0"
VALUE "InternalName", "spy.dll"
VALUE "LegalCopyright", "Copyright (C) 2023"
VALUE "OriginalFilename", "spy.dll"
Expand Down
6 changes: 6 additions & 0 deletions WeChatFerry/spy/spy_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,11 @@ typedef struct CallOcr {
DWORD call3;
} CallOcr_t;

typedef struct CallFm {
DWORD call1;
DWORD call2;
} CallFm_t;

typedef struct WxCalls {
DWORD login; // 登录状态
UserInfoCall_t ui; // 用户信息
Expand All @@ -173,6 +178,7 @@ typedef struct WxCalls {
CallPatMsg_t pm; // 发送拍一拍消息
CallInviteCM_t irm; // 邀请群成员
CallOcr_t ocr; // OCR
CallFm_t fm; // 转发消息
} WxCalls_t;

struct WxString {
Expand Down
19 changes: 19 additions & 0 deletions clients/python/wcferry/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,25 @@ def send_pat_msg(self, roomid: str, wxid: str) -> int:
rsp = self._send_request(req)
return rsp.status

def forward_msg(self, id: int, receiver: str) -> int:
"""转发消息。可以转发文本、图片、表情、甚至各种 XML;
语音也行,不过效果嘛,自己验证吧。
Args:
id (str): 待转发消息的 id
receiver (str): 消息接收者,wxid 或者 roomid
Returns:
int: 1 为成功,其他失败
"""
req = wcf_pb2.Request()
req.func = wcf_pb2.FUNC_FORWARD_MSG # FUNC_FORWARD_MSG
req.fm.id = id
req.fm.receiver = receiver

rsp = self._send_request(req)
return rsp.status

def get_msg(self, block=True) -> WxMsg:
"""从消息队列中获取消息
Expand Down
Loading

0 comments on commit 2ae40a2

Please sign in to comment.