diff --git a/kpatch.ini b/kpatch.ini index 77dd203..60a809b 100644 --- a/kpatch.ini +++ b/kpatch.ini @@ -1,7 +1,7 @@ [System] debug = false -; Too Many Indices 的上限数值(buffer 大小+ 判断) +; Too Many Indices 的上限数值(buffer 大小 + 判断) [Indices] enable = true value = 131072 @@ -18,4 +18,3 @@ enable = false debug = true old_value = 32768 new_value = 65536 - diff --git a/src/dllmain.cpp b/src/dllmain.cpp index 79ff66e..2523a03 100644 --- a/src/dllmain.cpp +++ b/src/dllmain.cpp @@ -21,6 +21,8 @@ #include "hooks_indices.h" #include "hooks_dvb.h" +#include "hooks_indexbuffer.h" +#include "hooks_vertexbuffer.h" void InitConsole() { @@ -115,7 +117,7 @@ DWORD __stdcall Main(void*) { auto absPath = std::filesystem::absolute(relPath); std::wcout << absPath << std::endl; - spdlog::info(L"Loading Dll fromg {}", absPath.wstring()); + spdlog::info(L"Loading Dll from {}", absPath.wstring()); HMODULE hDll = LoadLibraryExW(absPath.c_str(), nullptr, LOAD_WITH_ALTERED_SEARCH_PATH); @@ -138,6 +140,10 @@ DWORD __stdcall Main(void*) { ret += PatchIndices(hDll, dllName); ret += hooks_dvb(hDll, dllName); + // Experiments + // ret += hooks_indexbuffer(hDll, dllName); + // ret += VertexBuffer::hooks_vertexbuffer(hDll, dllName); + if (ret != 0) { MessageBoxW(NULL, L"未能正常应用补丁,patch 未生效,请联系开发者\n这只是一个警告,可能不影响游戏运行", L"L4D2 Fix", MB_OK); } else { diff --git a/src/hooks_indexbuffer.h b/src/hooks_indexbuffer.h new file mode 100644 index 0000000..52b42dc --- /dev/null +++ b/src/hooks_indexbuffer.h @@ -0,0 +1,83 @@ +#pragma once +#define SPDLOG_WCHAR_TO_UTF8_SUPPORT +#include +#include + +#include +#include +#include +#include + +#include + +#include "inipp.h" + +#include "helper.hpp" +#include "vars.h" + +// --------------------------------------------------------------------------------- + +using CIndexBufferCtorFn = void* (__thiscall*)(void*, void*, int, char, char); +CIndexBufferCtorFn oCIndexBufferCtorFn = nullptr; + +void*__fastcall hCIndexBufferCtorFn( + void* This, DWORD EDX, + void* pD3Device, + int bufSize, char a6, char a7) +{ + if (cfg::IndexBuffer::debug) { + std::string msg = std::format("CIndexBuffer bufSize: {}", bufSize); + spdlog::info(msg); + } + + MEMORYSTATUSEX statex; + statex.dwLength = sizeof(statex); + if (GlobalMemoryStatusEx(&statex)) { + spdlog::info("Total physical memory: {} MB", statex.ullTotalPhys / (1024 * 1024)); + spdlog::info("Available physical memory: {} MB", statex.ullAvailPhys / (1024 * 1024)); + spdlog::info("Total virtual memory: {} MB", statex.ullTotalVirtual / (1024 * 1024)); + spdlog::info("Available virtual memory: {} MB", statex.ullAvailVirtual / (1024 * 1024)); + spdlog::info("===================="); + } + + + // count *= 2; + // if (count > 131072) count = 131072; + // if (count > 131072) count = 131072; + if (bufSize == 0x8000) bufSize = 0xF0000; + // if (bufSize > 0x20000) bufSize = 0x20000; + + return oCIndexBufferCtorFn(This, pD3Device, bufSize, a6, a7); +} + +int patchIndexBuffer(HMODULE hDll) { + const char* pat = "55 8B EC 8A 45 10 24 01 02 C0 56 8B F1 8A 4D 14 8A 56 14 02 C0 80 E1 01 0A C1 02 C0 57 8B 7D 0C"; + std::uint8_t* ptr = Memory::PatternScan(hDll, pat, 0); + if (ptr == nullptr) { + spdlog::info(L"Can not find the CIndexBuffer::Ctor"); + return -1; + } + + spdlog::info(L"Hook the CIndexBuffer::Ctor @ 0x{:0x}", (intptr_t)ptr - (intptr_t)hDll); + oCIndexBufferCtorFn = reinterpret_cast(ptr); + + DetourRestoreAfterWith(); + DetourTransactionBegin(); + DetourUpdateThread(GetCurrentThread()); + DetourAttach(&(PVOID&)oCIndexBufferCtorFn, hCIndexBufferCtorFn); + DetourTransactionCommit(); + + return 0; +} + +// --------------------------------------------------------------------------------- + +int hooks_indexbuffer(HMODULE hDll, std::wstring dllName) { + auto ret = 0; + + if (cfg::IndexBuffer::enable) { + ret += patchIndexBuffer(hDll); + } + + return ret; +} diff --git a/src/hooks_vertexbuffer.h b/src/hooks_vertexbuffer.h new file mode 100644 index 0000000..88580d3 --- /dev/null +++ b/src/hooks_vertexbuffer.h @@ -0,0 +1,74 @@ +#pragma once +#define SPDLOG_WCHAR_TO_UTF8_SUPPORT +#include +#include + +#include +#include +#include +#include + +#include + +#include "inipp.h" + +#include "helper.hpp" +#include "vars.h" + +// --------------------------------------------------------------------------------- + +namespace VertexBuffer { + +using CVertexBufferCtorFn = void* (__thiscall*)(void*, void*, int, int, int, int, int, char*, char, char); +CVertexBufferCtorFn oCVertexBufferCtorFn = nullptr; + +void*__fastcall hCVertexBufferCtorFn( + void* This, DWORD EDX, + void* pD3Device, int a3, int a4, int a5, + int count, int bufSize, + char * source, char a6, char a7) +{ + if (cfg::VertexBuffer::debug) { + std::string msg = std::format("CVertexBuffer count: {}, bufSize: {}", count, bufSize); + spdlog::info(msg); + } + + if (bufSize == 0x8000) bufSize = 0xF0000; + // if (bufSize > 0x20000) bufSize = 0x20000; + + return oCVertexBufferCtorFn(This, pD3Device, a3, a4, a5, count, bufSize, source, a6, a7); +} + +int patchVertexBuffer(HMODULE hDll) { + const char* pat = "55 8B EC 81 EC 08 01 00 00 A1 ?? ?? ?? ?? 33 C5 89 45 FC 53 56 57 8B 45 08"; + std::uint8_t* ptr = Memory::PatternScan(hDll, pat, 0); + if (ptr == nullptr) { + spdlog::info(L"Can not find the CVertexBuffer::Ctor"); + return -1; + } + + spdlog::info(L"Hook the CVertexBuffer::Ctor @ 0x{:0x}", (intptr_t)ptr - (intptr_t)hDll); + oCVertexBufferCtorFn = reinterpret_cast(ptr); + + DetourRestoreAfterWith(); + DetourTransactionBegin(); + DetourUpdateThread(GetCurrentThread()); + DetourAttach(&(PVOID&)oCVertexBufferCtorFn, hCVertexBufferCtorFn); + DetourTransactionCommit(); + + return 0; +} + +// --------------------------------------------------------------------------------- + +int hooks_vertexbuffer(HMODULE hDll, std::wstring dllName) { + auto ret = 0; + + if (cfg::VertexBuffer::enable) { + ret += patchVertexBuffer(hDll); + } + + return ret; +} + +} diff --git a/src/vars.h b/src/vars.h index 809db14..83ab776 100644 --- a/src/vars.h +++ b/src/vars.h @@ -15,7 +15,7 @@ HMODULE thisModule; // Fix DLL // Version std::string sFixName = "L4D2Fix"; -std::string sFixVer = "1.3.0"; +std::string sFixVer = "1.4.0-debug"; std::string sLogFile = sFixName + ".log"; // Logger @@ -39,6 +39,18 @@ namespace Indices { int value; } +namespace IndexBuffer { + bool enable; + bool debug; + int value; +} + +namespace VertexBuffer { + bool enable; + bool debug; + int value; +} + namespace DynamicVB { bool enable; bool debug; @@ -71,6 +83,20 @@ void LoadIni() { inipp::extract(ini.sections["Indices"]["value"], value); } + // { + // using namespace IndexBuffer; + // inipp::extract(ini.sections["IndexBuffer"]["enable"], enable); + // inipp::extract(ini.sections["IndexBuffer"]["debug"], debug); + // inipp::extract(ini.sections["IndexBuffer"]["value"], value); + // } + + // { + // using namespace VertexBuffer; + // inipp::extract(ini.sections["VertexBuffer"]["enable"], enable); + // inipp::extract(ini.sections["VertexBuffer"]["debug"], debug); + // inipp::extract(ini.sections["VertexBuffer"]["value"], value); + // } + { using namespace DynamicVB; inipp::extract(ini.sections["DynamicVB"]["enable"], enable); diff --git a/xmake-requires.lock b/xmake-requires.lock new file mode 100644 index 0000000..48a446b --- /dev/null +++ b/xmake-requires.lock @@ -0,0 +1,29 @@ +{ + __meta__ = { + version = "1.0" + }, + ["windows|x64"] = { + ["minhook#31fecfc4"] = { + repo = { + branch = "master", + commit = "497ce0d3bcc07368698f1f7ec828b4cf991dbe14", + url = "https://github.com/xmake-io/xmake-repo.git" + }, + version = "v1.3.3" + }, + ["spdlog#31fecfc4"] = { + repo = { + branch = "master", + commit = "497ce0d3bcc07368698f1f7ec828b4cf991dbe14", + url = "https://github.com/xmake-io/xmake-repo.git" + }, + version = "v1.15.2" + }, + ["vcpkg::detours#31fecfc4"] = { + version = "latest" + }, + ["vcpkg::inipp#31fecfc4"] = { + version = "latest" + } + } +} \ No newline at end of file diff --git a/xmake.lua b/xmake.lua index c78e238..f69718e 100644 --- a/xmake.lua +++ b/xmake.lua @@ -1,6 +1,7 @@ -- add_requires("microsoft-proxy 2.4.0") add_rules("plugin.compile_commands.autoupdate") add_rules("mode.debug", "mode.release") +set_policy("package.requires_lock", true) set_languages("cxx20", "c++20")