Skip to content

Miasm - Reverse Engineering Framework Cheatsheet

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

MethodCommand
pippip install miasm
From sourcegit clone https://github.com/cea-sec/miasm && cd miasm && pip install -e .
Optional JIT (LLVM)pip install llvmlite (faster emulation backend)
Dockerdocker build -t miasm . from the repo
Verifypython -c "import miasm; print('ok')"

Core Modules

ModulePurpose
miasm.analysis.binaryLoad a binary container (ELF/PE/raw)
miasm.analysis.machineArchitecture abstraction (Machine("x86_64"))
miasm.core.locationdbTrack addresses/labels across analysis
miasm.irIntermediate representation of instructions
miasm.analysis.dseDynamic symbolic execution engine
miasm.jitterEmulation/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)
CallDescription
mdis.dis_block(addr)Disassemble a single basic block
mdis.dis_multiblock(addr)Recursively disassemble into a CFG
asmcfg.blocksIterate basic blocks
asmcfg.dot()Export the control-flow graph to Graphviz

Intermediate Representation (IR)

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)
BackendTrade-off
pythonPortable, slowest
gccFaster, needs a compiler
llvmFastest, needs llvmlite
FeatureUse
add_breakpoint(addr, cb)Run a Python callback at an address
vm.set_mem(addr, data)Write memory before running
Custom syscalls/APIsHook 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

GoalApproach
Export a CFG to viewasmcfg.dot() → render with Graphviz
Unpack/deobfuscateEmulate with the jitter, dump memory at OEP
Solve for an inputSymbolic execution + an SMT solver (z3)
Cross-arch analysisLift to IR, run the same passes regardless of arch

Miasm vs Other RE Frameworks

AspectMiasmangrGhidra
LanguagePythonPythonJava/GUI
IROwn IRVEXP-code
EmulationBuilt-in JITUnicorn-basedEmulator API
Symbolic execYesYes (core strength)Limited
Best forScripted analysis, deobfuscationSymbolic/CTFInteractive RE

Resources