
Vm And Bytecode Reverse
Reverse custom virtual machines and proprietary bytecode in CTF binaries or protected software when native disassembly misleads the agent.
Overview
VM and Bytecode Reverse Engineering is an agent skill for the Ship phase that walks through custom VM dispatcher identification, opcode mapping, and ISA reconstruction for CTF and protector-backed binaries.
Install
npx skills add https://github.com/yaklang/hack-skills --skill vm-and-bytecode-reverseWhat is this skill?
- Identifies switch-, table-, and if-chain VM dispatchers from fetch-decode-execute loops
- Maps opcodes to semantic operations and reconstructs a custom ISA
- Routes to obfuscation, symbolic execution, and anti-debug skills for protector-heavy cases
- Covers maze-style VM challenges and commercial VMProtect/Themida-style contexts via related skills
- Prevents treating VM bytecode as native machine code during analysis
Adoption & trust: 1.1k installs on skills.sh; 980 GitHub stars; 2/3 security scanners passed (skills.sh audits).
What problem does it solve?
Your agent keeps disassembling VM bytecode as x86/ARM and misses the central interpreter loop that actually executes the program.
Who is it for?
CTF reversers, security researchers, and builders validating how hard their licensing VM is to peel apart.
Skip if: Typical SaaS shipping paths with no native binaries or VM obfuscation—use standard debugging skills instead.
When should I use this skill?
CTF challenges or protected software implement custom virtual machines with proprietary bytecode, dispatcher loops, or maze-style challenges.
What do I get? / Deliverables
You reconstruct opcode semantics and a custom disassembly strategy so the hidden program logic becomes analyzable or solvable.
- Opcode-to-operation map
- Custom ISA notes or disassembler outline
- Pointers to symbolic or deobfuscation follow-ups
Recommended Skills
Journey fit
Ship → Security is the canonical shelf for malware/CTF analysis and protector teardown that informs whether shipped binaries can be trivially cracked or understood. Security subphase captures RE against obfuscated or VM-wrapped logic rather than day-to-day application coding in Build.
How it compares
Specialized VM ISA playbook versus generic decompiler output on protected binaries.
Common Questions / FAQ
Who is vm-and-bytecode-reverse for?
Reverse engineers, CTF competitors, and developers analyzing custom bytecode interpreters or maze VM challenges—not frontend or growth marketers.
When should I use vm-and-bytecode-reverse?
During Ship security or challenge work when you see a tight dispatcher loop, proprietary bytecode sections, or commercial VM protectors obscuring real instructions.
Is vm-and-bytecode-reverse safe to install?
It is analysis guidance only; check the Security Audits panel on this page and analyze binaries you are allowed to reverse.
SKILL.md
READMESKILL.md - Vm And Bytecode Reverse
# SKILL: VM & Bytecode Reverse Engineering — Expert Analysis Playbook > **AI LOAD INSTRUCTION**: Expert techniques for reversing custom virtual machines and bytecode interpreters. Covers dispatcher identification, opcode mapping, custom ISA reconstruction, disassembler/decompiler writing, maze challenges, and real-world VM protector analysis. Base models often fail to recognize the fetch-decode-execute pattern or attempt to analyze VM bytecode as native code. ## 0. RELATED ROUTING - [code-obfuscation-deobfuscation](../code-obfuscation-deobfuscation/SKILL.md) when the VM is a commercial protector (VMProtect/Themida) - [symbolic-execution-tools](../symbolic-execution-tools/SKILL.md) when using angr to solve VM-based challenges - [anti-debugging-techniques](../anti-debugging-techniques/SKILL.md) when the VM includes anti-debug checks ### Quick identification | Binary Pattern | Likely VM Type | Start With | |---|---|---| | `while(1) { switch(bytecode[pc]) }` | Switch-based dispatcher | Map each case to an operation | | Indirect jump via table `jmp [table + opcode*8]` | Table-based dispatcher | Dump jump table, analyze handlers | | Nested if-else chain on byte value | If-chain dispatcher | Same as switch, just different syntax | | Stack push/pop dominant operations | Stack-based VM | Identify push, pop, arithmetic ops | | `reg[X] = ...` array operations | Register-based VM | Map register indices to operations | | 2D grid + direction input | Maze challenge | Extract grid, apply BFS/DFS | --- ## 1. CUSTOM VM IDENTIFICATION ### 1.1 Structural Indicators ``` VM Architecture Components: ┌─────────────────────────────────┐ │ Bytecode Program (data section)│ ├─────────────────────────────────┤ │ Program Counter (pc/ip) │ │ Register File / Stack │ │ Memory / Data Area │ ├─────────────────────────────────┤ │ Dispatcher Loop │ │ ├─ Fetch: opcode = code[pc] │ │ ├─ Decode: lookup handler │ │ └─ Execute: run handler │ └─────────────────────────────────┘ ``` ### 1.2 IDA/Ghidra Signatures **Switch dispatcher** (most common in CTF): ```c while (running) { unsigned char op = bytecode[pc++]; switch (op) { case 0x00: /* nop */ break; case 0x01: /* push imm */ stack[sp++] = bytecode[pc++]; break; case 0x02: /* add */ stack[sp-2] += stack[sp-1]; sp--; break; // ... case 0xFF: /* halt */ running = 0; break; } } ``` **Table dispatcher** (more optimized): ```c typedef void (*handler_t)(vm_ctx_t*); handler_t handlers[256] = { handle_nop, handle_push, handle_add, ... }; while (running) { handlers[bytecode[pc++]](&ctx); } ``` --- ## 2. ANALYSIS METHODOLOGY ### Step 1: Find the Dispatcher Look for: - Large switch statement (many cases) in a loop - Array of function pointers indexed by a byte from a data buffer - Single function with high cyclomatic complexity - Cross-references to a data buffer read byte-by-byte ### Step 2: Map Opcodes to Operations For each case/handler, determine: | Property | How to Identify | |---|---| | Opcode value | Case number or table index | | Operation type | Register/stack modifications | | Operand count | How many bytes consumed after opcode | | Operand type | Immediate value, register index, or memory address | | Side effects | Output, memory write, flag modification | ### Step 3: Extract Bytecode Program ```python # Typical extraction from binary import struct with open('challenge', 'rb') as f: f.seek(bytecode_offset) bytecode = f.read(bytecode_length) # Or from IDA: # bytecode = idc.get_bytes(bytecode_addr, bytecode_len) ``` ### Step 4: Write Custom Disassembler ```python OPCODES = { 0x00: ("