UserInfo.cpp 5.0 KB
Newer Older
L
ljc545w 已提交
1 2 3 4 5
#include "pch.h"
#include <typeinfo>
#include <string>
#include <vector>

L
ljc545w 已提交
6
// 获取好友信息CALL1偏移
L
ljc545w 已提交
7
#define GetUserInfoCall1Offset 0x5946D570 - 0x593B0000
L
ljc545w 已提交
8
// 获取好友信息CALL2偏移
L
ljc545w 已提交
9
#define GetUserInfoCall2Offset 0x59B20980 - 0x593B0000
L
ljc545w 已提交
10
// 获取好友信息CALL3偏移
L
ljc545w 已提交
11 12 13 14 15
#define GetUserInfoCall3Offset 0x59816270 - 0x593B0000
// 清理好友信息缓存参数
#define DeleteUserInfoCacheCall1Offset 0x59A752B0 - 0x593B0000
// 清理好友信息缓存CALL2
#define DeleteUserInfoCacheCall2Offset 0x5946E680 - 0x593B0000
L
ljc545w 已提交
16

L
ljc545w 已提交
17 18 19 20 21
/*
* 外部调用时的返回类型
* message:wUserInfo.c_str()
* length:wUserInfo字符串长度
*/
L
ljc545w 已提交
22 23 24 25 26
struct GetUserInfoStruct {
	DWORD message;
	DWORD length;
};

L
ljc545w 已提交
27
// 保存好友信息的字符串
L
ljc545w 已提交
28
wstring wUserInfo = L"";
L
ljc545w 已提交
29
// 外部调用时的具体返回对象
L
ljc545w 已提交
30 31
GetUserInfoStruct ret = { 0 };

L
ljc545w 已提交
32 33 34 35 36
/*
* 根据缓冲区内容拼接好友信息
* address:缓冲区地址
* return:void
*/
L
ljc545w 已提交
37 38 39 40 41
VOID WxUserInfo(DWORD address) {
	vector<DWORD> InfoType{
		address + 0x10,
		address + 0x24,
		address + 0x38,
L
ljc545w 已提交
42
		address + 0x58,
L
ljc545w 已提交
43 44 45 46 47 48 49 50 51 52 53 54 55
		address + 0x6C,
		address + 0xFC,
		address + 0x110,
		address + 0x19C,
		address + 0x1B0,
		address + 0x1C4,
		address + 0x1D8,
		address + 0x27C
	};
	vector<wchar_t*> InfoTypeName{
		(WCHAR*)L"\"wxId\"",
		(WCHAR*)L"\"wxNumber\"",
		(WCHAR*)L"\"wxV3\"",
L
ljc545w 已提交
56
		(WCHAR*)L"\"wxRemark\"",
L
ljc545w 已提交
57 58 59 60 61 62 63 64 65 66 67 68
		(WCHAR*)L"\"wxNickName\"",
		(WCHAR*)L"\"wxBigAvatar\"",
		(WCHAR*)L"\"wxSmallAvatar\"",
		(WCHAR*)L"\"wxSignature\"",
		(WCHAR*)L"\"wxNation\"",
		(WCHAR*)L"\"wxProvince\"",
		(WCHAR*)L"\"wxCity\"",
		(WCHAR*)L"\"wxBackground\"",
	};
	wUserInfo += L"{";
	for (unsigned int i = 0; i < InfoType.size(); i++) {
		wchar_t* wstemp = ((*((DWORD*)InfoType[i])) != 0) ? (WCHAR*)(*((LPVOID*)InfoType[i])) : (WCHAR*)L"null";
L
ljc545w 已提交
69 70
		wstring wsrtemp = wreplace(wstemp,L'\"',L"\\\"");
		wUserInfo = wUserInfo + InfoTypeName[i] + L":\"" + wsrtemp + L"\"";
L
ljc545w 已提交
71 72 73 74 75 76 77 78 79 80 81
		if (i != InfoType.size() - 1) {
			wUserInfo += L",";
		}
	}
	wUserInfo += L"}";
#ifdef _DEBUG
	wcout.imbue(locale("chs"));
	wcout << wUserInfo.c_str() << endl;
#endif
}

L
ljc545w 已提交
82 83 84 85 86
/*
* 供外部调用的获取好友信息接口
* lparamter:保存好友wxid的地址
* return:DWORD,`ret`的首地址
*/
L
ljc545w 已提交
87 88 89 90 91 92 93 94 95 96 97
DWORD GetWxUserInfoRemote(LPVOID lparamter) {
	wchar_t* userwxid = (wchar_t*)lparamter;
	
	if (!GetUserInfoByWxId(userwxid)) {
		return 0;
	}
	ret.message = (DWORD)wUserInfo.c_str();
	ret.length = (DWORD)wUserInfo.length();
	return (DWORD)&ret;
}

L
ljc545w 已提交
98 99 100 101
/*
* 供外部调用的清空好友信息缓存的接口
* return:void
*/
L
ljc545w 已提交
102 103 104 105 106 107 108 109
VOID DeleteUserInfoCacheRemote() {
	if (ret.length) {
		ZeroMemory((wchar_t*)ret.message, ret.length * 2 + 2);
		ret.length = 0;
		wUserInfo = L"";
	}
}

