Miasm - Reverse Engineering Framework Cheatsheet
Miasm is a free, open-source Python framework for analyzing, generating, and manipulating binaries. It can disassemble across many architectures (x86/x64, ARM, MIPS, PPC, and more), lift code into its own intermediate representation (IR), emulate execution with a JIT, and run symbolic execution for deobfuscation and constraint solving. It is a programmatic toolkit — you drive it from Python — which makes it powerful for automating reverse-engineering and unpacking tasks that GUI tools cannot script easily.
Installation
| Method | Command |
|---|
| pip | pip install miasm |
| From source | git clone https://github.com/cea-sec/miasm && cd miasm && pip install -e . |
| Optional JIT (LLVM) | pip install llvmlite (faster emulation backend) |
| Docker | docker build -t miasm . from the repo |
| Verify | python -c "import miasm; print('ok')" |
Core Modules
| Module | Purpose |
|---|
miasm.analysis.binary | Load a binary container (ELF/PE/raw) |
miasm.analysis.machine | Architecture abstraction (Machine("x86_64")) |
miasm.core.locationdb | Track addresses/labels across analysis |
miasm.ir | Intermediate representation of instructions |
miasm.analysis.dse | Dynamic symbolic execution engine |
miasm.jitter | Emulation/JIT engine |
Disassembly
from miasm.analysis.binary import Container
from miasm.analysis.machine import Machine
from miasm.core.locationdb import LocationDB
loc_db = LocationDB()
cont = Container.from_stream(open("target.bin", "rb"), loc_db)
machine = Machine(cont.arch)
mdis = machine.dis_engine(cont.bin_stream, loc_db=loc_db)
asmcfg = mdis.dis_multiblock(cont.entry_point) # recursive disassembly → CFG
for block in asmcfg.blocks:
print(block)
| Call | Description |
|---|
mdis.dis_block(addr) | Disassemble a single basic block |
mdis.dis_multiblock(addr) | Recursively disassemble into a CFG |
asmcfg.blocks | Iterate basic blocks |
asmcfg.dot() | Export the control-flow graph to Graphviz |
lifter = machine.lifter_model_call(mdis.loc_db)
ircfg = lifter.new_ircfg_from_asmcfg(asmcfg)
for lbl, irblock in ircfg.blocks.items():
print(irblock)
The IR normalizes architecture-specific instructions into a small typed language, which is what makes cross-architecture analysis and symbolic reasoning possible.
Emulation (Jitter)
from miasm.analysis.machine import Machine
jitter = Machine("x86_64").jitter("llvm") # or "python", "gcc"
jitter.init_stack()
# map code, set registers, then:
jitter.run(0x401000)
| Backend | Trade-off |
|---|
python | Portable, slowest |
gcc | Faster, needs a compiler |
llvm | Fastest, needs llvmlite |
| Feature | Use |
|---|
add_breakpoint(addr, cb) | Run a Python callback at an address |
vm.set_mem(addr, data) | Write memory before running |
| Custom syscalls/APIs | Hook library calls during emulation |
Symbolic Execution
from miasm.ir.symbexec import SymbolicExecutionEngine
sb = SymbolicExecutionEngine(lifter)
symbolic_pc = sb.run_at(ircfg, 0x401000)
print(sb.symbols) # symbolic register/memory state
Symbolic execution is the basis for deobfuscation, solving for inputs, and simplifying junk/opaque predicates.
Common Workflows
| Goal | Approach |
|---|
| Export a CFG to view | asmcfg.dot() → render with Graphviz |
| Unpack/deobfuscate | Emulate with the jitter, dump memory at OEP |
| Solve for an input | Symbolic execution + an SMT solver (z3) |
| Cross-arch analysis | Lift to IR, run the same passes regardless of arch |
Miasm vs Other RE Frameworks
| Aspect | Miasm | angr | Ghidra |
|---|
| Language | Python | Python | Java/GUI |
| IR | Own IR | VEX | P-code |
| Emulation | Built-in JIT | Unicorn-based | Emulator API |
| Symbolic exec | Yes | Yes (core strength) | Limited |
| Best for | Scripted analysis, deobfuscation | Symbolic/CTF | Interactive RE |
Resources