Fix injector

This commit is contained in:
Changhua 2024-04-17 00:35:43 +08:00
parent 651ab8959d
commit 5bf45402a8
5 changed files with 112 additions and 90 deletions

View File

@ -4,9 +4,9 @@
#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 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))

View File

@ -1,9 +1,43 @@
#include "injector.h"
#include "framework.h"
#include "psapi.h"
#include <filesystem>
#include <stdio.h>
#include <string>
#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);

View File

@ -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);

View File

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

View File

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