Unicorn
Unicorn is a CPU emulator. It is the right tool when you can define memory, registers, and stop conditions yourself.
Use Unicorn when
- the target is shellcode, a decoder, checksum loop, custom VM handler, crypto primitive, or small boot stub
- OS behavior would be noise
- you know or can infer load address, entry address, mapped memory, stack, registers, and inputs
- memory/register hooks are the evidence you need
Do not use Unicorn as a shortcut for real userland execution. If the target needs syscalls, files, dynamic linking, registry, interrupts, or hardware peripherals, use Qiling, QEMU, or Renode instead.
Setup checklist
- architecture, mode, endian, ARM/Thumb state
- code mapping address and permissions
- stack address and size
- input buffers and output buffers
- initial registers and calling convention
- imported function stubs or syscall stop points
- maximum instruction count or address stop
Hook strategy
| Hook |
Use |
| basic block |
coverage, control-flow sketch, custom VM dispatch |
| instruction |
exact trace, self-modifying code, privileged instruction stop |
| memory read/write |
watchpoints, decrypted output, MMIO discovery |
| unmapped memory |
identify missing mapping, import thunk, stack growth, bad pointer |
| interrupt/syscall |
stop or fake external behavior |
Keep hooks narrow. Broad instruction hooks over large regions can make emulation painfully slow.
Good targets
- XOR/RC4/AES wrapper that fills a plaintext buffer
- password checker inner loop
- architecture-specific shellcode decoder
- VM bytecode dispatcher over a byte array
- bare-metal reset stub before first peripheral wait
- opaque predicate or anti-debug gadget
Bad targets
- dynamically linked application with many libc calls
- Windows or macOS binary that needs real APIs
- Linux service that opens files, forks, listens on sockets, or uses
/proc
- MCU firmware stuck in timer/UART/GPIO MMIO loops unless those reads/writes are stubbed deliberately
- kernel boot, drivers, or interrupt-heavy RTOS behavior
Evidence
- initial register/memory state
- hook outputs and stop reason
- memory dump of transformed buffers
- branch or address coverage proving the target path
- exact stubs used for external calls
State clearly that the proof is CPU-level unless OS or board behavior was validated elsewhere.
1---2name: unicorn3description: Auth/lab ref: Unicorn Engine CPU-only emulation for shellcode, decryptors, custom VM handlers, instruction tracing, memory hooks, and register-level experiments.4license: MIT5---67# Unicorn89Unicorn is a CPU emulator. It is the right tool when you can define memory, registers, and stop conditions yourself.1011## Use Unicorn when1213- the target is shellcode, a decoder, checksum loop, custom VM handler, crypto primitive, or small boot stub14- OS behavior would be noise15- you know or can infer load address, entry address, mapped memory, stack, registers, and inputs16- memory/register hooks are the evidence you need1718Do not use Unicorn as a shortcut for real userland execution. If the target needs syscalls, files, dynamic linking, registry, interrupts, or hardware peripherals, use Qiling, QEMU, or Renode instead.1920## Setup checklist2122- architecture, mode, endian, ARM/Thumb state23- code mapping address and permissions24- stack address and size25- input buffers and output buffers26- initial registers and calling convention27- imported function stubs or syscall stop points28- maximum instruction count or address stop2930## Hook strategy3132| Hook | Use |33|---|---|34| basic block | coverage, control-flow sketch, custom VM dispatch |35| instruction | exact trace, self-modifying code, privileged instruction stop |36| memory read/write | watchpoints, decrypted output, MMIO discovery |37| unmapped memory | identify missing mapping, import thunk, stack growth, bad pointer |38| interrupt/syscall | stop or fake external behavior |3940Keep hooks narrow. Broad instruction hooks over large regions can make emulation painfully slow.4142## Good targets4344- XOR/RC4/AES wrapper that fills a plaintext buffer45- password checker inner loop46- architecture-specific shellcode decoder47- VM bytecode dispatcher over a byte array48- bare-metal reset stub before first peripheral wait49- opaque predicate or anti-debug gadget5051## Bad targets5253- dynamically linked application with many libc calls54- Windows or macOS binary that needs real APIs55- Linux service that opens files, forks, listens on sockets, or uses `/proc`56- MCU firmware stuck in timer/UART/GPIO MMIO loops unless those reads/writes are stubbed deliberately57- kernel boot, drivers, or interrupt-heavy RTOS behavior5859## Evidence6061- initial register/memory state62- hook outputs and stop reason63- memory dump of transformed buffers64- branch or address coverage proving the target path65- exact stubs used for external calls6667State clearly that the proof is CPU-level unless OS or board behavior was validated elsewhere.68