From 5bf45402a8081f180b40ab80314dc70656ad8ccf Mon Sep 17 00:00:00 2001 From: Changhua Date: Wed, 17 Apr 2024 00:35:43 +0800 Subject: [PATCH] Fix injector --- WeChatFerry/com/util.h | 10 +-- WeChatFerry/sdk/injector.cpp | 116 +++++++++++++++++++++++++++-------- WeChatFerry/sdk/injector.h | 2 +- WeChatFerry/sdk/sdk.cpp | 66 ++++---------------- WeChatFerry/spy/spy.cpp | 8 +-- 5 files changed, 112 insertions(+), 90 deletions(-) diff --git a/WeChatFerry/com/util.h b/WeChatFerry/com/util.h index 5d79b4a..68808a6 100644 --- a/WeChatFerry/com/util.h +++ b/WeChatFerry/com/util.h @@ -2,11 +2,11 @@ #include -#define WECHAREXE L"WeChat.exe" -#define WECHATWINDLL L"WeChatWin.dll" -#define WECHATSDKDLL L"sdk.dll" -#define WECHATINJECTDLL L"spy.dll" -#define WECHATINJECTDLL_DEBUG L"spy_debug.dll" +#define WECHAREXE L"WeChat.exe" +#define WECHATWINDLL L"WeChatWin.dll" +#define WCFSDKDLL L"sdk.dll" +#define WCFSPYDLL L"spy.dll" +#define WCFSPYDLL_DEBUG L"spy_debug.dll" #define GET_DWORD(addr) ((DWORD) * (DWORD *)(addr)) #define GET_QWORD(addr) ((uint64_t) * (uint64_t *)(addr)) diff --git a/WeChatFerry/sdk/injector.cpp b/WeChatFerry/sdk/injector.cpp index fa67e55..ca84e7d 100644 --- a/WeChatFerry/sdk/injector.cpp +++ b/WeChatFerry/sdk/injector.cpp @@ -1,9 +1,43 @@ -#include "injector.h" +#include "framework.h" +#include "psapi.h" +#include +#include +#include + +#include "injector.h" +#include "util.h" + +HMODULE GetTargetModuleBase(HANDLE process, std::string dll) +{ + DWORD cbNeeded; + HMODULE moduleHandleList[512]; + BOOL ret = EnumProcessModulesEx(process, moduleHandleList, sizeof(moduleHandleList), &cbNeeded, LIST_MODULES_64BIT); + if (!ret) { + MessageBox(NULL, L"获取模块失败", L"GetTargetModuleBase", 0); + return NULL; + } + + if (cbNeeded > sizeof(moduleHandleList)) { + MessageBox(NULL, L"模块数量过多", L"GetTargetModuleBase", 0); + return NULL; + } + DWORD processCount = cbNeeded / sizeof(HMODULE); + + char moduleName[32]; + for (DWORD i = 0; i < processCount; i++) { + GetModuleBaseNameA(process, moduleHandleList[i], moduleName, 32); + if (!strncmp(dll.c_str(), moduleName, dll.size())) { + return moduleHandleList[i]; + } + } + return NULL; +} HANDLE InjectDll(DWORD pid, LPCWSTR dllPath, HMODULE *injectedBase) { HANDLE hThread; SIZE_T cszDLL = (wcslen(dllPath) + 1) * sizeof(WCHAR); + // 1. 打开目标进程 HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid); if (hProcess == NULL) { @@ -38,13 +72,17 @@ HANDLE InjectDll(DWORD pid, LPCWSTR dllPath, HMODULE *injectedBase) if (hThread == NULL) { VirtualFreeEx(hProcess, pRemoteAddress, 0, MEM_RELEASE); CloseHandle(hProcess); - + MessageBox(NULL, L"CreateRemoteThread 失败", L"InjectDll", 0); return NULL; } WaitForSingleObject(hThread, -1); - // GetExitCodeThread(hThread, (LPDWORD)injectedBase); CloseHandle(hThread); + + *injectedBase = GetTargetModuleBase(hProcess, std::filesystem::path(Wstring2String(dllPath)).filename().string()); + + printf("hProcess: %p, pRemoteAddress: %p, injectedBase: %p\n", hProcess, pRemoteAddress, *injectedBase); + VirtualFreeEx(hProcess, pRemoteAddress, 0, MEM_RELEASE); // CloseHandle(hProcess); // Close when exit @@ -55,6 +93,8 @@ bool EjectDll(HANDLE process, HMODULE dllBase) { HANDLE hThread = NULL; + printf("process: %p, dllBase: %p\n", process, dllBase); + // 使目标进程调用 FreeLibrary,卸载 DLL HMODULE k32 = GetModuleHandle(L"kernel32.dll"); if (k32 == NULL) { @@ -62,7 +102,8 @@ bool EjectDll(HANDLE process, HMODULE dllBase) return NULL; } - FARPROC libAddr = GetProcAddress(k32, "FreeLibrary"); + // FARPROC libAddr = GetProcAddress(k32, "FreeLibrary"); + FARPROC libAddr = GetProcAddress(k32, "FreeLibraryAndExitThread"); if (!libAddr) { MessageBox(NULL, L"获取 FreeLibrary 失败", L"InjectDll", 0); return NULL; @@ -79,35 +120,50 @@ bool EjectDll(HANDLE process, HMODULE dllBase) return true; } -static void *GetFuncAddr(LPCWSTR dllPath, HMODULE dllBase, LPCSTR funcName) +static LPVOID GetFuncAddr(HMODULE dllBase, LPCSTR funcName) { - HMODULE hLoaded = LoadLibrary(dllPath); - if (hLoaded == NULL) { - return NULL; - } + printf("dllBase: %p, funcName: %s\n", dllBase, funcName); + LPVOID absAddr = GetProcAddress(dllBase, funcName); + UINT64 offset = (UINT64)absAddr - (UINT64)dllBase; - void *absAddr = GetProcAddress(hLoaded, funcName); - DWORD offset = (DWORD)absAddr - (DWORD)hLoaded; - - FreeLibrary(hLoaded); - - return (void *)((DWORD)dllBase + offset); + printf("absAddr: %p, offset: %lld\n", absAddr, offset); + return (LPVOID)((UINT64)dllBase + offset); } -bool CallDllFunc(HANDLE process, LPCWSTR dllPath, HMODULE dllBase, LPCSTR funcName, LPVOID parameter, DWORD *ret) +static UINT64 GetFuncOffset(LPCWSTR dllPath, LPCSTR funcName) { - void *pFunc = GetFuncAddr(dllPath, dllBase, funcName); - if (pFunc == NULL) { - return false; + HMODULE dll = LoadLibrary(dllPath); + if (dll == NULL) { + MessageBox(NULL, L"获取 DLL 失败", L"GetFuncOffset", 0); + return 0; } - HANDLE hThread = CreateRemoteThread(process, NULL, 0, (LPTHREAD_START_ROUTINE)pFunc, parameter, 0, NULL); + LPVOID absAddr = GetProcAddress(dll, funcName); + UINT64 offset = (UINT64)absAddr - (UINT64)dll; + FreeLibrary(dll); + + return offset; +} + +bool CallDllFunc(HANDLE process, LPCWSTR dllPath, HMODULE dllBase, LPCSTR funcName, LPDWORD ret) +{ + // LPVOID pFunc = GetFuncAddr(dllBase, funcName); + UINT64 offset = GetFuncOffset(dllPath, funcName); + if (offset == 0) { + return false; + } + UINT64 pFunc = (UINT64)dllBase + GetFuncOffset(dllPath, funcName); + if (pFunc <= (UINT64)dllBase) { + return false; + } + printf("pFunc: %p\n", pFunc); + HANDLE hThread = CreateRemoteThread(process, NULL, 0, (LPTHREAD_START_ROUTINE)pFunc, NULL, 0, NULL); if (hThread == NULL) { return false; } WaitForSingleObject(hThread, INFINITE); if (ret != NULL) { - GetExitCodeThread(hThread, (LPDWORD)ret); + GetExitCodeThread(hThread, ret); } CloseHandle(hThread); @@ -115,13 +171,23 @@ bool CallDllFunc(HANDLE process, LPCWSTR dllPath, HMODULE dllBase, LPCSTR funcNa } bool CallDllFuncEx(HANDLE process, LPCWSTR dllPath, HMODULE dllBase, LPCSTR funcName, LPVOID parameter, size_t sz, - DWORD *ret) + LPDWORD ret) { - void *pFunc = GetFuncAddr(dllPath, dllBase, funcName); - if (pFunc == NULL) { + // LPVOID pFunc = GetFuncAddr(dllBase, funcName); + // if (pFunc == NULL) { + // return false; + // } + + UINT64 offset = GetFuncOffset(dllPath, funcName); + if (offset == 0) { + return false; + } + UINT64 pFunc = (UINT64)dllBase + GetFuncOffset(dllPath, funcName); + if (pFunc <= (UINT64)dllBase) { return false; } + printf("pFunc: %p\n", pFunc); LPVOID pRemoteAddress = VirtualAllocEx(process, NULL, sz, MEM_COMMIT, PAGE_READWRITE); if (pRemoteAddress == NULL) { MessageBox(NULL, L"申请内存失败", L"CallDllFuncEx", 0); @@ -139,7 +205,7 @@ bool CallDllFuncEx(HANDLE process, LPCWSTR dllPath, HMODULE dllBase, LPCSTR func WaitForSingleObject(hThread, INFINITE); VirtualFree(pRemoteAddress, 0, MEM_RELEASE); if (ret != NULL) { - GetExitCodeThread(hThread, (LPDWORD)ret); + GetExitCodeThread(hThread, ret); } CloseHandle(hThread); diff --git a/WeChatFerry/sdk/injector.h b/WeChatFerry/sdk/injector.h index e212a0e..07b4a28 100644 --- a/WeChatFerry/sdk/injector.h +++ b/WeChatFerry/sdk/injector.h @@ -4,6 +4,6 @@ HANDLE InjectDll(DWORD pid, LPCWSTR dllPath, HMODULE *injectedBase); bool EjectDll(HANDLE process, HMODULE dllBase); -bool CallDllFunc(HANDLE process, LPCWSTR dllPath, HMODULE dllBase, LPCSTR funcName, LPVOID parameter, DWORD *ret); +bool CallDllFunc(HANDLE process, LPCWSTR dllPath, HMODULE dllBase, LPCSTR funcName, DWORD *ret); bool CallDllFuncEx(HANDLE process, LPCWSTR dllPath, HMODULE dllBase, LPCSTR funcName, LPVOID parameter, size_t sz, DWORD *ret); diff --git a/WeChatFerry/sdk/sdk.cpp b/WeChatFerry/sdk/sdk.cpp index b657403..50270ef 100644 --- a/WeChatFerry/sdk/sdk.cpp +++ b/WeChatFerry/sdk/sdk.cpp @@ -10,19 +10,19 @@ #define WCF_LOCK ".wcf.lock" -static bool debugMode = false; +static bool dbg = false; static HANDLE wcProcess = NULL; static HMODULE spyBase = NULL; static WCHAR spyDllPath[MAX_PATH] = { 0 }; static int GetDllPath(bool debug, wchar_t *dllPath) { - GetModuleFileName(GetModuleHandle(WECHATSDKDLL), dllPath, MAX_PATH); + GetModuleFileName(GetModuleHandle(WCFSDKDLL), dllPath, MAX_PATH); PathRemoveFileSpec(dllPath); if (debug) { - PathAppend(dllPath, WECHATINJECTDLL_DEBUG); + PathAppend(dllPath, WCFSPYDLL_DEBUG); } else { - PathAppend(dllPath, WECHATINJECTDLL); + PathAppend(dllPath, WCFSPYDLL); } if (!PathFileExists(dllPath)) { @@ -35,6 +35,7 @@ static int GetDllPath(bool debug, wchar_t *dllPath) int WxInitSDK(bool debug, int port) { + dbg = debug; int status = 0; DWORD wcPid = 0; @@ -56,67 +57,22 @@ int WxInitSDK(bool debug, int port) return -1; } - return 0; - PortPath_t pp = { 0 }; pp.port = port; sprintf_s(pp.path, MAX_PATH, "%s", std::filesystem::current_path().string().c_str()); - MessageBoxA(NULL, pp.path, "WxInitSDK", 0); - // if (!CallDllFuncEx(wcProcess, spyDllPath, spyBase, "InitSpy", (LPVOID)&pp, sizeof(PortPath_t), NULL)) { - // MessageBox(NULL, L"初始化失败", L"WxInitSDK", 0); - // return -1; - // } - -#ifdef WCF - FILE *fd = fopen(WCF_LOCK, "wb"); - if (fd == NULL) { - MessageBox(NULL, L"无法打开lock文件", L"WxInitSDK", 0); - return -2; + printf("process: %p, base: %p, path: %s\n", wcProcess, spyBase, pp.path); + if (!CallDllFuncEx(wcProcess, spyDllPath, spyBase, "InitSpy", (LPVOID)&pp, sizeof(PortPath_t), NULL)) { + MessageBox(NULL, L"初始化失败", L"WxInitSDK", 0); + return -1; } - fwrite((uint8_t *)&debug, sizeof(debug), 1, fd); - fwrite((uint8_t *)&spyBase, sizeof(spyBase), 1, fd); - fclose(fd); -#endif - debugMode = debug; + return 0; } int WxDestroySDK() { - int status = 0; -#ifdef WCF - bool debug; - DWORD pid = GetWeChatPid(); - if (pid == 0) { - MessageBox(NULL, L"微信未运行", L"WxDestroySDK", 0); - return status; - } - - wcProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid); - if (wcProcess == NULL) { - MessageBox(NULL, L"微信未运行", L"WxDestroySDK", 0); - return -1; - } - - FILE *fd = fopen(WCF_LOCK, "rb"); - if (fd == NULL) { - MessageBox(NULL, L"无法打开lock文件", L"WxDestroySDK", 0); - return -2; - } - fread((uint8_t *)&debug, sizeof(debug), 1, fd); - fread((uint8_t *)&spyBase, sizeof(spyBase), 1, fd); - fclose(fd); - status = GetDllPath(debug, spyDllPath); -#else - status = GetDllPath(debugMode, spyDllPath); -#endif - - if (status != 0) { - return status; - } - - if (!CallDllFunc(wcProcess, spyDllPath, spyBase, "CleanupSpy", NULL, NULL)) { + if (!CallDllFunc(wcProcess, spyDllPath, spyBase, "CleanupSpy", NULL)) { return -1; } diff --git a/WeChatFerry/spy/spy.cpp b/WeChatFerry/spy/spy.cpp index ffabb53..48e73ad 100644 --- a/WeChatFerry/spy/spy.cpp +++ b/WeChatFerry/spy/spy.cpp @@ -12,7 +12,7 @@ DWORD g_WeChatWinDllAddr = 0; void InitSpy(LPVOID args) { MessageBox(NULL, L"InitSpy", L"InitSpy", 0); -#if 0 +#if 1 wchar_t version[16] = { 0 }; PortPath_t *pp = (PortPath_t *)args; int port = pp->port; @@ -21,7 +21,7 @@ void InitSpy(LPVOID args) InitLogger(path); g_WeChatWinDllAddr = (DWORD)GetModuleHandle(L"WeChatWin.dll"); // 获取wechatWin模块地址 if (g_WeChatWinDllAddr == 0) { - LOG_ERROR("获取wechatWin.dll模块地址失败"); + LOG_ERROR("获取 wechatWin.dll 模块地址失败"); return; } @@ -36,10 +36,10 @@ void InitSpy(LPVOID args) return; } - RpcStartServer(port); + // RpcStartServer(port); #endif } -void CleanupSpy() { /*RpcStopServer();*/ } +void CleanupSpy() { /*RpcStopServer();*/ MessageBox(NULL, L"CleanupSpy", L"CleanupSpy", 0);} int IsLogin(void) { return (int)GET_DWORD(g_WeChatWinDllAddr + g_WxCalls.login); }