Fuzzing Engine
Sogen includes a powerful fuzzing engine that leverages its snapshot and state management capabilities to perform high-performance coverage-guided fuzzing of Windows applications.Overview
The fuzzing engine works by:- Emulating the target application to a specific point (the target function)
- Creating a snapshot of the emulator state
- Spawning multiple fuzzer instances across CPU cores
- Each instance restores the snapshot, injects fuzzed input, and tracks code coverage
- Crashes and new coverage paths are automatically detected
Fuzzer Executable
Sogen provides a dedicatedfuzzer.exe utility for fuzzing applications. The fuzzer requires the Rust-based Icicle backend to be enabled at compile time.
Basic Usage
Command Line Options
-d flag enables GDB stub integration, allowing you to attach a debugger to inspect crashes.
How the Fuzzing Engine Works
1. Target Function Setup
The fuzzer looks for an exported function namedvulnerable in your target executable:
vulnerable function, then stops and captures the state.
2. State Serialization
The entire emulator state is serialized and shared across fuzzer instances:3. Parallel Execution
The fuzzer spawns multiple workers based on CPU core count:4. Input Injection
Fuzzed data is injected via registers before execution:RCX= pointer to fuzzed input bufferRDX= size of fuzzed input
5. Coverage Tracking
The fuzzer tracks which basic blocks have been executed:6. Crash Detection
Exceptions and crashes are automatically caught:Implementing a Fuzzable Target
To make your application fuzzable with Sogen:1. Export a Target Function
2. Compile Your Target
Build your target application as a standard Windows executable or DLL with thevulnerable export.
3. Run the Fuzzer
- Load your executable
- Run until the
vulnerablefunction - Take a snapshot
- Start fuzzing with automatic input generation
Fuzzer Architecture
Executer Interface
Each fuzzer worker implements thefuzzer::executer interface:
Fuzzing Handler
The main fuzzing logic implementsfuzzer::fuzzing_handler:
Performance Optimization
Snapshot vs. Deserialization
The fuzzer uses fast in-memory snapshots instead of full deserialization:Memory Management
The fuzzer allocates memory for each input and cleans up automatically:Backend Requirements
The fuzzer requires the Icicle backend (Rust-based emulation):Example: Fuzzing a Parser
Here’s a complete example of a fuzzable parser:Troubleshooting
”Fuzzer requires rust code to be enabled”
You need to build Sogen with Rust support enabled:No Coverage Increase
Ensure:- Your
vulnerablefunction is actually being called - The function performs different operations based on input
- The emulator isn’t hitting infinite loops
Out of Memory
Reduce concurrency:Next Steps
- Learn about State Management for understanding snapshots
- Explore Custom Backends for Icicle configuration
- Use GDB Integration to debug crashes found by the fuzzer