diff --git a/230130-hookgamesendto/inc/inject.h b/230130-hookgamesendto/inc/inject.h index d44264722bbbaddcf9aa51bf71ced4aaa1576602..e591b1b8f62367da700ed728443d7e4116d59b28 100644 --- a/230130-hookgamesendto/inc/inject.h +++ b/230130-hookgamesendto/inc/inject.h @@ -3,3 +3,5 @@ bool inject_dll(DWORD pid, const char *dll_path); DWORD find_pid_by_name(const char *name); +HMODULE find_module_handle_from_pid(DWORD pid, const char *module_name); +bool remove_module(DWORD pid, HMODULE module_handle); diff --git a/230130-hookgamesendto/injciv6/Makefile b/230130-hookgamesendto/injciv6/Makefile index 553cfb44a6be0914f249c41ed502a1026a2803c6..bd0883e56dd5279b36f28c9076ac184ea77f4103 100644 --- a/230130-hookgamesendto/injciv6/Makefile +++ b/230130-hookgamesendto/injciv6/Makefile @@ -4,13 +4,19 @@ cxxflags = -c -O1 -I ../inc cxx64prefix = x86_64-w64-mingw32- objdir = ./obj/ bindir = ../bin/ -src = injciv6.cpp inject.cpp -obj = $(patsubst %.cpp, $(objdir)%.o, $(src)) -target = $(bindir)injciv6.exe +src_inject = injciv6.cpp inject.cpp +src_remove = civ6remove.cpp inject.cpp +obj_inject = $(patsubst %.cpp, $(objdir)%.o, $(src_inject)) +obj_remove = $(patsubst %.cpp, $(objdir)%.o, $(src_remove)) +target_inject = $(bindir)injciv6.exe +target_remove = $(bindir)civ6remove.exe -all: check $(target) +all: check $(target_inject) $(target_remove) -$(target): $(obj) +$(target_inject): $(obj_inject) + $(cxx64prefix)$(cxx) -o $@ $^ -static -mwindows + +$(target_remove): $(obj_remove) $(cxx64prefix)$(cxx) -o $@ $^ -static -mwindows $(objdir)%.o: %.cpp diff --git a/230130-hookgamesendto/injciv6/civ6remove.cpp b/230130-hookgamesendto/injciv6/civ6remove.cpp new file mode 100644 index 0000000000000000000000000000000000000000..cf0fbd3d311309f2539e88d670a558191b3f679e --- /dev/null +++ b/230130-hookgamesendto/injciv6/civ6remove.cpp @@ -0,0 +1,41 @@ +#include +#include "inject.h" +#include "injciv6.h" + +int main(int argc, char *argv[]) +{ + bool isadmin = IsUserAnAdmin(); + DWORD pid = 0; + int msgres = 0; + HMODULE module_handle = 0; + pid = get_civ6_proc(); + if (pid == 0) { + MessageBoxW(0, L"找不到游戏进程", L"错误", MB_ICONERROR); + return 0; + } + module_handle = find_module_handle_from_pid(pid, "hookdll64.dll"); + if (module_handle == 0) { + MessageBoxW(0, L"当前没有注入DLL", L"错误", MB_ICONERROR); + return 0; + } +retry_remove: + if (remove_module(pid, module_handle)) { + MessageBoxW(0, L"成功移除DLL!", L"成功", MB_OK); + return 0; + } + if (isadmin) { + msgres = MessageBoxW(0, L"移除失败", L"错误", MB_RETRYCANCEL | MB_ICONERROR); + if (msgres == IDRETRY) + goto retry_remove; + return 0; + } + msgres = MessageBoxW(0, L"移除失败,是否以管理员权限重试?", L"错误", MB_ICONERROR | MB_RETRYCANCEL); + if (msgres == IDRETRY) { + retry_runas: + if (runas_admin(argv[0])) // 成功运行就退出自己 + return 0; + msgres = MessageBoxW(0, L"请在弹出的窗口中点击“是”", L"错误", MB_ICONERROR | MB_RETRYCANCEL); + if (msgres == IDRETRY) + goto retry_runas; + } +} diff --git a/230130-hookgamesendto/injciv6/injciv6.cpp b/230130-hookgamesendto/injciv6/injciv6.cpp index 6eb5d0bbb098df4299e3a98db368be6a73b6e0cb..fbe91cdbc1e77e79ddd0af8fecb4761032033c46 100644 --- a/230130-hookgamesendto/injciv6/injciv6.cpp +++ b/230130-hookgamesendto/injciv6/injciv6.cpp @@ -1,27 +1,7 @@ #include #include -#include #include "inject.h" - -bool runas_admin(const char *exename) -{ - SHELLEXECUTEINFOA sei; - memset(&sei, 0, sizeof(sei)); - sei.cbSize = sizeof(sei); - sei.fMask = SEE_MASK_FLAG_DDEWAIT | SEE_MASK_FLAG_NO_UI; // 设置等待+不显示错误框 - sei.lpVerb = "runas"; - sei.lpFile = exename; - sei.nShow = SW_SHOWNORMAL; - return ShellExecuteExA(&sei); -} - -static DWORD get_civ6_proc() -{ - DWORD pid = find_pid_by_name("CivilizationVI.exe"); - if (pid == 0) - pid = find_pid_by_name("CivilizationVI_DX12.exe"); - return pid; -} +#include "injciv6.h" int main(int argc, char *argv[]) { diff --git a/230130-hookgamesendto/injciv6/injciv6.h b/230130-hookgamesendto/injciv6/injciv6.h new file mode 100644 index 0000000000000000000000000000000000000000..c8e6dc0580bac3891f7b7ffbf0c8e5d904f70869 --- /dev/null +++ b/230130-hookgamesendto/injciv6/injciv6.h @@ -0,0 +1,24 @@ +#pragma once + +#include +#include "inject.h" + +inline bool runas_admin(const char *exename) +{ + SHELLEXECUTEINFOA sei; + memset(&sei, 0, sizeof(sei)); + sei.cbSize = sizeof(sei); + sei.fMask = SEE_MASK_FLAG_DDEWAIT | SEE_MASK_FLAG_NO_UI; + sei.lpVerb = "runas"; + sei.lpFile = exename; + sei.nShow = SW_SHOWNORMAL; + return ShellExecuteExA(&sei); +} + +inline DWORD get_civ6_proc() +{ + DWORD pid = find_pid_by_name("CivilizationVI.exe"); + if (pid == 0) + pid = find_pid_by_name("CivilizationVI_DX12.exe"); + return pid; +} diff --git a/230130-hookgamesendto/src/inject.cpp b/230130-hookgamesendto/src/inject.cpp index 26957731df7a91f5d7f8806b0010aa51ab7527b1..5942312909a4b2b616b763f8235e069f0f1848eb 100644 --- a/230130-hookgamesendto/src/inject.cpp +++ b/230130-hookgamesendto/src/inject.cpp @@ -49,3 +49,41 @@ DWORD find_pid_by_name(const char *name) CloseHandle(procsnapshot); return 0; } + +HMODULE find_module_handle_from_pid(DWORD pid, const char *module_name) +{ + HMODULE h_result = 0; + HANDLE hsnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid); + MODULEENTRY32 module_entry; + module_entry.dwSize = sizeof(MODULEENTRY32); + Module32First(hsnap, &module_entry); + do { + if (strcmp(module_entry.szModule, module_name) == 0) { + h_result = module_entry.hModule; + break; + } + } while (Module32Next(hsnap, &module_entry)); + CloseHandle(hsnap); + return h_result; +} + +bool remove_module(DWORD pid, HMODULE module_handle) +{ + HANDLE hproc = 0; + HANDLE hthread = 0; + bool result = false; + hproc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid); + if (hproc == 0) goto finally; + hthread = CreateRemoteThread(hproc, NULL, 0, (LPTHREAD_START_ROUTINE)FreeLibrary, module_handle, 0, NULL); // 创建远程线程注入 + if (hthread == 0) goto finally; + WaitForSingleObject(hthread, INFINITE); + DWORD threadres; + GetExitCodeThread(hthread, &threadres); + result = threadres != 0; +finally: + if (hthread != 0) + CloseHandle(hthread); + if (hproc != 0) + CloseHandle(hproc); + return result; +}