mirror of
https://github.com/EricPlayZ/EGameTools.git
synced 2025-07-18 17:37:53 +08:00
backup of new update
This commit is contained in:
@ -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>
|
||||||
|
@ -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();
|
||||||
|
@ -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) {}
|
||||||
|
@ -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));\
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
@ -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());
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user