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 <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <semaphore>
|
||||
|
||||
#include <dxgi.h>
|
||||
#include <dxgi1_4.h>
|
||||
|
@ -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();
|
||||
|
@ -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) {}
|
||||
|
@ -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));\
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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());
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user