Fixed a bug where the game would crash. Now Unreal Engine offsets are editable

This commit is contained in:
2025-09-10 22:14:51 +02:00
parent e75ee6aa0a
commit d5da29b505

View File

@@ -7,11 +7,13 @@
#include <chrono> #include <chrono>
#include "Memory.hpp"; #include "Memory.hpp";
#include "Maths.hpp"; #include "Maths.hpp";
#include "UEngine.hpp";
#include "ObfuscateString.h" #include "ObfuscateString.h"
#include "SDK/CoreUObject_classes.hpp" //#include "SDK/CoreUObject_classes.hpp"
#include "SDK/Engine_classes.hpp" #include "SDK/Engine_classes.hpp"
//#include "SDK/Engine_structs.hpp" //#include "SDK/Engine_structs.hpp"
//#include "SDK/Cronos_classes.hpp" //#include "SDK/Cronos_classes.hpp"
//#include "SDK/PlayerHudWidget_BP_classes.hpp"
using namespace SDK; using namespace SDK;
@@ -56,12 +58,17 @@ static uint8_t* Vignettingaddress = nullptr;
static uint8_t* Fogaddress = nullptr; static uint8_t* Fogaddress = nullptr;
static uint8_t* CameraDistanceaddress = nullptr; static uint8_t* CameraDistanceaddress = nullptr;
// AOB Unreal Engine offsets addresses
static uint8_t* GObjectsaddress = nullptr;
static uint8_t* AppendStringaddress = nullptr;
static uint8_t* ProcessEventaddress = nullptr;
// Hooking // Hooking
static SafetyHookMid FOVHook{}; static SafetyHookMid FOVHook{};
static SafetyHookMid AspectHook{}; static SafetyHookMid AspectHook{};
static SafetyHookMid FogHook{}; static SafetyHookMid FogHook{};
static SafetyHookMid CameraDistanceHook{}; static SafetyHookMid CameraDistanceHook{};
//static SafetyHookMid PEHook{}; static SafetyHookMid PEHook{};
// Prototypes // Prototypes
static void FOVFixEnabled(bool fix_enabled); static void FOVFixEnabled(bool fix_enabled);
@@ -71,7 +78,7 @@ static void VignettingFixEnabled(bool fix_enabled);
static void FogFixEnabled(bool fix_enabled); static void FogFixEnabled(bool fix_enabled);
static void CameraDistanceFixEnabled(bool fix_enabled); static void CameraDistanceFixEnabled(bool fix_enabled);
static void EnableConsole(); static void EnableConsole();
//static void ProcessEvent(); static void ProcessEvent();
uint8_t* basePtr = reinterpret_cast<uint8_t*>(GetModuleHandleA(nullptr)); uint8_t* basePtr = reinterpret_cast<uint8_t*>(GetModuleHandleA(nullptr));
@@ -187,6 +194,45 @@ extern "C" __declspec(dllexport) void SetFixEnabled(bool enabled, bool init)
AOBScanDone = true; AOBScanDone = true;
} }
// Unreal Engine Offsets updates (needed when the game reveives an update and to prevent the fix from crashing the game)
if (!GObjectsaddress || !AppendStringaddress || !ProcessEventaddress) {
logger->info("------------ UEngine offsets search ------------");
constexpr auto GObjetcsStringObfuscated = make_obfuscated<0x4A>("48 8B ?? ?? ?? ?? ?? 48 8B ?? ?? 48 8D ?? ?? EB ?? 33");
GObjectsaddress = Memory::AOBScan(gameExecutable, GObjetcsStringObfuscated.decrypt(), PAGE_EXECUTE_READ);
constexpr auto AppendStringStringObfuscated = make_obfuscated<0x4A>("48 89 ?? ?? ?? 48 89 ?? ?? ?? 57 48 83 ?? ?? 80 3D ?? ?? ?? ?? ?? 48 8B F2 8B");
AppendStringaddress = Memory::AOBScan(gameExecutable, AppendStringStringObfuscated.decrypt(), PAGE_EXECUTE_READ);
constexpr auto ProcessEventStringObfuscated = make_obfuscated<0x4A>("40 ?? 56 57 41 ?? 41 ?? 41 ?? 41 ?? 48 81 ?? ?? ?? ?? ?? 48 8D ?? ?? ?? 48 89 ?? ?? ?? ?? ?? 48 8B ?? ?? ?? ?? ?? 48 33 ?? 48 89 ?? ?? ?? ?? ?? 4D ?? ?? 48");
ProcessEventaddress = Memory::AOBScan(gameExecutable, ProcessEventStringObfuscated.decrypt(), PAGE_EXECUTE_READ);
if (!GObjectsaddress)
logger->warn("GObjects signature not found. Maybe your game has been updated and is no more compatible with this plugin.");
else {
uint32_t gObjectsOffset = static_cast<uint32_t>(Memory::GetOffsetFromOpcode(GObjectsaddress + 0x3) -
reinterpret_cast<uint8_t*>(GetModuleHandleA(gameExecutable.c_str())));
logger->info("GObjects offset is: 0x{:X}.", gObjectsOffset);
Offsets::GObjects = static_cast<UC::uint32>(gObjectsOffset); // Update GObjects offset
}
if (!AppendStringaddress)
logger->warn("AppendString signature not found. Maybe your game has been updated and is no more compatible with this plugin.");
else {
std::optional<uint32_t> gAppendStringOffsetOpt = UE::CalculateOffset(gameExecutable, AppendStringaddress); // Get Offset from opcode
uint32_t gAppendStringOffset = *gAppendStringOffsetOpt;
logger->info("AppendString offset is: 0x{:X}.", gAppendStringOffset);
Offsets::AppendString = static_cast<UC::uint32>(gAppendStringOffset); // Update AppendString offset
}
if (!ProcessEventaddress)
logger->warn("Process Event signature not found. Maybe your game has been updated and is no more compatible with this plugin.");
else {
std::optional<uint32_t> gProcessEventOffsetOpt = UE::CalculateOffset(gameExecutable, ProcessEventaddress);
uint32_t gProcessEventOffset = *gProcessEventOffsetOpt;
logger->info("Process Event offset is: 0x{:X}.", gProcessEventOffset);
Offsets::ProcessEvent = static_cast<UC::uint32>(gProcessEventOffset);// Update ProcessEvent offset
}
}
logger->info("-------------- Fixes initialisation -------------"); logger->info("-------------- Fixes initialisation -------------");
} }
@@ -370,7 +416,6 @@ static void CameraDistanceFixEnabled(bool fix_enabled) {
logger->info("Camera distance fix disabled"); logger->info("Camera distance fix disabled");
} }
} }
// Debuggin function intended to find specific class or object // Debuggin function intended to find specific class or object
// UE Process Event signature to search for : 48 ?? ?? 48 89 ?? ?? ?? ?? ?? 4D ?? ?? 48 ?? ?? 4C ?? ?? 48 ?? ?? 0F 84 // UE Process Event signature to search for : 48 ?? ?? 48 89 ?? ?? ?? ?? ?? 4D ?? ?? 48 ?? ?? 4C ?? ?? 48 ?? ?? 0F 84
//static void ProcessEvent() { //static void ProcessEvent() {
@@ -381,6 +426,7 @@ static void CameraDistanceFixEnabled(bool fix_enabled) {
// std::this_thread::sleep_for(std::chrono::milliseconds(100)); // std::this_thread::sleep_for(std::chrono::milliseconds(100));
// //
// uintptr_t base_module = (uintptr_t)GetModuleHandle(NULL); // uintptr_t base_module = (uintptr_t)GetModuleHandle(NULL);
// static auto lastLogTime = std::chrono::steady_clock::now();
// //
// ProcessEventaddress = reinterpret_cast<uint8_t*>(base_module + static_cast<uintptr_t>(Offsets::ProcessEvent)); // ProcessEventaddress = reinterpret_cast<uint8_t*>(base_module + static_cast<uintptr_t>(Offsets::ProcessEvent));
// //
@@ -390,7 +436,39 @@ static void CameraDistanceFixEnabled(bool fix_enabled) {
// UObject* object = (UObject*)ctx.rcx; // UObject* object = (UObject*)ctx.rcx;
// UFunction* func = (UFunction*)ctx.rdx; // UFunction* func = (UFunction*)ctx.rdx;
// //
// if (object && object->GetFullName().contains("SHPlayerCameraManagerPlay")) { // if (object && object->GetFullName().contains("PlayerHudWidget_BP_C") && func->GetFullName().contains("Tick")) {
// //logger->info("PlayerHudWidget trouve: {} = {}", object->GetFullName(), func->GetFullName());
// static double NormallastX = 0, NormallastY = 0, UltralastX = 0, UltralastY = 0, SuperlastX = 0, SuperlastY = 0;
// auto* HUDWidget = reinterpret_cast<UPlayerHudWidget_BP_C*>(object);
// if (HUDWidget) {
// static auto lastLogTime = std::chrono::steady_clock::now();
//
// auto* aspectZone = HUDWidget->KeepAspectZone_0;
// if (aspectZone && aspectZone->IsA(UKeepAspectZone::StaticClass())) {
// auto now = std::chrono::steady_clock::now();
// auto diff = std::chrono::duration_cast<std::chrono::milliseconds>(now - lastLogTime).count();
//
// if (diff > 1000) { // une fois par seconde
// lastLogTime = now;
//
// const FVector2D ratioNormal = aspectZone->DesireAspectRatio;
// const FVector2D ratioUltra = aspectZone->DesireAspectRatioUltraWide;
// const FVector2D ratioSuper = aspectZone->DesireAspectRatioSuperUltraWide;
//
// if (ratioNormal.X != NormallastX || ratioNormal.Y != NormallastY ||
// ratioUltra.X != UltralastX || ratioUltra.Y != UltralastY ||
// ratioSuper.X != SuperlastX || ratioSuper.Y != SuperlastY) {
// logger->info("Classe: {} // Ratio Normal X = {:.4f}, Y = {:.4f} // Ratio Super X = {:.4f}, Y = {:.4f} // Ratio Ultra X = {:.4f}, Y = {:.4f} ",
// object->GetName(), ratioNormal.X, ratioNormal.Y, ratioSuper.X, ratioSuper.Y, ratioUltra.X, ratioUltra.Y);
//
// NormallastX = ratioNormal.X; NormallastY = ratioNormal.Y;
// UltralastX = ratioUltra.X; UltralastY = ratioUltra.Y;
// SuperlastX = ratioSuper.X; SuperlastY = ratioSuper.Y;
// }
// }
// }
//
// }
// auto* camModifier = reinterpret_cast<UCameraModifier*>(object); // auto* camModifier = reinterpret_cast<UCameraModifier*>(object);
// auto* camOwner = camModifier->CameraOwner; // auto* camOwner = camModifier->CameraOwner;
// //
@@ -415,6 +493,11 @@ static void CameraDistanceFixEnabled(bool fix_enabled) {
static void EnableConsole() static void EnableConsole()
{ {
logger->info("-------------- Console re-enabling --------------"); logger->info("-------------- Console re-enabling --------------");
if (!GObjectsaddress || !AppendStringaddress || !ProcessEventaddress) {
logger->warn("Could not re-enable console");
logger->info("------------------ User inputs ------------------");
return;
}
std::thread([&]() { std::thread([&]() {
auto start = std::chrono::high_resolution_clock::now(); // Measure the time to renable console auto start = std::chrono::high_resolution_clock::now(); // Measure the time to renable console