Refactoring
This commit is contained in:
parent
1bec8ce8a2
commit
e012efc682
@ -3,13 +3,12 @@
|
||||
#include <filesystem>
|
||||
#include <iomanip>
|
||||
#include <memory>
|
||||
#include <spdlog/sinks/rotating_file_sink.h>
|
||||
#include <spdlog/sinks/stdout_color_sinks.h>
|
||||
#include <spdlog/spdlog.h>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include "util.h"
|
||||
#include <spdlog/sinks/rotating_file_sink.h>
|
||||
#include <spdlog/sinks/stdout_color_sinks.h>
|
||||
#include <spdlog/spdlog.h>
|
||||
|
||||
#define LOG_DEBUG(...) SPDLOG_DEBUG(__VA_ARGS__)
|
||||
#define LOG_INFO(...) SPDLOG_INFO(__VA_ARGS__)
|
||||
@ -48,7 +47,7 @@ inline void InitLogger(const std::string &path)
|
||||
logger = spdlog::rotating_logger_mt(DEFAULT_LOGGER_NAME, filename.string(), DEFAULT_LOGGER_MAX_SIZE,
|
||||
DEFAULT_LOGGER_MAX_FILES);
|
||||
} catch (const spdlog::spdlog_ex &ex) {
|
||||
MessageBox(NULL, util::s2w(ex.what()).c_str(), L"Init LOGGER ERROR", MB_ICONERROR);
|
||||
MessageBoxA(NULL, ex.what(), "Init LOGGER ERROR", MB_ICONERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,9 @@
|
||||
namespace util
|
||||
{
|
||||
|
||||
constexpr std::wstring_view WECHATEXE = L"WeChat.exe";
|
||||
constexpr std::string_view WECHATWINDLL = "WeChatWin.dll";
|
||||
|
||||
std::wstring s2w(const std::string &s)
|
||||
{
|
||||
if (s.empty()) return std::wstring();
|
||||
@ -60,7 +63,7 @@ static DWORD get_wechat_pid()
|
||||
|
||||
PROCESSENTRY32 pe32 = { sizeof(PROCESSENTRY32) };
|
||||
while (Process32Next(hSnapshot, &pe32)) {
|
||||
if (w2s(pe32.szExeFile) == WECHATEXE) {
|
||||
if (pe32.szExeFile == WECHATEXE) {
|
||||
pid = pe32.th32ProcessID;
|
||||
break;
|
||||
}
|
||||
|
@ -9,13 +9,6 @@
|
||||
|
||||
namespace util
|
||||
{
|
||||
|
||||
inline constexpr char WECHATEXE[] = "WeChat.exe";
|
||||
inline constexpr char WECHATWINDLL[] = "WeChatWin.dll";
|
||||
inline constexpr wchar_t WCFSDKDLL[] = L"sdk.dll";
|
||||
inline constexpr wchar_t WCFSPYDLL[] = L"spy.dll";
|
||||
inline constexpr wchar_t WCFSPYDLL_DEBUG[] = L"spy_debug.dll";
|
||||
|
||||
struct PortPath {
|
||||
int port;
|
||||
char path[MAX_PATH];
|
||||
|
@ -1,112 +1,108 @@
|
||||
#include "framework.h"
|
||||
#include "psapi.h"
|
||||
#include <filesystem>
|
||||
#include <string>
|
||||
#include "injector.h"
|
||||
|
||||
#include "injector.h"
|
||||
#include "util.h"
|
||||
#include <filesystem>
|
||||
|
||||
#include "psapi.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
HMODULE GetTargetModuleBase(HANDLE process, string dll)
|
||||
static void handle_injection_error(HANDLE process, LPVOID remote_address, const std::string &error_msg)
|
||||
{
|
||||
DWORD cbNeeded;
|
||||
HMODULE moduleHandleList[512];
|
||||
BOOL ret = EnumProcessModulesEx(process, moduleHandleList, sizeof(moduleHandleList), &cbNeeded, LIST_MODULES_64BIT);
|
||||
if (!ret) {
|
||||
MessageBox(NULL, L"获取模块失败", L"GetTargetModuleBase", 0);
|
||||
MessageBoxA(NULL, error_msg.c_str(), "Error", MB_ICONERROR);
|
||||
if (remote_address) {
|
||||
VirtualFreeEx(process, remote_address, 0, MEM_RELEASE);
|
||||
}
|
||||
if (process) {
|
||||
CloseHandle(process);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
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];
|
||||
DWORD count = needed / sizeof(HMODULE);
|
||||
char module_name[MAX_PATH];
|
||||
for (DWORD i = 0; i < count; i++) {
|
||||
GetModuleBaseNameA(process, modules[i], module_name, sizeof(module_name));
|
||||
if (!strncmp(dll.c_str(), module_name, dll.size())) {
|
||||
return modules[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
HANDLE InjectDll(DWORD pid, LPCWSTR dllPath, HMODULE *injectedBase)
|
||||
HANDLE inject_dll(DWORD pid, const string &dll_path, HMODULE *injected_base)
|
||||
{
|
||||
HANDLE hThread;
|
||||
SIZE_T cszDLL = (wcslen(dllPath) + 1) * sizeof(WCHAR);
|
||||
SIZE_T path_size = dll_path.size() + 1;
|
||||
|
||||
// 1. 打开目标进程
|
||||
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
|
||||
if (hProcess == NULL) {
|
||||
MessageBox(NULL, L"打开进程失败", L"InjectDll", 0);
|
||||
if (!hProcess) {
|
||||
MessageBoxA(NULL, "打开进程失败", "inject_dll", 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// 2. 在目标进程的内存里开辟空间
|
||||
LPVOID pRemoteAddress = VirtualAllocEx(hProcess, NULL, cszDLL, MEM_COMMIT, PAGE_READWRITE);
|
||||
if (pRemoteAddress == NULL) {
|
||||
MessageBox(NULL, L"DLL 路径写入失败", L"InjectDll", 0);
|
||||
LPVOID pRemoteAddress = VirtualAllocEx(hProcess, NULL, path_size, MEM_COMMIT, PAGE_READWRITE);
|
||||
if (!pRemoteAddress) {
|
||||
handle_injection_error(hProcess, NULL, "DLL 路径写入失败");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// 3. 把 dll 的路径写入到目标进程的内存空间中
|
||||
WriteProcessMemory(hProcess, pRemoteAddress, dllPath, cszDLL, NULL);
|
||||
WriteProcessMemory(hProcess, pRemoteAddress, dll_path.c_str(), path_size, NULL);
|
||||
|
||||
// 3. 创建一个远程线程,让目标进程调用 LoadLibrary
|
||||
HMODULE k32 = GetModuleHandle(L"kernel32.dll");
|
||||
if (k32 == NULL) {
|
||||
MessageBox(NULL, L"获取 kernel32 失败", L"InjectDll", 0);
|
||||
// 4. 创建一个远程线程,让目标进程调用 LoadLibrary
|
||||
HMODULE k32 = GetModuleHandleA("kernel32.dll");
|
||||
if (!k32) {
|
||||
handle_injection_error(hProcess, pRemoteAddress, "获取 kernel32 失败");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FARPROC libAddr = GetProcAddress(k32, "LoadLibraryW");
|
||||
FARPROC libAddr = GetProcAddress(k32, "LoadLibraryA");
|
||||
if (!libAddr) {
|
||||
MessageBox(NULL, L"获取 LoadLibrary 失败", L"InjectDll", 0);
|
||||
handle_injection_error(hProcess, pRemoteAddress, "获取 LoadLibrary 失败");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)libAddr, pRemoteAddress, 0, NULL);
|
||||
if (hThread == NULL) {
|
||||
VirtualFreeEx(hProcess, pRemoteAddress, 0, MEM_RELEASE);
|
||||
CloseHandle(hProcess);
|
||||
MessageBox(NULL, L"CreateRemoteThread 失败", L"InjectDll", 0);
|
||||
HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)libAddr, pRemoteAddress, 0, NULL);
|
||||
if (!hThread) {
|
||||
handle_injection_error(hProcess, pRemoteAddress, "CreateRemoteThread 失败");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
WaitForSingleObject(hThread, -1);
|
||||
WaitForSingleObject(hThread, INFINITE);
|
||||
CloseHandle(hThread);
|
||||
|
||||
*injectedBase = GetTargetModuleBase(hProcess, filesystem::path(util::w2s(dllPath)).filename().string());
|
||||
*injected_base = get_target_module_base(hProcess, filesystem::path(dll_path).filename().string());
|
||||
|
||||
VirtualFreeEx(hProcess, pRemoteAddress, 0, MEM_RELEASE);
|
||||
// CloseHandle(hProcess); // Close when exit
|
||||
|
||||
return hProcess;
|
||||
}
|
||||
|
||||
bool EjectDll(HANDLE process, HMODULE dllBase)
|
||||
bool eject_dll(HANDLE process, HMODULE dll_base)
|
||||
{
|
||||
HANDLE hThread = NULL;
|
||||
|
||||
// 使目标进程调用 FreeLibrary,卸载 DLL
|
||||
HMODULE k32 = GetModuleHandle(L"kernel32.dll");
|
||||
if (k32 == NULL) {
|
||||
MessageBox(NULL, L"获取 kernel32 失败", L"InjectDll", 0);
|
||||
return NULL;
|
||||
HMODULE k32 = GetModuleHandleA("kernel32.dll");
|
||||
if (!k32) {
|
||||
MessageBoxA(NULL, "获取 kernel32 失败", "eject_dll", 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
FARPROC libAddr = GetProcAddress(k32, "FreeLibraryAndExitThread");
|
||||
if (!libAddr) {
|
||||
MessageBox(NULL, L"获取 FreeLibrary 失败", L"InjectDll", 0);
|
||||
return NULL;
|
||||
MessageBoxA(NULL, "获取 FreeLibrary 失败", "eject_dll", 0);
|
||||
return false;
|
||||
}
|
||||
hThread = CreateRemoteThread(process, NULL, 0, (LPTHREAD_START_ROUTINE)libAddr, (LPVOID)dllBase, 0, NULL);
|
||||
if (hThread == NULL) {
|
||||
MessageBox(NULL, L"FreeLibrary 调用失败!", L"EjectDll", 0);
|
||||
|
||||
HANDLE hThread = CreateRemoteThread(process, NULL, 0, (LPTHREAD_START_ROUTINE)libAddr, (LPVOID)dll_base, 0, NULL);
|
||||
if (!hThread) {
|
||||
MessageBoxA(NULL, "FreeLibrary 调用失败!", "eject_dll", 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -116,38 +112,34 @@ bool EjectDll(HANDLE process, HMODULE dllBase)
|
||||
return true;
|
||||
}
|
||||
|
||||
static UINT64 GetFuncOffset(LPCWSTR dllPath, LPCSTR funcName)
|
||||
static uint64_t get_func_offset(const string &dll_path, const string &func_name)
|
||||
{
|
||||
HMODULE dll = LoadLibrary(dllPath);
|
||||
if (dll == NULL) {
|
||||
MessageBox(NULL, L"获取 DLL 失败", L"GetFuncOffset", 0);
|
||||
HMODULE dll = LoadLibraryA(dll_path.c_str());
|
||||
if (!dll) {
|
||||
MessageBoxA(NULL, "获取 DLL 失败", "get_func_offset", 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
LPVOID absAddr = GetProcAddress(dll, funcName);
|
||||
UINT64 offset = (UINT64)absAddr - (UINT64)dll;
|
||||
LPVOID absAddr = GetProcAddress(dll, func_name.c_str());
|
||||
uint64_t offset = reinterpret_cast<uint64_t>(absAddr) - reinterpret_cast<uint64_t>(dll);
|
||||
FreeLibrary(dll);
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
bool CallDllFunc(HANDLE process, LPCWSTR dllPath, HMODULE dllBase, LPCSTR funcName, LPDWORD ret)
|
||||
bool call_dll_func(HANDLE process, const string &dll_path, HMODULE dll_base, const string &func_name, DWORD *ret)
|
||||
{
|
||||
UINT64 offset = GetFuncOffset(dllPath, funcName);
|
||||
if (offset == 0) {
|
||||
return false;
|
||||
uint64_t offset = get_func_offset(dll_path, func_name);
|
||||
if (offset == 0 || offset > (UINT64_MAX - reinterpret_cast<uint64_t>(dll_base))) {
|
||||
return false; // 避免溢出
|
||||
}
|
||||
UINT64 pFunc = (UINT64)dllBase + GetFuncOffset(dllPath, funcName);
|
||||
if (pFunc <= (UINT64)dllBase) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint64_t pFunc = reinterpret_cast<uint64_t>(dll_base) + offset;
|
||||
HANDLE hThread = CreateRemoteThread(process, NULL, 0, (LPTHREAD_START_ROUTINE)pFunc, NULL, 0, NULL);
|
||||
if (hThread == NULL) {
|
||||
if (!hThread) {
|
||||
return false;
|
||||
}
|
||||
WaitForSingleObject(hThread, INFINITE);
|
||||
if (ret != NULL) {
|
||||
if (ret) {
|
||||
GetExitCodeThread(hThread, ret);
|
||||
}
|
||||
|
||||
@ -155,35 +147,32 @@ bool CallDllFunc(HANDLE process, LPCWSTR dllPath, HMODULE dllBase, LPCSTR funcNa
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CallDllFuncEx(HANDLE process, LPCWSTR dllPath, HMODULE dllBase, LPCSTR funcName, LPVOID parameter, size_t sz,
|
||||
LPDWORD ret)
|
||||
bool call_dll_func_ex(HANDLE process, const string &dll_path, HMODULE dll_base, const string &func_name,
|
||||
LPVOID parameter, size_t size, DWORD *ret)
|
||||
{
|
||||
UINT64 offset = GetFuncOffset(dllPath, funcName);
|
||||
if (offset == 0) {
|
||||
return false;
|
||||
uint64_t offset = get_func_offset(dll_path, func_name);
|
||||
if (offset == 0 || offset > (UINT64_MAX - reinterpret_cast<uint64_t>(dll_base))) {
|
||||
return false; // 避免溢出
|
||||
}
|
||||
UINT64 pFunc = (UINT64)dllBase + GetFuncOffset(dllPath, funcName);
|
||||
if (pFunc <= (UINT64)dllBase) {
|
||||
uint64_t pFunc = reinterpret_cast<uint64_t>(dll_base) + offset;
|
||||
LPVOID pRemoteAddress = VirtualAllocEx(process, NULL, size, MEM_COMMIT, PAGE_READWRITE);
|
||||
if (!pRemoteAddress) {
|
||||
MessageBoxA(NULL, "申请内存失败", "call_dll_func_ex", 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
LPVOID pRemoteAddress = VirtualAllocEx(process, NULL, sz, MEM_COMMIT, PAGE_READWRITE);
|
||||
if (pRemoteAddress == NULL) {
|
||||
MessageBox(NULL, L"申请内存失败", L"CallDllFuncEx", 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
WriteProcessMemory(process, pRemoteAddress, parameter, sz, NULL);
|
||||
WriteProcessMemory(process, pRemoteAddress, parameter, size, NULL);
|
||||
|
||||
HANDLE hThread = CreateRemoteThread(process, NULL, 0, (LPTHREAD_START_ROUTINE)pFunc, pRemoteAddress, 0, NULL);
|
||||
if (hThread == NULL) {
|
||||
VirtualFree(pRemoteAddress, 0, MEM_RELEASE);
|
||||
MessageBox(NULL, L"远程调用失败", L"CallDllFuncEx", 0);
|
||||
if (!hThread) {
|
||||
VirtualFreeEx(process, pRemoteAddress, 0, MEM_RELEASE);
|
||||
MessageBoxA(NULL, "远程调用失败", "call_dll_func_ex", 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
WaitForSingleObject(hThread, INFINITE);
|
||||
VirtualFree(pRemoteAddress, 0, MEM_RELEASE);
|
||||
if (ret != NULL) {
|
||||
VirtualFreeEx(process, pRemoteAddress, 0, MEM_RELEASE);
|
||||
if (ret) {
|
||||
GetExitCodeThread(hThread, ret);
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "framework.h"
|
||||
|
||||
HANDLE InjectDll(DWORD pid, LPCWSTR dllPath, HMODULE *injectedBase);
|
||||
bool EjectDll(HANDLE process, HMODULE dllBase);
|
||||
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);
|
||||
HANDLE inject_dll(DWORD pid, const std::string &dll_path, HMODULE *injected_base);
|
||||
bool eject_dll(HANDLE process, HMODULE dll_base);
|
||||
bool call_dll_func(HANDLE process, const std::string &dll_path, HMODULE dll_base, const std::string &func, DWORD *ret);
|
||||
bool call_dll_func_ex(HANDLE process, const std::string &dll_path, HMODULE dll_base, const std::string &func,
|
||||
LPVOID parameter, size_t size, DWORD *ret);
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "framework.h"
|
||||
#include "sdk.h"
|
||||
|
||||
#include <chrono>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
@ -6,55 +7,56 @@
|
||||
#include <process.h>
|
||||
#include <sstream>
|
||||
#include <thread>
|
||||
|
||||
#include "framework.h"
|
||||
#include <tlhelp32.h>
|
||||
|
||||
#include "injector.h"
|
||||
#include "sdk.h"
|
||||
#include "util.h"
|
||||
|
||||
static BOOL injected = false;
|
||||
static bool injected = false;
|
||||
static HANDLE wcProcess = NULL;
|
||||
static HMODULE spyBase = NULL;
|
||||
static std::wstring spyDllPath;
|
||||
static std::string spyDllPath;
|
||||
|
||||
constexpr char DISCLAIMER_FILE[] = ".license_accepted.flag";
|
||||
constexpr char DISCLAIMER_TEXT_FILE[] = "DISCLAIMER.md";
|
||||
constexpr std::string_view WCFSDKDLL = "sdk.dll";
|
||||
constexpr std::string_view WCFSPYDLL = "spy.dll";
|
||||
constexpr std::string_view 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<std::wstring> ReadDisclaimerText(const char *filePath)
|
||||
static std::optional<std::string> read_disclaimer_text(const std::string &path)
|
||||
{
|
||||
std::ifstream file(filePath, std::ios::binary);
|
||||
std::ifstream file(path, std::ios::binary);
|
||||
if (!file.is_open()) {
|
||||
return std::nullopt; // 文件打开失败
|
||||
}
|
||||
|
||||
std::string content((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
|
||||
return util::s2w(content);
|
||||
return std::string((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
|
||||
}
|
||||
|
||||
static bool ShowDisclaimer()
|
||||
static bool show_disclaimer()
|
||||
{
|
||||
if (std::filesystem::exists(DISCLAIMER_FILE)) {
|
||||
if (std::filesystem::exists(DISCLAIMER_FLAG)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
std::optional<std::wstring> disclaimerTextOpt = ReadDisclaimerText(DISCLAIMER_TEXT_FILE);
|
||||
if (!disclaimerTextOpt.has_value() || disclaimerTextOpt->empty()) {
|
||||
MessageBox(NULL, L"免责声明文件为空或读取失败。", L"错误", MB_ICONERROR);
|
||||
auto disclaimerTextOpt = read_disclaimer_text(std::string(DISCLAIMER_TEXT_FILE));
|
||||
if (!disclaimerTextOpt || disclaimerTextOpt->empty()) {
|
||||
MessageBoxA(NULL, "免责声明文件为空或读取失败。", "错误", MB_ICONERROR);
|
||||
return false;
|
||||
}
|
||||
|
||||
std::wstring disclaimerText = *disclaimerTextOpt;
|
||||
|
||||
int result = MessageBox(NULL, disclaimerText.c_str(), L"免责声明", MB_ICONWARNING | MB_OKCANCEL | MB_DEFBUTTON2);
|
||||
|
||||
int result
|
||||
= MessageBoxA(NULL, disclaimerTextOpt->c_str(), "免责声明", MB_ICONWARNING | MB_OKCANCEL | MB_DEFBUTTON2);
|
||||
if (result == IDCANCEL) {
|
||||
MessageBox(NULL, L"您拒绝了免责声明,程序将退出。", L"提示", MB_ICONINFORMATION);
|
||||
MessageBoxA(NULL, "您拒绝了免责声明,程序将退出。", "提示", MB_ICONINFORMATION);
|
||||
return false;
|
||||
}
|
||||
|
||||
std::ofstream flagFile(DISCLAIMER_FILE, std::ios::out | std::ios::trunc);
|
||||
std::ofstream flagFile(std::string(DISCLAIMER_FLAG), std::ios::out | std::ios::trunc);
|
||||
if (!flagFile) {
|
||||
MessageBox(NULL, L"无法创建协议标志文件。", L"错误", MB_ICONERROR);
|
||||
MessageBoxA(NULL, "无法创建协议标志文件。", "错误", MB_ICONERROR);
|
||||
return false;
|
||||
}
|
||||
flagFile << "User accepted the license agreement.";
|
||||
@ -62,62 +64,56 @@ static bool ShowDisclaimer()
|
||||
return true;
|
||||
}
|
||||
|
||||
static std::wstring GetDllPath(bool debug)
|
||||
static std::string get_dll_path(bool debug)
|
||||
{
|
||||
WCHAR buffer[MAX_PATH] = { 0 };
|
||||
GetModuleFileName(GetModuleHandle(WCFSDKDLL), buffer, MAX_PATH);
|
||||
char buffer[MAX_PATH] = { 0 };
|
||||
GetModuleFileNameA(GetModuleHandleA(WCFSDKDLL), buffer, MAX_PATH);
|
||||
|
||||
std::filesystem::path path(buffer);
|
||||
path.remove_filename(); // 移除文件名,保留目录路径
|
||||
|
||||
path.remove_filename(); // 只保留目录路径
|
||||
path /= debug ? WCFSPYDLL_DEBUG : WCFSPYDLL;
|
||||
|
||||
if (!std::filesystem::exists(path)) {
|
||||
MessageBox(NULL, path.c_str(), L"文件不存在", MB_ICONERROR);
|
||||
return L"";
|
||||
MessageBoxA(NULL, path.string().c_str(), "文件不存在", MB_ICONERROR);
|
||||
return "";
|
||||
}
|
||||
|
||||
return path.wstring();
|
||||
return path.string();
|
||||
}
|
||||
|
||||
int WxInitSDK(bool debug, int port)
|
||||
{
|
||||
if (!ShowDisclaimer()) {
|
||||
if (!show_disclaimer()) {
|
||||
exit(-1); // 用户拒绝协议,退出程序
|
||||
}
|
||||
|
||||
int status = 0;
|
||||
DWORD wcPid = 0;
|
||||
|
||||
spyDllPath = GetDllPath(debug);
|
||||
spyDllPath = get_dll_path(debug);
|
||||
if (spyDllPath.empty()) {
|
||||
return ERROR_FILE_NOT_FOUND; // DLL 文件路径不存在
|
||||
}
|
||||
|
||||
status = util::open_wechat(&wcPid);
|
||||
if (status != 0) {
|
||||
MessageBox(NULL, L"打开微信失败", L"WxInitSDK", 0);
|
||||
MessageBoxA(NULL, "打开微信失败", "WxInitSDK", 0);
|
||||
return status;
|
||||
}
|
||||
|
||||
if (!IsProcessX64(wcPid)) {
|
||||
MessageBox(NULL, L"只支持 64 位微信", L"WxInitSDK", 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::seconds(2)); // 等待微信打开
|
||||
wcProcess = InjectDll(wcPid, spyDllPath.c_str(), &spyBase);
|
||||
wcProcess = inject_dll(wcPid, spyDllPath, &spyBase);
|
||||
if (wcProcess == NULL) {
|
||||
MessageBox(NULL, L"注入失败", L"WxInitSDK", 0);
|
||||
MessageBoxA(NULL, "注入失败", "WxInitSDK", 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
PortPath_t pp = { 0 };
|
||||
pp.port = port;
|
||||
sprintf_s(pp.path, MAX_PATH, "%s", std::filesystem::current_path().string().c_str());
|
||||
util::PortPath pp = { 0 };
|
||||
pp.port = port;
|
||||
snprintf(pp.path, MAX_PATH, "%s", std::filesystem::current_path().string().c_str());
|
||||
|
||||
if (!CallDllFuncEx(wcProcess, spyDllPath.c_str(), spyBase, "InitSpy", (LPVOID)&pp, sizeof(PortPath_t), NULL)) {
|
||||
MessageBox(NULL, L"初始化失败", L"WxInitSDK", 0);
|
||||
if (!call_dll_func_ex(wcProcess, spyDllPath, spyBase, "InitSpy", (LPVOID)&pp, sizeof(PortPath_t), NULL)) {
|
||||
MessageBoxA(NULL, "初始化失败", "WxInitSDK", 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -128,16 +124,16 @@ int WxInitSDK(bool debug, int port)
|
||||
int WxDestroySDK()
|
||||
{
|
||||
if (!injected) {
|
||||
return 1; // 未注入
|
||||
}
|
||||
|
||||
if (!call_dll_func(wcProcess, spyDllPath, spyBase, "CleanupSpy", NULL)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!CallDllFunc(wcProcess, spyDllPath.c_str(), spyBase, "CleanupSpy", NULL)) {
|
||||
if (!eject_dll(wcProcess, spyBase)) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (!EjectDll(wcProcess, spyBase)) {
|
||||
return -3; // TODO: Unify error codes
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user