Skip to content

Extract ClassNetCache data from UE5 binaries and cooked packages

Notifications You must be signed in to change notification settings

Mokocoder/UE5_ClassNetCache_Extractor

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

UE5 ClassNetCache Extractor

Extracts ClassNetCache data from Unreal Engine 5 games: SerializeInt Max values and per-field handle indices. These values are required by netcode implementations that replicate UE5 network traffic outside the engine.

The pipeline consists of two stages:

  1. z_construct_parser.py — Static analysis of the game binary (PE) to extract Max values and field indices for all C++ native classes
  2. MaxExtractor — Reads cooked .pak archives via CUE4Parse to extract data for Blueprint classes, then merges both into a single output

Requirements

  • Python 3.10+ with pefile
  • .NET 8.0 SDK

Build

git clone --recurse-submodules https://github.com/Mokocoder/UE5_ClassNetCache_Extractor.git
cd UE5_ClassNetCache_Extractor
dotnet build MaxExtractor/MaxExtractor.csproj -c Release

Usage

Step 1: Extract C++ Seed Data

python z_construct_parser.py <Game.exe> [output.json]

Scans Z_Construct_UClass static registration stubs in the .text section, identifies ConstructUClass via fingerprint scoring, and computes Max values + field indices by walking the class hierarchy. Tested on UE 5.7.

Example (Lyra Starter Game, UE 5.7):

python z_construct_parser.py "LyraStarterGame/Binaries/Win64/LyraGame.exe" lyra_cpp_seed.json
[*] Loading LyraGame.exe...
[*] ImageBase = 0x140000000
[*] ConstructUClass @ 0x142183CF0  (5523 classes, score=3)
[*] Mapping class names...
[*] 5523/5523 names resolved
[*] Parsing class metadata...
[*] Computing Max values and field indices...
[*] Written 5523 Max values + 472 fields (334p + 138f) → lyra_cpp_seed.json (43.1s)

Output format:

{
  "stats": {
    "total_classes": 5523,
    "named": 5523,
    "resolved_max": 5523,
    "resolved_fields": 198,
    "total_fields": 472,
    "total_props": 334,
    "total_funcs": 138,
    "elapsed_sec": 43.1
  },
  "seed_values": {
    "AIController": 15,
    "Actor": 29,
    "Character": 35,
    ...
  },
  "per_class": {
    "Actor": {
      "fields_base": 0,
      "fields": {
        "0": { "name": "RemoteRole", "type": "property" },
        "1": { "name": "Owner", "type": "property" },
        ...
      }
    },
    ...
  },
  "flat_index": {
    "Actor::RemoteRole": 0,
    "Actor::Owner": 1,
    ...
  }
}

Step 2: Merge Blueprint Data

MaxExtractor <PaksDir> <SeedJson> [GameName] [UsmapPath] [OutputPath]
Argument Required Description
PaksDir Yes Directory containing .pak / .utoc / .ucas files
SeedJson Yes Output from Step 1
GameName No CUE4Parse EGame enum value (default: GAME_UE5_7)
UsmapPath No Path to .usmap mappings file, required for unversioned packages
OutputPath No Output JSON path (default: ./class_net_cache.json)

Example (Lyra Starter Game, UE 5.7):

dotnet run --project MaxExtractor -c Release -- \
  "LyraStarterGame/Saved/StagedBuilds/Windows/LyraStarterGame/Content/Paks" \
  lyra_cpp_seed.json \
  GAME_UE5_7
[*] Loaded 5523 C++ seed values, 198 field entries
[*] Mounted 6 containers, 9828 files (194ms)
[*] Scanning 3834 packages...
[*] Scan complete: 292 BPs in 3834 packages (1812ms)
[*] Resolved: 289, Unresolved: 0
[*] Field indices: 472 C++ + 30 BP = 502 total
[*] Written 5812 Max values (5523 C++ + 289 BP), 502 fields → class_net_cache.json

Output format:

{
  "stats": {
    "cpp_classes": 5523,
    "bp_classes": 289,
    "resolved": 5812,
    "unresolved": 0,
    "total_fields": 502,
    "packages": 3834,
    "skipped": 3542,
    "errors": 0
  },
  "max_values": {
    "AIController": 15,
    "Actor": 29,
    "Character": 35,
    ...
  },
  "per_class": {
    "Actor": {
      "fields_base": 0,
      "fields": {
        "0": { "name": "RemoteRole", "type": "property" },
        ...
      }
    },
    ...
  },
  "flat_index": {
    "Actor::RemoteRole": 0,
    ...
  }
}

Notes

  • Unversioned packages: Most shipping builds use unversioned property serialization. In this case, a .usmap mappings file is required for Step 2. Use UnrealMappingsDumper to generate one from a running process.
  • UE version support: Tested on UE 5.7. Other versions may work but are not verified.

Example Output

The example/ directory contains extraction results from Lyra Starter Game (UE 5.7):

  • lyra_cpp_seed.json — 5,523 C++ native classes (Max values + 472 field indices)
  • lyra_class_net_cache.json — 5,812 merged classes (C++ + Blueprint, 502 field indices)

Project Structure

├── z_construct_parser.py       # Step 1: PE binary → C++ seed data
├── MaxExtractor/
│   ├── MaxExtractor.csproj
│   └── Program.cs              # Step 2: .pak archives → merged output
├── CUE4Parse/                  # Git submodule
└── example/
    ├── lyra_cpp_seed.json
    └── lyra_class_net_cache.json

License

This project uses CUE4Parse (Apache-2.0) as a git submodule.

About

Extract ClassNetCache data from UE5 binaries and cooked packages

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published