Fix injector
This commit is contained in:
parent
651ab8959d
commit
5bf45402a8
@ -2,11 +2,11 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#define WECHAREXE L"WeChat.exe"
|
#define WECHAREXE L"WeChat.exe"
|
||||||
#define WECHATWINDLL L"WeChatWin.dll"
|
#define WECHATWINDLL L"WeChatWin.dll"
|
||||||
#define WECHATSDKDLL L"sdk.dll"
|
#define WCFSDKDLL L"sdk.dll"
|
||||||
#define WECHATINJECTDLL L"spy.dll"
|
#define WCFSPYDLL L"spy.dll"
|
||||||
#define WECHATINJECTDLL_DEBUG L"spy_debug.dll"
|
#define WCFSPYDLL_DEBUG L"spy_debug.dll"
|
||||||
|
|
||||||
#define GET_DWORD(addr) ((DWORD) * (DWORD *)(addr))
|
#define GET_DWORD(addr) ((DWORD) * (DWORD *)(addr))
|
||||||
#define GET_QWORD(addr) ((uint64_t) * (uint64_t *)(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 InjectDll(DWORD pid, LPCWSTR dllPath, HMODULE *injectedBase)
|
||||||
{
|
{
|
||||||
HANDLE hThread;
|
HANDLE hThread;
|
||||||
SIZE_T cszDLL = (wcslen(dllPath) + 1) * sizeof(WCHAR);
|
SIZE_T cszDLL = (wcslen(dllPath) + 1) * sizeof(WCHAR);
|
||||||
|
|
||||||
// 1. 打开目标进程
|
// 1. 打开目标进程
|
||||||
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
|
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
|
||||||
if (hProcess == NULL) {
|
if (hProcess == NULL) {
|
||||||
@ -38,13 +72,17 @@ HANDLE InjectDll(DWORD pid, LPCWSTR dllPath, HMODULE *injectedBase)
|
|||||||
if (hThread == NULL) {
|
if (hThread == NULL) {
|
||||||
VirtualFreeEx(hProcess, pRemoteAddress, 0, MEM_RELEASE);
|
VirtualFreeEx(hProcess, pRemoteAddress, 0, MEM_RELEASE);
|
||||||
CloseHandle(hProcess);
|
CloseHandle(hProcess);
|
||||||
|
MessageBox(NULL, L"CreateRemoteThread 失败", L"InjectDll", 0);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
WaitForSingleObject(hThread, -1);
|
WaitForSingleObject(hThread, -1);
|
||||||
// GetExitCodeThread(hThread, (LPDWORD)injectedBase);
|
|
||||||
CloseHandle(hThread);
|
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);
|
VirtualFreeEx(hProcess, pRemoteAddress, 0, MEM_RELEASE);
|
||||||
// CloseHandle(hProcess); // Close when exit
|
// CloseHandle(hProcess); // Close when exit
|
||||||
|
|
||||||
@ -55,6 +93,8 @@ bool EjectDll(HANDLE process, HMODULE dllBase)
|
|||||||
{
|
{
|
||||||
HANDLE hThread = NULL;
|
HANDLE hThread = NULL;
|
||||||
|
|
||||||
|
printf("process: %p, dllBase: %p\n", process, dllBase);
|
||||||
|
|
||||||
// 使目标进程调用 FreeLibrary,卸载 DLL
|
// 使目标进程调用 FreeLibrary,卸载 DLL
|
||||||
HMODULE k32 = GetModuleHandle(L"kernel32.dll");
|
HMODULE k32 = GetModuleHandle(L"kernel32.dll");
|
||||||
if (k32 == NULL) {
|
if (k32 == NULL) {
|
||||||
@ -62,7 +102,8 @@ bool EjectDll(HANDLE process, HMODULE dllBase)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
FARPROC libAddr = GetProcAddress(k32, "FreeLibrary");
|
// FARPROC libAddr = GetProcAddress(k32, "FreeLibrary");
|
||||||
|
FARPROC libAddr = GetProcAddress(k32, "FreeLibraryAndExitThread");
|
||||||
if (!libAddr) {
|
if (!libAddr) {
|
||||||
MessageBox(NULL, L"获取 FreeLibrary 失败", L"InjectDll", 0);
|
MessageBox(NULL, L"获取 FreeLibrary 失败", L"InjectDll", 0);
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -79,35 +120,50 @@ bool EjectDll(HANDLE process, HMODULE dllBase)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *GetFuncAddr(LPCWSTR dllPath, HMODULE dllBase, LPCSTR funcName)
|
static LPVOID GetFuncAddr(HMODULE dllBase, LPCSTR funcName)
|
||||||
{
|
{
|
||||||
HMODULE hLoaded = LoadLibrary(dllPath);
|
printf("dllBase: %p, funcName: %s\n", dllBase, funcName);
|
||||||
if (hLoaded == NULL) {
|
LPVOID absAddr = GetProcAddress(dllBase, funcName);
|
||||||
return NULL;
|
UINT64 offset = (UINT64)absAddr - (UINT64)dllBase;
|
||||||
}
|
|
||||||
|
|
||||||
void *absAddr = GetProcAddress(hLoaded, funcName);
|
printf("absAddr: %p, offset: %lld\n", absAddr, offset);
|
||||||
DWORD offset = (DWORD)absAddr - (DWORD)hLoaded;
|
return (LPVOID)((UINT64)dllBase + offset);
|
||||||
|
|
||||||
FreeLibrary(hLoaded);
|
|
||||||
|
|
||||||
return (void *)((DWORD)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);
|
HMODULE dll = LoadLibrary(dllPath);
|
||||||
if (pFunc == NULL) {
|
if (dll == NULL) {
|
||||||
return false;
|
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) {
|
if (hThread == NULL) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
WaitForSingleObject(hThread, INFINITE);
|
WaitForSingleObject(hThread, INFINITE);
|
||||||
if (ret != NULL) {
|
if (ret != NULL) {
|
||||||
GetExitCodeThread(hThread, (LPDWORD)ret);
|
GetExitCodeThread(hThread, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
CloseHandle(hThread);
|
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,
|
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);
|
// LPVOID pFunc = GetFuncAddr(dllBase, funcName);
|
||||||
if (pFunc == NULL) {
|
// 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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf("pFunc: %p\n", pFunc);
|
||||||
LPVOID pRemoteAddress = VirtualAllocEx(process, NULL, sz, MEM_COMMIT, PAGE_READWRITE);
|
LPVOID pRemoteAddress = VirtualAllocEx(process, NULL, sz, MEM_COMMIT, PAGE_READWRITE);
|
||||||
if (pRemoteAddress == NULL) {
|
if (pRemoteAddress == NULL) {
|
||||||
MessageBox(NULL, L"申请内存失败", L"CallDllFuncEx", 0);
|
MessageBox(NULL, L"申请内存失败", L"CallDllFuncEx", 0);
|
||||||
@ -139,7 +205,7 @@ bool CallDllFuncEx(HANDLE process, LPCWSTR dllPath, HMODULE dllBase, LPCSTR func
|
|||||||
WaitForSingleObject(hThread, INFINITE);
|
WaitForSingleObject(hThread, INFINITE);
|
||||||
VirtualFree(pRemoteAddress, 0, MEM_RELEASE);
|
VirtualFree(pRemoteAddress, 0, MEM_RELEASE);
|
||||||
if (ret != NULL) {
|
if (ret != NULL) {
|
||||||
GetExitCodeThread(hThread, (LPDWORD)ret);
|
GetExitCodeThread(hThread, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
CloseHandle(hThread);
|
CloseHandle(hThread);
|
||||||
|
@ -4,6 +4,6 @@
|
|||||||
|
|
||||||
HANDLE InjectDll(DWORD pid, LPCWSTR dllPath, HMODULE *injectedBase);
|
HANDLE InjectDll(DWORD pid, LPCWSTR dllPath, HMODULE *injectedBase);
|
||||||
bool EjectDll(HANDLE process, HMODULE dllBase);
|
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,
|
bool CallDllFuncEx(HANDLE process, LPCWSTR dllPath, HMODULE dllBase, LPCSTR funcName, LPVOID parameter, size_t sz,
|
||||||
DWORD *ret);
|
DWORD *ret);
|
||||||
|
@ -10,19 +10,19 @@
|
|||||||
|
|
||||||
#define WCF_LOCK ".wcf.lock"
|
#define WCF_LOCK ".wcf.lock"
|
||||||
|
|
||||||
static bool debugMode = false;
|
static bool dbg = false;
|
||||||
static HANDLE wcProcess = NULL;
|
static HANDLE wcProcess = NULL;
|
||||||
static HMODULE spyBase = NULL;
|
static HMODULE spyBase = NULL;
|
||||||
static WCHAR spyDllPath[MAX_PATH] = { 0 };
|
static WCHAR spyDllPath[MAX_PATH] = { 0 };
|
||||||
|
|
||||||
static int GetDllPath(bool debug, wchar_t *dllPath)
|
static int GetDllPath(bool debug, wchar_t *dllPath)
|
||||||
{
|
{
|
||||||
GetModuleFileName(GetModuleHandle(WECHATSDKDLL), dllPath, MAX_PATH);
|
GetModuleFileName(GetModuleHandle(WCFSDKDLL), dllPath, MAX_PATH);
|
||||||
PathRemoveFileSpec(dllPath);
|
PathRemoveFileSpec(dllPath);
|
||||||
if (debug) {
|
if (debug) {
|
||||||
PathAppend(dllPath, WECHATINJECTDLL_DEBUG);
|
PathAppend(dllPath, WCFSPYDLL_DEBUG);
|
||||||
} else {
|
} else {
|
||||||
PathAppend(dllPath, WECHATINJECTDLL);
|
PathAppend(dllPath, WCFSPYDLL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!PathFileExists(dllPath)) {
|
if (!PathFileExists(dllPath)) {
|
||||||
@ -35,6 +35,7 @@ static int GetDllPath(bool debug, wchar_t *dllPath)
|
|||||||
|
|
||||||
int WxInitSDK(bool debug, int port)
|
int WxInitSDK(bool debug, int port)
|
||||||
{
|
{
|
||||||
|
dbg = debug;
|
||||||
int status = 0;
|
int status = 0;
|
||||||
DWORD wcPid = 0;
|
DWORD wcPid = 0;
|
||||||
|
|
||||||
@ -56,67 +57,22 @@ int WxInitSDK(bool debug, int port)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
PortPath_t pp = { 0 };
|
PortPath_t pp = { 0 };
|
||||||
pp.port = port;
|
pp.port = port;
|
||||||
sprintf_s(pp.path, MAX_PATH, "%s", std::filesystem::current_path().string().c_str());
|
sprintf_s(pp.path, MAX_PATH, "%s", std::filesystem::current_path().string().c_str());
|
||||||
|
|
||||||
MessageBoxA(NULL, pp.path, "WxInitSDK", 0);
|
printf("process: %p, base: %p, path: %s\n", wcProcess, spyBase, pp.path);
|
||||||
// if (!CallDllFuncEx(wcProcess, spyDllPath, spyBase, "InitSpy", (LPVOID)&pp, sizeof(PortPath_t), NULL)) {
|
if (!CallDllFuncEx(wcProcess, spyDllPath, spyBase, "InitSpy", (LPVOID)&pp, sizeof(PortPath_t), NULL)) {
|
||||||
// MessageBox(NULL, L"初始化失败", L"WxInitSDK", 0);
|
MessageBox(NULL, L"初始化失败", L"WxInitSDK", 0);
|
||||||
// return -1;
|
return -1;
|
||||||
// }
|
|
||||||
|
|
||||||
#ifdef WCF
|
|
||||||
FILE *fd = fopen(WCF_LOCK, "wb");
|
|
||||||
if (fd == NULL) {
|
|
||||||
MessageBox(NULL, L"无法打开lock文件", L"WxInitSDK", 0);
|
|
||||||
return -2;
|
|
||||||
}
|
}
|
||||||
fwrite((uint8_t *)&debug, sizeof(debug), 1, fd);
|
|
||||||
fwrite((uint8_t *)&spyBase, sizeof(spyBase), 1, fd);
|
|
||||||
fclose(fd);
|
|
||||||
#endif
|
|
||||||
debugMode = debug;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int WxDestroySDK()
|
int WxDestroySDK()
|
||||||
{
|
{
|
||||||
int status = 0;
|
if (!CallDllFunc(wcProcess, spyDllPath, spyBase, "CleanupSpy", NULL)) {
|
||||||
#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)) {
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ DWORD g_WeChatWinDllAddr = 0;
|
|||||||
void InitSpy(LPVOID args)
|
void InitSpy(LPVOID args)
|
||||||
{
|
{
|
||||||
MessageBox(NULL, L"InitSpy", L"InitSpy", 0);
|
MessageBox(NULL, L"InitSpy", L"InitSpy", 0);
|
||||||
#if 0
|
#if 1
|
||||||
wchar_t version[16] = { 0 };
|
wchar_t version[16] = { 0 };
|
||||||
PortPath_t *pp = (PortPath_t *)args;
|
PortPath_t *pp = (PortPath_t *)args;
|
||||||
int port = pp->port;
|
int port = pp->port;
|
||||||
@ -21,7 +21,7 @@ void InitSpy(LPVOID args)
|
|||||||
InitLogger(path);
|
InitLogger(path);
|
||||||
g_WeChatWinDllAddr = (DWORD)GetModuleHandle(L"WeChatWin.dll"); // 获取wechatWin模块地址
|
g_WeChatWinDllAddr = (DWORD)GetModuleHandle(L"WeChatWin.dll"); // 获取wechatWin模块地址
|
||||||
if (g_WeChatWinDllAddr == 0) {
|
if (g_WeChatWinDllAddr == 0) {
|
||||||
LOG_ERROR("获取wechatWin.dll模块地址失败");
|
LOG_ERROR("获取 wechatWin.dll 模块地址失败");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -36,10 +36,10 @@ void InitSpy(LPVOID args)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
RpcStartServer(port);
|
// RpcStartServer(port);
|
||||||
#endif
|
#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); }
|
int IsLogin(void) { return (int)GET_DWORD(g_WeChatWinDllAddr + g_WxCalls.login); }
|
||||||
|
Loading…
Reference in New Issue
Block a user