diff --git a/WeChatFerry/spy/message_sender.cpp b/WeChatFerry/spy/message_sender.cpp index ac4452d..bc6cad5 100644 --- a/WeChatFerry/spy/message_sender.cpp +++ b/WeChatFerry/spy/message_sender.cpp @@ -3,19 +3,17 @@ #include #include +#include "account_manager.h" #include "database_executor.h" #include "log.hpp" +#include "offsets.h" #include "rpc_helper.h" #include "spy_types.h" -#include "account_manager.h" #include "util.h" extern QWORD g_WeChatWinDllAddr; #define OS_NEW 0x1B5E140 -#define OS_FREE 0x1B55850 -#define OS_SEND_MSG_MGR 0x1B53FD0 -#define OS_SEND_TEXT 0x22C6B60 #define OS_SEND_IMAGE 0x22BC2F0 #define OS_GET_APP_MSG_MGR 0x1B58F70 #define OS_SEND_FILE 0x20D0230 @@ -32,6 +30,8 @@ extern QWORD g_WeChatWinDllAddr; namespace message { +namespace OsSend = Offsets::Message::Send; + Sender &Sender::get_instance() { static Sender instance; @@ -41,9 +41,9 @@ Sender &Sender::get_instance() Sender::Sender() { func_new = reinterpret_cast(g_WeChatWinDllAddr + OS_NEW); - func_free = reinterpret_cast(g_WeChatWinDllAddr + OS_FREE); - func_send_msg_mgr = reinterpret_cast(g_WeChatWinDllAddr + OS_SEND_MSG_MGR); - func_send_text = reinterpret_cast(g_WeChatWinDllAddr + OS_SEND_TEXT); + func_free = reinterpret_cast(g_WeChatWinDllAddr + OsSend::FREE); + func_send_msg_mgr = reinterpret_cast(g_WeChatWinDllAddr + OsSend::MGR); + func_send_text = reinterpret_cast(g_WeChatWinDllAddr + OsSend::TEXT); func_send_image = reinterpret_cast(g_WeChatWinDllAddr + OS_SEND_IMAGE); func_send_file = reinterpret_cast(g_WeChatWinDllAddr + OS_SEND_FILE); func_send_rich_text = reinterpret_cast(g_WeChatWinDllAddr + OS_SEND_RICH_TEXT); @@ -62,35 +62,42 @@ std::unique_ptr Sender::new_wx_string(const std::string &str) return std::make_unique(util::s2w(str)); } -std::vector Sender::parse_wxids(const string &wxids) +template struct WxStringHolder { + std::wstring ws; + WxString wx; + explicit WxStringHolder(const T &str) : ws(util::s2w(str)), wx(ws) { } +}; + +template struct AtWxidSplitResult { + std::vector wxids; + std::vector wxWxids; +}; + +AtWxidSplitResult<> parse_wxids(const std::string &atWxids) { - vector wx_members; - wstringstream wss(util::s2w(wxids)); - wstring wstr; - while (getline(wss, wstr, L',')) { - wx_members.emplace_back(wstr); + AtWxidSplitResult<> result; + if (!atWxids.empty()) { + std::wstringstream wss(util::s2w(atWxids)); + for (std::wstring wxid; std::getline(wss, wxid, L',');) { + result.wxids.push_back(wxid); + result.wxWxids.emplace_back(result.wxids.back()); + } } - return wx_members; + return result; } void Sender::send_text(const std::string &wxid, const std::string &msg, const std::string &at_wxids) { - auto wxWxid = new_wx_string(wxid); - auto wxMsg = new_wx_string(msg); + WxStringHolder holderMsg(msg); + WxStringHolder holderWxid(wxid); - std::vector wx_at_wxids; - if (!at_wxids.empty()) { - wx_at_wxids = parse_wxids(at_wxids); - } else { - wx_at_wxids.emplace_back(); - } + auto wxAtWxids = parse_wxids(at_wxids).wxWxids; + QWORD pWxAtWxids = wxAtWxids.empty() ? 0 : reinterpret_cast(&wxAtWxids); - QWORD wx_ater_list = reinterpret_cast(&(wx_at_wxids.front())); - - char buffer[0x460] = { 0 }; + char buffer[1104] = { 0 }; func_send_msg_mgr(); - func_send_text(reinterpret_cast(&buffer), reinterpret_cast(wxWxid.get()), - reinterpret_cast(wxMsg.get()), wx_ater_list, 1, 1, 0, 0); + func_send_text(reinterpret_cast(&buffer), reinterpret_cast(&holderWxid.wx), + reinterpret_cast(&holderMsg.wx), pWxAtWxids, 1, 1, 0, 0); func_free(reinterpret_cast(&buffer)); } diff --git a/WeChatFerry/spy/message_sender.h b/WeChatFerry/spy/message_sender.h index 1f0a855..4453ba9 100644 --- a/WeChatFerry/spy/message_sender.h +++ b/WeChatFerry/spy/message_sender.h @@ -75,6 +75,5 @@ private: std::unique_ptr new_wx_string(const char *str); std::unique_ptr new_wx_string(const std::string &str); - std::vector parse_wxids(const std::string &wxids); }; } diff --git a/WeChatFerry/spy/rpc_server.cpp b/WeChatFerry/spy/rpc_server.cpp index 8998fd0..6590897 100644 --- a/WeChatFerry/spy/rpc_server.cpp +++ b/WeChatFerry/spy/rpc_server.cpp @@ -54,7 +54,8 @@ void RpcServer::destroyInstance() } } -RpcServer::RpcServer(int port) : port_(port), handler_(message::Handler::getInstance()) +RpcServer::RpcServer(int port) + : port_(port), handler_(message::Handler::getInstance()), sender_(message::Sender::get_instance()) { LOG_DEBUG("RpcServer 构造: 端口 {}", port_); } @@ -247,7 +248,7 @@ const std::unordered_map RpcServer::rpcFu // { Functions_FUNC_GET_DB_NAMES, [](const Request &r, uint8_t *out, size_t *len) { return db::rpc_get_db_names(out, len); } }, // { Functions_FUNC_GET_DB_TABLES, [](const Request &r, uint8_t *out, size_t *len) { return db::rpc_get_db_tables(r.msg.str, out, len); } }, // { Functions_FUNC_GET_AUDIO_MSG, [](const Request &r, uint8_t *out, size_t *len) { return misc::rpc_get_audio(r.msg.am, out, len); } }, - // { Functions_FUNC_SEND_TXT, [](const Request &r, uint8_t *out, size_t *len) { return sender.rpc_send_text(r.msg.txt, out, len); } }, + { Functions_FUNC_SEND_TXT, [](const Request &r, uint8_t *out, size_t *len) { return RpcServer::getInstance().sender_.rpc_send_text(r.msg.txt, out, len); } }, // { Functions_FUNC_SEND_IMG, [](const Request &r, uint8_t *out, size_t *len) { return sender.rpc_send_image(r.msg.file, out, len); } }, // { Functions_FUNC_SEND_FILE, [](const Request &r, uint8_t *out, size_t *len) { return sender.rpc_send_file(r.msg.file, out, len); } }, // { Functions_FUNC_SEND_XML, [](const Request &r, uint8_t *out, size_t *len) { return sender.rpc_send_xml(r.msg.xml, out, len); } }, diff --git a/WeChatFerry/spy/rpc_server.h b/WeChatFerry/spy/rpc_server.h index 0bb96b9..76dbc1b 100644 --- a/WeChatFerry/spy/rpc_server.h +++ b/WeChatFerry/spy/rpc_server.h @@ -10,6 +10,7 @@ #include "wcf.pb.h" #include "message_handler.h" +#include "message_sender.h" class RpcServer { @@ -46,6 +47,7 @@ private: std::thread msgThread_; message::Handler &handler_; + message::Sender &sender_; struct Deleter { void operator()(RpcServer *server) const { delete server; }