L
ljc545w 已提交
110 111 112 113 114
/*
* 根据wxid获取好友信息的具体实现
* wxid:好友wxid
* return:BOOL,成功返回`1`,失败返回`0`
*/
L
ljc545w 已提交
115 116 117 118 119
BOOL __stdcall GetUserInfoByWxId(wchar_t* wxid) {
	DWORD WeChatWinBase = GetWeChatWinBase();
	DWORD WxGetUserInfoCall1 = WeChatWinBase + GetUserInfoCall1Offset;
	DWORD WxGetUserInfoCall2 = WeChatWinBase + GetUserInfoCall2Offset;
	DWORD WxGetUserInfoCall3 = WeChatWinBase + GetUserInfoCall3Offset;
L
ljc545w 已提交
120 121
	DWORD DeleteUserInfoCacheCall1 = WeChatWinBase + DeleteUserInfoCacheCall1Offset;
	DWORD DeleteUserInfoCacheCall2 = WeChatWinBase + DeleteUserInfoCacheCall2Offset;
L
ljc545w 已提交
122 123 124 125 126 127 128 129
	char buffer[0x3FC] = { 0 };
	WxBaseStruct pWxid(wxid);
	DWORD address = 0;
	DWORD isSuccess = 0;
	__asm
	{
		pushad;
		call WxGetUserInfoCall1;
L
ljc545w 已提交
130 131
		lea ebx, buffer;
		push ebx;
L
ljc545w 已提交
132
		sub esp, 0x14;
L
ljc545w 已提交
133 134
		mov esi, eax;
		lea eax, pWxid;
L
ljc545w 已提交
135
		mov ecx, esp;
L
ljc545w 已提交
136
		push eax;
L
ljc545w 已提交
137
		call WxGetUserInfoCall2;
L
ljc545w 已提交
138
		mov ecx, esi;
L
ljc545w 已提交
139 140
		call WxGetUserInfoCall3;
		mov isSuccess, eax;
L
ljc545w 已提交
141
		mov address, ebx;
L
ljc545w 已提交
142 143 144 145
		popad;
	}
	if(isSuccess)
		WxUserInfo(address);
L
ljc545w 已提交
146
	char deletebuffer[0x410] = { 0 };
L
ljc545w 已提交
147 148
	__asm {
		pushad;
L
ljc545w 已提交
149 150
		lea ecx, deletebuffer;
		call DeleteUserInfoCacheCall1;
L
ljc545w 已提交
151
		push eax;
L
ljc545w 已提交
152 153 154
		lea ebx,buffer;
		mov ecx, ebx;
		call DeleteUserInfoCacheCall2;
L
ljc545w 已提交
155 156 157
		popad;
	}
	return isSuccess;
L
ljc545w 已提交
158 159
}

L
ljc545w 已提交
160 161 162 163 164
/*
* 根据wxid获取联系人昵称,主要用于发送艾特消息接口
* wxid:联系人wxid
* return:wchar_t*,获取到的wxid
*/
L
ljc545w 已提交
165 166 167 168 169
wchar_t* __stdcall GetUserNickNameByWxId(wchar_t* wxid) {
	DWORD WeChatWinBase = GetWeChatWinBase();
	DWORD WxGetUserInfoCall1 = WeChatWinBase + GetUserInfoCall1Offset;
	DWORD WxGetUserInfoCall2 = WeChatWinBase + GetUserInfoCall2Offset;
	DWORD WxGetUserInfoCall3 = WeChatWinBase + GetUserInfoCall3Offset;
L
ljc545w 已提交
170 171
	DWORD DeleteUserInfoCacheCall1 = WeChatWinBase + DeleteUserInfoCacheCall1Offset;
	DWORD DeleteUserInfoCacheCall2 = WeChatWinBase + DeleteUserInfoCacheCall2Offset;
L
ljc545w 已提交
172 173 174 175 176 177 178 179
	char buffer[0x3FC] = { 0 };
	WxBaseStruct pWxid(wxid);
	DWORD address = 0;
	DWORD isSuccess = 0;
	__asm
	{
		pushad;
		call WxGetUserInfoCall1;
L
ljc545w 已提交
180 181
		lea ebx, buffer;
		push ebx;
L
ljc545w 已提交
182
		sub esp, 0x14;
L
ljc545w 已提交
183 184
		mov esi, eax;
		lea eax, pWxid;
L
ljc545w 已提交
185
		mov ecx, esp;
L
ljc545w 已提交
186
		push eax;
L
ljc545w 已提交
187
		call WxGetUserInfoCall2;
L
ljc545w 已提交
188
		mov ecx, esi;
L
ljc545w 已提交
189 190
		call WxGetUserInfoCall3;
		mov isSuccess, eax;
L
ljc545w 已提交
191
		mov address, ebx;
L
ljc545w 已提交
192 193 194 195 196 197 198 199 200
		popad;
	}
	wchar_t* NickName = NULL;
	if (isSuccess) {
		DWORD length = *(DWORD*)(address + 0x6C + 0x4);
		NickName = new wchar_t[length + 1];
		ZeroMemory(NickName, (length + 1) * 2);
		memcpy(NickName, (wchar_t*)(*(DWORD*)(address + 0x6C)), length * 2);
	}
L
ljc545w 已提交
201
	char deletebuffer[0x410] = { 0 };
L
ljc545w 已提交
202 203
	__asm {
		pushad;
L
ljc545w 已提交
204 205
		lea ecx, deletebuffer;
		call DeleteUserInfoCacheCall1;
L
ljc545w 已提交
206
		push eax;
L
ljc545w 已提交
207 208 209
		lea ebx, buffer;
		mov ecx, ebx;
		call DeleteUserInfoCacheCall2;
L
ljc545w 已提交
210 211 212
		popad;
	}
	return NickName;
L
ljc545w 已提交
213
}