feat(account): add user info retrieval and RPC methods
This commit is contained in:
parent
f5d9528e1a
commit
32876209a4
@ -1,9 +1,9 @@
|
||||
#include "account_manager.h"
|
||||
|
||||
#include <filesystem>
|
||||
#include <mutex>
|
||||
|
||||
#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<get_account_service_t>(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<uint8_t *>(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<get_current_data_path_t>(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<Functions_FUNC_GET_USER_INFO>(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();
|
||||
});
|
||||
}
|
||||
|
||||
|
21
WeChatFerry/spy/offsets.h
Normal file
21
WeChatFerry/spy/offsets.h
Normal file
@ -0,0 +1,21 @@
|
||||
#ifndef OFFSETS_H
|
||||
#define OFFSETS_H
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
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
|
@ -221,8 +221,8 @@ bool RpcServer::disableRecvMsg(uint8_t *out, size_t *len)
|
||||
const std::unordered_map<Functions, RpcServer::FunctionHandler> 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); } },
|
||||
|
Loading…
Reference in New Issue
Block a user