Fix injector
This commit is contained in:
parent
651ab8959d
commit
5bf45402a8
@ -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))
|
||||
|
@ -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;
|
||||
|
||||
printf("absAddr: %p, offset: %lld\n", absAddr, offset);
|
||||
return (LPVOID)((UINT64)dllBase + offset);
|
||||
}
|
||||
|
||||
void *absAddr = GetProcAddress(hLoaded, funcName);
|
||||
DWORD offset = (DWORD)absAddr - (DWORD)hLoaded;
|
||||
|
||||
FreeLibrary(hLoaded);
|
||||
|
||||
return (void *)((DWORD)dllBase + offset);
|
||||
static UINT64 GetFuncOffset(LPCWSTR dllPath, LPCSTR funcName)
|
||||
{
|
||||
HMODULE dll = LoadLibrary(dllPath);
|
||||
if (dll == NULL) {
|
||||
MessageBox(NULL, L"获取 DLL 失败", L"GetFuncOffset", 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool CallDllFunc(HANDLE process, LPCWSTR dllPath, HMODULE dllBase, LPCSTR funcName, LPVOID parameter, DWORD *ret)
|
||||
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)
|
||||
{
|
||||
void *pFunc = GetFuncAddr(dllPath, dllBase, funcName);
|
||||
if (pFunc == NULL) {
|
||||
// LPVOID pFunc = GetFuncAddr(dllBase, funcName);
|
||||
UINT64 offset = GetFuncOffset(dllPath, funcName);
|
||||
if (offset == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
HANDLE hThread = CreateRemoteThread(process, NULL, 0, (LPTHREAD_START_ROUTINE)pFunc, parameter, 0, NULL);
|
||||
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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
@ -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); }
|
||||
|
Loading…
Reference in New Issue
Block a user