Architecture Overview
Atlus is structured as a multi-layer C++20 application with clean separation
between analysis logic and presentation. The core is a static analysis library
(atlus_core) that operates on PE files, while a fully dockable
Dear ImGui GUI provides the interface.
- Core Library — PE parsing, diff algorithms, pattern generation
- Analysis Engine — Function identification, control flow graphs
- Disassembly — Zydis integration for x86/x64 disassembly
- Decompilation — Ghidra integration for C pseudocode
- GUI Layer — Dear ImGui with docking and multi-window support
Four-Level Diff Engine
The heart of Atlus is its hierarchical diff engine that compares binaries at increasing levels of abstraction:
Level 1: Byte-Level Diff
Raw byte comparison with optimized sliding window. Identifies changed, inserted, and deleted byte ranges. Fast for small files, provides ground truth for higher-level analysis.
Level 2: Section-Level Diff
Compares PE sections (.text, .data, .rsrc, etc.) independently. Handles section resizing, reordering, and attribute changes. Provides structural context missing from raw bytes.
Level 3: Function-Level Diff
Identifies functions via symbol tables or heuristic analysis, then compares them individually. Handles function inlining, outlining, and compiler optimization changes.
Level 4: AOB Signature Generation
Generates Array of Bytes signatures that can survive small updates. Supports both IDA-style patterns (with ? wildcards) and Cheat Engine format. These signatures can be used to find the same code in updated versions of a binary.
PE Analysis Pipeline
1. Parse PE headers (DOS, COFF, optional header)
2. Build section map with virtual/physical addresses
3. Extract exports and imports (IAT/EAT analysis)
4. Identify function boundaries
- Via symbols if available
- Via prologue/epilogue heuristics
- Via control flow analysis
5. Build control flow graphs
6. Run user-selected analysis:
- Diff against another binary
- Generate patterns
- Disassemble specific regions
Disassembly with Zydis
Atlus uses the Zydis disassembler for fast, accurate x86/x64 decoding:
- Full instruction encoding support (including AVX-512)
- Intel and AT&T syntax output
- Runtime address calculation
- Instruction categorization for analysis
Ghidra Decompiler Integration
For higher-level analysis, Atlus can send functions to Ghidra's decompiler and display the resulting C pseudocode:
- Asynchronous decompilation to keep UI responsive
- Caching of results for quick navigation
- Source-to-assembly correlation
Dear ImGui Docking Interface
The GUI is built with Dear ImGui's docking branch for a flexible workspace:
- Multi-window layout with docking
- Hex viewer with synchronized disassembly
- Function browser with filtering
- Diff view with side-by-side comparison
- Pattern output with copy-to-clipboard
Key Libraries
| Library | Purpose |
|---|---|
| LIEF | PE32/PE32+ parsing and manipulation |
| Zydis | x86/x64 disassembly |
| Dear ImGui | Immediate-mode GUI with docking |
| Ghidra | Decompiler integration (external) |
Performance Considerations
Binary analysis can be slow on large files. Atlus addresses this through:
- Memory-mapped file I/O for large binaries
- Lazy parsing (only analyze what's needed)
- Parallel diff for independent sections
- Caching of analysis results
What I Learned
Building Atlus taught me about the PE format in depth, including edge cases like packed executables, .NET hybrids, and the many ways compilers can structure the same code. The diff algorithm design was particularly interesting: balancing speed with accuracy across multiple abstraction levels.
Use Cases
- Patch Analysis — Compare game versions to find changed functions
- Malware Analysis — Diff malware samples to track evolution
- Reverse Engineering — Generate patterns for dynamic analysis tools
- Binary Auditing — Find code changes between software versions