FitDNuvo — Complete Denuvo Analysis on F1 25
Denuvo/SPEAR architecture, modules, hooks, initialization chain
FitDNuvo — Análise Completa do Denuvo no F1 25
Data: 2026-06-28 Status: Phase 1 & 2 complete Tools: Ghidra 12.1.2 + GhidraMCP 5.13.1, Python PE Scanner, SSH chicotv
Overview
FitDNuvo is a security research project to analyze, detect and remove Denuvo/EA SPEAR protection layers from Windows binaries. The case study is F1 25 (Codemasters/EA, 2025).
Ethical principle: The user must own a legitimate game license (Steam ownership validation via steam_api64.dll). FitDNuvo is a consumer preservation and defense tool, not a piracy tool.
F1 25 Protection Architecture
Full Stack
F1_25.exe (399MB, 23 PE sections)
├── .tls (282MB, XRW, entropy 6.85) ← DENUVO VM PAYLOAD
├── preloader_l.dll (46KB, 6 sections) ← Denuvo bootstrap + anti-debug
├── EAAntiCheat.cfg (signed PE) ← EA SPEAR AntiCheat config
├── EAAntiCheat.GameServiceLauncher.dll (48MB) ← SPEAR runtime
├── EAAntiCheat.Installer.exe (243MB) ← SPEAR installer
├── sl.interposer.dll (541KB) ← NVIDIA Streamline (injection vector)
├── steam_api64.dll (299KB) ← Steam ownership validation
└── EGO Engine ← Original Codemasters engine
Layer 1: preloader_l.dll (Denuvo Bootstrap)
- Entry point: 0x18000b030 with 6 UD2 (0x0F 0x0B) anti-debug instructions
- Exports:
preloader_link_func(ordinal 1), Denuvo hash token (ordinal 0) - Import fingerprint: 58 functions (44 ntdll, 8 user32, 1 gdi32, 1 advapi32)
- Non-standard sections:
.entry(48 bytes of code with UD2 traps) - Strings: "EA Javelin Anticheat", "EAAntiCheat.GameServiceLauncher.dll"
- Status: Fully obfuscated — decompiler returns "Bad instruction data" on all functions
Layer 2: F1_25.exe (Main Denuvo VM)
.tlssection: 282MB with XRW flags (executable + read + write)- Normal TLS is <1KB. 282MB = complete Denuvo VM payload
- Entropy 6.85 = compiled code, not encrypted (but possibly packed)
.text1section: Entropy 7.97 — packed/encrypted code.idatasection: XRW — self-modifying import table (Denuvo JIT hook).sbsssection: 83.5MB, executable, named as BSS — misdirection- Entry point: 0x189ed020 (non-standard, within Denuvo region)
Layer 3: EA SPEAR AntiCheat
- Version: 1.0.14073350
- Signature: EA SPEAR AntiCheat Engineering, Redwood City, CA
- Certificate chain: DigiCert Trusted G4 → DigiCert G4 Code Signing RSA4096 SHA384 2021 CA1 → Electronic Arts, Inc.
- Installation:
EAAntiCheat.Installer.exe --noui --install --read-cfg - Runtime:
EAAntiCheat.GameServiceLauncher.exe+EAAntiCheat.GameServiceLauncher.dll - Function: Runtime integrity validation, license check, anti-debug
Denuvo Fingerprint (58 assinaturas de import)
Core VM Setup (5/5 match no preloader)
NtAllocateVirtualMemory, NtCreateSection, NtMapViewOfSection,
NtProtectVirtualMemory, RtlAllocateHeap
Anti-Debug (8/9 match)
ZwQueryInformationProcess, GetProcessWindowStation,
GetUserObjectInformationW, IsChild, SetWindowLongPtrW,
GetWindowLongPtrW, CallNextHookEx, DefWindowProcW
License Validation (4/9)
ZwCreateUserProcess, ZwCreateThreadEx, ZwTerminateProcess,
ZwWaitForSingleObject
→ Denuvo creates child processes to validate license!
Process Introspection (9/9 — 100% match!)
LdrGetProcedureAddress, LdrFindEntryForAddress, LdrFindResource_U,
LdrAccessResource, RtlPcToFileHeader, RtlFindMessage,
RtlDosPathNameToNtPathName_U_WithStatus, RtlCreateEnvironment,
RtlCreateProcessParametersEx
Red Flags (5/5)
Pie (GDI32), MessageBoxW, RtlAppendUnicodeToString,
RtlCopyUnicodeString, RtlFindCharInUnicodeString
Injection Vector: sl.interposer.dll (NVIDIA Streamline)
The sl.interposer.dll is not just DLSS — it's a complete graphics API proxy:
- Streamline exports: slInit, slSetTag, slGetFeature, slSetConstants, slEvaluateFeature, slGetNewFrameToken, slAllocateResources, slFreeResources
- D3D12 exports: D3D12CreateDevice, D3D12GetDebugInterface, D3D12SerializeRootSignature
- D3D11 exports: D3D11CreateDevice, D3D11CreateDeviceAndSwapChain
- DXGI exports: CreateDXGIFactory, CreateDXGIFactory1, CreateDXGIFactory2
- Vulkan exports: vkCreateInstance, vkCreateDevice, vkEnumeratePhysicalDevices, +80 functions
- Suspicious strings: IsDebuggerPresent, VirtualProtect, OutputDebugStringA/W
→ The interceptor intercepts ALL graphics calls. It's the perfect FitDNuvo hook point.
Structural Findings
Non-standard sections as Denuvo signature
Denuvo-protected binaries exhibit:
.tls> 10MB with XRW → VM payload (98% confidence)- Entropy > 7.5 → packed/encrypted code (90%)
- XRW sections → self-modifying code / JIT VM (85%)
- Non-standard section names:
.sbss,.00cfg,.srdata,.xcode,.sxdata,.data1,.data2 - Executable section named as BSS → misdirection (75%)
F1 25 Engine vs Denuvo (scanner classification)
| Section | Size | Flags | Classification | Confidence |
|---|---|---|---|---|
| .tls | 282.3MB | XRW | DENUVO VM | 98% |
| .text1 | 0.1MB | RW | DENUVO (entropy 7.97) | 90% |
| .idata | 0.0MB | XRW | DENUVO JIT | 85% |
| .sbss | 83.5MB | XR | DENUVO (misdirection) | 60% |
| .00cfg | 13.5MB | RW | DENUVO (name) | 60% |
| .data | 0.0MB | RW | Engine | 90% |
| .rsrc | 1.5MB | R | Engine | 90% |
| .bss | 0.6MB | R | Engine | 90% |
Pipeline FitDNuvo
┌─────────────────────────────────────────────────────────┐
│ 1. SCANNER (Python) │ PE parser + fingerprint match │
│ │ Identifies Denuvo vs Engine │
├──────────────────────┼──────────────────────────────────┤
│ 2. STRIPPER (C++/Rust)│ Removes Denuvo sections from PE │
│ │ Rebuilds clean IAT │
│ │ Re-links steam_api64.dll │
│ │ Injects Steamworks Fix (IPv6 P2P) │
├──────────────────────┼──────────────────────────────────┤
│ 3. GUARD (C driver) │ Ring0Guardkeeper.sys │
│ │ Blocks *.ea.com, *.codemasters │
│ │ Allows IPv6 multicast P2P │
│ │ Hardware-bound license attestation │
└──────────────────────┴──────────────────────────────────┘
Tools and Files
| Tool | Location | Description |
|---|---|---|
| fitdnuvo_scanner.py | /tmp/fitdnuvo_scanner.py | PE Scanner + Denuvo fingerprint |
| FitDNuvoPhase1.java | ~/Library/ghidra/.../ghidra_scripts/ | VM pattern extractor (Ghidra) |
| FitDNuvoPhase2.java | ~/Library/ghidra/.../ghidra_scripts/ | RNG/seed detector (Ghidra) |
| Scanner report | /tmp/fitdnuvo_report_*.json | Scanner JSON output |
Analyzed binaries
| File | Size | Location |
|---|---|---|
| F1_25.exe | 399,280,512 (381MB) | D:/SteamLibrary/.../F1 25/ |
| preloader_l.dll | 46,840 | D:/SteamLibrary/.../F1 25/ |
| sl.interposer.dll | 541,168 | D:/SteamLibrary/.../F1 25/ |
| steam_api64.dll | 298,856 | D:/SteamLibrary/.../F1 25/ |
| EAAntiCheat.cfg | ~48MB (PE) | D:/SteamLibrary/.../F1 25/ |
Next Steps
- Scanner — automated Denuvo detection
- Stripper — removal of protection layers from PE
- Ring0Guardkeeper — kernel driver for blocking official servers
- Steamworks Fix — IPv6 P2P multiplayer without EA servers
- Fita-Launcher — unified interface for the complete pipeline
- Denuvo ISA Mapper — reverse engineering of the VM's custom ISA (requires RNG seed)
References
- fitdnuvo-scanner — Scanner Documentation
- fitalabs-infra — Local services (gateway, searxng, crawl4ai)
- chicotv — PC Windows com F1 25 instalado
- Ghidra 12.1.2 —
/opt/homebrew/Cellar/ghidra/12.1.2/ - GhidraMCP 5.13.1 —
/Users/alefita/.lib/ghidra-mcp/