diff --git a/WeChatFerry/spy/account_manager.cpp b/WeChatFerry/spy/account_manager.cpp index d5f9608..93b0b11 100644 --- a/WeChatFerry/spy/account_manager.cpp +++ b/WeChatFerry/spy/account_manager.cpp @@ -1,9 +1,9 @@ #include "account_manager.h" #include -#include #include "log.hpp" +#include "offsets.h" #include "rpc_helper.h" #include "util.h" @@ -11,63 +11,56 @@ extern UINT64 g_WeChatWinDllAddr; namespace account { -#define OS_LOGIN_STATUS 0x595C9E8 -#define OS_USER_HOME 0x5932770 -#define OS_USER_WXID 0x595C270 -#define OS_USER_NAME 0x595C3D8 -#define OS_USER_MOBILE 0x595C318 -bool is_logged_in() { return util::get_qword(g_WeChatWinDllAddr + OS_LOGIN_STATUS) != 0; } +namespace OsAcc = Offsets::Account; -std::string get_home_path() +using get_account_service_t = QWORD (*)(); +using get_current_data_path_t = QWORD (*)(QWORD); + +static uint64_t get_account_service() { - static std::once_flag flag; - static std::string home_path; + static auto GetService = reinterpret_cast(g_WeChatWinDllAddr + OsAcc::SERVICE); + return GetService ? GetService() : 0; +} - std::call_once(flag, [] { - std::string path = util::w2s(util::get_pp_wstring(g_WeChatWinDllAddr + OS_USER_HOME)) + "\\WeChat Files\\"; - home_path = std::filesystem::absolute(path).string(); - }); +static std::string get_string_value(uint64_t base_addr, uint64_t offset) +{ + uint64_t type = util::get_qword(base_addr + offset + 0x18); + return (type == 0xF) ? util::get_p_string(base_addr + offset) : util::get_pp_string(base_addr + offset); +} - return home_path; +bool is_logged_in() +{ + uint64_t service_addr = get_account_service(); + return service_addr && util::get_qword(service_addr + OsAcc::LOGIN) != 0; } std::string get_self_wxid() { - static std::once_flag flag; - static std::string wxid; + uint64_t service_addr = get_account_service(); + if (!service_addr) return ""; - std::call_once(flag, [] { - UINT64 wxid_type = 0; - try { - wxid_type = util::get_qword(g_WeChatWinDllAddr + OS_USER_WXID + 0x18); - if (wxid_type == 0xF) { - wxid = util::get_p_string(g_WeChatWinDllAddr + OS_USER_WXID); - } else { - wxid = util::get_pp_string(g_WeChatWinDllAddr + OS_USER_WXID); - } - - } catch (...) { - LOG_ERROR("Failed to get wxid, type: {:#x}", wxid_type); - LOG_BUFFER(reinterpret_cast(g_WeChatWinDllAddr + OS_USER_WXID), 20); - wxid = "获取wxid失败"; - } - }); - return wxid; + return get_string_value(service_addr, OsAcc::WXID); } UserInfo_t get_user_info() { UserInfo_t ui; + WxString home; + + auto GetDataPath = reinterpret_cast(g_WeChatWinDllAddr + OsAcc::PATH); + + uint64_t service_addr = get_account_service(); + if (!service_addr) return ui; + ui.wxid = get_self_wxid(); - - UINT64 name_type = util::get_qword(g_WeChatWinDllAddr + OS_USER_NAME + 0x18); - ui.name = (name_type == 0xF) ? util::get_p_string(g_WeChatWinDllAddr + OS_USER_NAME) - : util::get_pp_string(g_WeChatWinDllAddr + OS_USER_NAME); - - ui.mobile = util::get_p_string(g_WeChatWinDllAddr + OS_USER_MOBILE); - ui.home = get_home_path(); - + GetDataPath((QWORD)&home); + if (home.wptr) { + std::filesystem::path path = util::w2s(std::wstring(home.wptr, home.size)); + ui.home = path.generic_string(); + } + ui.name = get_string_value(service_addr, OsAcc::NAME); + ui.mobile = get_string_value(service_addr, OsAcc::MOBILE); return ui; } @@ -85,11 +78,11 @@ bool rpc_get_self_wxid(uint8_t *out, size_t *len) bool rpc_get_user_info(uint8_t *out, size_t *len) { return fill_response(out, len, [](Response &rsp) { - UserInfo_t ui = get_user_info(); - rsp.msg.ui.wxid = (char *)ui.wxid.c_str(); - rsp.msg.ui.name = (char *)ui.name.c_str(); - rsp.msg.ui.mobile = (char *)ui.mobile.c_str(); - rsp.msg.ui.home = (char *)ui.home.c_str(); + static UserInfo_t ui = get_user_info(); + rsp.msg.ui.wxid = (char *)ui.wxid.c_str(); + rsp.msg.ui.name = (char *)ui.name.c_str(); + rsp.msg.ui.mobile = (char *)ui.mobile.c_str(); + rsp.msg.ui.home = (char *)ui.home.c_str(); }); } diff --git a/WeChatFerry/spy/offsets.h b/WeChatFerry/spy/offsets.h new file mode 100644 index 0000000..05f61e5 --- /dev/null +++ b/WeChatFerry/spy/offsets.h @@ -0,0 +1,21 @@ +#ifndef OFFSETS_H +#define OFFSETS_H + +#include + +namespace Offsets +{ + +namespace Account +{ + constexpr uint64_t SERVICE = 0x1B58B50; // 账户服务 + constexpr uint64_t PATH = 0x2250920; // 数据路径 + constexpr uint64_t WXID = 0x80; // WXID + constexpr uint64_t NAME = 0x1E8; // 昵称 + constexpr uint64_t MOBILE = 0x128; // 手机号 + constexpr uint64_t LOGIN = 0x7F8; // 登录状态 +} + +} + +#endif // OFFSETS_H diff --git a/WeChatFerry/spy/rpc_server.cpp b/WeChatFerry/spy/rpc_server.cpp index dbbc02a..ddfcd32 100644 --- a/WeChatFerry/spy/rpc_server.cpp +++ b/WeChatFerry/spy/rpc_server.cpp @@ -221,8 +221,8 @@ bool RpcServer::disableRecvMsg(uint8_t *out, size_t *len) const std::unordered_map RpcServer::rpcFunctionMap = { // clang-format off { Functions_FUNC_IS_LOGIN, [](const Request &r, uint8_t *out, size_t *len) { return account::rpc_is_logged_in(out, len); } }, - // { Functions_FUNC_GET_SELF_WXID, [](const Request &r, uint8_t *out, size_t *len) { return account::rpc_get_self_wxid(out, len); } }, - // { Functions_FUNC_GET_USER_INFO, [](const Request &r, uint8_t *out, size_t *len) { return account::rpc_get_user_info(out, len); } }, + { Functions_FUNC_GET_SELF_WXID, [](const Request &r, uint8_t *out, size_t *len) { return account::rpc_get_self_wxid(out, len); } }, + { Functions_FUNC_GET_USER_INFO, [](const Request &r, uint8_t *out, size_t *len) { return account::rpc_get_user_info(out, len); } }, // { Functions_FUNC_GET_MSG_TYPES, [](const Request &r, uint8_t *out, size_t *len) { return handler.rpc_get_msg_types(out, len); } }, // { Functions_FUNC_GET_CONTACTS, [](const Request &r, uint8_t *out, size_t *len) { return contact::rpc_get_contacts(out, len); } }, // { Functions_FUNC_GET_DB_NAMES, [](const Request &r, uint8_t *out, size_t *len) { return db::rpc_get_db_names(out, len); } },