diff --git a/assets/请读我.txt b/assets/请读我.txt index 5ef767b..13b99f7 100644 --- a/assets/请读我.txt +++ b/assets/请读我.txt @@ -1,8 +1,8 @@ -使用方法: +使用方法 1: 将所有文件放到游戏根目录(left4dead2.exe 所在目录) -使用 `left4dead2_fix.exe` 启动游戏(目前不知道如何让 steam 能加载这个 launcher) +使用 `left4dead2_fix.exe` 启动游戏 如果需要添加启动项,请右键 `left4dead2_fix.exe` 创建快捷方式,之后在目标字段后面添加启动项(如果不会请问 deepseek) @@ -10,7 +10,27 @@ 由于动态修改代码,请以 -insecure 启动,或者自觉不要进有 vac 的服务器(被 vac 后果自负) -4gb_patch.exe 用于让 left4dead2.exe 最多只能用 2G 内存提高到 4G (32 位系统下内存总计 4G,默认情况下应用只被允许用 2G,剩下的分配给系统) + + + +使用方法 2: + +将所有文件放到游戏根目录(left4dead2.exe 所在目录) + +将真正的游戏 exe (left4dead2.exe) 改名为 left4dead2.orig.exe + +将 `left4dead2_fix.exe` 改名为 `left4dead2.exe` + +修改 ini 文件,设置 Redirect 中的 enable = true。 + +在 steam 中添加启动项 -steam -secure + +从 Steam 启动游戏,确认弹出的警告。 + +该方法会允许进入 vac 服务器,但是后果自负。 + + + 配置文件说明: @@ -18,6 +38,12 @@ [System] debug = false ; 开启调试输出 +[Redirect] +enable = true ; 开启伪装 exe +target = left4dead2.orig.exe ; 真正的 l4d2 游戏 exe 文件 +origin = left4dead2.exe ; 伪装的名字(必须是这个,游戏会自动寻找 left4dead2 文件夹加载资源) + + ; Too Many Indices 的上限数值(buffer 大小+ 判断) [Indices] enable = true ; 修改too many indices 上限和对应的判断检测。 diff --git a/justfile b/justfile index 9995961..1a15e87 100644 --- a/justfile +++ b/justfile @@ -38,7 +38,6 @@ release: cp build/windows/x86/release/left4dead2_fix.exe release/ cp assets/请读我.txt release/ cp "assets/left4dead2_fix - Shortcut.lnk" release/ - cp third/4gb_patch.exe release/ cp kpatch.ini release/ @run: diff --git a/kpatch.ini b/kpatch.ini index 8c96937..468d592 100644 --- a/kpatch.ini +++ b/kpatch.ini @@ -1,6 +1,12 @@ [System] debug = false -target = left4dead2.exe + + +[Redirect] +enable = false +target = left4dead2.orig.exe +origin = left4dead2.exe + ; Too Many Indices 的上限数值(buffer 大小 + 判断) [Indices] diff --git a/launcher/main.cpp b/launcher/main.cpp index 59420f9..e56dd2e 100644 --- a/launcher/main.cpp +++ b/launcher/main.cpp @@ -10,6 +10,8 @@ #include #include +#include "vars.h" + namespace fs = std::filesystem; // const wchar_t* game_name = L"left4dead2.exe"; @@ -17,14 +19,25 @@ bool debug = false; std::wstring game_name = L"left4dead2.exe"; void init_cfg() { - std::ifstream is("kpatch.ini"); - inipp::Ini ini; + // std::ifstream is("kpatch.ini"); + // inipp::Ini ini; - ini.parse(is); - inipp::extract(ini.sections["System"]["debug"], debug); - std::string tmp_name; - inipp::extract(ini.sections["System"]["target"], tmp_name); - game_name = std::wstring(tmp_name.begin(), tmp_name.end()); + // ini.parse(is); + // inipp::extract(ini.sections["System"]["debug"], debug); + // std::string tmp_name; + // inipp::extract(ini.sections["System"]["target"], tmp_name); + LoadIni(); + if (cfg::Redirect::enable) { + game_name = cfg::Redirect::target; + } else { + game_name = L"left4dead2.exe"; + } +} + +template +void debugPrint(T fmt, Args... args) { + std::wstring errMsg = std::wstring(L"[L4D2Fix] ") + std::vformat(fmt, std::make_wformat_args(args...)); + OutputDebugStringW(errMsg.c_str()); } int WINAPI wWinMain( @@ -33,6 +46,7 @@ int WINAPI wWinMain( _In_ LPWSTR lpwCmdLine, _In_ int nShowCmd ) { + std::wstring errMsg; init_cfg(); WCHAR working_path[MAX_PATH]; @@ -40,11 +54,12 @@ int WINAPI wWinMain( // Change the working directory to the directory containing the DLL. fs::path path(working_path); - SetCurrentDirectoryW(path.parent_path().wstring().c_str()); + debugPrint(L"working_path {}\n", working_path); LPCSTR dll_path = "kpatch.dll"; LPCWSTR target_exe_path = game_name.c_str(); + debugPrint(L"target_exe_path {}\n", target_exe_path); STARTUPINFOW si; PROCESS_INFORMATION pi; @@ -71,7 +86,7 @@ int WINAPI wWinMain( dll_path, nullptr)) { auto dwError = GetLastError(); - printf("DetourCreateProcessWithDllEx failed with error %ld\n", dwError); + debugPrint(L"DetourCreateProcessWithDllEx failed with error {}\n", dwError); ExitProcess(9009); } diff --git a/src/dllmain.cpp b/src/dllmain.cpp index 2523a03..32a2e94 100644 --- a/src/dllmain.cpp +++ b/src/dllmain.cpp @@ -23,6 +23,7 @@ #include "hooks_dvb.h" #include "hooks_indexbuffer.h" #include "hooks_vertexbuffer.h" +#include "hooks_exename.h" void InitConsole() { @@ -87,10 +88,25 @@ DWORD __stdcall Main(void*) { MessageBoxW(NULL, L"警告:你已开启 debug 输出。", L"L4D2 Fix", MB_OK|MB_SYSTEMMODAL|MB_ICONWARNING); } + if (cfg::Redirect::enable && cfg::Redirect::origin == L"left4dead2.exe") { + auto ret = MessageBoxW( + NULL, + L"警告,你可能开启了 L4D2Fix 伪装为 Left 4 Dead 2 原版 exe。\n该方法配合 -secure -steam 启动项将允许连接 VAC 服务器。\n如果造成 VAC 封禁,请自行承担后果。", L"L4D2 Fix", MB_OKCANCEL|MB_SYSTEMMODAL|MB_ICONWARNING); + switch (ret) { + case IDOK: + spdlog::warn(L"用户已确认,补丁将继续加载..."); + break; + case IDCANCEL: + spdlog::warn(L"用户取消补丁加载..."); + ExitProcess(0); + return TRUE; + } + } + std::filesystem::path startup_check = L"success.txt"; if (!std::filesystem::exists(startup_check)) { - MessageBoxW( + auto ret = MessageBoxW( NULL, L"这是一个启动测试,用于检验补丁是否正常运行。\n请注意由于修改内存,请不要进 VAC 服,后果自负。\n本弹窗仅首次启动出现,后续运行情况参见 L4D2Fix.log 日志文件。\n\n关注B站 5050 直播间,谢谢喵 by KurikoMoe!", L"L4D2 Fix", MB_OK); @@ -134,6 +150,11 @@ DWORD __stdcall Main(void*) { exit(-1); } + // Fix exe name + initExeNameHook(); + LPSTR buf = new char[255]; + GetModuleFileNameA(NULL, buf, 255); // Trigger the hook once + // Not known auto ret = 0; diff --git a/src/hooks_exename.h b/src/hooks_exename.h new file mode 100644 index 0000000..8eb7d28 --- /dev/null +++ b/src/hooks_exename.h @@ -0,0 +1,47 @@ +#pragma once +#define SPDLOG_WCHAR_TO_UTF8_SUPPORT +#include +#include + +#include +#include + +#include "vars.h" + +namespace fs = std::filesystem; + +decltype(&GetModuleFileNameA) oGetModuleFileNameAFn = nullptr; + +DWORD __stdcall hGetModuleFileNameA( + HMODULE hModule, + LPSTR lpFilename, + DWORD nSize +) { + // MessageBoxA(NULL, "GetModuleFileNameA Hooked!", "Info", MB_OK); + auto ret = oGetModuleFileNameAFn(hModule, lpFilename, nSize); + if (!lpFilename) return ret; + + fs::path filePath(lpFilename); + fs::path newFilePath(lpFilename); + std::wstring exeName = filePath.filename().wstring(); + if (cfg::Redirect::enable && exeName == cfg::Redirect::target) { + std::string newExeName = std::string( + cfg::Redirect::origin.begin(), cfg::Redirect::origin.end()); + newFilePath = newFilePath.replace_filename(newExeName); + std::string newFilePathStr = newFilePath.string(); + memcpy_s(lpFilename, nSize, newFilePath.string().c_str(), newFilePathStr.size() + 1); + spdlog::info("GetModuleFileNameA hooked: \n{} => {}", filePath.string(), newFilePath.string()); + } + return ret; +} + + + +void initExeNameHook() { + oGetModuleFileNameAFn = &GetModuleFileNameA; + DetourRestoreAfterWith(); + DetourTransactionBegin(); + DetourUpdateThread(GetCurrentThread()); + DetourAttach(&(PVOID&)oGetModuleFileNameAFn, hGetModuleFileNameA); + DetourTransactionCommit(); +} diff --git a/src/vars.h b/src/vars.h index c33f6a1..e0e4946 100644 --- a/src/vars.h +++ b/src/vars.h @@ -31,7 +31,12 @@ inipp::Ini ini; namespace cfg { namespace System { bool debug; +} + +namespace Redirect { + bool enable; std::wstring target; + std::wstring origin; } namespace Indices { @@ -75,9 +80,18 @@ void LoadIni() { { using namespace System; inipp::extract(ini.sections["System"]["debug"], debug); - std::string tmp_name; - inipp::extract(ini.sections["System"]["target"], tmp_name); - target = std::wstring(tmp_name.begin(), tmp_name.end()); + } + + { + using namespace Redirect; + inipp::extract(ini.sections["Redirect"]["enable"], enable); + if (enable) { + std::string tmp_name; + inipp::extract(ini.sections["Redirect"]["target"], tmp_name); + target = std::wstring(tmp_name.begin(), tmp_name.end()); + inipp::extract(ini.sections["Redirect"]["origin"], tmp_name); + origin = std::wstring(tmp_name.begin(), tmp_name.end()); + } } { diff --git a/xmake-requires.lock b/xmake-requires.lock index d0e1b07..ac7e4ce 100644 --- a/xmake-requires.lock +++ b/xmake-requires.lock @@ -2,6 +2,30 @@ __meta__ = { version = "1.0" }, + ["mingw|x86"] = { + ["minhook#31fecfc4"] = { + repo = { + branch = "master", + commit = "3d19345df6ab7745c5c779ee9b20166f96bc559a", + url = "https://github.com/xmake-io/xmake-repo.git" + }, + version = "v1.3.4" + }, + ["spdlog#31fecfc4"] = { + repo = { + branch = "master", + commit = "4333aa942c37880a4830485b0d2043d02d02391d", + url = "https://github.com/xmake-io/xmake-repo.git" + }, + version = "v1.15.3" + }, + ["vcpkg::detours#31fecfc4"] = { + version = "latest" + }, + ["vcpkg::inipp#31fecfc4"] = { + version = "latest" + } + }, ["mingw|x86_64"] = { ["minhook#31fecfc4"] = { repo = { diff --git a/xmake.lua b/xmake.lua index f69718e..9b10869 100644 --- a/xmake.lua +++ b/xmake.lua @@ -25,5 +25,7 @@ target(name) set_kind("binary") add_files("launcher/main.cpp") add_files("assets/app.rc") + add_includedirs("./src") + add_packages("spdlog", "vcpkg::inipp") add_links("user32", "gdi32") add_packages("vcpkg::detours")