From 77a3938e1fa86a7680a2584885f9d41a5fac8532 Mon Sep 17 00:00:00 2001 From: Changhua Date: Thu, 27 Feb 2025 00:23:44 +0800 Subject: [PATCH] feat(message): impl send rich text --- WeChatFerry/spy/message_sender.cpp | 63 ++++++++++++++++++------------ WeChatFerry/spy/message_sender.h | 4 +- WeChatFerry/spy/rpc_server.cpp | 2 +- 3 files changed, 43 insertions(+), 26 deletions(-) diff --git a/WeChatFerry/spy/message_sender.cpp b/WeChatFerry/spy/message_sender.cpp index 82a0efa..efe79da 100644 --- a/WeChatFerry/spy/message_sender.cpp +++ b/WeChatFerry/spy/message_sender.cpp @@ -47,7 +47,9 @@ Sender::Sender() func_send_image = reinterpret_cast(g_WeChatWinDllAddr + OsSend::IMAGE); func_get_app_mgr = reinterpret_cast(g_WeChatWinDllAddr + OsSend::APP_MGR); func_send_file = reinterpret_cast(g_WeChatWinDllAddr + OsSend::FILE); - func_send_rich_text = reinterpret_cast(g_WeChatWinDllAddr + OS_SEND_RICH_TEXT); + func_new_mmreader = reinterpret_cast(g_WeChatWinDllAddr + OsSend::NEW_MM_READER); + func_free_mmreader = reinterpret_cast(g_WeChatWinDllAddr + OsSend::FREE_MM_READER); + func_send_rich_text = reinterpret_cast(g_WeChatWinDllAddr + OsSend::RICH_TEXT); func_send_pat = reinterpret_cast(g_WeChatWinDllAddr + OS_SEND_PAT_MSG); func_forward = reinterpret_cast(g_WeChatWinDllAddr + OS_FORWARD_MSG); func_get_emotion_mgr = reinterpret_cast(g_WeChatWinDllAddr + OsSend::EMOTION_MGR); @@ -221,36 +223,49 @@ void Sender::send_emotion(const std::string &wxid, const std::string &path) int Sender::send_rich_text(const RichText &rt) { -#define SRTM_SIZE 0x3F0 QWORD status = -1; - char *buff = static_cast(HeapAlloc(GetProcessHeap(), 0, SRTM_SIZE)); - if (!buff) { + char *buff = util::AllocBuffer(0x3F0); + WxString *pReceiver = util::CreateWxString(rt.receiver); + WxString *pTitle = util::CreateWxString(rt.title); + WxString *pUrl = util::CreateWxString(rt.url); + WxString *pThumburl = util::CreateWxString(rt.thumburl); + WxString *pDigest = util::CreateWxString(rt.digest); + WxString *pAccount = util::CreateWxString(rt.account); + WxString *pName = util::CreateWxString(rt.name); + if (!buff || !pReceiver || !pTitle || !pUrl || !pThumburl || !pDigest || !pAccount || !pName) { + util::FreeWxString(pReceiver); + util::FreeWxString(pTitle); + util::FreeWxString(pUrl); + util::FreeWxString(pThumburl); + util::FreeWxString(pDigest); + util::FreeWxString(pAccount); + util::FreeWxString(pName); + util::FreeBuffer(buff); LOG_ERROR("Out of Memory..."); - return -1; + return static_cast(status); } - memset(buff, 0, SRTM_SIZE); - func_get_instance(reinterpret_cast(buff)); + func_new_mmreader(reinterpret_cast(buff)); + memcpy(buff + 0x8, pTitle, sizeof(WxString)); + memcpy(buff + 0x48, pUrl, sizeof(WxString)); + memcpy(buff + 0xB0, pThumburl, sizeof(WxString)); + memcpy(buff + 0xF0, pDigest, sizeof(WxString)); + memcpy(buff + 0x2C0, pAccount, sizeof(WxString)); + memcpy(buff + 0x2E0, pName, sizeof(WxString)); - auto pReceiver = new_wx_string(rt.receiver); - auto pTitle = new_wx_string(rt.title); - auto pUrl = new_wx_string(rt.url); - auto pThumburl = new_wx_string(rt.thumburl); - auto pDigest = new_wx_string(rt.digest); - auto pAccount = new_wx_string(rt.account); - auto pName = new_wx_string(rt.name); + status = func_send_rich_text(func_get_app_mgr(), pReceiver, buff); + func_free_mmreader(reinterpret_cast(buff)); - memcpy(buff + 0x8, pTitle.get(), sizeof(WxString)); - memcpy(buff + 0x48, pUrl.get(), sizeof(WxString)); - memcpy(buff + 0xB0, pThumburl.get(), sizeof(WxString)); - memcpy(buff + 0xF0, pDigest.get(), sizeof(WxString)); - memcpy(buff + 0x2C0, pAccount.get(), sizeof(WxString)); - memcpy(buff + 0x2E0, pName.get(), sizeof(WxString)); - - QWORD mgr = func_get_app_mgr(); - status = func_send_rich_text(mgr, reinterpret_cast(pReceiver.get()), reinterpret_cast(buff)); - func_free_chat_msg(reinterpret_cast(buff)); + // TODO: 验证是否有内存泄露 + // util::FreeWxString(pReceiver); + // util::FreeWxString(pTitle); + // util::FreeWxString(pUrl); + // util::FreeWxString(pThumburl); + // util::FreeWxString(pDigest); + // util::FreeWxString(pAccount); + // util::FreeWxString(pName); + util::FreeBuffer(buff); return static_cast(status); } diff --git a/WeChatFerry/spy/message_sender.h b/WeChatFerry/spy/message_sender.h index f25da25..ee752a6 100644 --- a/WeChatFerry/spy/message_sender.h +++ b/WeChatFerry/spy/message_sender.h @@ -50,7 +50,7 @@ private: using SendImage_t = QWORD (*)(QWORD, QWORD, QWORD, QWORD, QWORD); using SendFile_t = QWORD (*)(QWORD, char *, WxString *, WxString *, QWORD, QWORD *, QWORD, QWORD *, QWORD, QWORD *, QWORD, QWORD); - using SendRichText_t = QWORD (*)(QWORD, QWORD, QWORD); + using SendRichText_t = QWORD (*)(QWORD, WxString *, char *); using SendPat_t = QWORD (*)(QWORD, QWORD); using Forward_t = QWORD (*)(QWORD, QWORD, QWORD, QWORD); using GetEmotionMgr_t = QWORD (*)(); @@ -65,6 +65,8 @@ private: SendText_t func_send_text; SendImage_t func_send_image; SendFile_t func_send_file; + New_t func_new_mmreader; + Free_t func_free_mmreader; SendRichText_t func_send_rich_text; SendPat_t func_send_pat; Forward_t func_forward; diff --git a/WeChatFerry/spy/rpc_server.cpp b/WeChatFerry/spy/rpc_server.cpp index 9658df8..bdcde26 100644 --- a/WeChatFerry/spy/rpc_server.cpp +++ b/WeChatFerry/spy/rpc_server.cpp @@ -253,7 +253,7 @@ const std::unordered_map RpcServer::rpcFu { Functions_FUNC_SEND_FILE, [](const Request &r, uint8_t *out, size_t *len) { return RpcServer::getInstance().sender_.rpc_send_file(r.msg.file, out, len); } }, { Functions_FUNC_SEND_XML, [](const Request &r, uint8_t *out, size_t *len) { return RpcServer::getInstance().sender_.rpc_send_xml(r.msg.xml, out, len); } }, { Functions_FUNC_SEND_EMOTION, [](const Request &r, uint8_t *out, size_t *len) { return RpcServer::getInstance().sender_.rpc_send_emotion(r.msg.file, out, len); } }, - // { Functions_FUNC_SEND_RICH_TXT, [](const Request &r, uint8_t *out, size_t *len) { return sender.rpc_send_rich_text(r.msg.rt, out, len); } }, + { Functions_FUNC_SEND_RICH_TXT, [](const Request &r, uint8_t *out, size_t *len) { return RpcServer::getInstance().sender_.rpc_send_rich_text(r.msg.rt, out, len); } }, // { Functions_FUNC_SEND_PAT_MSG, [](const Request &r, uint8_t *out, size_t *len) { return sender.rpc_send_pat(r.msg.pm, out, len); } }, // { Functions_FUNC_FORWARD_MSG, [](const Request &r, uint8_t *out, size_t *len) { return sender.rpc_forward(r.msg.fm, out, len); } }, // { Functions_FUNC_EXEC_DB_QUERY, [](const Request &r, uint8_t *out, size_t *len) { return db::rpc_exec_db_query(r.msg.query, out, len); } },