The centre graph is a control-flow-flattened dispatcher: every real block reads a state variable, runs, then jumps back to the dispatcher, which switches on the new state — exactly like a decompiler sees a packed/obfuscated binary before analysis.
Bolted onto four of the real blocks are opaque predicates — conditions like (x²+x) mod 2 == 0 that are engineered to always evaluate the same way, no matter the input, so one of their two branches can never execute. A static analyzer that can't prove this must keep both branches "possible", bloating the graph with dead code.
Run deobfuscation algebraically proves each predicate's fixed outcome one at a time (the proof appears in the log), then prunes the branch — and every decoy block hanging off it — that can never be reached. The node counter shrinks live as dead subtrees are removed.
- Left ghost — the original bloated CFG, frozen for reference.
- Centre — the live graph being deobfuscated.
- Right ghost — fades in once pruning is complete: the true, simple CFG side-by-side with the original.