Refactoring
This commit is contained in:
parent
f2c017de10
commit
b109bd72d2
@ -1,10 +1,15 @@
|
|||||||
#pragma execution_character_set("utf-8")
|
#pragma execution_character_set("utf-8")
|
||||||
|
|
||||||
#include "contact_mgmt.h"
|
#include "contact_mgmt.h"
|
||||||
|
#include "fill_response.h"
|
||||||
#include "log.hpp"
|
#include "log.hpp"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
namespace contact_mgmt
|
||||||
|
{
|
||||||
|
|
||||||
extern QWORD g_WeChatWinDllAddr;
|
extern QWORD g_WeChatWinDllAddr;
|
||||||
|
|
||||||
#define OS_GET_CONTACT_MGR 0x1B417A0
|
#define OS_GET_CONTACT_MGR 0x1B417A0
|
||||||
@ -18,30 +23,29 @@ extern QWORD g_WeChatWinDllAddr;
|
|||||||
#define OS_CONTACT_GENDER 0x0E
|
#define OS_CONTACT_GENDER 0x0E
|
||||||
#define OS_CONTACT_STEP 0x6A8
|
#define OS_CONTACT_STEP 0x6A8
|
||||||
|
|
||||||
typedef QWORD (*GetContactMgr_t)();
|
using get_contact_mgr_t = QWORD (*)();
|
||||||
typedef QWORD (*GetContactList_t)(QWORD, QWORD);
|
using get_contact_list_t = QWORD (*)(QWORD, QWORD);
|
||||||
|
|
||||||
#define FEAT_LEN 5
|
#define FEAT_LEN 5
|
||||||
static const uint8_t FEAT_COUNTRY[FEAT_LEN] = { 0xA4, 0xD9, 0x02, 0x4A, 0x18 };
|
static const uint8_t FEAT_COUNTRY[FEAT_LEN] = { 0xA4, 0xD9, 0x02, 0x4A, 0x18 };
|
||||||
static const uint8_t FEAT_PROVINCE[FEAT_LEN] = { 0xE2, 0xEA, 0xA8, 0xD1, 0x18 };
|
static const uint8_t FEAT_PROVINCE[FEAT_LEN] = { 0xE2, 0xEA, 0xA8, 0xD1, 0x18 };
|
||||||
static const uint8_t FEAT_CITY[FEAT_LEN] = { 0x1D, 0x02, 0x5B, 0xBF, 0x18 };
|
static const uint8_t FEAT_CITY[FEAT_LEN] = { 0x1D, 0x02, 0x5B, 0xBF, 0x18 };
|
||||||
|
|
||||||
static QWORD FindMem(QWORD start, QWORD end, const void *target, size_t len)
|
static QWORD find_mem(QWORD start, QWORD end, const void *target, size_t len)
|
||||||
{
|
{
|
||||||
uint8_t *p = (uint8_t *)start;
|
uint8_t *p = reinterpret_cast<uint8_t *>(start);
|
||||||
while ((QWORD)p < end) {
|
while (reinterpret_cast<QWORD>(p) < end) {
|
||||||
if (memcmp((void *)p, target, len) == 0) {
|
if (memcmp(p, target, len) == 0) {
|
||||||
return (QWORD)p;
|
return reinterpret_cast<QWORD>(p);
|
||||||
}
|
}
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static string GetCntString(QWORD start, QWORD end, const uint8_t *feat, size_t len)
|
static string get_cnt_string(QWORD start, QWORD end, const uint8_t *feat, size_t len)
|
||||||
{
|
{
|
||||||
QWORD pfeat = FindMem(start, end, feat, len);
|
QWORD pfeat = find_mem(start, end, feat, len);
|
||||||
if (pfeat == 0) {
|
if (pfeat == 0) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
@ -54,21 +58,23 @@ static string GetCntString(QWORD start, QWORD end, const uint8_t *feat, size_t l
|
|||||||
return Wstring2String(wstring(GET_WSTRING_FROM_P(pfeat + FEAT_LEN + 4), lfeat));
|
return Wstring2String(wstring(GET_WSTRING_FROM_P(pfeat + FEAT_LEN + 4), lfeat));
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<RpcContact_t> GetContacts()
|
vector<RpcContact_t> get_contacts()
|
||||||
{
|
{
|
||||||
vector<RpcContact_t> contacts;
|
vector<RpcContact_t> contacts;
|
||||||
GetContactMgr_t funcGetContactMgr = (GetContactMgr_t)(g_WeChatWinDllAddr + OS_GET_CONTACT_MGR);
|
get_contact_mgr_t func_get_contact_mgr
|
||||||
GetContactList_t funcGetContactList = (GetContactList_t)(g_WeChatWinDllAddr + OS_GET_CONTACT_LIST);
|
= reinterpret_cast<get_contact_mgr_t>(g_WeChatWinDllAddr + OS_GET_CONTACT_MGR);
|
||||||
|
get_contact_list_t func_get_contact_list
|
||||||
|
= reinterpret_cast<get_contact_list_t>(g_WeChatWinDllAddr + OS_GET_CONTACT_LIST);
|
||||||
|
|
||||||
QWORD mgr = funcGetContactMgr();
|
QWORD mgr = func_get_contact_mgr();
|
||||||
QWORD addr[3] = { 0 };
|
QWORD addr[3] = { 0 };
|
||||||
if (funcGetContactList(mgr, (QWORD)addr) != 1) {
|
if (func_get_contact_list(mgr, reinterpret_cast<QWORD>(addr)) != 1) {
|
||||||
LOG_ERROR("GetContacts failed");
|
LOG_ERROR("get_contacts failed");
|
||||||
return contacts;
|
return contacts;
|
||||||
}
|
}
|
||||||
|
|
||||||
QWORD pstart = (QWORD)addr[0];
|
QWORD pstart = addr[0];
|
||||||
QWORD pend = (QWORD)addr[2];
|
QWORD pend = addr[2];
|
||||||
while (pstart < pend) {
|
while (pstart < pend) {
|
||||||
RpcContact_t cnt;
|
RpcContact_t cnt;
|
||||||
QWORD pbin = GET_QWORD(pstart + OS_CONTACT_BIN);
|
QWORD pbin = GET_QWORD(pstart + OS_CONTACT_BIN);
|
||||||
@ -79,15 +85,11 @@ vector<RpcContact_t> GetContacts()
|
|||||||
cnt.remark = GetStringByWstrAddr(pstart + OS_CONTACT_REMARK);
|
cnt.remark = GetStringByWstrAddr(pstart + OS_CONTACT_REMARK);
|
||||||
cnt.name = GetStringByWstrAddr(pstart + OS_CONTACT_NAME);
|
cnt.name = GetStringByWstrAddr(pstart + OS_CONTACT_NAME);
|
||||||
|
|
||||||
cnt.country = GetCntString(pbin, pbin + lenbin, FEAT_COUNTRY, FEAT_LEN);
|
cnt.country = get_cnt_string(pbin, pbin + lenbin, FEAT_COUNTRY, FEAT_LEN);
|
||||||
cnt.province = GetCntString(pbin, pbin + lenbin, FEAT_PROVINCE, FEAT_LEN);
|
cnt.province = get_cnt_string(pbin, pbin + lenbin, FEAT_PROVINCE, FEAT_LEN);
|
||||||
cnt.city = GetCntString(pbin, pbin + lenbin, FEAT_CITY, FEAT_LEN);
|
cnt.city = get_cnt_string(pbin, pbin + lenbin, FEAT_CITY, FEAT_LEN);
|
||||||
|
|
||||||
if (pbin == 0) {
|
cnt.gender = (pbin == 0) ? 0 : static_cast<DWORD>(*(uint8_t *)(pbin + OS_CONTACT_GENDER));
|
||||||
cnt.gender = 0;
|
|
||||||
} else {
|
|
||||||
cnt.gender = (DWORD) * (uint8_t *)(pbin + OS_CONTACT_GENDER);
|
|
||||||
}
|
|
||||||
|
|
||||||
contacts.push_back(cnt);
|
contacts.push_back(cnt);
|
||||||
pstart += OS_CONTACT_STEP;
|
pstart += OS_CONTACT_STEP;
|
||||||
@ -96,68 +98,69 @@ vector<RpcContact_t> GetContacts()
|
|||||||
return contacts;
|
return contacts;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
int accept_new_friend(string v3, string v4, int scene)
|
||||||
int AcceptNewFriend(string v3, string v4, int scene)
|
|
||||||
{
|
{
|
||||||
int success = 0;
|
int success = -1;
|
||||||
|
#if 0
|
||||||
DWORD acceptNewFriendCall1 = g_WeChatWinDllAddr + g_WxCalls.anf.call1;
|
DWORD accept_new_friend_call1 = g_WeChatWinDllAddr + g_WxCalls.anf.call1;
|
||||||
DWORD acceptNewFriendCall2 = g_WeChatWinDllAddr + g_WxCalls.anf.call2;
|
DWORD accept_new_friend_call2 = g_WeChatWinDllAddr + g_WxCalls.anf.call2;
|
||||||
DWORD acceptNewFriendCall3 = g_WeChatWinDllAddr + g_WxCalls.anf.call3;
|
DWORD accept_new_friend_call3 = g_WeChatWinDllAddr + g_WxCalls.anf.call3;
|
||||||
DWORD acceptNewFriendCall4 = g_WeChatWinDllAddr + g_WxCalls.anf.call4;
|
DWORD accept_new_friend_call4 = g_WeChatWinDllAddr + g_WxCalls.anf.call4;
|
||||||
|
|
||||||
char buffer[0x40] = { 0 };
|
char buffer[0x40] = { 0 };
|
||||||
char nullbuffer[0x3CC] = { 0 };
|
char nullbuffer[0x3CC] = { 0 };
|
||||||
|
|
||||||
LOG_DEBUG("\nv3: {}\nv4: {}\nscene: {}", v3, v4, scene);
|
LOG_DEBUG("\nv3: {}\nv4: {}\nscene: {}", v3, v4, scene);
|
||||||
|
|
||||||
wstring wsV3 = String2Wstring(v3);
|
wstring ws_v3 = String2Wstring(v3);
|
||||||
wstring wsV4 = String2Wstring(v4);
|
wstring ws_v4 = String2Wstring(v4);
|
||||||
WxString wxV3(wsV3);
|
WxString wx_v3(ws_v3);
|
||||||
WxString wxV4(wsV4);
|
WxString wx_v4(ws_v4);
|
||||||
|
|
||||||
__asm {
|
__asm {
|
||||||
pushad;
|
pushad;
|
||||||
pushfd;
|
pushfd;
|
||||||
lea ecx, buffer;
|
lea ecx, buffer;
|
||||||
call acceptNewFriendCall1;
|
call accept_new_friend_call1;
|
||||||
mov esi, 0x0;
|
mov esi, 0x0;
|
||||||
mov edi, scene;
|
mov edi, scene;
|
||||||
push esi;
|
push esi;
|
||||||
push edi;
|
push edi;
|
||||||
sub esp, 0x14;
|
sub esp, 0x14;
|
||||||
mov ecx, esp;
|
mov ecx, esp;
|
||||||
lea eax, wxV4;
|
lea eax, wx_v4;
|
||||||
push eax;
|
push eax;
|
||||||
call acceptNewFriendCall2;
|
call accept_new_friend_call2;
|
||||||
sub esp, 0x8;
|
sub esp, 0x8;
|
||||||
push 0x0;
|
push 0x0;
|
||||||
lea eax, nullbuffer;
|
lea eax, nullbuffer;
|
||||||
push eax;
|
push eax;
|
||||||
lea eax, wxV3;
|
lea eax, wx_v3;
|
||||||
push eax;
|
push eax;
|
||||||
lea ecx, buffer;
|
lea ecx, buffer;
|
||||||
call acceptNewFriendCall3;
|
call accept_new_friend_call3;
|
||||||
mov success, eax;
|
mov success, eax;
|
||||||
lea ecx, buffer;
|
lea ecx, buffer;
|
||||||
call acceptNewFriendCall4;
|
call accept_new_friend_call4;
|
||||||
popfd;
|
popfd;
|
||||||
popad;
|
popad;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return success; // 成功返回 1
|
return success; // 成功返回 1
|
||||||
}
|
}
|
||||||
|
|
||||||
/*没啥用,非好友获取不到*/
|
RpcContact_t get_contact_by_wxid(string wxid)
|
||||||
RpcContact_t GetContactByWxid(string wxid)
|
|
||||||
{
|
{
|
||||||
RpcContact_t contact;
|
RpcContact_t contact;
|
||||||
|
#if 0
|
||||||
char buff[0x440] = { 0 };
|
char buff[0x440] = { 0 };
|
||||||
wstring wsWxid = String2Wstring(wxid);
|
wstring ws_wxid = String2Wstring(wxid);
|
||||||
WxString pri(wsWxid);
|
WxString pri(ws_wxid);
|
||||||
|
|
||||||
DWORD contact_mgr_addr = g_WeChatWinDllAddr + 0x75A4A0;
|
DWORD contact_mgr_addr = g_WeChatWinDllAddr + 0x75A4A0;
|
||||||
DWORD get_contact_addr = g_WeChatWinDllAddr + 0xC04E00;
|
DWORD get_contact_addr = g_WeChatWinDllAddr + 0xC04E00;
|
||||||
DWORD free_contact_addr = g_WeChatWinDllAddr + 0xEA7880;
|
DWORD free_contact_addr = g_WeChatWinDllAddr + 0xEA7880;
|
||||||
|
|
||||||
__asm {
|
__asm {
|
||||||
PUSHAD
|
PUSHAD
|
||||||
PUSHFD
|
PUSHFD
|
||||||
@ -173,10 +176,10 @@ RpcContact_t GetContactByWxid(string wxid)
|
|||||||
}
|
}
|
||||||
|
|
||||||
contact.wxid = wxid;
|
contact.wxid = wxid;
|
||||||
contact.code = GetStringByWstrAddr((DWORD)buff + g_WxCalls.contact.wxCode);
|
contact.code = GetStringByWstrAddr(reinterpret_cast<DWORD>(buff) + g_WxCalls.contact.wxCode);
|
||||||
contact.remark = GetStringByWstrAddr((DWORD)buff + g_WxCalls.contact.wxRemark);
|
contact.remark = GetStringByWstrAddr(reinterpret_cast<DWORD>(buff) + g_WxCalls.contact.wxRemark);
|
||||||
contact.name = GetStringByWstrAddr((DWORD)buff + g_WxCalls.contact.wxName);
|
contact.name = GetStringByWstrAddr(reinterpret_cast<DWORD>(buff) + g_WxCalls.contact.wxName);
|
||||||
contact.gender = GET_DWORD((DWORD)buff + 0x148);
|
contact.gender = GET_DWORD(reinterpret_cast<DWORD>(buff) + 0x148);
|
||||||
|
|
||||||
__asm {
|
__asm {
|
||||||
PUSHAD
|
PUSHAD
|
||||||
@ -186,7 +189,32 @@ RpcContact_t GetContactByWxid(string wxid)
|
|||||||
POPFD
|
POPFD
|
||||||
POPAD
|
POPAD
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return contact;
|
return contact;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
bool rpc_get_contacts(uint8_t *out, size_t *len)
|
||||||
|
{
|
||||||
|
return fill_response<Functions_FUNC_GET_CONTACTS>(out, len, [](Response &rsp) {
|
||||||
|
vector<RpcContact_t> contacts = get_contacts();
|
||||||
|
rsp.msg.contacts.contacts.funcs.encode = encode_contacts;
|
||||||
|
rsp.msg.contacts.contacts.arg = &contacts;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
bool rpc_get_contact_info(const string &wxid, uint8_t *out, size_t *len)
|
||||||
|
{
|
||||||
|
return fill_response<Functions_FUNC_GET_CONTACT_INFO>(out, len, [&](Response &rsp) {
|
||||||
|
vector<RpcContact_t> contacts = { get_contact_by_wxid(wxid) };
|
||||||
|
rsp.msg.contacts.contacts.funcs.encode = encode_contacts;
|
||||||
|
rsp.msg.contacts.contacts.arg = &contacts;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
bool rpc_accept_friend(const string &v3, const string &v4, int scene, uint8_t *out, size_t *len)
|
||||||
|
{
|
||||||
|
return fill_response<Functions_FUNC_ACCEPT_FRIEND>(
|
||||||
|
out, len, [&](Response &rsp) { rsp.msg.status = accept_friend(v3, v4, scene); });
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace contact_mgmt
|
||||||
|
@ -1,11 +1,28 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "string"
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "pb_types.h"
|
#include "pb_types.h"
|
||||||
|
|
||||||
vector<RpcContact_t> GetContacts();
|
namespace contact_mgmt
|
||||||
int AcceptNewFriend(std::string v3, std::string v4, int scene);
|
{
|
||||||
int AddFriendByWxid(std::string wxid, std::string msg);
|
|
||||||
RpcContact_t GetContactByWxid(std::string wxid);
|
// 获取所有联系人
|
||||||
|
std::vector<RpcContact_t> get_contacts();
|
||||||
|
|
||||||
|
// 根据 wxid 获取联系人信息
|
||||||
|
RpcContact_t get_contact_by_wxid(const std::string &wxid);
|
||||||
|
|
||||||
|
// 接受好友请求
|
||||||
|
int accept_friend(const std::string &v3, const std::string &v4, int scene);
|
||||||
|
|
||||||
|
// 发送好友请求
|
||||||
|
// int add_friend_by_wxid(const std::string &wxid, const std::string &msg);
|
||||||
|
|
||||||
|
// RPC 方法
|
||||||
|
bool rpc_get_contacts(uint8_t *out, size_t *len);
|
||||||
|
bool rpc_get_contact_info(const std::string &wxid, uint8_t *out, size_t *len);
|
||||||
|
bool rpc_accept_friend(const std::string &v3, const std::string &v4, int scene, uint8_t *out, size_t *len);
|
||||||
|
|
||||||
|
} // namespace contact_mgmt
|
||||||
|
@ -103,7 +103,7 @@ static bool func_get_msg_types(uint8_t *out, size_t *len)
|
|||||||
static bool func_get_contacts(uint8_t *out, size_t *len)
|
static bool func_get_contacts(uint8_t *out, size_t *len)
|
||||||
{
|
{
|
||||||
return FillResponse<Functions_FUNC_GET_CONTACTS>(Response_contacts_tag, out, len, [](Response &rsp) {
|
return FillResponse<Functions_FUNC_GET_CONTACTS>(Response_contacts_tag, out, len, [](Response &rsp) {
|
||||||
static std::vector<RpcContact_t> contacts = GetContacts();
|
static std::vector<RpcContact_t> contacts = contact_mgmt::get_contacts();
|
||||||
rsp.msg.contacts.contacts.funcs.encode = encode_contacts;
|
rsp.msg.contacts.contacts.funcs.encode = encode_contacts;
|
||||||
rsp.msg.contacts.contacts.arg = &contacts;
|
rsp.msg.contacts.contacts.arg = &contacts;
|
||||||
});
|
});
|
||||||
@ -410,7 +410,6 @@ static bool func_receive_transfer(char *wxid, char *tfid, char *taid, uint8_t *o
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
static bool func_accept_friend(char *v3, char *v4, int32_t scene, uint8_t *out, size_t *len)
|
static bool func_accept_friend(char *v3, char *v4, int32_t scene, uint8_t *out, size_t *len)
|
||||||
{
|
{
|
||||||
return FillResponse<Functions_FUNC_ACCEPT_FRIEND>(Response_status_tag, out, len, [v3, v4, scene](Response &rsp) {
|
return FillResponse<Functions_FUNC_ACCEPT_FRIEND>(Response_status_tag, out, len, [v3, v4, scene](Response &rsp) {
|
||||||
@ -418,7 +417,7 @@ static bool func_accept_friend(char *v3, char *v4, int32_t scene, uint8_t *out,
|
|||||||
LOG_ERROR("Empty V3 or V4.");
|
LOG_ERROR("Empty V3 or V4.");
|
||||||
rsp.msg.status = -1;
|
rsp.msg.status = -1;
|
||||||
} else {
|
} else {
|
||||||
rsp.msg.status = AcceptNewFriend(v3, v4, scene);
|
rsp.msg.status = contact_mgmt::accept_friend(v3, v4, scene);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -426,15 +425,11 @@ static bool func_accept_friend(char *v3, char *v4, int32_t scene, uint8_t *out,
|
|||||||
static bool func_get_contact_info(std::string wxid, uint8_t *out, size_t *len)
|
static bool func_get_contact_info(std::string wxid, uint8_t *out, size_t *len)
|
||||||
{
|
{
|
||||||
return FillResponse<Functions_FUNC_GET_CONTACT_INFO>(Response_contacts_tag, out, len, [wxid](Response &rsp) {
|
return FillResponse<Functions_FUNC_GET_CONTACT_INFO>(Response_contacts_tag, out, len, [wxid](Response &rsp) {
|
||||||
static std::vector<RpcContact_t> contacts;
|
std::vector<RpcContact_t> contacts = contact_mgmt::get_contact_by_wxid(wxid);
|
||||||
contacts.clear();
|
|
||||||
contacts.push_back(GetContactByWxid(wxid));
|
|
||||||
|
|
||||||
rsp.msg.contacts.contacts.funcs.encode = encode_contacts;
|
rsp.msg.contacts.contacts.funcs.encode = encode_contacts;
|
||||||
rsp.msg.contacts.contacts.arg = &contacts;
|
rsp.msg.contacts.contacts.arg = &contacts;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
static bool func_decrypt_image(DecPath dec, uint8_t *out, size_t *len)
|
static bool func_decrypt_image(DecPath dec, uint8_t *out, size_t *len)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user