2022-08-06 21:44:26 +08:00
|
|
|
|
#include "Shlwapi.h"
|
2021-02-12 23:21:57 +08:00
|
|
|
|
#include "framework.h"
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <strsafe.h>
|
|
|
|
|
#include <wchar.h>
|
|
|
|
|
|
|
|
|
|
#include "util.h"
|
|
|
|
|
|
|
|
|
|
#pragma comment(lib, "shlwapi")
|
|
|
|
|
#pragma comment(lib, "Version.lib")
|
|
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
|
|
|
|
|
int GetWeChatPath(wchar_t *path);
|
|
|
|
|
int GetWeChatWinDLLPath(wchar_t *path);
|
|
|
|
|
int GetWeChatVersion(wchar_t *version);
|
|
|
|
|
bool GetFileVersion(const wchar_t *filePath, wchar_t *version);
|
|
|
|
|
|
|
|
|
|
int GetWeChatPath(wchar_t *path)
|
|
|
|
|
{
|
|
|
|
|
int ret = -1;
|
|
|
|
|
HKEY hKey = NULL;
|
|
|
|
|
// HKEY_CURRENT_USER\Software\Tencent\WeChat InstallPath = xx
|
|
|
|
|
if (ERROR_SUCCESS != RegOpenKey(HKEY_CURRENT_USER, L"Software\\Tencent\\WeChat", &hKey)) {
|
|
|
|
|
ret = GetLastError();
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DWORD Type = REG_SZ;
|
|
|
|
|
DWORD cbData = MAX_PATH * sizeof(WCHAR);
|
|
|
|
|
if (ERROR_SUCCESS != RegQueryValueEx(hKey, L"InstallPath", 0, &Type, (LPBYTE)path, &cbData)) {
|
|
|
|
|
ret = GetLastError();
|
|
|
|
|
goto __exit;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (path != NULL) {
|
|
|
|
|
PathAppend(path, WECHAREXE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
__exit:
|
|
|
|
|
if (hKey) {
|
|
|
|
|
RegCloseKey(hKey);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ERROR_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int GetWeChatWinDLLPath(wchar_t *path)
|
|
|
|
|
{
|
|
|
|
|
int ret = GetWeChatPath(path);
|
|
|
|
|
if (ret != ERROR_SUCCESS) {
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PathRemoveFileSpecW(path);
|
|
|
|
|
PathAppendW(path, WECHATWINDLL);
|
2022-08-06 16:49:37 +08:00
|
|
|
|
if (!PathFileExists(path)) {
|
|
|
|
|
// 微信从(大约)3.7开始,增加了一层版本目录: [3.7.0.29]
|
|
|
|
|
PathRemoveFileSpec(path);
|
|
|
|
|
_wfinddata_t findData;
|
2022-08-07 15:03:17 +08:00
|
|
|
|
wstring dir = wstring(path) + L"\\[*.*";
|
2022-08-06 16:49:37 +08:00
|
|
|
|
intptr_t handle = _wfindfirst(dir.c_str(), &findData);
|
|
|
|
|
if (handle == -1) { // 检查是否成功
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
wstring dllPath = wstring(path) + L"\\" + findData.name;
|
|
|
|
|
wcscpy_s(path, MAX_PATH, dllPath.c_str());
|
|
|
|
|
PathAppend(path, WECHATWINDLL);
|
2022-08-07 15:03:17 +08:00
|
|
|
|
}
|
2021-02-12 23:21:57 +08:00
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int GetWeChatVersion(wchar_t *version)
|
|
|
|
|
{
|
|
|
|
|
WCHAR Path[MAX_PATH] = { 0 };
|
|
|
|
|
|
|
|
|
|
int ret = GetWeChatWinDLLPath(Path);
|
|
|
|
|
if (ret != ERROR_SUCCESS) {
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ret = GetFileVersion(Path, version);
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool GetFileVersion(const wchar_t *filePath, wchar_t *version)
|
|
|
|
|
{
|
|
|
|
|
if (wcslen(filePath) > 0 && PathFileExists(filePath)) {
|
|
|
|
|
VS_FIXEDFILEINFO *pVerInfo = NULL;
|
|
|
|
|
DWORD dwTemp, dwSize;
|
|
|
|
|
BYTE *pData = NULL;
|
|
|
|
|
UINT uLen;
|
|
|
|
|
|
|
|
|
|
dwSize = GetFileVersionInfoSize(filePath, &dwTemp);
|
|
|
|
|
if (dwSize == 0) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pData = new BYTE[dwSize + 1];
|
|
|
|
|
if (pData == NULL) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!GetFileVersionInfo(filePath, 0, dwSize, pData)) {
|
|
|
|
|
delete[] pData;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!VerQueryValue(pData, TEXT("\\"), (void **)&pVerInfo, &uLen)) {
|
|
|
|
|
delete[] pData;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DWORD verMS = pVerInfo->dwFileVersionMS;
|
|
|
|
|
DWORD verLS = pVerInfo->dwFileVersionLS;
|
|
|
|
|
DWORD major = HIWORD(verMS);
|
|
|
|
|
DWORD minor = LOWORD(verMS);
|
|
|
|
|
DWORD build = HIWORD(verLS);
|
|
|
|
|
DWORD revision = LOWORD(verLS);
|
|
|
|
|
delete[] pData;
|
|
|
|
|
|
|
|
|
|
StringCbPrintf(version, 0x20, TEXT("%d.%d.%d.%d"), major, minor, build, revision);
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int OpenWeChat(DWORD *pid)
|
|
|
|
|
{
|
|
|
|
|
int ret = -1;
|
|
|
|
|
STARTUPINFO si = { sizeof(si) };
|
2022-08-07 15:03:17 +08:00
|
|
|
|
WCHAR Path[MAX_PATH] = { 0 };
|
2021-02-12 23:21:57 +08:00
|
|
|
|
PROCESS_INFORMATION pi = { 0 };
|
|
|
|
|
|
2022-08-07 15:03:17 +08:00
|
|
|
|
ret = GetWeChatPath(Path);
|
2021-02-12 23:21:57 +08:00
|
|
|
|
if (ERROR_SUCCESS != ret) {
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!CreateProcess(NULL, Path, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
|
2022-08-07 15:03:17 +08:00
|
|
|
|
return GetLastError();
|
2021-02-12 23:21:57 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CloseHandle(pi.hThread);
|
|
|
|
|
CloseHandle(pi.hProcess);
|
|
|
|
|
|
|
|
|
|
*pid = pi.dwProcessId;
|
|
|
|
|
|
2022-08-07 15:03:17 +08:00
|
|
|
|
return ERROR_SUCCESS;
|
2021-02-12 23:21:57 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int GetWstringByAddress(DWORD address, wchar_t *buffer, DWORD buffer_size)
|
|
|
|
|
{
|
|
|
|
|
DWORD strLength = GET_DWORD(address + 4);
|
|
|
|
|
if (strLength == 0) {
|
|
|
|
|
return 0;
|
|
|
|
|
} else if (strLength > buffer_size) {
|
|
|
|
|
strLength = buffer_size - 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
wmemcpy_s(buffer, strLength + 1, GET_WSTRING(address), strLength + 1);
|
|
|
|
|
|
|
|
|
|
return strLength;
|
|
|
|
|
}
|
|
|
|
|
|
2022-08-07 20:50:49 +08:00
|
|
|
|
BSTR GetBstrByAddress(DWORD address)
|
|
|
|
|
{
|
|
|
|
|
wchar_t *p = GET_WSTRING(address);
|
|
|
|
|
if (p == NULL) {
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return SysAllocStringLen(GET_WSTRING(address), GET_DWORD(address + 4));
|
|
|
|
|
}
|
2022-08-07 15:03:17 +08:00
|
|
|
|
|
2022-08-07 20:08:54 +08:00
|
|
|
|
wstring GetWstringFromBstr(BSTR p)
|
2022-08-07 15:03:17 +08:00
|
|
|
|
{
|
2022-08-07 20:08:54 +08:00
|
|
|
|
wstring ws = L"";
|
2022-08-07 20:50:49 +08:00
|
|
|
|
if (p != NULL) {
|
2022-08-07 20:08:54 +08:00
|
|
|
|
ws = wstring(p);
|
2022-08-07 15:03:17 +08:00
|
|
|
|
SysFreeString(p);
|
|
|
|
|
}
|
2022-08-07 20:08:54 +08:00
|
|
|
|
return ws;
|
2022-08-07 15:03:17 +08:00
|
|
|
|
}
|
|
|
|
|
|
2022-08-07 23:49:37 +08:00
|
|
|
|
BSTR GetBstrFromString(const char *str)
|
|
|
|
|
{
|
|
|
|
|
int wslen = MultiByteToWideChar(CP_ACP, 0, str, strlen(str), 0, 0);
|
|
|
|
|
BSTR bstr = SysAllocStringLen(0, wslen);
|
|
|
|
|
MultiByteToWideChar(CP_ACP, 0, str, strlen(str), bstr, wslen);
|
|
|
|
|
|
|
|
|
|
return bstr;
|
|
|
|
|
}
|
|
|
|
|
|
2022-08-07 23:32:25 +08:00
|
|
|
|
BSTR GetBstrFromWstring(wstring ws)
|
|
|
|
|
{
|
|
|
|
|
if (!ws.empty()) {
|
|
|
|
|
return SysAllocStringLen(ws.data(), ws.size());
|
|
|
|
|
}
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2022-08-07 15:03:17 +08:00
|
|
|
|
void GetRpcMessage(WxMessage_t *wxMsg, RpcMessage_t rpcMsg)
|
|
|
|
|
{
|
|
|
|
|
wxMsg->self = rpcMsg.self;
|
|
|
|
|
wxMsg->type = rpcMsg.type;
|
|
|
|
|
wxMsg->source = rpcMsg.source;
|
|
|
|
|
wxMsg->id = GetWstringFromBstr(rpcMsg.id);
|
|
|
|
|
wxMsg->xml = GetWstringFromBstr(rpcMsg.xml);
|
|
|
|
|
wxMsg->wxId = GetWstringFromBstr(rpcMsg.wxId);
|
|
|
|
|
wxMsg->roomId = GetWstringFromBstr(rpcMsg.roomId);
|
|
|
|
|
wxMsg->content = GetWstringFromBstr(rpcMsg.content);
|
|
|
|
|
}
|
|
|
|
|
|
2021-02-12 23:21:57 +08:00
|
|
|
|
DWORD GetMemoryIntByAddress(HANDLE hProcess, DWORD address)
|
|
|
|
|
{
|
|
|
|
|
DWORD value = 0;
|
|
|
|
|
|
|
|
|
|
unsigned char data[4] = { 0 };
|
|
|
|
|
if (ReadProcessMemory(hProcess, (LPVOID)address, data, 4, 0)) {
|
|
|
|
|
value = data[0] & 0xFF;
|
|
|
|
|
value |= ((data[1] << 8) & 0xFF00);
|
|
|
|
|
value |= ((data[2] << 16) & 0xFF0000);
|
|
|
|
|
value |= ((data[3] << 24) & 0xFF000000);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
wstring GetUnicodeInfoByAddress(HANDLE hProcess, DWORD address)
|
|
|
|
|
{
|
|
|
|
|
wstring value = L"";
|
|
|
|
|
|
|
|
|
|
DWORD strAddress = GetMemoryIntByAddress(hProcess, address);
|
|
|
|
|
DWORD strLen = GetMemoryIntByAddress(hProcess, address + 0x4);
|
|
|
|
|
if (strLen > 500)
|
|
|
|
|
return value;
|
|
|
|
|
|
|
|
|
|
wchar_t cValue[500] = { 0 };
|
|
|
|
|
memset(cValue, 0, sizeof(cValue) / sizeof(wchar_t));
|
|
|
|
|
if (ReadProcessMemory(hProcess, (LPVOID)strAddress, cValue, (strLen + 1) * 2, 0)) {
|
|
|
|
|
value = wstring(cValue);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return value;
|
|
|
|
|
}
|