Open-source project
mrphrazer/obfuscation_detection avatar
mrphrazer/obfuscation_detection

Obfuscation Detection finds the functions a reverse engineer should look at first

Binary Ninja plugin to identify obfuscated code and other interesting code constructs

685 stars74 forksPythonGPL-2.0

At a glance

What is it?
This Binary Ninja plugin scores a binary with a set of heuristics and tells you which functions are worth attention, and its nine detectors are best understood as a list of statistical and graph-theoretic questions asked of every function.
Who is it for?
Obfuscation Detection suits a reverse engineer who has just been handed a large binary and needs a shortlist rather than a reading order, and it suits anyone who wants the same heuristics applied in an automated pipeline. It is the wrong tool if you need a proof of obfuscation rather than a heuristic pointer, because every detector here is a threshold on a population of functions and the readme is explicit that it identifies the top ten percent on a given measure.
Can I use it commercially?
Yes, with conditions. GPL-2.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
Is it still maintained?
Yes. The repository last received commits 155 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What the plugin is for

Obfuscation Detection is a Binary Ninja plugin to detect obfuscated code and interesting code constructs such as state machines in binaries. Given a binary, the plugin eases analysis by identifying code locations which might be worth a closer look during reverse engineering. The mechanism is stated plainly. Based on various heuristics, the plugin pinpoints functions that contain complex or uncommon code constructs. The constructs such code may implement are listed, and they are the reason the tool exists: obfuscated code, state machines and protocols, C and C server communication, string decryption routines and cryptographic algorithms. The framing matters, because this is a triage tool rather than an analysis tool. It does not tell you what a function does, it tells you which functions in a binary of two hundred thousand are unlike the others, and the reading of the results is left to the analyst.

The heuristics are documented as blog posts

The readme points at four blog posts that explain the underlying heuristics and demonstrate their use cases. There is one on automated detection of control-flow flattening, one on automated detection of obfuscated code, one on statistical analysis to detect uncommon code, and one on the identification of API functions in binaries. That list is effectively the project's documentation, and it is unusual to have it. Most plugins of this kind ship a heuristic and a description, and the reasoning behind the thresholds is in the author's head or in an issue thread. Here the thresholds are argued in public, with worked examples, which means a user can disagree with a detector on the basis of the same argument the author made. The project also points at example use cases in the examples directory and at the REcon talk Unveiling Secrets in Binaries using Code Detection Strategies, with the slides and the recording both linked, and the author is Tim Blazytko of the Synthesis team.

Installing it, including for headless use

The straightforward installation path is Binary Ninja's plugin manager. For the headless version the readme gives three commands.

code
git clone https://github.com/mrphrazer/obfuscation_detection.git
cd obfuscation_detection

# install obfuscation_detection
pip install .

The separate mention of the headless path is worth noting, because it tells you that the plugin is not only a menu command in the GUI. The core features list says the plugin runs as a background task, can be used in UI and headless mode, and automatically tags identified functions with the corresponding heuristic or utility, which means the results end up in Binary Ninja's own tagging system rather than only in a log window. That is what makes the detections usable afterwards, in a script or in a note, because a tagged function carries its label with it.

The nine detectors, and the questions each one asks

The detector list is the substance of the tool, and each entry is a specific question asked of every function. The large basic block heuristic identifies the top 10% of functions with the largest average number of instructions per basic block, which catches unrolled code, cryptographic implementations, initialization routines and arithmetic obfuscation in the form of mixed boolean-arithmetic. The complex function heuristic finds the top 10% with the most complex control-flow graphs by cyclomatic complexity, which catches complex dispatching routines, state machines and functions obfuscated with opaque predicates. The state machine heuristic uses graph-theoretic properties to find functions implementing state machines, usually switch statements dispatched in a loop, and it points at network protocol dispatching, file parsing logic, command dispatching and control-flow flattening.

The remaining six detectors

