| name | unreal5 |
| description | Unreal Engine 5 internal structures and memory layouts for reverse engineering. Covers UObject hierarchy, FNamePool, FUObjectArray, FProperty system, UFunction, FField, GWorld, Large World Coordinates, and key UE5 global arrays. Use this when analyzing UE5 game binaries. |
Unreal Engine 5 Structures
Comprehensive reference for UE5 internal data structures used during reverse engineering. All offsets are for 64-bit builds and should be verified per game build — custom engine modifications and compiler padding may shift fields.
Scope: UE5.x only (5.0–5.5+). UE4 uses different structures (e.g., TNameEntryArray instead of FNamePool, UProperty instead of FProperty).
1. Core Object System
1.1 UObjectBase
The true root of the hierarchy. UObject inherits from UObjectBase.
struct UObjectBase {
void **VTableObject;
EObjectFlags ObjectFlags;
int32_t InternalIndex;
UClass *ClassPrivate;
FName NamePrivate;
UObject *OuterPrivate;
};
Key notes:
ClassPrivate at 0x10 is the most important field for RE — it gives access to all reflection data
NamePrivate at 0x18 can be resolved to a string via FNamePool
InternalIndex at 0x0C is the object's slot in GUObjectArray
1.2 UObject
struct UObject : UObjectBase {
};
1.3 EObjectFlags (bitmask)
enum EObjectFlags : uint32_t {
RF_NoFlags = 0x00000000,
RF_Public = 0x00000001,
RF_Standalone = 0x00000002,
RF_MarkAsNative = 0x00000004,
RF_Transactional = 0x00000008,
RF_ClassDefaultObject = 0x00000010,
RF_ArchetypeObject = 0x00000020,
RF_Transient = 0x00000040,
RF_MarkAsRootSet = 0x00000080,
RF_TagGarbageTemp = 0x00000100,
RF_NeedInitialization = 0x00000200,
RF_NeedLoad = 0x00000400,
RF_KeepForCooker = 0x00000800,
RF_NeedPostLoad = 0x00001000,
RF_NeedPostLoadSubobjects = 0x00002000,
RF_NewerVersionExists = 0x00004000,
RF_BeginDestroyed = 0x00008000,
RF_FinishDestroyed = 0x00010000,
RF_BeingRegenerated = 0x00020000,
RF_DefaultSubObject = 0x00040000,
RF_WasLoaded = 0x00080000,
RF_TextExportTransient = 0x00100000,
RF_LoadCompleted = 0x00200000,
RF_InheritableComponentTemplate = 0x00400000,
RF_DuplicateTransient = 0x00800000,
RF_StrongRefOnFrame = 0x01000000,
RF_NonPIEDuplicateTransient = 0x02000000,
RF_WillBeLoaded = 0x20000000,
RF_HasExternalPackage = 0x40000000,
};
2. Name System (FNamePool)
UE5 replaced UE4's TNameEntryArray with a bucket-based FNamePool.
2.1 FName
struct FName {
FNameEntryId ComparisonIndex;
int32_t Number;
};
Usage: Number == 0 means the base name. Number == 3 means the name has suffix _2 (Number - 1).
2.2 FNameEntryId
struct FNameEntryId {
uint32_t Value;
};
Decoding:
block = FNameEntryId.Value >> 16
offset = FNameEntryId.Value & 0xFFFF
2.3 FNamePool
struct FNamePool {
FRWLock Lock;
uint32_t CurrentBlock;
uint32_t CurrentByteCursor;
FNameEntryAllocator_Block Blocks[8192];
};
2.4 FNameEntry
struct FNameEntry {
uint16_t Header;
};
Reading an FNameEntry:
len = Header >> 6
isWide = Header & 1
strData = &entry + 2 (immediately after the 2-byte header)
Stride: Entries in FNamePool are aligned to 2-byte boundaries. The stride for addressing within a block is 2 bytes per unit (i.e., offset * 2 gives the byte offset within the block).
2.5 FName Resolution Procedure
1. Extract ComparisonIndex.Value from FName
2. block = Value >> 16
3. offset = Value & 0xFFFF
4. blockBase = FNamePool.Blocks[block] (read pointer)
5. entryAddr = blockBase + (offset * 2)
6. header = read uint16 at entryAddr
7. len = header >> 6
8. isWide = header & 1
9. strData = entryAddr + 2
10. Read len bytes (ANSI) or len * 2 bytes (wide) from strData
Encryption warning: Some UE5 titles XOR/rotate FNameEntry headers or string data. If step 7 yields garbage lengths, reverse the FName::ToString or FName::AppendString function to find the decryption logic — typically a compile-time XOR constant.
3. Object Array (FUObjectArray / GObjects)
3.1 FUObjectArray
struct FUObjectArray {
int32_t ObjFirstGCIndex;
int32_t ObjLastNonGCIndex;
int32_t MaxObjectsNotConsideredByGC;
bool OpenForDisregardForGC;
FChunkedFixedUObjectArray ObjObjects;
};
3.2 FChunkedFixedUObjectArray
struct FChunkedFixedUObjectArray {
FUObjectItem **Objects;
FUObjectItem *PreAllocated;
int32_t MaxElements;
int32_t NumElements;
int32_t MaxChunks;
int32_t NumChunks;
};
3.3 FUObjectItem
struct FUObjectItem {
UObject *Object;
int32_t Flags;
int32_t ClusterRootIndex;
int32_t SerialNumber;
};
3.4 GObjects Traversal Procedure
1. Locate GUObjectArray global (exported or found via xrefs)
2. Read ObjObjects at offset 0x10 from GUObjectArray base
3. numElements = ObjObjects.NumElements (at ObjObjects + 0x14)
4. chunksBase = ObjObjects.Objects (at ObjObjects + 0x00, pointer to pointer array)
5. For index i = 0..numElements-1:
chunkIndex = i / 65536
withinChunk = i % 65536
chunkPtr = read pointer at (chunksBase + chunkIndex * pointerSize)
itemAddr = chunkPtr + (withinChunk * 0x18)
objPtr = read pointer at itemAddr
if objPtr != null:
ClassPrivate = read pointer at (objPtr + 0x10)
NamePrivate = read FName at (objPtr + 0x18)
4. Reflection System
4.1 UField (legacy base)
struct UField : UObject {
UField *Next;
};
4.2 UStruct
struct UStruct : UField {
UStruct *SuperStruct;
UField *Children;
FField *ChildProperties;
int32_t PropertiesSize;
int32_t MinAlignment;
TArray<uint8_t> Script;
FProperty *PropertyLink;
FProperty *RefLink;
FProperty *DestructorLink;
FProperty *PostConstructLink;
TArray<UObject*> ScriptAndPropertyObjectReferences;
};
Important for RE:
SuperStruct at 0x30 lets you walk the inheritance chain
ChildProperties at 0x40 is the FProperty linked list — this is how you enumerate struct/class fields in UE5
Children at 0x38 still holds UFunctions
PropertiesSize at 0x48 tells you the instance size
4.3 UClass
struct UClass : UStruct {
UObject* (*ClassConstructor)(...);
UObject* (*ClassVTableHelperCtorCaller)(...);
FUObjectCppClassStaticFunctions ClassStaticFunctions;
void (*ClassAddReferencedObjects)(UObject*, FReferenceCollector&);
uint32_t ClassUnique;
EClassFlags ClassFlags;
EClassCastFlags ClassCastFlags;
UClass *ClassWithin;
UObject *ClassGeneratedBy;
FName ClassConfigName;
TArray<FRepRecord> ClassReps;
TArray<UField*> NetFields;
UObject *ClassDefaultObject;
};
Key fields for RE:
ClassDefaultObject (CDO) — read default property values from here
ClassFlags — check for CLASS_Abstract, CLASS_Native, CLASS_Config
ClassCastFlags — fast IsA() check for common types (AActor, APawn, UActorComponent, etc.)
4.4 EClassCastFlags (bitmask — commonly checked types)
enum EClassCastFlags : uint64_t {
CASTCLASS_None = 0x0000000000000000,
CASTCLASS_UField = 0x0000000000000001,
CASTCLASS_FInt8Property = 0x0000000000000002,
CASTCLASS_UEnum = 0x0000000000000004,
CASTCLASS_UStruct = 0x0000000000000008,
CASTCLASS_UScriptStruct = 0x0000000000000010,
CASTCLASS_UClass = 0x0000000000000020,
CASTCLASS_FByteProperty = 0x0000000000000040,
CASTCLASS_FIntProperty = 0x0000000000000080,
CASTCLASS_FFloatProperty = 0x0000000000000100,
CASTCLASS_FUInt64Property = 0x0000000000000200,
CASTCLASS_FClassProperty = 0x0000000000000400,
CASTCLASS_FUInt32Property = 0x0000000000000800,
CASTCLASS_FInterfaceProperty = 0x0000000000001000,
CASTCLASS_FNameProperty = 0x0000000000002000,
CASTCLASS_FStrProperty = 0x0000000000004000,
CASTCLASS_FProperty = 0x0000000000008000,
CASTCLASS_FObjectProperty = 0x0000000000010000,
CASTCLASS_FBoolProperty = 0x0000000000020000,
CASTCLASS_FUInt16Property = 0x0000000000040000,
CASTCLASS_UFunction = 0x0000000000080000,
CASTCLASS_FStructProperty = 0x0000000000100000,
CASTCLASS_FArrayProperty = 0x0000000000200000,
CASTCLASS_FInt64Property = 0x0000000000400000,
CASTCLASS_FDelegateProperty = 0x0000000000800000,
CASTCLASS_FNumericProperty = 0x0000000001000000,
CASTCLASS_FMulticastDelegateProperty = 0x0000000002000000,
CASTCLASS_FObjectPropertyBase = 0x0000000004000000,
CASTCLASS_FWeakObjectProperty = 0x0000000008000000,
CASTCLASS_FLazyObjectProperty = 0x0000000010000000,
CASTCLASS_FSoftObjectProperty = 0x0000000020000000,
CASTCLASS_FTextProperty = 0x0000000040000000,
CASTCLASS_FInt16Property = 0x0000000080000000,
CASTCLASS_FDoubleProperty = 0x0000000100000000,
CASTCLASS_FSoftClassProperty = 0x0000000200000000,
CASTCLASS_UPackage = 0x0000000400000000,
CASTCLASS_ULevel = 0x0000000800000000,
CASTCLASS_AActor = 0x0000001000000000,
CASTCLASS_APlayerController = 0x0000002000000000,
CASTCLASS_APawn = 0x0000004000000000,
CASTCLASS_USceneComponent = 0x0000008000000000,
CASTCLASS_UPrimitiveComponent = 0x0000010000000000,
CASTCLASS_USkinnedMeshComponent = 0x0000020000000000,
CASTCLASS_USkeletalMeshComponent= 0x0000040000000000,
CASTCLASS_UBlueprint = 0x0000080000000000,
CASTCLASS_UDelegateFunction = 0x0000100000000000,
CASTCLASS_UStaticMeshComponent = 0x0000200000000000,
CASTCLASS_FMapProperty = 0x0000400000000000,
CASTCLASS_FSetProperty = 0x0000800000000000,
CASTCLASS_FEnumProperty = 0x0001000000000000,
CASTCLASS_USparseDelegateFunction = 0x0002000000000000,
CASTCLASS_FMulticastInlineDelegateProperty = 0x0004000000000000,
CASTCLASS_FMulticastSparseDelegateProperty = 0x0008000000000000,
CASTCLASS_FFieldPathProperty = 0x0010000000000000,
CASTCLASS_FObjectPtrProperty = 0x0020000000000000,
CASTCLASS_FClassPtrProperty = 0x0040000000000000,
CASTCLASS_FLargeWorldCoordinatesRealProperty = 0x0080000000000000,
};
5. FField / FProperty System (UE5)
UE5 replaced UProperty (which was a full UObject) with lightweight FField/FProperty objects. These are not in GUObjectArray — they are allocated separately and linked from UStruct::ChildProperties.
5.1 FFieldClass
struct FFieldClass {
FName Name;
uint64_t Id;
uint64_t CastFlags;
EClassFlags ClassFlags;
FFieldClass *SuperClass;
};
5.2 FField
struct FField {
void **VTableObject;
FFieldClass *ClassPrivate;
FFieldVariant Owner;
FField *Next;
FName NamePrivate;
EObjectFlags FlagsPrivate;
};
5.3 FProperty
struct FProperty : FField {
int32_t ArrayDim;
int32_t ElementSize;
EPropertyFlags PropertyFlags;
uint16_t RepIndex;
uint16_t BlueprintReplicationCondition;
int32_t Offset_Internal;
FName RepNotifyFunc;
FProperty *PropertyLinkNext;
FProperty *NextRef;
FProperty *DestructorLinkNext;
FProperty *PostConstructLinkNext;
};
Key field for RE: Offset_Internal at 0x4C — this is the byte offset where this property's data lives within an instance of the owning struct/class.
5.4 EPropertyFlags (bitmask)
enum EPropertyFlags : uint64_t {
CPF_None = 0,
CPF_Edit = 0x0000000000000001,
CPF_ConstParm = 0x0000000000000002,
CPF_BlueprintVisible = 0x0000000000000004,
CPF_ExportObject = 0x0000000000000008,
CPF_BlueprintReadOnly = 0x0000000000000010,
CPF_Net = 0x0000000000000020,
CPF_EditFixedSize = 0x0000000000000040,
CPF_Parm = 0x0000000000000080,
CPF_OutParm = 0x0000000000000100,
CPF_ZeroConstructor = 0x0000000000000200,
CPF_ReturnParm = 0x0000000000000400,
CPF_DisableEditOnTemplate = 0x0000000000000800,
CPF_Transient = 0x0000000000002000,
CPF_Config = 0x0000000000004000,
CPF_DisableEditOnInstance = 0x0000000000010000,
CPF_EditConst = 0x0000000000020000,
CPF_GlobalConfig = 0x0000000000040000,
CPF_InstancedReference = 0x0000000000080000,
CPF_DuplicateTransient = 0x0000000000200000,
CPF_SaveGame = 0x0000000001000000,
CPF_NoClear = 0x0000000002000000,
CPF_ReferenceParm = 0x0000000008000000,
CPF_BlueprintAssignable = 0x0000000010000000,
CPF_Deprecated = 0x0000000020000000,
CPF_IsPlainOldData = 0x0000000040000000,
CPF_RepSkip = 0x0000000080000000,
CPF_RepNotify = 0x0000000100000000,
CPF_Interp = 0x0000000200000000,
CPF_NonTransactional = 0x0000000400000000,
CPF_EditorOnly = 0x0000000800000000,
CPF_NoDestructor = 0x0000001000000000,
CPF_AutoWeak = 0x0000004000000000,
CPF_ContainsInstancedReference = 0x0000008000000000,
CPF_AssetRegistrySearchable = 0x0000010000000000,
CPF_SimpleDisplay = 0x0000020000000000,
CPF_AdvancedDisplay = 0x0000040000000000,
CPF_Protected = 0x0000080000000000,
CPF_BlueprintCallable = 0x0000100000000000,
CPF_BlueprintAuthorityOnly = 0x0000200000000000,
CPF_TextExportTransient = 0x0000400000000000,
CPF_NonPIEDuplicateTransient= 0x0000800000000000,
CPF_ExposeOnSpawn = 0x0001000000000000,
CPF_PersistentInstance = 0x0002000000000000,
CPF_UObjectWrapper = 0x0004000000000000,
CPF_HasGetValueTypeHash = 0x0008000000000000,
CPF_NativeAccessSpecifierPublic = 0x0010000000000000,
CPF_NativeAccessSpecifierProtected = 0x0020000000000000,
CPF_NativeAccessSpecifierPrivate = 0x0040000000000000,
CPF_SkipSerialization = 0x0080000000000000,
};
5.5 Common FProperty Subtypes
| Subtype | FFieldClass Name | Data Description |
|---|
FBoolProperty | BoolProperty | Single bit or byte boolean. Has FieldSize, ByteOffset, ByteMask, FieldMask for bitfield access. |
FByteProperty | ByteProperty | uint8_t, optionally backed by a UEnum. |
FIntProperty | IntProperty | int32_t |
FInt64Property | Int64Property | int64_t |
FFloatProperty | FloatProperty | float (32-bit) |
FDoubleProperty | DoubleProperty | double (64-bit) — used extensively in UE5 LWC |
FStrProperty | StrProperty | FString (heap-allocated TArray<TCHAR>) |
FNameProperty | NameProperty | FName (8 bytes) |
FTextProperty | TextProperty | FText (localized string, complex internal layout) |
FObjectProperty | ObjectProperty | Raw UObject* pointer. Has PropertyClass field pointing to the expected UClass. |
FObjectPtrProperty | ObjectPtrProperty | UE5 TObjectPtr<T> — lazy-resolved object reference. FObjectPtr { FObjectHandle Handle; } |
FWeakObjectProperty | WeakObjectProperty | TWeakObjectPtr<T> — { int32_t ObjectIndex; int32_t ObjectSerialNumber; } |
FSoftObjectProperty | SoftObjectProperty | TSoftObjectPtr<T> — { FSoftObjectPath { FTopLevelAssetPath, FString SubPath } } |
FStructProperty | StructProperty | Inline struct. Has Struct field → UScriptStruct* for the struct type definition. |
FArrayProperty | ArrayProperty | TArray<T>. Has Inner → FProperty* for element type. |
FMapProperty | MapProperty | TMap<K,V>. Has KeyProp and ValueProp → FProperty*. |
FSetProperty | SetProperty | TSet<T>. Has ElementProp → FProperty*. |
FEnumProperty | EnumProperty | Backed by UEnum*. Has UnderlyingProp → FNumericProperty* for storage type. |
FDelegateProperty | DelegateProperty | Singlecast delegate. Has SignatureFunction → UFunction*. |
FMulticastDelegateProperty | MulticastInlineDelegateProperty | Multicast delegate (event dispatcher). |
FInterfaceProperty | InterfaceProperty | TScriptInterface<T>. Has InterfaceClass → UClass*. |
FClassProperty | ClassProperty | TSubclassOf<T>. Has MetaClass → UClass* for the base class constraint. |
FFieldPathProperty | FieldPathProperty | TFieldPath<T> — path to an FField. |
6. UFunction
6.1 UFunction Layout
struct UFunction : UStruct {
uint32_t FunctionFlags;
uint8_t NumParms;
uint16_t ParmsSize;
uint16_t ReturnValueOffset;
uint16_t RPCId;
uint16_t RPCResponseId;
FProperty *FirstPropertyToInit;
UFunction *EventGraphFunction;
int32_t EventGraphCallOffset;
void *Func;
};
6.2 EFunctionFlags
enum EFunctionFlags : uint32_t {
FUNC_None = 0x00000000,
FUNC_Final = 0x00000001,
FUNC_RequiredAPI = 0x00000002,
FUNC_BlueprintAuthorityOnly = 0x00000004,
FUNC_BlueprintCosmetic = 0x00000008,
FUNC_Net = 0x00000040,
FUNC_NetReliable = 0x00000080,
FUNC_NetRequest = 0x00000100,
FUNC_Exec = 0x00000200,
FUNC_Native = 0x00000400,
FUNC_Event = 0x00000800,
FUNC_NetResponse = 0x00001000,
FUNC_Static = 0x00002000,
FUNC_NetMulticast = 0x00004000,
FUNC_UbergraphFunction = 0x00008000,
FUNC_MulticastDelegate = 0x00010000,
FUNC_Public = 0x00020000,
FUNC_Private = 0x00040000,
FUNC_Protected = 0x00080000,
FUNC_Delegate = 0x00100000,
FUNC_NetServer = 0x00200000,
FUNC_NetClient = 0x00400000,
FUNC_DLLImport = 0x00800000,
FUNC_BlueprintCallable = 0x04000000,
FUNC_BlueprintEvent = 0x08000000,
FUNC_BlueprintPure = 0x10000000,
FUNC_EditorOnly = 0x20000000,
FUNC_Const = 0x40000000,
FUNC_NetValidate = 0x80000000,
FUNC_AllFlags = 0xFFFFFFFF,
};
6.3 UFunction Parameter Layout
UFunction parameters are stored as a contiguous struct. Each parameter is an FProperty in the function's ChildProperties chain:
1. Walk UFunction.ChildProperties (FProperty linked list)
2. For each FProperty:
- Check PropertyFlags for CPF_Parm (is a parameter)
- Check PropertyFlags for CPF_ReturnParm (is the return value)
- Check PropertyFlags for CPF_OutParm (is an output parameter)
- Offset_Internal gives the offset within the params struct
- ElementSize gives the size
3. Total params struct size = UFunction.ParmsSize
7. World and Actor System
7.1 GWorld
UWorld **GWorld;
7.2 UWorld (key fields)
struct UWorld : UObject {
ULevel *PersistentLevel;
FName StreamingLevelsPrefix;
ULevel *CurrentLevelPendingVisibility;
ULevel *CurrentLevelPendingInvisibility;
UDemoNetDriver *DemoNetDriver;
AGameStateBase *GameState;
TArray<ULevel*> Levels;
TArray<AActor*> LevelActors;
AGameModeBase *AuthorityGameMode;
UGameInstance *OwningGameInstance;
};
7.3 ULevel
struct ULevel : UObject {
TArray<AActor*> Actors;
};
7.4 AActor (key fields)
struct AActor : UObject {
USceneComponent *RootComponent;
TArray<UActorComponent*> OwnedComponents;
AActor *Owner;
FName NetDriverName;
ENetRole Role;
ENetRole RemoteRole;
FRepMovement ReplicatedMovement;
};
7.5 TArray
template<typename T>
struct TArray {
T *Data;
int32_t ArrayNum;
int32_t ArrayMax;
};
7.6 FString
struct FString {
TArray<TCHAR> Data;
};
8. Large World Coordinates (LWC)
UE5 uses double precision for spatial data:
8.1 FVector (UE5 LWC)
struct FVector {
double X;
double Y;
double Z;
};
8.2 FRotator
struct FRotator {
double Pitch;
double Yaw;
double Roll;
};
8.3 FTransform
struct FTransform {
FQuat Rotation;
FVector Translation;
FVector Scale3D;
};
8.4 Impact on RE
- All
FVector, FRotator, FTransform reads must use readDouble() instead of readFloat()
- Property offsets and struct sizes are larger than UE4 equivalents
- Physics, navigation, AI, and gameplay code all use double precision
FLargeWorldCoordinatesRealProperty in the reflection system marks LWC-aware properties
9. Commonly Needed Offset Summary
Quick reference table (verify per build — offsets can shift):
| Structure | Field | Typical Offset | Size |
|---|
UObject | VTable | 0x00 | 8 |
UObject | ObjectFlags | 0x08 | 4 |
UObject | InternalIndex | 0x0C | 4 |
UObject | ClassPrivate | 0x10 | 8 |
UObject | NamePrivate | 0x18 | 8 |
UObject | OuterPrivate | 0x20 | 8 |
UField | Next | 0x28 | 8 |
UStruct | SuperStruct | 0x30 | 8 |
UStruct | Children | 0x38 | 8 |
UStruct | ChildProperties | 0x40 | 8 |
UStruct | PropertiesSize | 0x48 | 4 |
FField | ClassPrivate | 0x08 | 8 |
FField | Next | 0x20 | 8 |
FField | NamePrivate | 0x28 | 8 |
FProperty | ElementSize | 0x3C | 4 |
FProperty | PropertyFlags | 0x40 | 8 |
FProperty | Offset_Internal | 0x4C | 4 |
FUObjectItem | Object | 0x00 | 8 |
FUObjectItem | (total size) | — | 0x18 |
FName | ComparisonIndex | 0x00 | 4 |
FName | Number | 0x04 | 4 |
TArray | Data | 0x00 | 8 |
TArray | ArrayNum | 0x08 | 4 |
TArray | ArrayMax | 0x0C | 4 |
FVector (LWC) | X,Y,Z | 0x00 | 3×8=24 |
Disclaimer: These offsets are based on standard UE5 builds (5.1–5.4). Custom engine forks, plugin-heavy builds, or games with source-level modifications may have different layouts. Always verify with static analysis before relying on hardcoded offsets.