#include "Shlwapi.h" #include "framework.h" #include #include #include #include #include #include #include "util.h" #pragma comment(lib, "shlwapi") #pragma comment(lib, "Version.lib") using namespace std; wstring String2Wstring(string s) { if (s.empty()) return wstring(); int size_needed = MultiByteToWideChar(CP_UTF8, 0, &s[0], (int)s.size(), NULL, 0); wstring ws(size_needed, 0); MultiByteToWideChar(CP_UTF8, 0, &s[0], (int)s.size(), &ws[0], size_needed); return ws; } string Wstring2String(wstring ws) { if (ws.empty()) return string(); int size_needed = WideCharToMultiByte(CP_UTF8, 0, &ws[0], (int)ws.size(), NULL, 0, NULL, NULL); string s(size_needed, 0); WideCharToMultiByte(CP_UTF8, 0, &ws[0], (int)ws.size(), &s[0], size_needed, NULL, NULL); return s; } static 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; } static int GetWeChatWinDLLPath(wchar_t *path) { int ret = GetWeChatPath(path); if (ret != ERROR_SUCCESS) { return ret; } PathRemoveFileSpecW(path); PathAppendW(path, WECHATWINDLL); if (!PathFileExists(path)) { // 微信从(大约)3.7开始,增加了一层版本目录: [3.7.0.29] PathRemoveFileSpec(path); _wfinddata_t findData; wstring dir = wstring(path) + L"\\[*.*"; 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); } return ret; } static 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 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; } DWORD GetWeChatPid() { DWORD pid = 0; HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); PROCESSENTRY32 pe32 = { sizeof(PROCESSENTRY32) }; while (Process32Next(hSnapshot, &pe32)) { wstring strProcess = pe32.szExeFile; if (strProcess == WECHAREXE) { pid = pe32.th32ProcessID; break; } } CloseHandle(hSnapshot); return pid; } int OpenWeChat(DWORD *pid) { *pid = GetWeChatPid(); if (*pid) { return ERROR_SUCCESS; } int ret = -1; STARTUPINFO si = { sizeof(si) }; WCHAR Path[MAX_PATH] = { 0 }; PROCESS_INFORMATION pi = { 0 }; ret = GetWeChatPath(Path); if (ERROR_SUCCESS != ret) { return ret; } if (!CreateProcess(NULL, Path, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) { return GetLastError(); } CloseHandle(pi.hThread); CloseHandle(pi.hProcess); *pid = pi.dwProcessId; return ERROR_SUCCESS; } 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; } string GetStringByAddress(DWORD address) { DWORD strLength = GET_DWORD(address + 4); return Wstring2String(wstring(GET_WSTRING(address), strLength)); } 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; }