---
type: analysis
title: FitDNuvo — Complete Denuvo Analysis on F1 25
description: Denuvo/SPEAR architecture, modules, hooks, initialization chain
tags: [fitdnuvo, denuvo, spear, f1-25, reverse-engineering]
timestamp: 2026-06-28
---

# 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)

- **`.tls` section:** 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)
- **`.text1` section:** Entropy 7.97 — packed/encrypted code
- **`.idata` section:** XRW — self-modifying import table (Denuvo JIT hook)
- **`.sbss` section:** 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:
1. `.tls` > 10MB with XRW → VM payload (98% confidence)
2. Entropy > 7.5 → packed/encrypted code (90%)
3. XRW sections → self-modifying code / JIT VM (85%)
4. Non-standard section names: `.sbss`, `.00cfg`, `.srdata`, `.xcode`, `.sxdata`, `.data1`, `.data2`
5. 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

- [x] 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/`
