
Code Obfuscation Deobfuscation
Structured reversal of junk code, control-flow flattening, VM protectors, and string encryption when auditing or dissecting protected native binaries.
Overview
Code Obfuscation & Deobfuscation is an agent skill most often used in Ship (also Operate, Idea) that delivers an expert playbook for classifying and defeating native-code obfuscation in disassembler workflows.
Install
npx skills add https://github.com/yaklang/hack-skills --skill code-obfuscation-deobfuscationWhat is this skill?
- Symptom-to-technique routing table for IDA/Ghidra (flattened CFG, mov-only code, VM entry via pushad/pushfd)
- Playbook spans junk code, opaque predicates, self-modifying code, import hiding, and anti-disassembly
- Explicit static vs dynamic deobfuscation strategy guidance (avoids treating packing as obfuscation)
- VM-focused coverage for VMProtect, Themida, and Code Virtualizer class protectors
- Cross-links to anti-debugging, symbolic execution, and VM bytecode reverse skills in the same repo
- Quick identification table maps common IDA/Ghidra symptoms to obfuscation families and first-step tactics
- Explicitly covers VMProtect, Themida, and Code Virtualizer class VM protectors
Adoption & trust: 1.2k installs on skills.sh; 980 GitHub stars; 2/3 security scanners passed (skills.sh audits).
What problem does it solve?
You opened a protected binary in IDA or Ghidra and the control flow, strings, and imports look intentionally destroyed, so you cannot tell which deobfuscation tactic to try first.
Who is it for?
Indie security researchers, malware analysts, and builders hardening or red-teaming native apps who need a structured deobfuscation decision tree in Ghidra/IDA.
Skip if: Pure source-level refactors, web-only apps with no native binaries, or beginners who have not yet attached a debugger or loaded the sample in a disassembler.
When should I use this skill?
Reversing binaries protected by junk code, opaque predicates, self-modifying code, control flow flattening, VM protection, or string encryption.
What do I get? / Deliverables
You map symptoms to obfuscation families, pick static or dynamic defeat strategies, and route to anti-debug, symbolic execution, or VM bytecode skills when those layers appear.
- Obfuscation classification and recommended deobfuscation strategy
- Pointers to paired anti-debug, symbolic-execution, or VM-bytecode follow-up skills
Recommended Skills
Journey fit
Spans multiple journey phases - primary shelf plus alternate fits below.
Deobfuscation is the core work of pre-release security assessment and incident response on shipped native code, so Ship → Security is the canonical shelf. The playbook targets malware resistance and hardening patterns auditors hit during appsec review, not greenfield feature implementation.
Where it fits
Audit a release candidate EXE that fails static analysis because the CFG is flattened behind a dispatcher switch.
Investigate a production incident executable that hides imports and decrypts strings only at runtime.
Study how Themida-style VM entry sequences differ from packers before committing to a protector for your own native tool.
How it compares
Use as a procedural reversal playbook—not a generic “run strings” checklist or an MCP database integration.
Common Questions / FAQ
Who is code-obfuscation-deobfuscation for?
Solo builders and analysts reversing Windows/Linux native binaries protected by commercial or custom obfuscators, especially when static views in IDA or Ghidra stall.
When should I use code-obfuscation-deobfuscation?
During Ship security review when validating hardened builds, during Operate forensics on suspicious binaries, and during Idea-stage research when learning how protectors hide logic—whenever junk code, flattened CFG, VM entry, or encrypted strings block analysis.
Is code-obfuscation-deobfuscation safe to install?
Treat it like any third-party agent skill: review the Security Audits panel on this Prism page and only run reversal steps in isolated lab VMs on samples you are authorized to analyze.
SKILL.md
READMESKILL.md - Code Obfuscation Deobfuscation
# SKILL: Code Obfuscation & Deobfuscation — Expert Analysis Playbook > **AI LOAD INSTRUCTION**: Expert techniques for identifying, classifying, and defeating code obfuscation in native binaries. Covers junk code, opaque predicates, SMC, control flow flattening, movfuscator, VM protectors (VMProtect/Themida/Code Virtualizer), string encryption, import hiding, and anti-disassembly tricks. Base models often conflate packing with obfuscation and miss the distinction between static and dynamic deobfuscation strategies. ## 0. RELATED ROUTING - [anti-debugging-techniques](../anti-debugging-techniques/SKILL.md) when the obfuscated binary also has anti-debug layers - [symbolic-execution-tools](../symbolic-execution-tools/SKILL.md) when using angr/Z3 for automated deobfuscation - [vm-and-bytecode-reverse](../vm-and-bytecode-reverse/SKILL.md) for deep VM protector bytecode analysis ### Quick identification picks | Symptom in IDA/Ghidra | Likely Obfuscation | Start With | |---|---|---| | Flat CFG, single giant switch | Control flow flattening | Symbolic execution to recover CFG | | Only `mov` instructions | movfuscator | demovfuscation / trace-based lifting | | pushad/pushfd → VM entry | VM protector | Handler table extraction | | XOR loop before code execution | SMC / string encryption | Dynamic analysis, breakpoint after decode | | Impossible conditions (opaque predicates) | Junk code insertion | Pattern-based removal | | All strings unreadable | String encryption | Hook decryption routine, or emulate | | No imports in IAT | Import hiding | Trace GetProcAddress / hash resolution | --- ## 1. JUNK CODE & OPAQUE PREDICATES ### 1.1 Junk Code Insertion Dead code that never affects program output, added to increase analysis time. **Identification**: - Instructions that write to registers/memory never read afterward - Function calls whose return values are discarded and have no side effects - Loops with invariant bounds that compute unused results **Removal strategy**: 1. Compute def-use chains (IDA/Ghidra data flow analysis) 2. Mark instructions with no downstream use as dead 3. Verify removal doesn't change program behavior (trace comparison) ### 1.2 Opaque Predicates Conditional branches where the condition is always true or always false, but this is non-obvious. | Type | Example | Always Evaluates To | |---|---|---| | Arithmetic | `x² ≥ 0` | True | | Number theory | `x*(x+1) % 2 == 0` | True (product of consecutive ints) | | Pointer-based | `ptr == ptr` after aliasing | True | | Hash-based | `CRC32(constant) == known_value` | True | **Deobfuscation**: - Abstract interpretation: prove the condition is constant - Symbolic execution: Z3 proves `∀x: predicate(x) = True` - Pattern matching: recognize known opaque predicate families - Dynamic: trace and observe the branch is never taken / always taken ```python import z3 x = z3.BitVec('x', 32) s = z3.Solver() s.add(x * (x + 1) % 2 != 0) print(s.check()) # unsat → always true ``` --- ## 2. SELF-MODIFYING CODE (SMC) Runtime code patching: encrypted code is decrypted just before execution. ### 2.1 XOR Decryption Loop (Most Common) ```asm lea esi, [encrypted_code] mov ecx, code_length mov al, xor_key decrypt_loop: xor byte [esi], al inc esi loop decrypt_loop jmp encrypted_code ; now decrypted ``` ### 2.2 Analysis Strategy ``` 1. Identify the decryption routine (look for XOR/ADD/SUB in loops writing to .text) 2. Set breakpoint AFTER the loop completes 3. At breakpoint: dump the decrypted memory region 4. Re-analyze the dumped code in IDA/Ghidra 5. For multi-layer: repeat for each decryption stage ``` ### 2.3 Automated Unpacking via Emulation ```python from unicorn import * from unicorn.x