SDK dumper for Delta Force. Enumerates objects, decrypts names, and dumps class hierarchy with property layouts.
The game encrypts all name strings in the name pool with a per-entry XOR key. The key is a single byte derived from the string length:
uint8_t xor_key(uint32_t len) {
uint32_t k;
switch (len % 9) {
case 0: k = len + (len & 0x1F) + 0x80; break;
case 1: k = len + (len ^ 0xDF) + 0x80; break;
case 2: k = len + (len | 0xCF) + 0x80; break;
case 3: k = 33 * len + 128; break;
case 4: k = len + (len >> 2) + 128; break;
case 5: { uint32_t x = (3*len - 41 + 0x80) & 0xFF;
if (x < 0x80) x |= 0x80;
return (uint8_t)(x | 0x7F); }
case 6: k = len + ((4*len) | 5) + 128; break;
case 7: k = len + ((len >> 4) | 7) + 128; break;
case 8: k = len + (len ^ 0xC) + 128; break;
}
return (uint8_t)((k & 0xFF) | 0x7F);
}Each name entry has a 16-bit header: bit 0 = wide flag, bits 6-15 = string length. The raw bytes after the header are XOR'd with the key above.
You can verify the scheme works by checking the first entry in block 0 — it always decodes to "None".
id >> 18 → block index
id & 0x3FFFF → offset within block
pool[(block+1)*8] → block base pointer
base + offset * 2 → entry address
Chunked array, 0x10000 items per chunk, 0x10 bytes per item. For each object the dumper resolves the class name, builds the full outer path, and for structural types (Class, ScriptStruct, Function) walks the super chain and property list.
Encrypted pointers are masked, not shifted:
uint64_t decrypt(uint64_t enc) {
return enc & 0x0000FFFFFFFFFFFF;
}
// live example:
// HealthSet raw = 0x80200000_e428dd00
// decrypt(raw) = 0x0000_e428dd00 → HP = 100.0 ✓
// (raw >> 4) = 0x0802_0000_0e42_8dd0 → reads zero ✗LP → PC: read(LP + 0x30) → PlayerController (plain)
PC → Pawn: decrypt(read(PC + 0x3F0)) → AcknowledgedPawn
Pawn → PS: read(Pawn + 0x390) → PlayerState (plain)
Pawn → Mesh: decrypt(read(Pawn + 0x3D0))→ SkeletalMeshComponent
PC → PCM: decrypt(read(PC + 0x408)) → PlayerCameraManager
+0x478 PlayerNamePrivate (FString, UTF-16) → "<redacted>" ✓
+0x4B4 bDead (bool) = 0 ✓
+0x518 bIsAI (bool) = 0 ✓
+0x660 TeamID (i32) = 1 ✓
+0x664 Camp (i32) = 0 ✓
HealthComp = decrypt(read(Pawn + 0x10C8))
HealthSet = decrypt(read(HealthComp + 0x280))
HP = read<f32>(HealthSet + 0x3C) = 100.0 ✓
MaxHP = read<f32>(HealthSet + 0x54) = 100.0 ✓
ArmorHP = read<f32>(HealthSet + 0x74) = 0.0 ✓
MaxArmorHP = read<f32>(HealthSet + 0x8C) = 0.0 ✓
See example_output.txt. Format:
[00000003] 0000000051380090 Package 40000000 /Script/Engine
[00000030] 000000001F7EDD00 Class 42000000 /Script/CoreUObject.Interface
~ Class /Script/CoreUObject.Object
| Field | Offset |
|---|---|
| GObjects | 0x1606F0908 |
| FNamePool | 0x1606CBE00 |
| UObject::Class | +0x08 |
| UObject::Outer | +0x10 |
| UObject::Name | +0x1C |
| UStruct::Super | +0x48 |
| UStruct::ChildProperties | +0x70 |
| FField::Next | +0x20 |
| FField::ClassPrivate | +0x28 |
| FField::NamePrivate | +0x30 |
| FField::Offset_Internal | +0x54 |
