
Binary Ninja plugin to analyze and simplify obfuscated code
Authors: Tim Blazytko & Nicolò Altamura
Analyze and simplify obfuscated code
Obfuscation Analysis is a Binary Ninja plugin that takes the pain out of working with heavily protected binaries. It bundles a handful of focused helpers that let you
Some example use cases can be found in examples. Furthermore, the REcon talk "Breaking Mixed Boolean-Arithmetic Obfuscation in Real-World Applications" demonstrates some use cases. The slides can be found here. The plugin complements Obfuscation Detection: once suspicious functions are flagged, Obfuscation Analysis helps you clean and understand them. More helpers will be added over time.
The tool can be installed using Binary Ninja's plugin manager.
For a manual installation, follow these steps in Binary Ninja's plugin folder:
git clone https://github.com/mrphrazer/obfuscation_analysis.git
cd obfuscation_analysis
# optionally: use a virtual environment
python -m venv obfana-env
source obfana-env/bin/activate
# install requirements
pip install -r requirements.txt
If you use a virtual environment, you'll need to manually set the site-packages path in the Binary Ninja settings.
The plugin is available from Binary Ninja’s top-bar menu under Plugins -> Obfuscation Analysis.
To simplify arithmetic obfuscation, first highlight the HLIL expression you want to simplify in the decompiler view. Next, choose Plugins -> Obfuscation Analysis -> MBA Simplification -> Slice & Simplify. The plugin resolves the full computation, runs it through msynth, and inserts the simplified result as a comment on the same line. The short animation below shows the entire workflow:
MBA simplification relies on msynth. By default, the plugin uses msynth’s default simplification oracle, which ships with the plugin and is pre-configured. If you want to use a larger or custom oracle, set obfuscation_analysis.mba_oracle_path manually or browse to the file in Binary Ninja’s Settings window.
If something goes wrong the plugin writes a concise user-level message to the Log pane; switch the log view to Debug to see the full traceback.
The plugin ships focused helpers that target common roadblocks you hit when reversing protected binaries, each runnable as a background task from the UI or head-less scripts. Below are the features currently available.
Corrupted Functions are functions whose disassembly shows undefined artefacts—empty basic blocks, invalid or overlapping instructions, and the like. This helper walks the entire BinaryView, flags functions with those symptoms, and lists them such that the analyst can quickly inspect code that was mis-parsed or deliberately obfuscated. An optional remove action erases every flagged function and forces a fresh analysis, cleaning up the function list. It is particularly useful for locating
Mixed-Boolean Arithmetic (MBA) is an obfuscation technique that buries simple computations in long chains of arithmetic and Boolean operations. This feature simplifies such expressions in the decompiler. When you pick an HLIL instruction, the plugin collects its complete computation chain with an SSA backward slice restricted to the current basic block, translates that slice to Miasm IR, feeds it into msynth, and finally adds the simplified result as a comment in the decompiler view. This feature allows you to
For the currently selected function, this helper recursively inlines every callee inside the decompiler view, giving Binary Ninja a single, self-contained IL. With all boundaries gone the decompiler can propagate data across functions, enabling deeper constant folding, dead-code elimination, and generally clearer logic. Use it to
Note that HLIL can become very huge and slow to render on very large functions or deep call trees. In addition, some decompiler optimizations may be less effective once everything is merged into a single unit. To control this, you can limit the inlining depth: set Settings -> Obfuscation Analysis -> Max Function Inlining Depth to an upper bound N (per default set to 1). With a depth limit, only the first N call levels are inlined; deeper calls are not inlined.
The plugin has a few caveats you should be aware of, most of them related to the MBA simplification pipeline:
Binary Ninja bug: on BN 5.0 stable, the backward-slicing step may fail because of missing HLIL type-casts: https://github.com/Vector35/binaryninja-api/issues/6371; the issue is fixed in 5.1.7477-de and newer
slice confined to one basic block: variable definitions located in predecessor blocks are ignored (often control-flow dependent), so some MBA terms may stay partially resolved
HLIL to Miasm IR translation gaps: not every HLIL construct has a sound Miasm equivalent; when translation fails the expression is skipped and an error is logged
IL coverage: control-flow nodes and floating-point operations are currently not translated
inherited msynth constraints : MBA simplification inherits all msynth limitations
For more information, contact Tim Blazytko (@mr_phrazer) or Nicolò Altamura (@nicolodev).