diff --git a/Project Reboot 3.0/Actor.cpp b/Project Reboot 3.0/Actor.cpp index 1b4a815..cd1656f 100644 --- a/Project Reboot 3.0/Actor.cpp +++ b/Project Reboot 3.0/Actor.cpp @@ -187,6 +187,15 @@ bool AActor::IsNetStartup() return ReadBitfieldValue(bNetStartupOffset, bNetStartupFieldMask); } + +bool AActor::DoesReplicate() +{ + static auto bReplicatesOffset = GetOffset("bReplicates"); + static auto bReplicatesFieldMask = GetFieldMask(GetProperty("bReplicates")); + return ReadBitfieldValue(bReplicatesOffset, bReplicatesFieldMask); +} + + void AActor::SetOwner(AActor* Owner) { static auto SetOwnerFn = FindObject(L"/Script/Engine.Actor.SetOwner"); @@ -201,7 +210,8 @@ void AActor::ForceNetUpdate() bool AActor::IsNetStartupActor() { - return IsNetStartup(); // The implementation on this function depends on the version. + // bNetStartup || (!bActorInitialized && !bActorSeamlessTraveled && bNetLoadOnClient && GetLevel() && !GetLevel()->bAlreadyInitializedNetworkActors); + return IsNetStartup(); // ^^ The implementation on this function depends on the version. } bool AActor::IsPendingKillPending() diff --git a/Project Reboot 3.0/Actor.h b/Project Reboot 3.0/Actor.h index 04912ec..f6f5f95 100644 --- a/Project Reboot 3.0/Actor.h +++ b/Project Reboot 3.0/Actor.h @@ -36,6 +36,7 @@ public: float GetDistanceTo(AActor* OtherActor); struct FRotator GetActorRotation(); void FlushNetDormancy(); + bool DoesReplicate(); bool TeleportTo(const FVector& DestLocation, const FRotator& DestRotation); bool IsActorBeingDestroyed(); bool IsNetStartup(); diff --git a/Project Reboot 3.0/Class.h b/Project Reboot 3.0/Class.h index 2c47d72..5f38f90 100644 --- a/Project Reboot 3.0/Class.h +++ b/Project Reboot 3.0/Class.h @@ -21,18 +21,12 @@ struct UFieldPadding : UObject template static inline PropertyType* GetNext(void* Field) { - return Fortnite_Version >= 12.10 ? *(PropertyType**)(__int64(Field) + 0x20) : ((UField*)Field)->Next; + return *(PropertyType**)(__int64(Field) + Offsets::Next); } static inline FName* GetFNameOfProp(void* Property) { - FName* NamePrivate = nullptr; - - if (Fortnite_Version >= 12.10) - NamePrivate = (FName*)(__int64(Property) + 0x28); - else - NamePrivate = &((UField*)Property)->NamePrivate; - + FName* NamePrivate = (FName*)(__int64(Property) + Offsets::PropName); return NamePrivate; } diff --git a/Project Reboot 3.0/FortGameModeAthena.cpp b/Project Reboot 3.0/FortGameModeAthena.cpp index 258e911..4fd0dde 100644 --- a/Project Reboot 3.0/FortGameModeAthena.cpp +++ b/Project Reboot 3.0/FortGameModeAthena.cpp @@ -184,7 +184,7 @@ void AFortGameModeAthena::StartAircraftPhase() if (Addresses::StartAircraftPhase) { static void (*StartAircraftPhaseOriginal)(AFortGameModeAthena*, bool bDoNotSpawnAircraft) = decltype(StartAircraftPhaseOriginal)(Addresses::StartAircraftPhase); - StartAircraftPhaseOriginal(this, false); // love the double negative fortnite + StartAircraftPhaseOriginal(this, false); // love the double negative Fortnite } else { @@ -1471,6 +1471,29 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena SpawnIsland_FloorLoot_Actors.Free(); BRIsland_FloorLoot_Actors.Free(); +#if 0 + if (Fortnite_Version >= 23) // Partitioning real + { + auto& StreamingLevels = GetWorld()->GetStreamingLevels(); + + for (int i = 0; i < StreamingLevels.Num(); ++i) + { + auto StreamingLevel = StreamingLevels.At(i); + + static auto SetIsRequestingUnloadAndRemovalFn = FindObject(L"/Script/Engine.LevelStreaming.SetIsRequestingUnloadAndRemoval"); + static auto SetShouldBeLoadedFn = FindObject(L"/Script/Engine.LevelStreaming.SetShouldBeLoaded"); + static auto SetShouldBeVisibleFn = FindObject(L"/Script/Engine.LevelStreaming.SetShouldBeVisible"); + + bool bTrue = true; + bool bFalse = false; + + StreamingLevel->ProcessEvent(SetShouldBeLoadedFn, &bTrue); + StreamingLevel->ProcessEvent(SetShouldBeVisibleFn, &bTrue); + StreamingLevel->ProcessEvent(SetIsRequestingUnloadAndRemovalFn, &bFalse); + } + } +#endif + LOG_INFO(LogDev, "Spawned loot!"); #endif } diff --git a/Project Reboot 3.0/FortPlayerController.cpp b/Project Reboot 3.0/FortPlayerController.cpp index 5732aaf..84b6312 100644 --- a/Project Reboot 3.0/FortPlayerController.cpp +++ b/Project Reboot 3.0/FortPlayerController.cpp @@ -1332,7 +1332,17 @@ void AFortPlayerController::ClientOnPawnDiedHook(AFortPlayerController* PlayerCo *(bool*)(__int64(DeathInfo) + MemberOffsets::DeathInfo::bDBNO) = DeadPawn->IsDBNO(); *(uint8*)(__int64(DeathInfo) + MemberOffsets::DeathInfo::DeathCause) = DeathCause; - *(AActor**)(__int64(DeathInfo) + MemberOffsets::DeathInfo::FinisherOrDowner) = KillerPlayerState ? KillerPlayerState : DeadPlayerState; + + auto FinisherOrDowner = KillerPlayerState ? KillerPlayerState : DeadPlayerState;; + + if (MemberOffsets::DeathInfo::bIsWeakFinisherOrDowner) + { + TWeakObjectPtr WeakFinisherOrDowner{}; + WeakFinisherOrDowner.ObjectIndex = FinisherOrDowner->InternalIndex; + WeakFinisherOrDowner.ObjectSerialNumber = GetItemByIndex(FinisherOrDowner->InternalIndex)->SerialNumber; + } + else + *(AActor**)(__int64(DeathInfo) + MemberOffsets::DeathInfo::FinisherOrDowner) = FinisherOrDowner; if (MemberOffsets::DeathInfo::DeathLocation != -1) *(FVector*)(__int64(DeathInfo) + MemberOffsets::DeathInfo::DeathLocation) = DeathLocation; diff --git a/Project Reboot 3.0/NetDriver.cpp b/Project Reboot 3.0/NetDriver.cpp index 801086a..29db7b3 100644 --- a/Project Reboot 3.0/NetDriver.cpp +++ b/Project Reboot 3.0/NetDriver.cpp @@ -12,6 +12,17 @@ #include "bots.h" #include "gui.h" +enum class EChannelCloseReason : uint8 +{ + Destroyed, + Dormancy, + LevelUnloaded, + Relevancy, + TearOff, + /* reserved */ + MAX = 15 // this value is used for serialization, modifying it may require a network version change +}; + FNetworkObjectList& UNetDriver::GetNetworkObjectList() { return *(*(TSharedPtr*)(__int64(this) + Offsets::NetworkObjectList)); @@ -225,7 +236,7 @@ void UNetDriver::ServerReplicateActors_BuildConsiderList(std::vectorGetOffset("NetDormancy"); - if (Actor->Get(NetDormancyOffset) == ENetDormancy::DORM_Initial && Actor->IsNetStartupActor()) // IsDormInitialStartupActor + if (Actor->Get(NetDormancyOffset) == ENetDormancy::DORM_Initial && Actor->IsNetStartupActor()) // IsDormInitialStartupActor { continue; } @@ -288,6 +299,9 @@ void UNetDriver::ServerReplicateActors_BuildConsiderList(std::vectorDoesReplicate()) + continue; + if (Actor->IsPendingKillPending()) // if (Actor->IsPendingKill()) { @@ -581,7 +595,7 @@ int32 UNetDriver::ServerReplicateActors() ++(*(int*)(__int64(this) + Offsets::ReplicationFrame)); const int32 NumClientsToTick = ServerReplicateActors_PrepConnections(this); - + // LOG_INFO(LogDev, "NumClientsToTick: {}", NumClientsToTick); if (NumClientsToTick == 0) { // No connections are ready this frame @@ -613,7 +627,7 @@ int32 UNetDriver::ServerReplicateActors() ServerReplicateActors_BuildConsiderList(ConsiderList, ServerTickTime); - // LOG_INFO(LogReplication, "Considering {} actors.", ConsiderList.size()); + LOG_INFO(LogReplication, "Considering {} actors.", ConsiderList.size()); static UChannel* (*CreateChannel)(UNetConnection*, int, bool, int32_t) = decltype(CreateChannel)(Addresses::CreateChannel); static __int64 (*ReplicateActor)(UActorChannel*) = decltype(ReplicateActor)(Addresses::ReplicateActor); @@ -782,30 +796,44 @@ int32 UNetDriver::ServerReplicateActors() if (Addresses::ActorChannelClose && Offsets::IsNetRelevantFor) { static void (*ActorChannelClose)(UActorChannel*) = decltype(ActorChannelClose)(Addresses::ActorChannelClose); + static void (*ActorChannelCloseParams)(UActorChannel*, EChannelCloseReason) = decltype(ActorChannelCloseParams)(Addresses::ActorChannelClose); - if (!Actor->IsAlwaysRelevant() && !Actor->UsesOwnerRelevancy() && !Actor->IsOnlyRelevantToOwner()) + if (!Actor->IsAlwaysRelevant()) { - if (Connection && Connection->GetViewTarget()) + if (!Actor->UsesOwnerRelevancy() && !Actor->IsOnlyRelevantToOwner()) { - auto Viewer = Connection->GetViewTarget(); - auto Loc = Viewer->GetActorLocation(); - - if (!IsActorRelevantToConnection(Actor, ConnectionViewers)) + if (auto Viewer = Connection->GetViewTarget()) { - // LOG_INFO(LogReplication, "Actor is not relevant!"); + auto Loc = Viewer->GetActorLocation(); - if (Channel) - ActorChannelClose(Channel); + if (!IsActorRelevantToConnection(Actor, ConnectionViewers)) + { + // LOG_INFO(LogReplication, "Actor is not relevant!"); - continue; + if (Channel) + { + // can we just call yes + if (Fortnite_Version > 20) + ActorChannelCloseParams(Channel, EChannelCloseReason::Relevancy); + else + ActorChannelClose(Channel); + } + + continue; + } } } + else + { + // TODO ? + } } } if (!Channel) { - if (Actor->IsA(APlayerController::StaticClass()) && Actor != Connection->GetPlayerController()) // isnetrelevantfor should handle this iirc + if (!Offsets::IsNetRelevantFor + && Actor->IsA(APlayerController::StaticClass()) && Actor != Connection->GetPlayerController()) // isnetrelevantfor should handle this iirc continue; if (bLevelInitializedForActor) diff --git a/Project Reboot 3.0/World.h b/Project Reboot 3.0/World.h index 10fe581..1d95761 100644 --- a/Project Reboot 3.0/World.h +++ b/Project Reboot 3.0/World.h @@ -6,6 +6,7 @@ #include "Rotator.h" #include "Actor.h" #include "GameInstance.h" +#include "Array.h" struct FNetworkNotify { @@ -222,6 +223,12 @@ public: return this->Get(GameStateOffset); } + TArray& GetStreamingLevels() + { + static auto StreamingLevelsOffset = GetOffset("StreamingLevels"); + return this->Get>(StreamingLevelsOffset); + } + class UNetDriver*& GetNetDriver() { static auto NetDriverOffset = GetOffset("NetDriver"); diff --git a/Project Reboot 3.0/addresses.cpp b/Project Reboot 3.0/addresses.cpp index 72c520c..83ade26 100644 --- a/Project Reboot 3.0/addresses.cpp +++ b/Project Reboot 3.0/addresses.cpp @@ -258,9 +258,6 @@ void Addresses::FindAll() LOG_INFO(LogDev, "Finding StepExplicitProperty"); Addresses::FrameStepExplicitProperty = FindStepExplicitProperty(); - LOG_INFO(LogDev, "Finding Free"); - Addresses::Free = FindFree(); - LOG_INFO(LogDev, "Finding ClearAbility"); Addresses::ClearAbility = FindClearAbility(); @@ -386,7 +383,6 @@ void Addresses::Print() LOG_INFO(LogDev, "RemoveFromAlivePlayers: 0x{:x}", RemoveFromAlivePlayers - Base); LOG_INFO(LogDev, "ActorChannelClose: 0x{:x}", ActorChannelClose - Base); LOG_INFO(LogDev, "FrameStepExplicitProperty: 0x{:x}", FrameStepExplicitProperty - Base); - LOG_INFO(LogDev, "Free: 0x{:x}", Free - Base); LOG_INFO(LogDev, "ClearAbility: 0x{:x}", ClearAbility - Base); LOG_INFO(LogDev, "ApplyGadgetData: 0x{:x}", ApplyGadgetData - Base); LOG_INFO(LogDev, "RemoveGadgetData: 0x{:x}", RemoveGadgetData - Base); @@ -412,7 +408,8 @@ void Addresses::Print() void Offsets::FindAll() { - Offsets::Offset_Internal = Fortnite_Version >= 12.10 && std::floor(Fortnite_Version) < 20 ? 0x4C : 0x44; + Offsets::Offset_Internal = Fortnite_Version >= 24 ? 0x3C + : Fortnite_Version >= 12.10 && std::floor(Fortnite_Version) < 20 ? 0x4C : 0x44; Offsets::SuperStruct = Engine_Version >= 422 ? 0x40 : 0x30; Offsets::Children = Fortnite_Version >= 12.10 ? 0x50 : Offsets::SuperStruct + 8; Offsets::PropertiesSize = Offsets::Children + 8; @@ -520,11 +517,18 @@ void Offsets::FindAll() } if (Fortnite_Version >= 23) { - Offsets::ReplicationFrame = 0x440; // checked only on 23.40 + Offsets::ReplicationFrame = 0x440; // checked on 23.40 & 23.50 } Offsets::IsNetRelevantFor = FindIsNetRelevantForOffset(); Offsets::Script = Offsets::Children + 8 + 4 + 4; + + Offsets::PropName = Fortnite_Version >= 12.10 + ? Fortnite_Version >= 24 ? 0x20 + : 0x28 : 0x18; + Offsets::Next = Fortnite_Version >= 12.10 + ? Fortnite_Version >= 24 ? 0x18 + : 0x20 : 0x28; } void Offsets::Print() diff --git a/Project Reboot 3.0/addresses.h b/Project Reboot 3.0/addresses.h index ce593e0..c148979 100644 --- a/Project Reboot 3.0/addresses.h +++ b/Project Reboot 3.0/addresses.h @@ -89,6 +89,8 @@ namespace Addresses namespace Offsets { + extern inline uint64 PropName = 0; + extern inline uint64 Next = 0; extern inline uint64 Func = 0; extern inline uint64 PropertiesSize = 0; extern inline uint64 Children = 0; diff --git a/Project Reboot 3.0/dllmain.cpp b/Project Reboot 3.0/dllmain.cpp index 65294ce..b62e91e 100644 --- a/Project Reboot 3.0/dllmain.cpp +++ b/Project Reboot 3.0/dllmain.cpp @@ -665,6 +665,15 @@ UObject* GetAIDirectorHook() return GameMode->Get(AIDirectorOffset); } +DWORD WINAPI ClientThread(LPVOID) +{ + while (true) + { + + return 0; + } +} + void ChangeLevels() { constexpr bool bUseRemovePlayer = false; @@ -782,13 +791,40 @@ void ChangeLevels() static inline char (*oFunc)(__int64) = nullptr; static inline __int64 (*func2)(__int64) = nullptr; +static inline int persi = 0x0; char Func(__int64 a1) { - if (auto r = func2(a1)) + __int64 r = 0; + if (Fortnite_Version >= 24) + { + if (a1) + { + auto v1 = a1; + + while ((*(uint8_t*)(__int64(v1) + 8) & 0x30) == 0) + { + v1 = *(__int64*)(v1 + 32); + if (!v1) + goto LABEL_4; + } + r = 0LL; + } + else + { + LABEL_4: + r = *(__int64*)(a1 + 32); + } + } + else + { + r = func2(a1); + } + + if (r) { if (auto v5 = *(__int64*)(__int64(r) + 0x38)) { - auto persisntelevle = *(__int64*)(__int64(v5) + 0x98); + auto persisntelevle = *(__int64*)(__int64(v5) + persi); if (!persisntelevle) { LOG_INFO(LogDev, "tralaleo trallala"); @@ -804,8 +840,21 @@ void ApplyNullAndRetTrues() { if (Fortnite_Version >= 23) { - auto sig = Memcury::Scanner::FindPattern("48 89 5C 24 ? 57 48 83 EC 20 48 8B D9 E8 ? ? ? ? 48 8B F8 48 8B 83 ? ? ? ? 48 85 C0").Get(); // 23.40 - func2 = decltype(func2)(Memcury::Scanner::FindPattern("48 83 EC 28 BA ? ? ? ? 4C 8B C1 E8 ? ? ? ? 84 C0 74 04 33 C0 EB 04 49 8B 40 20").Get()); + persi = 0x98; + + __int64 sig = 0; + + if (Fortnite_Version >= 24) + { + persi = 0xA0; + sig = Memcury::Scanner::FindPattern("48 89 5C 24 ? 57 48 83 EC 20 48 8B C1 48 85 C9 74 0F F6 40 08 30 75 61 48 8B 40 20 48 85 C0 75 F1 48 8B 59 20 48 8B 81").Get(); // 24.40 + } + else + { + func2 = decltype(func2)(Memcury::Scanner::FindPattern("48 83 EC 28 BA ? ? ? ? 4C 8B C1 E8 ? ? ? ? 84 C0 74 04 33 C0 EB 04 49 8B 40 20").Get()); + sig = Memcury::Scanner::FindPattern("48 89 5C 24 ? 57 48 83 EC 20 48 8B D9 E8 ? ? ? ? 48 8B F8 48 8B 83 ? ? ? ? 48 85 C0").Get(); // 23.40 + } + Hooking::MinHook::Hook((PVOID)sig, Func, (void**)&oFunc); } @@ -847,6 +896,13 @@ void ApplyNullAndRetTrues() } } +bool (*ReplicateActorOriginal)(UActorChannel* Channel) = nullptr; +bool ReplicateActorHook(UActorChannel* Channel) +{ + LOG_INFO(LogDev, "[ReplicateActorHook] Replicating: {}", Channel->GetActor()->GetFullName()); + return ReplicateActorOriginal(Channel); +} + DWORD WINAPI Main(LPVOID) { InitLogger(); @@ -947,6 +1003,20 @@ DWORD WINAPI Main(LPVOID) if (Fortnite_Version >= 20 || Fortnite_Version == 12.00) ApplyNullAndRetTrues(); + auto ObjectNum = ChunkedObjects ? ChunkedObjects->Num() : UnchunkedObjects ? UnchunkedObjects->Num() : 0; + + std::ofstream obj("ObjectsDump.txt"); + + for (int i = 0; i < ObjectNum; ++i) + { + auto CurrentObject = GetObjectByIndex(i); + + if (!CurrentObject) + continue; + + obj << CurrentObject->GetFullName() << '\n'; + } + // UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), L"log LogNetPackageMap VeryVerbose", nullptr); // UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), L"log LogNetTraffic VeryVerbose", nullptr); // UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), L"log LogNet VeryVerbose", nullptr); @@ -977,6 +1047,8 @@ DWORD WINAPI Main(LPVOID) Hooking::MinHook::Hook((PVOID)Addresses::GetNetMode, (PVOID)GetNetModeHook, nullptr); Hooking::MinHook::Hook((PVOID)Addresses::DispatchRequest, (PVOID)DispatchRequestHook, (PVOID*)&DispatchRequestOriginal); + Hooking::MinHook::Hook((PVOID)Addresses::ReplicateActor, (PVOID)ReplicateActorHook, (PVOID*)&ReplicateActorOriginal); + GSRandSeed = FGenericPlatformTime::Cycles(); ReplicationRandStream = FRandomStream(FGenericPlatformTime::Cycles()); @@ -1196,6 +1268,9 @@ DWORD WINAPI Main(LPVOID) Hooking::MinHook::Hook((PVOID)ApplyHomebaseEffectsOnPlayerSetupAddr, ApplyHomebaseEffectsOnPlayerSetupHook, (PVOID*)&ApplyHomebaseEffectsOnPlayerSetupOriginal); } + Hooking::MinHook::Hook(FindObject(L"/Script/FortniteGame.Default__FortAthenaVehicleSpawner"), FindObject(L"/Script/FortniteGame.FortAthenaVehicleSpawner.SpawnVehicle"), + AFortAthenaVehicleSpawner::SpawnVehicleHook, nullptr, false); + Hooking::MinHook::Hook(GameModeDefault, FindObject(L"/Script/Engine.GameMode.ReadyToStartMatch"), AFortGameModeAthena::Athena_ReadyToStartMatchHook, (PVOID*)&AFortGameModeAthena::Athena_ReadyToStartMatchOriginal, false, false, true); @@ -1554,9 +1629,6 @@ DWORD WINAPI Main(LPVOID) Hooking::MinHook::Hook(InventoryManagementLibraryDefault, FindObject(L"/Script/FortniteGame.InventoryManagementLibrary.SwapItems"), UInventoryManagementLibrary::SwapItemsHook, (PVOID*)&UInventoryManagementLibrary::SwapItemsOriginal, false, true); - Hooking::MinHook::Hook(FindObject(L"/Script/FortniteGame.Default__FortAthenaVehicleSpawner"), FindObject(L"/Script/FortniteGame.FortAthenaVehicleSpawner.SpawnVehicle"), - AFortAthenaVehicleSpawner::SpawnVehicleHook, nullptr, false); - static auto ServerHandlePickupInfoFn = FindObject(L"/Script/FortniteGame.FortPlayerPawn.ServerHandlePickupInfo"); if (ServerHandlePickupInfoFn) @@ -1574,6 +1646,7 @@ DWORD WINAPI Main(LPVOID) static auto PredictionKeyStruct = FindObject(L"/Script/GameplayAbilities.PredictionKey"); static auto PredictionKeySize = PredictionKeyStruct->GetPropertiesSize(); + if (Addresses::InternalTryActivateAbility) { int InternalServerTryActivateAbilityIndex = 0; @@ -1714,6 +1787,7 @@ DWORD WINAPI Main(LPVOID) MemberOffsets::DeathInfo::Distance = FindOffsetStruct("/Script/FortniteGame.DeathInfo", "Distance", false); MemberOffsets::DeathInfo::DeathTags = FindOffsetStruct("/Script/FortniteGame.DeathInfo", "DeathTags", false); MemberOffsets::DeathInfo::DeathLocation = FindOffsetStruct("/Script/FortniteGame.DeathInfo", "DeathLocation", false); + MemberOffsets::DeathInfo::bIsWeakFinisherOrDowner = false; MemberOffsets::DeathReport::Tags = FindOffsetStruct("/Script/FortniteGame.FortPlayerDeathReport", "Tags"); MemberOffsets::DeathReport::KillerPawn = FindOffsetStruct("/Script/FortniteGame.FortPlayerDeathReport", "KillerPawn"); diff --git a/Project Reboot 3.0/finder.cpp b/Project Reboot 3.0/finder.cpp index c8c1cb3..07359c0 100644 --- a/Project Reboot 3.0/finder.cpp +++ b/Project Reboot 3.0/finder.cpp @@ -48,15 +48,22 @@ uint64 FindGIsClient() { // if (Fortnite_Version >= 19) return 0; - auto Addr = Memcury::Scanner::FindStringRef(L"AllowCommandletRendering"); + auto Addr = Memcury::Scanner::FindStringRef(L"AllowCommandletRendering", false); if (!Addr.Get()) // pretty sure only 22+ since the string is split (we could maybe try just searching without the A?) { + // Looking for commandlet class + if (Fortnite_Version == 22.3) { // return __int64(GetModuleHandleW(0)) + 0xDCE9DFA; } + if (Fortnite_Version == 23.5) + { + // return __int64(GetModuleHandleW(0)) + 0xEBD8A4C; + } + LOG_ERROR(LogDev, "[FindGIsClient] Failed to find AllowCommandletRendering! Returning 0"); return 0; } @@ -190,7 +197,7 @@ uint64 FindGetPlayerViewpoint() uint64 FailedToSpawnPawnAddr = 0; - auto FailedToSpawnPawnStrRefAddr = Memcury::Scanner::FindStringRef(L"%s failed to spawn a pawn", true, 0, Fortnite_Version >= 19).Get(); + auto FailedToSpawnPawnStrRefAddr = Memcury::Scanner::FindStringRef(L"%s failed to spawn a pawn", true, 0, Fortnite_Version >= 19 && Fortnite_Version < 24).Get(); if (!FailedToSpawnPawnStrRefAddr) { diff --git a/Project Reboot 3.0/finder.h b/Project Reboot 3.0/finder.h index 04d078b..10362ff 100644 --- a/Project Reboot 3.0/finder.h +++ b/Project Reboot 3.0/finder.h @@ -134,7 +134,7 @@ static inline uint64 FindProcessEvent() return FindBytes(Addr, { 0x40, 0x55 }, 2000); // Addr.ScanFor({ 0x40, 0x55 }).Get(); } - auto Addr = Memcury::Scanner::FindStringRef(L"UMeshNetworkComponent::ProcessEvent: Invalid mesh network node type: %s", true, 0, Engine_Version >= 500); + auto Addr = Memcury::Scanner::FindStringRef(L"UMeshNetworkComponent::ProcessEvent: Invalid mesh network node type: %s", true, 0, Engine_Version >= 500 && Fortnite_Version < 24); return Memcury::Scanner(FindBytes(Addr, { 0xE8 }, 2000, 0, false, Engine_Version < 500 ? 1 : 3)).RelativeOffset(1).Get(); // Addr.ScanFor({ 0x40, 0x55 }).Get(); } @@ -318,6 +318,16 @@ static inline uint64 FindKickPlayer() return Memcury::Scanner::FindPattern("48 8B C4 48 89 58 08 48 89 70 10 48 89 78 18 4C 89 60 20 55 41 56 41 57 48 8B EC 48 83 EC 60 48 83 65 ? ? 4C 8B F2 83 65 E8 00 4C 8B E1 83 65 EC").Get(); if (std::floor(Fortnite_Version) == 19) return Memcury::Scanner::FindPattern("48 89 5C 24 ? 55 56 57 48 8B EC 48 83 EC 60 48 8B FA 48 8B F1 E8").Get(); + if (Fortnite_Version >= 23) + { + // User is validated as player, but marked as a spectator. kicking %s + auto addr = Memcury::Scanner::FindPattern("48 89 5C 24 ? 55 56 57 41 54 41 55 41 56 41 57 48 8D 6C 24 ? 48 81 EC ? ? ? ? 48 8B 05 ? ? ? ? 48 33 C4 48 89 45 08 45 33 FF 48 8B FA 41 8B", false).Get(); // 23.50 + + if (!addr) + addr = Memcury::Scanner::FindPattern("48 89 5C 24 ? 55 56 57 41 54 41 55 41 56 41 57 48 8D 6C 24 ? 48 81 EC ? ? ? ? 48 8B 05 ? ? ? ? 48 33 C4 48 89 45 10 45 33 ED 48 8B FA 41 8B DD 4C 8B F9 89 5D 80 E8 ? ? ? ? 48 8B D0 48 89 44 24").Get(); // 24.40 + + return addr; + } if (Engine_Version >= 423 || Engine_Version <= 425) // && instead of || ?? return Memcury::Scanner::FindPattern("48 89 5C 24 08 48 89 74 24 10 57 48 83 EC ? 49 8B F0 48 8B DA 48 85 D2").Get(); @@ -405,7 +415,14 @@ static inline uint64 FindPickSupplyDropLocation() static inline uint64 FindPauseBeaconRequests() { if (Engine_Version == 500) - return Memcury::Scanner::FindPattern("48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 57 48 83 EC 20 33 ED 48 8B F1 84 D2 74 27 80 3D").Get(); + { + auto ref = Memcury::Scanner::FindPattern("48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 57 48 83 EC 20 33 ED 48 8B F1 84 D2 74 27 80 3D", false).Get(); + + if (!ref) // just 27 -> 35 but im too scared to change + ref = Memcury::Scanner::FindPattern("48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 57 48 83 EC 20 33 ED 48 8B F1 84 D2 74 35 80 3D ? ? ? ? ? 72 13 48 8D 15").Get(); // 24.40 + + return ref; + } if (Engine_Version == 427) return Memcury::Scanner::FindPattern("48 89 5C 24 ? 48 89 74 24 ? 57 48 83 EC 30 33 F6 48 8B F9 84 D2 74").Get(); @@ -528,20 +545,6 @@ uint64 FindGetSessionInterface(); uint64 FindGetPlayerViewpoint(); uint64 ApplyGameSessionPatch(); -static inline uint64 FindFree() -{ - uint64 addr = 0; - - if (Engine_Version <= 420) // 3.3, 4.1, 4.5 - addr = Memcury::Scanner::FindPattern("48 85 C9 74 1D 4C 8B 05 ? ? ? ? 4D 85 C0 0F 84").Get(); - else if (Engine_Version >= 421 && Engine_Version <= 426) - addr = Memcury::Scanner::FindPattern("48 85 C9 74 2E 53 48 83 EC 20 48 8B D9").Get(); - else if (Engine_Version >= 427) - addr = Memcury::Scanner::FindPattern("48 85 C9 0F 84 ? ? ? ? 53 48 83 EC 20 48 89 7C 24 ? 48 8B D9 48 8B 3D").Get(); - - return addr; -} - static inline uint64 FindStepExplicitProperty() { return Memcury::Scanner::FindPattern("41 8B 40 ? 4D 8B C8").Get(); @@ -559,8 +562,10 @@ static inline uint64 FindIsNetRelevantForOffset() return 0x4D0 / 8; // checked 21.00 if (std::floor(Fortnite_Version) == 22) return 0x4D8 / 8; // checked 22.30 - if (Fortnite_Version >= 23) + if (std::floor(Fortnite_Version) == 23) return 0x4E0 / 8; // checked 23.40 + if (Fortnite_Version >= 24) + return 0x500 / 8; // checked 24.40 return 0; } @@ -571,10 +576,13 @@ static inline uint64 FindActorChannelClose() if (!StringRef.Get()) // 22.30 atleast (it just changed but also functionized im too lazy rn) { - auto addr = Memcury::Scanner::FindPattern("40 55 53 56 57 41 56 48 8B EC 48 83 EC 40 4C 8B 41 68 40 8A F2 48 8B 51 28 48 8B D9 48 8D 4D 48 E8 ? ? ? ? 80").Get(); // 20.40 + auto addr = Memcury::Scanner::FindPattern("40 55 53 56 57 41 56 48 8B EC 48 83 EC 40 4C 8B 41 68 40 8A F2 48 8B 51 28 48 8B D9 48 8D 4D 48 E8 ? ? ? ? 80", false).Get(); // 20.40 if (!addr) // TODO: Check 48 89 5C 24 ? 55 56 57 48 83 EC ? 4C 8B 41 ? 40 8A F2 48 8B 51 ? 48 8B - addr = Memcury::Scanner::FindPattern("48 89 5C 24 ? 55 56 57 48 83 EC ? 4C 8B 41 ? 40 8A F2 48 8B 51 ? 48 8B ? 48 8D 4C 24 ? E8").Get(); // 22.30 + 23.40 + addr = Memcury::Scanner::FindPattern("48 89 5C 24 ? 55 56 57 48 83 EC ? 4C 8B 41 ? 40 8A F2 48 8B 51 ? 48 8B ? 48 8D 4C 24 ? E8", false).Get(); // 22.30 + 23.40 + + if (!addr) + addr = Memcury::Scanner::FindPattern("48 89 5C 24 ? 48 89 74 24 ? 48 89 7C 24 ? 55 41 56 41 57 48 8B EC 48 83 EC 40 4C 8B 41 68 44 8A FA 48 8B").Get(); // 24.40 return addr; } @@ -626,6 +634,8 @@ static inline uint64 FindSetWorld() SetWorldIndex = 0x7C; // 21.00 if (Fortnite_Season == 22 || Fortnite_Season == 23) SetWorldIndex = 0x7B; // 22.30 & 23.50 + if (Fortnite_Season == 24) + SetWorldIndex = 0x7D; // 24.40 if (!SetWorldIndex) { @@ -639,7 +649,14 @@ static inline uint64 FindSetWorld() static inline uint64 FindInitListen() { if (Engine_Version == 500) - return Memcury::Scanner::FindPattern("4C 8B DC 49 89 5B 10 49 89 73 18 57 48 83 EC 50 48 8B BC 24 ?? ?? ?? ?? 49 8B F0 48 8B").Get(); + { + auto addr = Memcury::Scanner::FindPattern("4C 8B DC 49 89 5B 10 49 89 73 18 57 48 83 EC 50 48 8B BC 24 ?? ?? ?? ?? 49 8B F0 48 8B", false).Get(); + + if (!addr) + addr = Memcury::Scanner::FindPattern("4C 8B DC 49 89 5B 08 49 89 73 10 57 48 83 EC 40 48 8B 7C 24 ? 49 8B F0 48 8B 01 48 8B D9 49 89 7B E0 45").Get(); // 24.40 + + return addr; + } if (Engine_Version >= 427) return Memcury::Scanner::FindPattern("4C 8B DC 49 89 5B 08 49 89 73 10 57 48 83 EC 50 48 8B BC 24 ? ? ? ? 49 8B F0 48 8B 01 48 8B").Get(); @@ -650,14 +667,9 @@ static inline uint64 FindInitListen() static inline uint64 FindOnDamageServer() { - if (Fortnite_Version >= 20) // 8B 15 on name ref??? + if (Fortnite_Version >= 20) // pawn has one too gg { - auto addr = Memcury::Scanner::FindPattern("E8 ? ? ? ? 41 39 B4 24").RelativeOffset(1).Get(); // 20.40 (not 21.00) - - if (!addr) - addr = Memcury::Scanner::FindPattern("E8 ? ? ? ? 4C 8D 96 ? ? ? ? 49 8B CA E8 ? ? ? ? 45 33 E4").RelativeOffset(1).Get(); // 22.3 - - return addr; + return 0; } auto Addr = FindFunctionCall(L"OnDamageServer", @@ -1025,7 +1037,7 @@ static inline uint64 FindSetTimer() static inline uint64 FindEnterAircraft() { - auto Addr = Memcury::Scanner::FindStringRef(L"EnterAircraft: [%s] is attempting to enter aircraft after having already exited.", true, 0, Engine_Version >= 500).Get(); + auto Addr = Memcury::Scanner::FindStringRef(L"EnterAircraft: [%s] is attempting to enter aircraft after having already exited.", true, 0, Engine_Version >= 500 && Fortnite_Version < 24).Get(); for (int i = 0; i < 1000; i++) { @@ -1235,7 +1247,7 @@ static inline uint64 FindRemoveFromAlivePlayers() Addrr = Memcury::Scanner::FindStringRef(L"FortGameModeAthena: Player [%s] removed from alive players list (Team [%d]). Player count is now [%d]. PlayerBots count is now [%d]. Team count is now [%d].", false).Get(); if (!Addrr) - Addrr = Memcury::Scanner::FindStringRef(L"FortGameModeAthena::RemoveFromAlivePlayers: Player [%s] PC [%s] removed from alive players list (Team [%d]). Player count is now [%d]. PlayerBots count is now [%d]. Team count is now [%d].", true, 0, Fortnite_Version >= 16).Get(); // checked on 16.40 + Addrr = Memcury::Scanner::FindStringRef(L"FortGameModeAthena::RemoveFromAlivePlayers: Player [%s] PC [%s] removed from alive players list (Team [%d]). Player count is now [%d]. PlayerBots count is now [%d]. Team count is now [%d].", true, 0, Fortnite_Version >= 16 && Fortnite_Version < 24).Get(); // checked on 16.40 for (int i = 0; i < 2000; i++) { @@ -1677,7 +1689,7 @@ static inline uint64 FindPickTeam() static inline uint64 FindInternalTryActivateAbility() { - auto Addrr = Memcury::Scanner::FindStringRef(L"InternalTryActivateAbility called with invalid Handle! ASC: %s. AvatarActor: %s", true, 0, Fortnite_Version >= 16).Get(); // checked 16.40 + auto Addrr = Memcury::Scanner::FindStringRef(L"InternalTryActivateAbility called with invalid Handle! ASC: %s. AvatarActor: %s", true, 0, Fortnite_Version >= 16 && Fortnite_Version < 24).Get(); // checked 16.40 for (int i = 0; i < 1000; i++) { @@ -1686,7 +1698,7 @@ static inline uint64 FindInternalTryActivateAbility() return Addrr - i; } - if (*(uint8_t*)(uint8_t*)(Addrr - i) == 0x4C && *(uint8_t*)(uint8_t*)(Addrr - i + 1) == 0x89 && *(uint8_t*)(uint8_t*)(Addrr - i + 2) == 0x4C) + if (*(uint8_t*)(uint8_t*)(Addrr - i) == 0x4C && *(uint8_t*)(uint8_t*)(Addrr - i + 1) == 0x89 && *(uint8_t*)(uint8_t*)(Addrr - i + 2) == 0x4C) // checked on 24.40 { return Addrr - i; } @@ -1715,6 +1727,11 @@ static inline uint64 FindCanActivateAbility() auto Addrr = Memcury::Scanner::FindStringRef(L"CanActivateAbility %s failed, blueprint refused", true, 0, Engine_Version >= 500).Get(); + if (!Addrr) + { + return 0; + } + for (int i = 0; i < 2000; i++) { if (*(uint8_t*)(uint8_t*)(Addrr - i) == 0x48 && *(uint8_t*)(uint8_t*)(Addrr - i + 1) == 0x89 && *(uint8_t*)(uint8_t*)(Addrr - i + 2) == 0x5C) @@ -1748,6 +1765,11 @@ static inline uint64 FindGiveAbilityAndActivateOnce() auto Addrr = Memcury::Scanner::FindStringRef(L"GiveAbilityAndActivateOnce called on ability %s on the client, not allowed!", true, 0, Engine_Version >= 500).Get(); + if (!Addrr) + { + return 0; + } + for (int i = 0; i < 1000; i++) { if (*(uint8_t*)(uint8_t*)(Addrr - i) == 0x40 && *(uint8_t*)(uint8_t*)(Addrr - i + 1) == 0x55) @@ -1788,6 +1810,9 @@ static inline uint64 FindGiveAbility() if (!addr) addr = Memcury::Scanner::FindPattern("48 89 5C 24 ? 55 56 57 41 56 41 57 48 8B EC 48 83 EC ? 49 8B 40").Get(); // 22.3 + if (!addr) + addr = Memcury::Scanner::FindPattern("48 89 5C 24 ? 48 89 6C 24 ? 56 57 41 56 48 83 EC 30 49 8B 40 10 45 33 F6 49 8B E8 48 8B F2 48 8B").Get(); // 24.40 + return addr; } @@ -1841,6 +1866,7 @@ static inline uint64 FindReplaceBuildingActor() return FindBytes(StringRef, BytesToFind, 1000, 0, true); } +// UNetworkPredictionInterface static inline uint64 FindSendClientAdjustment() { auto addr = Memcury::Scanner::FindPattern("40 53 48 83 EC 20 48 8B 99 ? ? ? ? 48 39 99 ? ? ? ? 74 0A 48 83 B9", false).Get(); @@ -1849,7 +1875,10 @@ static inline uint64 FindSendClientAdjustment() addr = Memcury::Scanner::FindPattern("48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 57 48 83 EC ? 8B 91 ? ? ? ? 48 8B D9 83 FA", false).Get(); // 22.3 (this was painful to find) if (!addr) - addr = Memcury::Scanner::FindPattern("48 89 5C 24 ? 48 89 74 24 ? 57 48 83 EC 20 83 3D ? ? ? ? ? 48 8B D9 75 57 8B 91").Get(); + addr = Memcury::Scanner::FindPattern("48 89 5C 24 ? 48 89 74 24 ? 57 48 83 EC 20 83 3D ? ? ? ? ? 48 8B D9 75 57 8B 91", false).Get(); + + if (!addr) + addr = Memcury::Scanner::FindPattern("48 89 5C 24 ? 48 89 74 24 ? 57 48 83 EC 20 83 3D ? ? ? ? ? 48 8B D9 75 5A 8B 91 ? ? ? ? 83 FA FF 74 46 3B 91").Get(); // 24.40 return addr; } @@ -1875,10 +1904,10 @@ static inline uint64 FindReplicateActor() return Memcury::Scanner::FindPattern("48 8B C4 48 89 58 10 48 89 70 18 48 89 78 20 55 41 54 41 55 41 56 41 57 48 8D A8 ? ? ? ? 48 81 EC ? ? ? ? 48 8B 05 ? ? ? ? 48 33 C4 48 89 85 ? ? ? ? 4C 8D 69 68").Get(); if (Fortnite_Version >= 21) { - auto addr = Memcury::Scanner::FindPattern("48 8B C4 48 89 58 10 48 89 70 18 48 89 78 20 55 41 54 41 55 41 56 41 57 48 8D A8 ? ? ? ? 48 81 EC ? ? ? ? 48 8B 05 ? ? ? ? 48 33 C4 48 89 85 ? ? ? ? 45 33 FF 4C 8D 69 68 44 38 3D", false).Get(); + auto strRef = Memcury::Scanner::FindStringRef(L"STAT_NetReplicateActorTime"); + return strRef.ScanFor({ 0x48, 0x8B, 0xC4 }, false).Get(); - if (!addr) - addr = Memcury::Scanner::FindPattern("48 8B C4 48 89 58 ? 48 89 70 ? 48 89 78 ? 55 41 54 41 55 41 56 41 57 48 8D A8 ? ? ? ? 48 81 EC ? ? ? ? 48 8B 05 ? ? ? ? 48 33 C4 48 89 85 ? ? ? ? 45 33 FF 4C 8D 61 ? 44 38 3D ? ? ? ? 48 8D 05 ? ? ? ? 48 8B", false).Get(); // 22.30 + auto addr = Memcury::Scanner::FindPattern("48 8B C4 48 89 58 ? 48 89 70 ? 48 89 78 ? 55 41 54 41 55 41 56 41 57 48 8D A8 ? ? ? ? 48 81 EC ? ? ? ? 48 8B 05 ? ? ? ? 48 33 C4 48 89 85 ? ? ? ? 45 33 FF 4C 8D ? ? 44 38 3D", false).Get(); // 22.3 if (!addr) addr = Memcury::Scanner::FindPattern("40 55 41 54 41 55 41 56 41 57 48 81 EC ? ? ? ? 48 8D 6C 24 ? 48 89 9D ? ? ? ? 48 89 B5 ? ? ? ? 48 89 BD ? ? ? ? 48 8B 05 ? ? ? ? 48 33 C5 48 89 85 ? ? ? ? 45 33 E4 4C 8D 69 68 44 38 25 ? ? ? ? 48 8D 05 ? ? ? ? 48 8B F9 49 8B 4D").Get(); // 23.40 @@ -1894,7 +1923,14 @@ static inline uint64 FindCreateChannel() if (Fortnite_Version <= 3.3) return Memcury::Scanner::FindPattern("40 56 57 41 54 41 55 41 57 48 83 EC 60 48 8B 01 41 8B F9 45 0F B6 E0").Get(); if (Fortnite_Version >= 20) // 21.00 - return Memcury::Scanner::FindPattern("48 89 5C 24 ? 48 89 74 24 ? 44 89 4C 24 ? 55 57 41 54 41 56 41 57 48 8B EC 48 83 EC 50 45 33 E4 48 8D 05 ? ? ? ? 44 38 25").Get(); + { + auto addr = Memcury::Scanner::FindPattern("48 89 5C 24 ? 48 89 74 24 ? 44 89 4C 24 ? 55 57 41 54 41 56 41 57 48 8B EC 48 83 EC 50 45 33 E4 48 8D 05 ? ? ? ? 44 38 25", false).Get(); + + if (!addr) + addr = Memcury::Scanner::FindPattern("48 89 5C 24 ? 55 56 57 41 54 41 55 41 56 41 57 48 8B EC 48 83 EC 30 45 33 E4 48 8D 05 ? ? ? ? 44 38 25 ? ? ? ? 41 8B").Get(); + + return addr; + } return 0; } @@ -1924,7 +1960,10 @@ static inline uint64 FindSetChannelActor() auto addr = Memcury::Scanner::FindPattern("48 89 5C 24 ? 55 56 57 41 54 41 55 41 56 41 57 48 8D AC 24 ? ? ? ? 48 81 EC ? ? ? ? 33 FF 4C 8D 35 ? ? ? ? 89 BD", false).Get(); if (!addr) - addr = Memcury::Scanner::FindPattern("48 89 5C 24 ? 55 56 57 41 56 41 57 48 8D AC 24 ? ? ? ? 48 81 EC ? ? ? ? 45 33 F6 48 8D").Get(); // 22.30 & 23.40 + addr = Memcury::Scanner::FindPattern("48 89 5C 24 ? 55 56 57 41 56 41 57 48 8D AC 24 ? ? ? ? 48 81 EC ? ? ? ? 45 33 F6 48 8D", false).Get(); // 22.30 & 23.40 + + if (!addr) + addr = Memcury::Scanner::FindPattern("48 8B C4 48 89 58 10 48 89 70 18 48 89 78 20 55 41 54 41 55 41 56 41 57 48 8D A8 ? ? ? ? 48 81 EC ? ? ? ? 45 33 ED 48 8D 35 ? ? ? ? 44 89 AD ? ? ? ? 48 8B D9 48 8B 41 28 45 8B E0 48 8B FA 45 8B").Get(); // 24.40 return addr; } diff --git a/Project Reboot 3.0/hooking.h b/Project Reboot 3.0/hooking.h index ae53a99..14bcf45 100644 --- a/Project Reboot 3.0/hooking.h +++ b/Project Reboot 3.0/hooking.h @@ -152,7 +152,7 @@ inline __int64 GetFunctionIdxOrPtr(UFunction* Function, bool bBreakWhenHitRet = auto NativeAddr = __int64(Function->GetFunc()); - LOG_INFO(LogDev, "Getting name!") + LOG_INFO(LogDev, "[GetFunctionIdxOrPtr] Getting name!") auto FuncName = Function->GetName(); diff --git a/Project Reboot 3.0/reboot.h b/Project Reboot 3.0/reboot.h index e9bf2ff..31e6c45 100644 --- a/Project Reboot 3.0/reboot.h +++ b/Project Reboot 3.0/reboot.h @@ -66,8 +66,9 @@ template static inline T* FindObject(const std::string& NameStr, UClass* Class = nullptr, UObject* Outer = nullptr) { std::string name = NameStr; - auto NameCWSTR = std::wstring(name.begin(), name.end()).c_str(); - return StaticFindObject(Class, Outer, NameCWSTR); + auto NameWStr = std::wstring(name.begin(), name.end()); + auto NameCWStr = NameWStr.c_str(); + return StaticFindObject(Class, Outer, NameCWStr); } static inline UEngine* GetEngine() @@ -78,7 +79,7 @@ static inline UEngine* GetEngine() { __int64 starting = 2147482000; - for (__int64 i = starting; i < (starting + 1000); i++) + for (__int64 i = starting; i < (starting + 1000); ++i) { if (Engine = FindObject("/Engine/Transient.FortEngine_" + std::to_string(i))) break; @@ -162,6 +163,8 @@ inline uint8_t GetFieldMask(void* Property, int additional = 0) // 3 = sizeof(FieldSize) + sizeof(ByteOffset) + sizeof(ByteMask) + if (Fortnite_Version >= 24) + return *(uint8_t*)(__int64(Property) + (0x6B + additional)); if (Engine_Version <= 424 || Fortnite_Version >= 20) return *(uint8_t*)(__int64(Property) + (112 + 3 + additional)); else if (Engine_Version >= 425) @@ -292,7 +295,7 @@ inline void* FindPropertyStruct(const std::string& StructName, const std::string return Property; } - Property = Engine_Version >= 425 ? *(void**)(__int64(Property) + 0x20) : ((UField*)Property)->Next; + Property = GetNext(Property); PropName = Property ? GetFNameOfProp(Property)->ToString() : ""; } } @@ -413,6 +416,7 @@ namespace MemberOffsets namespace DeathInfo { extern inline int bDBNO = 0, Downer = 0, FinisherOrDowner = 0, DeathCause = 0, Distance = 0, DeathLocation = 0, bInitialized = 0, DeathTags = 0; + extern inline bool bIsWeakFinisherOrDowner = false; } } diff --git a/vendor/memcury.h b/vendor/memcury.h index 2cc6fb3..79da9a3 100644 --- a/vendor/memcury.h +++ b/vendor/memcury.h @@ -853,6 +853,13 @@ if (rdataSection.isInSection(stringAdd)) { auto strBytes = stringAdd.GetAs(); + auto pointerToRef = *(LPVOID*)strBytes; + + if (rdataSection.isInSection(pointerToRef)) // Credit: Ender + { + strBytes = (std::uint8_t*)pointerToRef; + stringAdd = PE::Address(pointerToRef); + } // Check if the first char is printable if (ASM::byteIsAscii(strBytes[0]))