Defeating control flow flattening
Skill meltedinhex/analyst-ai-pack/skills/defeating-control-flow-flattening
Defeats control-flow-flattening obfuscation by identifying the dispatcher/state- variable structure and reconstructing the original control flow so the logic becomes readable. Activates for requests to defeat control-flow flattening, deobfuscate an OLLVM-flattened function, or recover original control flow from a dispatcher loop.From its SKILL.md
npx -y skills add meltedinhex/analyst-ai-pack --skill defeating-control-flow-flatteningAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 21 stars21 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its file declares
Copied from the file, not written here
The file declares its own license as Apache-2.0. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.
SKILL.md
2.7 KB, 412 tokens by cl100k_base, as published. Nobody here has run it
Defeating Control-Flow Flattening
When to Use
- A function is flattened (a dispatcher loop switching on a state variable, with original blocks as switch cases) and you need to recover the original control flow.
- You are reversing OLLVM-style or similar flattening.
Do not use this on non-flattened code — confirm the dispatcher/state-variable pattern first. This skill analyzes disassembly/CFG data statically and executes nothing.
Prerequisites
- A disassembled function's basic-block/edge data (e.g., exported from Ghidra/IDA/Binary Ninja as JSON).
Workflow
Step 1: Detect the flattening structure
python scripts/analyst.py detect cfg.json
Identifies a dispatcher block (high in-degree, switch/compare on a state variable) and the relay/ case blocks that all branch back to it.
Step 2: Recover state transitions
Track the constant assigned to the state variable in each case to determine the successor block, rebuilding the true edges.
Step 3: Reconstruct the original CFG
Emit the deflattened successor mapping (case → next case) for re-annotation in the disassembler.
Step 4: Verify
Confirm the recovered flow has a single entry, sane successors, and no orphan blocks.
Validation
- The dispatcher is identified by in-degree and state-variable comparison.
- Each case's next-state constant maps to a real successor block.
- The reconstructed CFG covers all original (non-relay) blocks.
Pitfalls
- State variable computed (not a constant) — requires emulation/symbolic execution.
- Multiple dispatchers or nested flattening.
- Opaque predicates and bogus blocks inflating the case set.
References
- See
references/api-reference.mdfor the deflattener. - OLLVM and ATT&CK T1027 references (linked in frontmatter).
What ships with it: 3 files
4.0 KB alongside SKILL.md, 1 of them executable
references/
- api-reference.md1.3 KB
scripts/
- analyst.pyruns2.3 KB
- LICENSE340 B