Miasm - Reverse Engineering Framework Cheatsheet
Miasm est un framework Python libre et open-source pour analyser, générer et manipuler les binaires. Il peut désassembler sur plusieurs architectures (x86/x64, ARM, MIPS, PPC et d’autres), lifter le code dans sa propre représentation intermédiaire (IR), émuler l’exécution avec un JIT et exécuter l’exécution symbolique pour la désofuscation et la résolution de contraintes. C’est une boîte à outils programmatique — tu la pilotes depuis Python — ce qui la rend puissante pour automatiser les tâches d’ingénierie inverse et de déballage que les outils GUI ne peuvent pas scripter facilement.
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')" |
Modules Principaux
| Module | Purpose |
|---|
miasm.analysis.binary | Charger un conteneur binaire (ELF/PE/raw) |
miasm.analysis.machine | Abstraction d’architecture (Machine("x86_64")) |
miasm.core.locationdb | Tracker les adresses/labels lors de l’analyse |
miasm.ir | Représentation intermédiaire des instructions |
miasm.analysis.dse | Moteur d’exécution symbolique dynamique |
miasm.jitter | Moteur d’émulation/JIT |
Désassemblage
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) | Désassembler un bloc basique unique |
mdis.dis_multiblock(addr) | Désassembler récursivement en un CFG |
asmcfg.blocks | Itérer les blocs basiques |
asmcfg.dot() | Exporter le graphe de contrôle-flux en Graphviz |
Représentation Intermédiaire (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)
L’IR normalise les instructions spécifiques à l’architecture en un langage petit typé, ce qui rend l’analyse multi-architecture et le raisonnement symbolique possibles.
Émulation (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) | Exécuter un callback Python à une adresse |
vm.set_mem(addr, data) | Écrire de la mémoire avant l’exécution |
| Custom syscalls/APIs | Crocheter les appels de bibliothèque lors de l’émulation |
Exécution Symbolique
from miasm.ir.symbexec import SymbolicExecutionEngine
sb = SymbolicExecutionEngine(lifter)
symbolic_pc = sb.run_at(ircfg, 0x401000)
print(sb.symbols) # symbolic register/memory state
L’exécution symbolique est la base pour la désofuscation, la résolution pour les entrées et la simplification des déchets/prédicats opaques.
Workflows Courants
| Goal | Approach |
|---|
| Export a CFG to view | asmcfg.dot() → render with Graphviz |
| Unpack/deobfuscate | Émuler avec le jitter, dump mémoire à l’OEP |
| Solve for an input | Exécution symbolique + un solveur SMT (z3) |
| Cross-arch analysis | Lifter en IR, exécuter les mêmes passes indépendamment de l’architecture |
Miasm vs Autres Frameworks RE
| 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 | Oui | Oui (core strength) | Limité |
| Best for | Analyse scriptée, désofuscation | Symbolique/CTF | Interactive RE |
Ressources