From 32807681255da54f108401c37cde257d8301a603 Mon Sep 17 00:00:00 2001 From: EricPlayZ Date: Sat, 2 Nov 2024 02:04:12 +0200 Subject: [PATCH] backup of new update --- EGameTools/pch/pch.h | 1 + EGameTools/source/core.cpp | 27 ++++++++++---- EGameTools/source/core.h | 6 +-- EGameTools/source/offsets.h | 6 ++- EGameTools/source/utils/hook.h | 18 ++++----- EGameTools/source/utils/memory.cpp | 14 ++++++- EGameTools/source/utils/sigscan.cpp | 57 +++++++++++++++++++---------- EGameTools/source/utils/time.cpp | 22 +++-------- EGameTools/source/utils/time.h | 3 +- 9 files changed, 94 insertions(+), 60 deletions(-) diff --git a/EGameTools/pch/pch.h b/EGameTools/pch/pch.h index 9977fb2..501c99c 100644 --- a/EGameTools/pch/pch.h +++ b/EGameTools/pch/pch.h @@ -37,6 +37,7 @@ #include #include #include +#include #include #include diff --git a/EGameTools/source/core.cpp b/EGameTools/source/core.cpp index c1104dc..fef118d 100644 --- a/EGameTools/source/core.cpp +++ b/EGameTools/source/core.cpp @@ -43,6 +43,8 @@ namespace Core { int rendererAPI = 0; DWORD gameVer = 0; + static std::counting_semaphore<4> maxHookThreads(4); + static void LoopHookRenderer() { while (true) { if (exiting) @@ -225,14 +227,25 @@ namespace Core { CreateSymlinkForLoadingFiles(); - for (auto& hook : *Utils::Hook::HookBase::GetInstances()) { - spdlog::warn("Hooking \"{}\"", hook->name.data()); - std::thread([&hook]() { - if (hook->HookLoop()) - spdlog::info("Hooked \"{}\"!", hook->name.data()); - }).detach(); - } + while (true) { + if (!GetModuleHandle("gamedll_ph_x64_rwdi.dll") || !GetModuleHandle("engine_x64_rwdi.dll")) + continue; + for (auto& hook : *Utils::Hook::HookBase::GetInstances()) { + std::thread([&hook]() { + maxHookThreads.acquire(); + + spdlog::warn("Hooking \"{}\"", hook->name.data()); + if (hook->HookLoop()) + spdlog::info("Hooked \"{}\"!", hook->name.data()); + + maxHookThreads.release(); + }).detach(); + } + + break; + } + spdlog::warn("Sorting Player Variables"); std::thread([]() { GamePH::PlayerVariables::SortPlayerVars(); diff --git a/EGameTools/source/core.h b/EGameTools/source/core.h index 32e017f..16c31ea 100644 --- a/EGameTools/source/core.h +++ b/EGameTools/source/core.h @@ -16,9 +16,9 @@ #define VK_MWHEELUP 0x101 #endif -constexpr const char* MOD_VERSION_STR = "v1.2.0"; -constexpr DWORD MOD_VERSION = 10200; -constexpr DWORD GAME_VER_COMPAT = 11602; +constexpr const char* MOD_VERSION_STR = "v1.2.3"; +constexpr DWORD MOD_VERSION = 10203; +constexpr DWORD GAME_VER_COMPAT = 11800; struct Key { constexpr Key(std::string_view name, int code, ImGuiKey imGuiCode) : name(name), code(code), imGuiCode(imGuiCode) {} diff --git a/EGameTools/source/offsets.h b/EGameTools/source/offsets.h index 6e5159e..932cb67 100644 --- a/EGameTools/source/offsets.h +++ b/EGameTools/source/offsets.h @@ -5,7 +5,9 @@ #define AddOffset(name, moduleName, pattern, type, retType)\ static retType Get_## name () {\ static retType name = NULL;\ - if (Utils::Memory::IsValidPtr(name)) return name;\ + static int i = 0;\ + if (Utils::Memory::IsValidPtr(name) || i >= 10) return name;\ + i++;\ return name=reinterpret_cast(Utils::SigScan::PatternScanner::FindPattern(moduleName, {pattern, type}));\ } #define AddStaticOffset(name, off)\ @@ -24,7 +26,9 @@ static DWORD64 Get_## name () {\ #define AddVTOffset(name, moduleName, rttiName, retType)\ static retType GetVT_## name () {\ static retType VT_## name = NULL;\ + static int i = 0;\ if (Utils::Memory::IsValidPtr(VT_## name)) return VT_## name;\ + i++;\ return VT_## name=reinterpret_cast(Utils::RTTI::GetVTablePtr(moduleName, rttiName));\ } diff --git a/EGameTools/source/utils/hook.h b/EGameTools/source/utils/hook.h index af4154a..8bfa94f 100644 --- a/EGameTools/source/utils/hook.h +++ b/EGameTools/source/utils/hook.h @@ -40,11 +40,11 @@ namespace Utils { bool HookLoop() override { if (hooked || (optionRef && !optionRef->GetValue())) return true; - timeSpentHooking = Utils::Time::Timer(180000); + timeSpentHooking = Utils::Time::Timer(160000); while (true) { if (timeSpentHooking.DidTimePass()) { - spdlog::error("Failed hooking \"{}\" after 60 seconds", name); + spdlog::error("Failed hooking \"{}\" after 160 seconds", name); return false; } if (!pGetOffsetFunc || !pGetOffsetFunc()) @@ -111,7 +111,7 @@ namespace Utils { bool hooked = false; - Utils::Time::Timer timeSpentHooking{ 180000 }; + Utils::Time::Timer timeSpentHooking{ 160000 }; }; template class MHook : HookBase { @@ -121,11 +121,11 @@ namespace Utils { bool HookLoop() override { if (pOriginal) return true; - timeSpentHooking = Utils::Time::Timer(180000); + timeSpentHooking = Utils::Time::Timer(160000); while (true) { if (timeSpentHooking.DidTimePass()) { - spdlog::error("Failed hooking function \"{}\" after 60 seconds", name); + spdlog::error("Failed hooking function \"{}\" after 160 seconds", name); return false; } if (!pGetOffsetFunc) @@ -146,7 +146,7 @@ namespace Utils { GetTargetOffsetRetType(*pGetOffsetFunc)() = nullptr; OrigType pDetour = nullptr; - Utils::Time::Timer timeSpentHooking{ 180000 }; + Utils::Time::Timer timeSpentHooking{ 160000 }; }; template class VTHook : HookBase { @@ -156,11 +156,11 @@ namespace Utils { bool HookLoop() override { if (pOriginal) return true; - timeSpentHooking = Utils::Time::Timer(180000); + timeSpentHooking = Utils::Time::Timer(160000); while (true) { if (timeSpentHooking.DidTimePass()) { - spdlog::error("Failed hooking function \"{}\" after 60 seconds", name); + spdlog::error("Failed hooking function \"{}\" after 160 seconds", name); return false; } if (!pGetOffsetFunc) @@ -181,7 +181,7 @@ namespace Utils { LPVOID pInstance = nullptr; OrigType pDetour = nullptr; - Utils::Time::Timer timeSpentHooking{ 180000 }; + Utils::Time::Timer timeSpentHooking{ 160000 }; DWORD offset = 0x0; }; diff --git a/EGameTools/source/utils/memory.cpp b/EGameTools/source/utils/memory.cpp index 8b0ac62..9599b47 100644 --- a/EGameTools/source/utils/memory.cpp +++ b/EGameTools/source/utils/memory.cpp @@ -3,13 +3,23 @@ namespace Utils { namespace Memory { const MODULEINFO GetModuleInfo(const char* szModule) { - const HMODULE hModule = GetModuleHandle(szModule); + if (!szModule) + return MODULEINFO(); + + static std::unordered_map moduleInfoCache; + auto it = moduleInfoCache.find(szModule); + if (it != moduleInfoCache.end()) + return it->second; + + HMODULE hModule = GetModuleHandle(szModule); if (hModule == 0) return MODULEINFO(); MODULEINFO moduleInfo{}; GetModuleInformation(GetCurrentProcess(), hModule, &moduleInfo, sizeof(MODULEINFO)); - return moduleInfo; + moduleInfoCache[szModule] = moduleInfo; + + return moduleInfoCache[szModule]; } const FARPROC GetProcAddr(const std::string_view& module, const std::string_view& funcName) { const HMODULE moduleHandle = GetModuleHandleA(module.data()); diff --git a/EGameTools/source/utils/sigscan.cpp b/EGameTools/source/utils/sigscan.cpp index d004341..f4ba66f 100644 --- a/EGameTools/source/utils/sigscan.cpp +++ b/EGameTools/source/utils/sigscan.cpp @@ -96,30 +96,47 @@ namespace Utils { mask[bytesCounted] = '\0'; LPVOID ret = nullptr; - DWORD64 retAddress = reinterpret_cast(startAddress); - DWORD64 endAddress = retAddress + searchSize; + const DWORD64 retAddress = reinterpret_cast(startAddress); + const DWORD64 endAddress = retAddress + searchSize; size_t searchLen = bytesCounted; - while (retAddress < endAddress) { - __try { - bool found = true; - for (size_t j = 0; j < searchLen; j++) { - BYTE* currentByte = reinterpret_cast(retAddress + j); - if (mask[j] == 'x' && *currentByte != patt[j]) { - found = false; - break; + BYTE* retAddressPtr = reinterpret_cast(retAddress); + BYTE* endAddressPtr = reinterpret_cast(endAddress); + + while (retAddressPtr < endAddressPtr) { + MEMORY_BASIC_INFORMATION mbi; + if (VirtualQuery(retAddressPtr, &mbi, sizeof(mbi))) { + // Check if the memory region is readable + if (mbi.Protect & (PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_READONLY | PAGE_READWRITE)) { + // Adjust the end address to the end of this memory region + BYTE* regionEnd = reinterpret_cast(mbi.BaseAddress) + mbi.RegionSize; + + // Only scan within this region + while (retAddressPtr < regionEnd && retAddressPtr < endAddressPtr) { + bool found = true; + + for (size_t j = 0; j < searchLen; j++) { + if (mask[j] == 'x' && retAddressPtr[j] != patt[j]) { + found = false; + break; + } + } + + if (found) { + ret = reinterpret_cast(retAddressPtr + offset); + break; + } + + retAddressPtr++; } - } - if (found) { - ret = reinterpret_cast(retAddress + offset); - break; - } - - retAddress++; - } __except (EXCEPTION_EXECUTE_HANDLER) { - retAddress++; - } + if (ret != nullptr) + break; + } else + // Skip the non-readable memory region + retAddressPtr = reinterpret_cast(mbi.BaseAddress) + mbi.RegionSize; + } else + retAddressPtr++; } free(patt); diff --git a/EGameTools/source/utils/time.cpp b/EGameTools/source/utils/time.cpp index 51fd348..d1dff5f 100644 --- a/EGameTools/source/utils/time.cpp +++ b/EGameTools/source/utils/time.cpp @@ -4,36 +4,24 @@ namespace Utils { namespace Time { Timer::Timer(long timeMs) : timeToPass(std::chrono::milliseconds(timeMs)), timePassed(false) { start = std::chrono::time_point_cast(clock::now()); + end = start + timeToPass; } const long long Timer::GetTimePassed() { if (timePassed) return -1; - const auto end = clock::now(); - const auto duration = std::chrono::duration_cast(end - start); + const auto currentClock = clock::now(); + const auto duration = std::chrono::duration_cast(currentClock - start); const long long timePassedMs = duration.count(); - if (timePassedMs < 0) { - start = std::chrono::time_point_cast(clock::now()); - return -1; - } return timePassedMs; } const bool Timer::DidTimePass() { if (timePassed) - return timePassed; + return true; - const auto end = clock::now(); - const auto duration = std::chrono::duration_cast(end - start); - const long long timePassedMs = duration.count(); - - if (timePassedMs < 0) { - start = std::chrono::time_point_cast(clock::now()); - return false; - } - - if (duration >= timeToPass) + if (clock::now() >= end) timePassed = true; return timePassed; } diff --git a/EGameTools/source/utils/time.h b/EGameTools/source/utils/time.h index d84fab8..bbd60c6 100644 --- a/EGameTools/source/utils/time.h +++ b/EGameTools/source/utils/time.h @@ -5,7 +5,7 @@ namespace Utils { namespace Time { class Timer { - using clock = std::chrono::system_clock; + using clock = std::chrono::steady_clock; using time_point_type = std::chrono::time_point; public: std::chrono::milliseconds timeToPass; @@ -16,6 +16,7 @@ namespace Utils { const bool DidTimePass(); private: time_point_type start; + time_point_type end; bool timePassed; };