backup of new update

This commit is contained in:
EricPlayZ
2024-11-02 02:04:12 +02:00
parent 71b67d0e46
commit 3280768125
9 changed files with 94 additions and 60 deletions

View File

@ -37,6 +37,7 @@
#include <assert.h> #include <assert.h>
#include <unordered_map> #include <unordered_map>
#include <unordered_set> #include <unordered_set>
#include <semaphore>
#include <dxgi.h> #include <dxgi.h>
#include <dxgi1_4.h> #include <dxgi1_4.h>

View File

@ -43,6 +43,8 @@ namespace Core {
int rendererAPI = 0; int rendererAPI = 0;
DWORD gameVer = 0; DWORD gameVer = 0;
static std::counting_semaphore<4> maxHookThreads(4);
static void LoopHookRenderer() { static void LoopHookRenderer() {
while (true) { while (true) {
if (exiting) if (exiting)
@ -225,14 +227,25 @@ namespace Core {
CreateSymlinkForLoadingFiles(); CreateSymlinkForLoadingFiles();
for (auto& hook : *Utils::Hook::HookBase::GetInstances()) { while (true) {
spdlog::warn("Hooking \"{}\"", hook->name.data()); if (!GetModuleHandle("gamedll_ph_x64_rwdi.dll") || !GetModuleHandle("engine_x64_rwdi.dll"))
std::thread([&hook]() { continue;
if (hook->HookLoop())
spdlog::info("Hooked \"{}\"!", hook->name.data());
}).detach();
}
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"); spdlog::warn("Sorting Player Variables");
std::thread([]() { std::thread([]() {
GamePH::PlayerVariables::SortPlayerVars(); GamePH::PlayerVariables::SortPlayerVars();

View File

@ -16,9 +16,9 @@
#define VK_MWHEELUP 0x101 #define VK_MWHEELUP 0x101
#endif #endif
constexpr const char* MOD_VERSION_STR = "v1.2.0"; constexpr const char* MOD_VERSION_STR = "v1.2.3";
constexpr DWORD MOD_VERSION = 10200; constexpr DWORD MOD_VERSION = 10203;
constexpr DWORD GAME_VER_COMPAT = 11602; constexpr DWORD GAME_VER_COMPAT = 11800;
struct Key { struct Key {
constexpr Key(std::string_view name, int code, ImGuiKey imGuiCode) : name(name), code(code), imGuiCode(imGuiCode) {} constexpr Key(std::string_view name, int code, ImGuiKey imGuiCode) : name(name), code(code), imGuiCode(imGuiCode) {}

View File

@ -5,7 +5,9 @@
#define AddOffset(name, moduleName, pattern, type, retType)\ #define AddOffset(name, moduleName, pattern, type, retType)\
static retType Get_## name () {\ static retType Get_## name () {\
static retType name = NULL;\ 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<retType>(Utils::SigScan::PatternScanner::FindPattern(moduleName, {pattern, type}));\ return name=reinterpret_cast<retType>(Utils::SigScan::PatternScanner::FindPattern(moduleName, {pattern, type}));\
} }
#define AddStaticOffset(name, off)\ #define AddStaticOffset(name, off)\
@ -24,7 +26,9 @@ static DWORD64 Get_## name () {\
#define AddVTOffset(name, moduleName, rttiName, retType)\ #define AddVTOffset(name, moduleName, rttiName, retType)\
static retType GetVT_## name () {\ static retType GetVT_## name () {\
static retType VT_## name = NULL;\ static retType VT_## name = NULL;\
static int i = 0;\
if (Utils::Memory::IsValidPtr(VT_## name)) return VT_## name;\ if (Utils::Memory::IsValidPtr(VT_## name)) return VT_## name;\
i++;\
return VT_## name=reinterpret_cast<retType>(Utils::RTTI::GetVTablePtr(moduleName, rttiName));\ return VT_## name=reinterpret_cast<retType>(Utils::RTTI::GetVTablePtr(moduleName, rttiName));\
} }

View File

@ -40,11 +40,11 @@ namespace Utils {
bool HookLoop() override { bool HookLoop() override {
if (hooked || (optionRef && !optionRef->GetValue())) if (hooked || (optionRef && !optionRef->GetValue()))
return true; return true;
timeSpentHooking = Utils::Time::Timer(180000); timeSpentHooking = Utils::Time::Timer(160000);
while (true) { while (true) {
if (timeSpentHooking.DidTimePass()) { if (timeSpentHooking.DidTimePass()) {
spdlog::error("Failed hooking \"{}\" after 60 seconds", name); spdlog::error("Failed hooking \"{}\" after 160 seconds", name);
return false; return false;
} }
if (!pGetOffsetFunc || !pGetOffsetFunc()) if (!pGetOffsetFunc || !pGetOffsetFunc())
@ -111,7 +111,7 @@ namespace Utils {
bool hooked = false; bool hooked = false;
Utils::Time::Timer timeSpentHooking{ 180000 }; Utils::Time::Timer timeSpentHooking{ 160000 };
}; };
template <typename GetTargetOffsetRetType, typename OrigType> template <typename GetTargetOffsetRetType, typename OrigType>
class MHook : HookBase { class MHook : HookBase {
@ -121,11 +121,11 @@ namespace Utils {
bool HookLoop() override { bool HookLoop() override {
if (pOriginal) if (pOriginal)
return true; return true;
timeSpentHooking = Utils::Time::Timer(180000); timeSpentHooking = Utils::Time::Timer(160000);
while (true) { while (true) {
if (timeSpentHooking.DidTimePass()) { if (timeSpentHooking.DidTimePass()) {
spdlog::error("Failed hooking function \"{}\" after 60 seconds", name); spdlog::error("Failed hooking function \"{}\" after 160 seconds", name);
return false; return false;
} }
if (!pGetOffsetFunc) if (!pGetOffsetFunc)
@ -146,7 +146,7 @@ namespace Utils {
GetTargetOffsetRetType(*pGetOffsetFunc)() = nullptr; GetTargetOffsetRetType(*pGetOffsetFunc)() = nullptr;
OrigType pDetour = nullptr; OrigType pDetour = nullptr;
Utils::Time::Timer timeSpentHooking{ 180000 }; Utils::Time::Timer timeSpentHooking{ 160000 };
}; };
template <typename GetTargetOffsetRetType, typename OrigType> template <typename GetTargetOffsetRetType, typename OrigType>
class VTHook : HookBase { class VTHook : HookBase {
@ -156,11 +156,11 @@ namespace Utils {
bool HookLoop() override { bool HookLoop() override {
if (pOriginal) if (pOriginal)
return true; return true;
timeSpentHooking = Utils::Time::Timer(180000); timeSpentHooking = Utils::Time::Timer(160000);
while (true) { while (true) {
if (timeSpentHooking.DidTimePass()) { if (timeSpentHooking.DidTimePass()) {
spdlog::error("Failed hooking function \"{}\" after 60 seconds", name); spdlog::error("Failed hooking function \"{}\" after 160 seconds", name);
return false; return false;
} }
if (!pGetOffsetFunc) if (!pGetOffsetFunc)
@ -181,7 +181,7 @@ namespace Utils {
LPVOID pInstance = nullptr; LPVOID pInstance = nullptr;
OrigType pDetour = nullptr; OrigType pDetour = nullptr;
Utils::Time::Timer timeSpentHooking{ 180000 }; Utils::Time::Timer timeSpentHooking{ 160000 };
DWORD offset = 0x0; DWORD offset = 0x0;
}; };

View File

@ -3,13 +3,23 @@
namespace Utils { namespace Utils {
namespace Memory { namespace Memory {
const MODULEINFO GetModuleInfo(const char* szModule) { const MODULEINFO GetModuleInfo(const char* szModule) {
const HMODULE hModule = GetModuleHandle(szModule); if (!szModule)
return MODULEINFO();
static std::unordered_map<std::string_view, MODULEINFO> moduleInfoCache;
auto it = moduleInfoCache.find(szModule);
if (it != moduleInfoCache.end())
return it->second;
HMODULE hModule = GetModuleHandle(szModule);
if (hModule == 0) if (hModule == 0)
return MODULEINFO(); return MODULEINFO();
MODULEINFO moduleInfo{}; MODULEINFO moduleInfo{};
GetModuleInformation(GetCurrentProcess(), hModule, &moduleInfo, sizeof(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 FARPROC GetProcAddr(const std::string_view& module, const std::string_view& funcName) {
const HMODULE moduleHandle = GetModuleHandleA(module.data()); const HMODULE moduleHandle = GetModuleHandleA(module.data());

View File

@ -96,30 +96,47 @@ namespace Utils {
mask[bytesCounted] = '\0'; mask[bytesCounted] = '\0';
LPVOID ret = nullptr; LPVOID ret = nullptr;
DWORD64 retAddress = reinterpret_cast<DWORD64>(startAddress); const DWORD64 retAddress = reinterpret_cast<DWORD64>(startAddress);
DWORD64 endAddress = retAddress + searchSize; const DWORD64 endAddress = retAddress + searchSize;
size_t searchLen = bytesCounted; size_t searchLen = bytesCounted;
while (retAddress < endAddress) { BYTE* retAddressPtr = reinterpret_cast<BYTE*>(retAddress);
__try { BYTE* endAddressPtr = reinterpret_cast<BYTE*>(endAddress);
bool found = true;
for (size_t j = 0; j < searchLen; j++) { while (retAddressPtr < endAddressPtr) {
BYTE* currentByte = reinterpret_cast<BYTE*>(retAddress + j); MEMORY_BASIC_INFORMATION mbi;
if (mask[j] == 'x' && *currentByte != patt[j]) { if (VirtualQuery(retAddressPtr, &mbi, sizeof(mbi))) {
found = false; // Check if the memory region is readable
break; 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<BYTE*>(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<LPVOID>(retAddressPtr + offset);
break;
}
retAddressPtr++;
} }
}
if (found) { if (ret != nullptr)
ret = reinterpret_cast<LPVOID>(retAddress + offset); break;
break; } else
} // Skip the non-readable memory region
retAddressPtr = reinterpret_cast<BYTE*>(mbi.BaseAddress) + mbi.RegionSize;
retAddress++; } else
} __except (EXCEPTION_EXECUTE_HANDLER) { retAddressPtr++;
retAddress++;
}
} }
free(patt); free(patt);

View File

@ -4,36 +4,24 @@ namespace Utils {
namespace Time { namespace Time {
Timer::Timer(long timeMs) : timeToPass(std::chrono::milliseconds(timeMs)), timePassed(false) { Timer::Timer(long timeMs) : timeToPass(std::chrono::milliseconds(timeMs)), timePassed(false) {
start = std::chrono::time_point_cast<std::chrono::milliseconds>(clock::now()); start = std::chrono::time_point_cast<std::chrono::milliseconds>(clock::now());
end = start + timeToPass;
} }
const long long Timer::GetTimePassed() { const long long Timer::GetTimePassed() {
if (timePassed) if (timePassed)
return -1; return -1;
const auto end = clock::now(); const auto currentClock = clock::now();
const auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start); const auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(currentClock - start);
const long long timePassedMs = duration.count(); const long long timePassedMs = duration.count();
if (timePassedMs < 0) {
start = std::chrono::time_point_cast<std::chrono::milliseconds>(clock::now());
return -1;
}
return timePassedMs; return timePassedMs;
} }
const bool Timer::DidTimePass() { const bool Timer::DidTimePass() {
if (timePassed) if (timePassed)
return timePassed; return true;
const auto end = clock::now(); if (clock::now() >= end)
const auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
const long long timePassedMs = duration.count();
if (timePassedMs < 0) {
start = std::chrono::time_point_cast<std::chrono::milliseconds>(clock::now());
return false;
}
if (duration >= timeToPass)
timePassed = true; timePassed = true;
return timePassed; return timePassed;
} }

View File

@ -5,7 +5,7 @@
namespace Utils { namespace Utils {
namespace Time { namespace Time {
class Timer { class Timer {
using clock = std::chrono::system_clock; using clock = std::chrono::steady_clock;
using time_point_type = std::chrono::time_point<clock, std::chrono::milliseconds>; using time_point_type = std::chrono::time_point<clock, std::chrono::milliseconds>;
public: public:
std::chrono::milliseconds timeToPass; std::chrono::milliseconds timeToPass;
@ -16,6 +16,7 @@ namespace Utils {
const bool DidTimePass(); const bool DidTimePass();
private: private:
time_point_type start; time_point_type start;
time_point_type end;
bool timePassed; bool timePassed;
}; };