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 <unordered_map>
#include <unordered_set>
#include <semaphore>
#include <dxgi.h>
#include <dxgi1_4.h>

View File

@ -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();

View File

@ -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) {}

View File

@ -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<retType>(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<retType>(Utils::RTTI::GetVTablePtr(moduleName, rttiName));\
}

View File

@ -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 <typename GetTargetOffsetRetType, typename OrigType>
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 <typename GetTargetOffsetRetType, typename OrigType>
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;
};

View File

@ -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<std::string_view, MODULEINFO> 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());

View File

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

View File

@ -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<std::chrono::milliseconds>(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<std::chrono::milliseconds>(end - start);
const auto currentClock = clock::now();
const auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(currentClock - start);
const long long timePassedMs = duration.count();
if (timePassedMs < 0) {
start = std::chrono::time_point_cast<std::chrono::milliseconds>(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<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)
if (clock::now() >= end)
timePassed = true;
return timePassed;
}

View File

@ -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<clock, std::chrono::milliseconds>;
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;
};