OLLVM Deobfuscation Workflows in reverse-skill: A Complete 7-Tool Guide
The reverse-skill repository provides seven distinct OLLVM deobfuscation workflows spanning GUI tools, symbolic execution engines, and lightweight emulators, organized in a decision matrix that lets analysts choose based on their environment (IDA Pro, Binary Ninja, or pure Python).
The reverse-skill project maintains a comprehensive, community-curated guide for reversing Obfuscator-LLVM (OLLVM) protected binaries. Located at skills/reverse-engineering/references/ollvm-deobfuscation.md, this resource documents battle-tested deobfuscation pipelines for modern OLLVM variants including Hikari, Polaris, O-MVLL, and amice.
OLLVM Deobfuscation Workflow Structure
The reverse-skill guide organizes its OLLVM deobfuscation coverage into five interconnected sections. Each section builds toward actionable tool selection and execution.
Section 0: Quick Decision Matrix
The entry point for any analysis is the Quick Decision Matrix — a reference table that maps your constraints to the optimal tool. Key decision factors include:
- Disassembler available: IDA Pro, Binary Ninja, or neither
- Target architecture: x86/x64, ARM64, or mixed
- Network connectivity: Required for cloud-based solutions
- Automation level: Fully automated vs. script-based
This matrix prioritizes obpo-plugin for networked IDA environments, falls back to d810-ng for offline IDA workflows, and routes headless or ARM64 cases to Unicorn-based alternatives.
Section 1: Modern OLLVM Variant Landscape (2026)
OLLVM deobfuscation requires variant identification before tool selection. The guide catalogs active derivatives:
- Hikari: Maintained fork with additional passes
- Polaris: Commercial variant with enhanced flattening
- O-MVLL: Mobile-focused implementation
- amice: VM-flattened hybrid requiring specialized handling
Each variant introduces distinct dispatcher patterns and anti-analysis tricks that affect pipeline selection.
Section 2: OLLVM Obfuscation-Type Detection
Before applying any OLLVM deobfuscation workflow, analysts must identify which core passes are present. The guide provides detection signatures for:
| Pass | Signature Pattern | IDA View Cue |
|---|---|---|
fla (Control-Flow Flattening) |
State-variable dispatcher, switch-based routing | Large switch tables, artificial while(1) loops |
bcf (Bogus Control Flow) |
Opaque predicates with opaque constants | Redundant conditional branches with always-true/false conditions |
sub (Substitute/Arithmetic Encryption) |
LLVM sub pass patterns, constant arrays |
Encrypted constants in .data, runtime decryption stubs |
The section includes indirect-branch variants that require modified detection heuristics.
The Three OLLVM Deobfuscation Pipeline Tracks
The reverse-skill guide divides execution into three tracks based on tooling constraints. Each track contains validated, step-by-step procedures.
Track 1: GUI-Based Tools (IDA Pro / Binary Ninja)
For analysts with commercial disassemblers, these tools provide the highest automation:
obpo-plugin — Cloud-powered IDA microcode plugin
- Requires IDA 7.5+ and network connectivity
- Strongest overall results for complex flattening
- Offloads symbolic execution to remote infrastructure
d810-ng — Local open-source alternative
- Integrates Z3 SMT solver for path constraint solving
- Handles OLLVM, Tigress, Hodur, and Approov obfuscators
- No network dependency; fully offline operation
ollvm-breaker — Binary Ninja exclusive
- Purpose-built for Android
.sobinaries - Native MLIL (Medium Level Intermediate Language) transformations
Track 2: Symbolic Execution Scripts
When no GUI is available, these pure-Python OLLVM deobfuscation workflows operate headlessly:
ollvm-unflattener — Miasm-based engine
- Targets x86/x64 architectures
- Implements symbolic execution with loop unrolling heuristics
- Ideal for server-side batch processing
angr — Python-native symbolic execution
- Best suited for CTF challenges and research prototypes
- Extensible via exploration techniques and state merging
Example invocation using the angr pipeline:
import angr, sys
binary = sys.argv[1]
proj = angr.Project(binary, auto_load_libs=False)
state = proj.factory.entry_state()
sim = proj.factory.simulation_manager(state)
# Apply loop-unrolling heuristic to defeat flattening
sim.explore(find=lambda s: s.addr == proj.loader.main_object.get_symbol('main').rebased_addr)
deobf_state = sim.found[0]
deobf_state.memory.store(deobf_state.regs.pc, b'\x90' * 5) # NOP patch placeholder
deobf_state.dump()
Track 3: Lightweight Emulator Approaches
For ARM64-specific OLLVM deobfuscation or resource-constrained environments:
deollvm — Unicorn-based flattening remover
- Targets ARM64 binaries (common in mobile reverse engineering)
- Emulates dispatcher logic, reconstructs original control flow
- Minimal dependencies: Unicorn engine + Python bindings
Example workflow:
from deollvm import DeOllvm
deobf = DeOllvm('libnative.so')
deobf.unflatten()
deobf.save('libnative_unflat.so')
DeObfBR — Data-segment read-only trick
- Addresses indirect-branch (BR) obfuscation specifically
- Exploits memory protection settings to eliminate false branches
- Lightweight; no emulation required
Tool-Specific Workflow Details
d810-ng Complete Workflow
As the primary open-source recommendation, d810-ng receives detailed coverage:
# Basic unflattening execution
d810-ng -i sample.bin -o sample_unflat.bin
# With SMT solver timeout adjustment for complex predicates
d810-ng -i sample.bin -o sample_unflat.bin --z3-timeout 30000
The tool's Z3 integration handles arithmetic expression simplification for the sub pass automatically.
Fallback Strategy
The reverse-skill guide emphasizes graceful degradation. If the primary tool fails:
obpo-plugin→d810-ng(network loss or unsupported version)d810-ng→ollvm-unflattenerorangr(binary incompatibility)- Emulator tools → manual dispatcher reconstruction (last resort)
Handling Anti-Detection and Edge Cases
Section 5 of the guide addresses common pitfalls in OLLVM deobfuscation workflows:
- "Trap Angr" passes: Deliberate constructions that cause path explosion; mitigated via loop bounds and state merging heuristics
- VM-Flattened variants (e.g., amice): Require hybrid emulation + symbolic approaches
- Constant-encryption stubs: Identified by
.datasegment patterns, decrypted via Unicorn emulation of init routines - False branches in
bcf: Eliminated through read-only data-segment configurations that trigger segfaults on invalid paths
Key Repository Files
| File Path | Purpose |
|---|---|
skills/reverse-engineering/references/ollvm-deobfuscation.md |
Primary documentation; decision matrix, tool pipelines, variant taxonomy |
skills/reverse-engineering/tools-advanced.md |
Advanced tool overview with quick-reference links |
skills/routing.md |
Task routing that maps OLLVM binaries to appropriate guides |
README.md |
Top-level feature listing for OLLVM deobfuscation |
Summary
- reverse-skill maintains the definitive community guide for OLLVM deobfuscation at
skills/reverse-engineering/references/ollvm-deobfuscation.md - The Quick Decision Matrix routes analysts to one of seven tools based on environment constraints
- GUI tools (
obpo-plugin,d810-ng,ollvm-breaker) provide highest automation for IDA/Binary Ninja users - Symbolic execution scripts (
ollvm-unflattener,angr) enable headless, Python-native workflows - Unicorn-based tools (
deollvm,DeObfBR) solve ARM64 and indirect-branch obfuscation without heavy dependencies - All workflows include fallback procedures and anti-detection mitigations for modern OLLVM variants
Frequently Asked Questions
What is the fastest OLLVM deobfuscation workflow for IDA Pro users?
obpo-plugin delivers the fastest results when network connectivity is available, offloading heavy symbolic execution to cloud infrastructure. For offline environments, d810-ng provides equivalent capabilities locally with Z3 integration. The reverse-skill guide recommends obpo-plugin as first priority in the decision matrix, falling back to d810-ng automatically upon connection failure.
Can I deobfuscate OLLVM-protected ARM64 binaries without IDA or Binary Ninja?
Yes. The deollvm tool implements a Unicorn-based OLLVM deobfuscation workflow specifically for ARM64. It requires only the Unicorn CPU emulator and Python, operates entirely from command line, and reconstructs control flow through emulation rather than static analysis. This is the recommended path in the decision matrix when target_arch == "ARM64" and no commercial disassembler is present.
How do I detect which OLLVM passes were applied to my binary?
Consult Section 2 of the reverse-skill OLLVM deobfuscation guide. Look for these indicators:
fla: State-variable dispatcher with artificial infinite loopsbcf: Opaque predicates using always-true/false conditionssub: Runtime constant decryption routines referencing encrypted data tables
The guide provides IDA View cues and hex-pattern signatures for automated detection.
What should I do if standard tools fail against a new OLLVM variant?
The reverse-skill guide recommends the hybrid fallback sequence: attempt angr with custom exploration heuristics for path explosion resistance, then try ollvm-unflattener with Miasm's more permissive emulation. For VM-flattened variants like amice, combine Unicorn emulation with manual dispatcher reconstruction using the patterns documented in Section 5's anti-detection coverage.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →