diff --git a/WeChatFerry/com/util.h b/WeChatFerry/com/util.h index e2a0e4a..1998fbb 100644 --- a/WeChatFerry/com/util.h +++ b/WeChatFerry/com/util.h @@ -70,6 +70,12 @@ inline void FreeBuffer(void *buffer) { if (buffer) HeapFree(GetProcessHeap(), 8, buffer); } +inline int MsgBox(HWND hWnd, const std::string &text, const std::string &caption = "WCF", UINT uType = MB_OK) +{ + std::wstring wText = s2w(text); + std::wstring wCaption = s2w(caption); + return MessageBoxW(nullptr, wText.c_str(), wCaption.c_str(), uType); +} template static T *AllocBuffer(size_t count) { diff --git a/WeChatFerry/sdk/injector.cpp b/WeChatFerry/sdk/injector.cpp index d990854..913ba87 100644 --- a/WeChatFerry/sdk/injector.cpp +++ b/WeChatFerry/sdk/injector.cpp @@ -4,11 +4,13 @@ #include "psapi.h" +#include "util.h" + using namespace std; static void handle_injection_error(HANDLE process, LPVOID remote_address, const std::string &error_msg) { - MessageBoxA(NULL, error_msg.c_str(), "Error", MB_ICONERROR); + util::MsgBox(NULL, error_msg.c_str(), "Error", MB_ICONERROR); if (remote_address) { VirtualFreeEx(process, remote_address, 0, MEM_RELEASE); } @@ -22,7 +24,7 @@ HMODULE get_target_module_base(HANDLE process, const string &dll) DWORD needed; HMODULE modules[512]; if (!EnumProcessModulesEx(process, modules, sizeof(modules), &needed, LIST_MODULES_64BIT)) { - MessageBoxA(NULL, "获取模块失败", "get_target_module_base", 0); + util::MsgBox(NULL, "获取模块失败", "get_target_module_base", 0); return NULL; } @@ -44,7 +46,7 @@ HANDLE inject_dll(DWORD pid, const string &dll_path, HMODULE *injected_base) // 1. 打开目标进程 HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid); if (!hProcess) { - MessageBoxA(NULL, "打开进程失败", "inject_dll", 0); + util::MsgBox(NULL, "打开进程失败", "inject_dll", 0); return NULL; } @@ -90,19 +92,19 @@ bool eject_dll(HANDLE process, HMODULE dll_base) { HMODULE k32 = GetModuleHandleA("kernel32.dll"); if (!k32) { - MessageBoxA(NULL, "获取 kernel32 失败", "eject_dll", 0); + util::MsgBox(NULL, "获取 kernel32 失败", "eject_dll", 0); return false; } FARPROC libAddr = GetProcAddress(k32, "FreeLibraryAndExitThread"); if (!libAddr) { - MessageBoxA(NULL, "获取 FreeLibrary 失败", "eject_dll", 0); + util::MsgBox(NULL, "获取 FreeLibrary 失败", "eject_dll", 0); return false; } HANDLE hThread = CreateRemoteThread(process, NULL, 0, (LPTHREAD_START_ROUTINE)libAddr, (LPVOID)dll_base, 0, NULL); if (!hThread) { - MessageBoxA(NULL, "FreeLibrary 调用失败!", "eject_dll", 0); + util::MsgBox(NULL, "FreeLibrary 调用失败!", "eject_dll", 0); return false; } @@ -116,7 +118,7 @@ static uint64_t get_func_offset(const string &dll_path, const string &func_name) { HMODULE dll = LoadLibraryA(dll_path.c_str()); if (!dll) { - MessageBoxA(NULL, "获取 DLL 失败", "get_func_offset", 0); + util::MsgBox(NULL, "获取 DLL 失败", "get_func_offset", 0); return 0; } @@ -157,7 +159,7 @@ bool call_dll_func_ex(HANDLE process, const string &dll_path, HMODULE dll_base, uint64_t pFunc = reinterpret_cast(dll_base) + offset; LPVOID pRemoteAddress = VirtualAllocEx(process, NULL, size, MEM_COMMIT, PAGE_READWRITE); if (!pRemoteAddress) { - MessageBoxA(NULL, "申请内存失败", "call_dll_func_ex", 0); + util::MsgBox(NULL, "申请内存失败", "call_dll_func_ex", 0); return false; } @@ -166,7 +168,7 @@ bool call_dll_func_ex(HANDLE process, const string &dll_path, HMODULE dll_base, HANDLE hThread = CreateRemoteThread(process, NULL, 0, (LPTHREAD_START_ROUTINE)pFunc, pRemoteAddress, 0, NULL); if (!hThread) { VirtualFreeEx(process, pRemoteAddress, 0, MEM_RELEASE); - MessageBoxA(NULL, "远程调用失败", "call_dll_func_ex", 0); + util::MsgBox(NULL, "远程调用失败", "call_dll_func_ex", 0); return false; } diff --git a/WeChatFerry/sdk/sdk.cpp b/WeChatFerry/sdk/sdk.cpp index e1dbdc8..8363414 100644 --- a/WeChatFerry/sdk/sdk.cpp +++ b/WeChatFerry/sdk/sdk.cpp @@ -14,6 +14,8 @@ #include "injector.h" #include "util.h" +extern "C" IMAGE_DOS_HEADER __ImageBase; + static bool injected = false; static HANDLE wcProcess = NULL; static HMODULE spyBase = NULL; @@ -26,38 +28,46 @@ constexpr char WCFSPYDLL_DEBUG[] = "spy_debug.dll"; constexpr std::string_view DISCLAIMER_FLAG = ".license_accepted.flag"; constexpr std::string_view DISCLAIMER_TEXT_FILE = "DISCLAIMER.md"; -static std::optional read_disclaimer_text(const std::string &path) -{ - std::ifstream file(path, std::ios::binary); - if (!file.is_open()) { - return std::nullopt; // 文件打开失败 - } +namespace fs = std::filesystem; - return std::string((std::istreambuf_iterator(file)), std::istreambuf_iterator()); +static fs::path get_module_directory() +{ + char buffer[MAX_PATH] = { 0 }; + HMODULE hModule = reinterpret_cast(&__ImageBase); + GetModuleFileNameA(hModule, buffer, MAX_PATH); + fs::path modulePath(buffer); + return modulePath.parent_path(); } static bool show_disclaimer() { - if (std::filesystem::exists(DISCLAIMER_FLAG)) { + fs::path sdk_path = get_module_directory(); + if (fs::exists(sdk_path / DISCLAIMER_FLAG)) { return true; } - auto disclaimerTextOpt = read_disclaimer_text(std::string(DISCLAIMER_TEXT_FILE)); - if (!disclaimerTextOpt || disclaimerTextOpt->empty()) { - MessageBoxA(NULL, "免责声明文件为空或读取失败。", "错误", MB_ICONERROR); + fs::path path = sdk_path / DISCLAIMER_TEXT_FILE; + std::ifstream file(path, std::ios::binary); + if (!file.is_open()) { + util::MsgBox(NULL, "免责声明文件读取失败。", "错误", MB_ICONERROR); return false; } - int result - = MessageBoxA(NULL, disclaimerTextOpt->c_str(), "免责声明", MB_ICONWARNING | MB_OKCANCEL | MB_DEFBUTTON2); + auto disclaimerText = std::string((std::istreambuf_iterator(file)), std::istreambuf_iterator()); + if (disclaimerText.empty()) { + util::MsgBox(NULL, "免责声明文件为空", "错误", MB_ICONERROR); + return false; + } + + int result = util::MsgBox(NULL, disclaimerText.c_str(), "免责声明", MB_ICONWARNING | MB_OKCANCEL | MB_DEFBUTTON2); if (result == IDCANCEL) { - MessageBoxA(NULL, "您拒绝了免责声明,程序将退出。", "提示", MB_ICONINFORMATION); + util::MsgBox(NULL, "您拒绝了免责声明,程序将退出。", "提示", MB_ICONINFORMATION); return false; } - std::ofstream flagFile(std::string(DISCLAIMER_FLAG), std::ios::out | std::ios::trunc); + std::ofstream flagFile(sdk_path / DISCLAIMER_FLAG, std::ios::out | std::ios::trunc); if (!flagFile) { - MessageBoxA(NULL, "无法创建协议标志文件。", "错误", MB_ICONERROR); + util::MsgBox(NULL, "无法创建协议标志文件。", "错误", MB_ICONERROR); return false; } flagFile << "User accepted the license agreement."; @@ -70,12 +80,12 @@ static std::string get_dll_path(bool debug) char buffer[MAX_PATH] = { 0 }; GetModuleFileNameA(GetModuleHandleA(WCFSDKDLL), buffer, MAX_PATH); - std::filesystem::path path(buffer); + fs::path path(buffer); path.remove_filename(); // 只保留目录路径 path /= debug ? WCFSPYDLL_DEBUG : WCFSPYDLL; - if (!std::filesystem::exists(path)) { - MessageBoxA(NULL, path.string().c_str(), "文件不存在", MB_ICONERROR); + if (!fs::exists(path)) { + util::MsgBox(NULL, path.string().c_str(), "文件不存在", MB_ICONERROR); return ""; } @@ -98,21 +108,21 @@ int WxInitSDK(bool debug, int port) status = util::open_wechat(wcPid); if (status != 0) { - MessageBoxA(NULL, "打开微信失败", "WxInitSDK", 0); + util::MsgBox(NULL, "打开微信失败", "WxInitSDK", 0); return status; } std::this_thread::sleep_for(std::chrono::seconds(2)); // 等待微信打开 wcProcess = inject_dll(wcPid, spyDllPath, &spyBase); if (wcProcess == NULL) { - MessageBoxA(NULL, "注入失败", "WxInitSDK", 0); + util::MsgBox(NULL, "注入失败", "WxInitSDK", 0); return -1; } injected = true; util::PortPath pp = { 0 }; pp.port = port; - snprintf(pp.path, MAX_PATH, "%s", std::filesystem::current_path().string().c_str()); + snprintf(pp.path, MAX_PATH, "%s", fs::current_path().string().c_str()); status = -3; // TODO: 统一错误码 bool success = call_dll_func_ex(wcProcess, spyDllPath, spyBase, "InitSpy", (LPVOID)&pp, sizeof(util::PortPath), diff --git a/WeChatFerry/spy/spy.cpp b/WeChatFerry/spy/spy.cpp index ae5ee39..dc6a700 100644 --- a/WeChatFerry/spy/spy.cpp +++ b/WeChatFerry/spy/spy.cpp @@ -25,7 +25,7 @@ int Init(void *args) std::string msg = fmt::format("WCF 支持版本: {},当前版本: {}", SUPPORT_VERSION, version); if (version != SUPPORT_VERSION) { LOG_ERROR(msg); - MessageBoxA(NULL, msg.c_str(), "微信版本错误", MB_ICONERROR); + util::MsgBox(NULL, msg.c_str(), "微信版本错误", MB_ICONERROR); return -2; }