WeChatFerry/SDK/util.cpp

251 lines
6.3 KiB
C++
Raw Normal View History

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;
}