The uncommon instruction sequence heuristic performs a statistical analysis to find the top 10% of functions whose code patterns deviate from a pre-computed ground truth, which surfaces cryptographic implementations, intense floating point arithmetic, mixed boolean-arithmetic and generic obfuscation patterns. The overlapping instruction heuristic finds functions with disaligned instructions, where instruction bytes are shared by two different instructions, and it catches broken disassembly such as data marked as code, and opaque predicates which jump into other instructions. The most called function heuristic finds the top 10% with the largest number of calls from different functions, which points at string decryption routines and library functions in statically linked binaries. The loop frequency heuristic finds functions with a high number of loops, which might be complex parsing logic for structured data formats or intensive algorithmic computations, and it also helps pinpoint potential performance bottlenecks. The irreducible loop heuristic finds rare and complex loop structures, which typically suggest aggressive compiler optimizations, hand-written assembly, the use of goto statements or obfuscated code. The XOR decryption loop heuristic finds functions performing an XOR with a constant inside a loop, which catches string decryption routines, code decryption stubs and cryptographic implementations. And the complex arithmetic expression heuristic finds functions where expressions have more than one arithmetic operation and one boolean operation simultaneously.

Running it from the interface and from a script

In the user interface you choose Plugins, then Obfuscation Detection, to run individual heuristics, or Plugins, then Obfuscation Detection, then Utils, to run the individual utility detections, and the All command runs all heuristics and all utilities together. The results appear in the Log window, and clicking on an identified function address navigates Binary Ninja to that function. Headless, the same work is done by a script in the scripts directory.

code
$ python3 scripts/detect_obfuscation.py <binary>

That runs all heuristics and all utilities, and for machine-readable output you pass a flag.

code
$ python3 scripts/detect_obfuscation.py --json <binary>

The JSON payload contains all results under a detections key, and each detection has a stable identifier for automation and a human-readable name. Each tagged function finding includes the tag type and the description used by the plugin, which is the detail that makes the output automatable, since a stable identifier means a script can key on it and a changing human-readable name will not break the script. A separate script runs only the state machine heuristic, with the same optional JSON flag.

Where this is the wrong choice

Three limits are worth naming. The first is that every detector is a percentile, and the readme is explicit that each one identifies the top 10% of functions on a particular measure, which means a heuristic can only ever point at a fixed fraction of the binary rather than at the one function you care about. On a small binary of a few hundred functions, that is a large fraction of the code, and on a large one it is a large number of candidates still. The second is that the tool needs Binary Ninja, since the tag mechanism and the graph view highlighting of overlapping instructions are features of the host application, and the headless mode still assumes a Binary Ninja installation to analyse the binary. The third is that the ground truth behind the statistical detector is pre-computed, which means it encodes the instruction mix of a particular corpus and will be less effective on code from a different domain, for example a compiler or a game engine rather than the malware and firmware samples such a corpus tends to contain.

Editorial conclusion

Obfuscation Detection suits a reverse engineer who has just been handed a large binary and needs a shortlist rather than a reading order, and it suits anyone who wants the same heuristics applied in an automated pipeline. It is the wrong tool if you need a proof of obfuscation rather than a heuristic pointer, because every detector here is a threshold on a population of functions and the readme is explicit that it identifies the top ten percent on a given measure. It is also the wrong choice if you do not use Binary Ninja, since the graph view highlighting and the tag mechanism depend on it. Before running it on your own sample, read the heuristic descriptions rather than the feature list, because the value of the tool is in choosing which detector to trust for which question, and note that the author is explicit that the tool eases analysis rather than performing it. The last push was on 2026-05-21 and the current release is v2.4 from 2026-05-20.

Frequently asked questions

How do I install and run Obfuscation Detection?

Install it through Binary Ninja's plugin manager, or for headless use clone the repository and run pip install . in the cloned directory. In the interface you choose Plugins, then Obfuscation Detection, for individual heuristics or the All command for everything, and results appear in the Log window with clickable function addresses.

Which heuristics does the Obfuscation Detection plugin implement?

Nine of them: large basic block, complex function, state machine, uncommon instruction sequence, overlapping instruction, most called function, loop frequency, irreducible loop and XOR decryption loop, plus the complex arithmetic expression heuristic. Most identify the top 10% of functions on a particular measure, while the state machine heuristic uses graph-theoretic properties and the overlapping instruction heuristic looks for disaligned instructions.

Can Obfuscation Detection be run headless?

Yes. Run python3 scripts/detect_obfuscation.py with a binary to run all heuristics and utilities, add --json for machine-readable output whose results sit under a detections key with a stable identifier and a human-readable name for each, or use scripts/detect_state_machine.py to run only the state machine heuristic.

Official sources

  1. Issues
  2. License: GPL-2.0
  3. mrphrazer/obfuscation_detection on GitHub
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/mrphrazer-obfuscation-detection.svg)](https://hysenlabs.com/projects/mrphrazer-obfuscation-detection)

Was this useful?