miasm

cea-secGPL-2.0活跃维护

用 Python 写的逆向工程框架,集汇编、反汇编、模拟执行和符号执行于一体,方便分析二进制程序。

Reverse engineering framework in Python

v0.1.3发布于 2019-12-12 09:02 UTC4,014star497fork同步于 2026-11-10 11:39 UTC

怎么上手

由 README 提炼,执行前请确认
pip install miasm
硬件要求按 README 说明

README 未说明

支持 Apple Silicon
下载:源码 zip·GitHub Releases(安装包)本站不镜像安装包

项目说明

由 README 自动翻译提炼

Python 逆向工程框架,用于分析、修改和生成二进制程序

用 Python 写的逆向工程框架,集汇编、反汇编、模拟执行和符号执行于一体,方便分析二进制程序。

核心能力

  • 打开、修改、生成 PE 与 ELF 32/64 位大小端文件
  • 汇编与反汇编 X86/ARM/MIPS/SH4/MSP430
  • 将汇编语义提升为中间语言表示
  • 用 JIT 模拟执行做动态分析与脱壳
  • 符号执行与表达式化简辅助自动反混淆

容易踩的坑

README 未给出安装命令,示例均假设已安装 miasm 包;JIT 示例需指定 jit_type='python' 等后端;运行示例前需自行构造 LocationDB 等对象

内容由模型根据 README 生成,可能不完整或不准确,以官方文档为准。看原文 README

最近发版

5 个版本v0.1.3
  1. v0.1.3最新正式版2019-12-12 · 2019-12-12 09:02 UTC

    0.1.3 - 2019-12-12

    Added

    Fixed

    • Fixed DSE mem_read
  2. v0.1.22019-12-11 · 2019-12-11 13:51 UTC
    查看更新说明

    Added

    • find_path_from_src added by @nofiv to DiGraph
    • Some simplifications (cst == X+ cst; X ^cst = cst)
    • Add a cache for C types
    • IR Simplifier
    • Add "remove_breakpoints_by_address" capability to jitter
    • compose_and_mask simplification by @icecr4ck
    • X86: high level op saturation semantic
    • Add extended tests for travis
    • memory breakpoint example by @idl3r
    • Miasm Logo

    Fixed

    • Support Python2/Python3 done with @p-l-
    • Aarch64/PPC/x86 instructions/semantic
    • rev16/nop/ldrsb added by @hax0kartik
    • x86 rep instruction fixed by @nofiv
    • x86 ENDBR32/ENDBR64/CET fixed by @WilliamBruneau
    • SSA unused var
    • .shift to .base_address by @su-vikas
    • Propagate Phi with same sources
    • Clean unssa code
    • simplification fixed by @jie-lin
    • simplification fixed by @icecr4ck
    • Update/clean jitter code
    • PyGetInt/Python3/Bignum fix by @WilliamBruneau
    • macOS code fix by @trufae
    • macOS fix/updt by @icecr4ck
    • tipo by @Spl3en
    • Rename/Include elfesteem as loader in Miasm
    • Fix str/bytes by @carolineLe
    • Fix loader vm2pe by @WilliamBruneau
    • Codespell by @WilliamBruneau
    • internal representation for path as str
    • int1 handling by @losynix
    • x86 fix (ud2, roundsd, ir) by @htfy96
    • IDA graph example by @WilliamBruneau
    • Compilation on android by @WilliamBruneau
    • fix imports by @themaks
    • fix readme by @monperrus
    • get_win_str_[aw]/set_win_str_[aw] API out of jitter
    • get_c_str/set_c_str API in jitter
    • sembuilder fix by @htfy96
    • x86/rep by @a-vincent
    • Add simplifications regression tests
    • return ExprLoc on read_cst
    • Fix peb page name
    • Add explicit API for intervals
    • add sc2pe/get_exports by @WilliamBruneau
  3. v0.1.12019-01-17 · 2019-01-17 11:56 UTC
    查看更新说明

    Added

    • Graph: add postdominators computation from @GAJaloyan
    • Multiple X86/MeP/Arm/Amrt/Aarch64 mnemonics (@guedou, @w4kfu, @nguigo)
    • Qemu regression tests for X86_64
    • Start export of the intermediate language to LLVM
    • IR simplifications
    • Typos & codespell checker from @p-l-
    • High level flags for MSP430

    Fixed

    • Out-of-SSA with new algorithm
    • Travis cleanup/rework/improvement from @stephengroat
    • Jitter: pc update
    • Jitter/python: global refactoring
    • Change ExprMem pointer access (.ptr instead of .arg)
    • Rename IR operators idiv/imod to sdiv/smod for homogeneity
    • Clean replace_expr from @Mizari
    • Various fixes
    • Instruction to_string from @nofiv
  4. v0.1.02018-11-12 · 2018-11-12 22:28 UTC
    查看更新说明

    Added

    • Support for Windows added from @0vercl0k
    • Support for Appveyor
    • Symbolic execution memory management has been rewritten. As a result, the global performance of symbolic execution has improved
    • Support for some of Thumb2 instructions
    • Support for build on OpenBSD
    • Support for mips32b emulation
    • Support for XMMs registers / 128 bits operations for all jitter engine
    • New IR word: ExpLoc (representing a location in the code)
    • New symbol management: LocationDB (replacing symbol_pool)
    • Split IRCFG from IntermediateRepresntation
    • SSA transformation added from @mrphrazer
    • Support ELF relocations
    • Support for SSE (with qemu test)
    • Support for full Linux environment emulation + syscall
    • Support for explicit flags (eflags + size extend)
    • Support for (buggy) un-ssa
    • Improvement of floats handling
    • Added Toshiba MeP architecture added from @guedou
    • Add constant expressions propagation (ssa based)
    • Support for ARM SVC added from @aguinet
    • Introduce ExprMem.ptr
    • Add various expression simplifications
    • Add immediate postdominator computation from @GAJaloyan

    Removed

    • TCC support is dropped

    Fixed

    • Trace api improved
    • Various fixes for the PPC architecture
    • Various fixes for the x86 architecture
    • Various fixes for ARM instructions
    • Various fixes in IDA plugins
    • Various code refactoring
    • No more default size in any Expr
    • ExprAff renamed to ExprAssign
    • Problems who might occurs when comparing for inequality (!=) in some of Miasm objects
    • Instruction parsing codes have been cleaned and simplified
    • Resource rebuilding for PE
    • Better BigEndian handling in Miasm
    • Misleading name EXCEPT_BREAKPOINT_INTERN is renamed EXCEPT_BREAKPOINT_MEMORY
    • Gentoo compilation
    • Jitter memory page managment
    • Sanitization of floats representation
    • Fix build on 32 bit machines
    • Fix DSE read/write bug
    • Sandbox's option use-seh renamed to the more precise use-windows-structs
    • Clean simplifier cache on pass enabling
  5. v0.0.1Initial release2018-03-12 · 2018-03-12 15:28 UTC
    查看更新说明

    Added

    • This CHANGELOG file
    • Version tracking

用户点评

登录用户的真实使用记录,可按版本和硬件筛选
共 0 条

    还没有人点评。第一个说出真实体验的人最有价值。

    README 原文

    未翻译

    Miasm tests

    What is Miasm?

    Miasm is a free and open source (GPLv2) reverse engineering framework. Miasm aims to analyze / modify / generate binary programs. Here is a non-exhaustive list of features:

    • Opening / modifying / generating PE / ELF 32 / 64 LE / BE
    • Assembling / Disassembling X86 / ARM / MIPS / SH4 / MSP430
    • Representing assembly semantic using intermediate language
    • Emulating using JIT (dynamic code analysis, unpacking, ...)
    • Expression simplification for automatic de-obfuscation
    • ...

    See the official blog for more examples and demos.

    Table of Contents

    Basic examples

    Assembling / Disassembling

    Import Miasm x86 architecture:

    >>> from miasm.arch.x86.arch import mn_x86
    >>> from miasm.core.locationdb import LocationDB
    

    Get a location db:

    >>> loc_db = LocationDB()
    

    Assemble a line:

    >>> l = mn_x86.fromstring('XOR ECX, ECX', loc_db, 32)
    >>> print(l)
    XOR        ECX, ECX
    >>> mn_x86.asm(l)
    ['1\xc9', '3\xc9', 'g1\xc9', 'g3\xc9']
    

    Modify an operand:

    >>> l.args[0] = mn_x86.regs.EAX
    >>> print(l)
    XOR        EAX, ECX
    >>> a = mn_x86.asm(l)
    >>> print(a)
    ['1\xc8', '3\xc1', 'g1\xc8', 'g3\xc1']
    

    Disassemble the result:

    >>> print(mn_x86.dis(a[0], 32))
    XOR        EAX, ECX
    

    Using Machine abstraction:

    >>> from miasm.analysis.machine import Machine
    >>> mn = Machine('x86_32').mn
    >>> print(mn.dis('\x33\x30', 32))
    XOR        ESI, DWORD PTR [EAX]
    

    For MIPS:

    >>> mn = Machine('mips32b').mn
    >>> print(mn.dis(b'\x97\xa3\x00 ', "b"))
    LHU        V1, 0x20(SP)
    

    Intermediate representation

    Create an instruction:

    >>> machine = Machine('arml')
    >>> instr = machine.mn.dis('\x00 \x88\xe0', 'l')
    >>> print(instr)
    ADD        R2, R8, R0
    

    Create an intermediate representation object:

    >>> lifter = machine.lifter_model_call(loc_db)
    

    Create an empty ircfg:

    >>> ircfg = lifter.new_ircfg()
    

    Add instruction to the pool:

    >>> lifter.add_instr_to_ircfg(instr, ircfg)
    

    Print current pool:

    >>> for lbl, irblock in ircfg.blocks.items():
    ...     print(irblock)
    loc_0:
    R2 = R8 + R0
    
    IRDst = loc_4
    
    

    Working with IR, for instance by getting side effects:

    >>> for lbl, irblock in ircfg.blocks.items():
    ...     for assignblk in irblock:
    ...         rw = assignblk.get_rw()
    ...         for dst, reads in rw.items():
    ...             print('read:   ', [str(x) for x in reads])
    ...             print('written:', dst)
    ...             print()
    ...
    read:    ['R8', 'R0']
    written: R2
    
    read:    []
    written: IRDst
    
    

    More information on Miasm IR is in the corresponding Jupyter Notebook.

    Emulation

    Giving a shellcode:

    00000000 8d4904      lea    ecx, [ecx+0x4]
    00000003 8d5b01      lea    ebx, [ebx+0x1]
    00000006 80f901      cmp    cl, 0x1
    00000009 7405        jz     0x10
    0000000b 8d5bff      lea    ebx, [ebx-1]
    0000000e eb03        jmp    0x13
    00000010 8d5b01      lea    ebx, [ebx+0x1]
    00000013 89d8        mov    eax, ebx
    00000015 c3          ret
    >>> s = b'\x8dI\x04\x8d[\x01\x80\xf9\x01t\x05\x8d[\xff\xeb\x03\x8d[\x01\x89\xd8\xc3'
    

    Import the shellcode thanks to the Container abstraction:

    >>> from miasm.analysis.binary import Container
    >>> c = Container.from_string(s, loc_db)
    >>> c
    <miasm.analysis.binary.ContainerUnknown object at 0x7f34cefe6090>
    

    Disassembling the shellcode at address 0:

    >>> from miasm.analysis.machine import Machine
    >>> machine = Machine('x86_32')
    >>> mdis = machine.dis_engine(c.bin_stream, loc_db=loc_db)
    >>> asmcfg = mdis.dis_multiblock(0)
    >>> for block in asmcfg.blocks:
    ...  print(block)
    ...
    loc_0
    LEA        ECX, DWORD PTR [ECX + 0x4]
    LEA        EBX, DWORD PTR [EBX + 0x1]
    CMP        CL, 0x1
    JZ         loc_10
    ->      c_next:loc_b    c_to:loc_10
    loc_10
    LEA        EBX, DWORD PTR [EBX + 0x1]
    ->      c_next:loc_13
    loc_b
    LEA        EBX, DWORD PTR [EBX + 0xFFFFFFFF]
    JMP        loc_13
    ->      c_to:loc_13
    loc_13
    MOV        EAX, EBX
    RET
    

    Initializing the JIT engine with a stack:

    >>> jitter = machine.jitter(loc_db, jit_type='python')
    >>> jitter.init_stack()
    

    Add the shellcode in an arbitrary memory location:

    >>> run_addr = 0x40000000
    >>> from miasm.jitter.csts import PAGE_READ, PAGE_WRITE
    >>> jitter.vm.add_memory_page(run_addr, PAGE_READ | PAGE_WRITE, s)
    

    Create a sentinelle to catch the return of the shellcode:

    def code_sentinelle(jitter):
        jitter.running = False
        jitter.pc = 0
        return True
    
    >>> jitter.add_breakpoint(0x1337beef, code_sentinelle)
    >>> jitter.push_uint32_t(0x1337beef)
    

    Active logs:

    >>> jitter.set_trace_log()
    

    Run at arbitrary address:

    >>> jitter.init_run(run_addr)
    >>> jitter.continue_run()
    RAX 0000000000000000 RBX 0000000000000000 RCX 0000000000000000 RDX 0000000000000000
    RSI 0000000000000000 RDI 0000000000000000 RSP 000000000123FFF8 RBP 0000000000000000
    zf 0000000000000000 nf 0000000000000000 of 0000000000000000 cf 0000000000000000
    RIP 0000000040000000
    40000000 LEA        ECX, DWORD PTR [ECX+0x4]
    RAX 0000000000000000 RBX 0000000000000000 RCX 0000000000000004 RDX 0000000000000000
    RSI 0000000000000000 RDI 0000000000000000 RSP 000000000123FFF8 RBP 0000000000000000
    zf 0000000000000000 nf 0000000000000000 of 0000000000000000 cf 0000000000000000
    ....
    4000000e JMP        loc_0000000040000013:0x40000013
    RAX 0000000000000000 RBX 0000000000000000 RCX 0000000000000004 RDX 0000000000000000
    RSI 0000000000000000 RDI 0000000000000000 RSP 000000000123FFF8 RBP 0000000000000000
    zf 0000000000000000 nf 0000000000000000 of 0000000000000000 cf 0000000000000000
    RIP 0000000040000013
    40000013 MOV        EAX, EBX
    RAX 0000000000000000 RBX 0000000000000000 RCX 0000000000000004 RDX 0000000000000000
    RSI 0000000000000000 RDI 0000000000000000 RSP 000000000123FFF8 RBP 0000000000000000
    zf 0000000000000000 nf 0000000000000000 of 0000000000000000 cf 0000000000000000
    RIP 0000000040000013
    40000015 RET
    >>>
    
    

    Interacting with the jitter:

    >>> jitter.vm
    ad 1230000 size 10000 RW_ hpad 0x2854b40
    ad 40000000 size 16 RW_ hpad 0x25e0ed0
    
    >>> hex(jitter.cpu.EAX)
    '0x0L'
    >>> jitter.cpu.ESI = 12
    

    Symbolic execution

    Initializing the IR pool:

    >>> lifter = machine.lifter_model_call(loc_db)
    >>> ircfg = lifter.new_ircfg_from_asmcfg(asmcfg)
    

    Initializing the engine with default symbolic values:

    >>> from miasm.ir.symbexec import SymbolicExecutionEngine
    >>> sb = SymbolicExecutionEngine(lifter)
    

    Launching the execution:

    >>> symbolic_pc = sb.run_at(ircfg, 0)
    >>> print(symbolic_pc)
    ((ECX + 0x4)[0:8] + 0xFF)?(0xB,0x10)
    

    Same, with step logs (only changes are displayed):

    >>> sb = SymbolicExecutionEngine(lifter, machine.mn.regs.regs_init)
    >>> symbolic_pc = sb.run_at(ircfg, 0, step=True)
    Instr LEA        ECX, DWORD PTR [ECX + 0x4]
    Assignblk:
    ECX = ECX + 0x4
    ________________________________________________________________________________
    ECX                = ECX + 0x4
    ________________________________________________________________________________
    Instr LEA        EBX, DWORD PTR [EBX + 0x1]
    Assignblk:
    EBX = EBX + 0x1
    ________________________________________________________________________________
    EBX                = EBX + 0x1
    ECX                = ECX + 0x4
    ________________________________________________________________________________
    Instr CMP        CL, 0x1
    Assignblk:
    zf = (ECX[0:8] + -0x1)?(0x0,0x1)
    nf = (ECX[0:8] + -0x1)[7:8]
    pf = parity((ECX[0:8] + -0x1) & 0xFF)
    of = ((ECX[0:8] ^ (ECX[0:8] + -0x1)) & (ECX[0:8] ^ 0x1))[7:8]
    cf = (((ECX[0:8] ^ 0x1) ^ (ECX[0:8] + -0x1)) ^ ((ECX[0:8] ^ (ECX[0:8] + -0x1)) & (ECX[0:8] ^ 0x1)))[7:8]
    af = ((ECX[0:8] ^ 0x1) ^ (ECX[0:8] + -0x1))[4:5]
    ________________________________________________________________________________
    af                 = (((ECX + 0x4)[0:8] + 0xFF) ^ (ECX + 0x4)[0:8] ^ 0x1)[4:5]
    pf                 = parity((ECX + 0x4)[0:8] + 0xFF)
    zf                 = ((ECX + 0x4)[0:8] + 0xFF)?(0x0,0x1)
    ECX                = ECX + 0x4
    of                 = ((((ECX + 0x4)[0:8] + 0xFF) ^ (ECX + 0x4)[0:8]) & ((ECX + 0x4)[0:8] ^ 0x1))[7:8]
    nf                 = ((ECX + 0x4)[0:8] + 0xFF)[7:8]
    cf                 = (((((ECX + 0x4)[0:8] + 0xFF) ^ (ECX + 0x4)[0:8]) & ((ECX + 0x4)[0:8] ^ 0x1)) ^ ((ECX + 0x4)[0:8] + 0xFF) ^ (ECX + 0x4)[0:8] ^ 0x1)[7:8]
    EBX                = EBX + 0x1
    ________________________________________________________________________________
    Instr JZ         loc_key_1
    Assignblk:
    IRDst = zf?(loc_key_1,loc_key_2)
    EIP = zf?(loc_key_1,loc_key_2)
    ________________________________________________________________________________
    af                 = (((ECX + 0x4)[0:8] + 0xFF) ^ (ECX + 0x4)[0:8] ^ 0x1)[4:5]
    EIP                = ((ECX + 0x4)[0:8] + 0xFF)?(0xB,0x10)
    pf                 = parity((ECX + 0x4)[0:8] + 0xFF)
    IRDst              = ((ECX + 0x4)[0:8] + 0xFF)?(0xB,0x10)
    zf                 = ((ECX + 0x4)[0:8] + 0xFF)?(0x0,0x1)
    ECX                = ECX + 0x4
    of                 = ((((ECX + 0x4)[0:8] + 0xFF) ^ (ECX + 0x4)[0:8]) & ((ECX + 0x4)[0:8] ^ 0x1))[7:8]
    nf                 = ((ECX + 0x4)[0:8] + 0xFF)[7:8]
    cf                 = (((((ECX + 0x4)[0:8] + 0xFF) ^ (ECX + 0x4)[0:8]) & ((ECX + 0x4)[0:8] ^ 0x1)) ^ ((ECX + 0x4)[0:8] + 0xFF) ^ (ECX + 0x4)[0:8] ^ 0x1)[7:8]
    EBX                = EBX + 0x1
    ________________________________________________________________________________
    >>>
    

    Retry execution with a concrete ECX. Here, the symbolic / concolic execution reach the shellcode's end:

    >>> from miasm.expression.expression import ExprInt
    >>> sb.symbols[machine.mn.regs.ECX] = ExprInt(-3, 32)
    >>> symbolic_pc = sb.run_at(ircfg, 0, step=True)
    Instr LEA        ECX, DWORD PTR [ECX + 0x4]
    Assignblk:
    ECX = ECX + 0x4
    ________________________________________________________________________________
    af                 = (((ECX + 0x4)[0:8] + 0xFF) ^ (ECX + 0x4)[0:8] ^ 0x1)[4:5]
    EIP                = ((ECX + 0x4)[0:8] + 0xFF)?(0xB,0x10)
    pf                 = parity((ECX + 0x4)[0:8] + 0xFF)
    IRDst              = ((ECX + 0x4)[0:8] + 0xFF)?(0xB,0x10)
    zf                 = ((ECX + 0x4)[0:8] + 0xFF)?(0x0,0x1)
    ECX                = 0x1
    of                 = ((((ECX + 0x4)[0:8] + 0xFF) ^ (ECX + 0x4)[0:8]) & ((ECX + 0x4)[0:8] ^ 0x1))[7:8]
    nf                 = ((ECX + 0x4)[0:8] + 0xFF)[7:8]
    cf                 = (((((ECX + 0x4)[0:8] + 0xFF) ^ (ECX + 0x4)[0:8]) & ((ECX + 0x4)[0:8] ^ 0x1)) ^ ((ECX + 0x4)[0:8] + 0xFF) ^ (ECX + 0x4)[0:8] ^ 0x1)[7:8]
    EBX                = EBX + 0x1
    ________________________________________________________________________________
    Instr LEA        EBX, DWORD PTR [EBX + 0x1]
    Assignblk:
    EBX = EBX + 0x1
    ________________________________________________________________________________
    af                 = (((ECX + 0x4)[0:8] + 0xFF) ^ (ECX + 0x4)[0:8] ^ 0x1)[4:5]
    EIP                = ((ECX + 0x4)[0:8] + 0xFF)?(0xB,0x10)
    pf                 = parity((ECX + 0x4)[0:8] + 0xFF)
    IRDst              = ((ECX + 0x4)[0:8] + 0xFF)?(0xB,0x10)
    zf                 = ((ECX + 0x4)[0:8] + 0xFF)?(0x0,0x1)
    ECX                = 0x1
    of                 = ((((ECX + 0x4)[0:8] + 0xFF) ^ (ECX + 0x4)[0:8]) & ((ECX + 0x4)[0:8] ^ 0x1))[7:8]
    nf                 = ((ECX + 0x4)[0:8] + 0xFF)[7:8]
    cf                 = (((((ECX + 0x4)[0:8] + 0xFF) ^ (ECX + 0x4)[0:8]) & ((ECX + 0x4)[0:8] ^ 0x1)) ^ ((ECX + 0x4)[0:8] + 0xFF) ^ (ECX + 0x4)[0:8] ^ 0x1)[7:8]
    EBX                = EBX + 0x2
    ________________________________________________________________________________
    Instr CMP        CL, 0x1
    Assignblk:
    zf = (ECX[0:8] + -0x1)?(0x0,0x1)
    nf = (ECX[0:8] + -0x1)[7:8]
    pf = parity((ECX[0:8] + -0x1) & 0xFF)
    of = ((ECX[0:8] ^ (ECX[0:8] + -0x1)) & (ECX[0:8] ^ 0x1))[7:8]
    cf = (((ECX[0:8] ^ 0x1) ^ (ECX[0:8] + -0x1)) ^ ((ECX[0:8] ^ (ECX[0:8] + -0x1)) & (ECX[0:8] ^ 0x1)))[7:8]
    af = ((ECX[0:8] ^ 0x1) ^ (ECX[0:8] + -0x1))[4:5]
    ________________________________________________________________________________
    af                 = 0x0
    EIP                = ((ECX + 0x4)[0:8] + 0xFF)?(0xB,0x10)
    pf                 = 0x1
    IRDst              = ((ECX + 0x4)[0:8] + 0xFF)?(0xB,0x10)
    zf                 = 0x1
    ECX                = 0x1
    of                 = 0x0
    nf                 = 0x0
    cf                 = 0x0
    EBX                = EBX + 0x2
    ________________________________________________________________________________
    Instr JZ         loc_key_1
    Assignblk:
    IRDst = zf?(loc_key_1,loc_key_2)
    EIP = zf?(loc_key_1,loc_key_2)
    ________________________________________________________________________________
    af                 = 0x0
    EIP                = 0x10
    pf                 = 0x1
    IRDst              = 0x10
    zf                 = 0x1
    ECX                = 0x1
    of                 = 0x0
    nf                 = 0x0
    cf                 = 0x0
    EBX                = EBX + 0x2
    ________________________________________________________________________________
    Instr LEA        EBX, DWORD PTR [EBX + 0x1]
    Assignblk:
    EBX = EBX + 0x1
    ________________________________________________________________________________
    af                 = 0x0
    EIP                = 0x10
    pf                 = 0x1
    IRDst              = 0x10
    zf                 = 0x1
    ECX                = 0x1
    of                 = 0x0
    nf                 = 0x0
    cf                 = 0x0
    EBX                = EBX + 0x3
    ________________________________________________________________________________
    Instr LEA        EBX, DWORD PTR [EBX + 0x1]
    Assignblk:
    IRDst = loc_key_3
    ________________________________________________________________________________
    af                 = 0x0
    EIP                = 0x10
    pf                 = 0x1
    IRDst              = 0x13
    zf                 = 0x1
    ECX                = 0x1
    of                 = 0x0
    nf                 = 0x0
    cf                 = 0x0
    EBX                = EBX + 0x3
    ________________________________________________________________________________
    Instr MOV        EAX, EBX
    Assignblk:
    EAX = EBX
    ________________________________________________________________________________
    af                 = 0x0
    EIP                = 0x10
    pf                 = 0x1
    IRDst              = 0x13
    zf                 = 0x1
    ECX                = 0x1
    of                 = 0x0
    nf                 = 0x0
    cf                 = 0x0
    EBX                = EBX + 0x3
    EAX                = EBX + 0x3
    ________________________________________________________________________________
    Instr RET
    Assignblk:
    IRDst = @32[ESP[0:32]]
    ESP = {ESP[0:32] + 0x4 0 32}
    EIP = @32[ESP[0:32]]
    ________________________________________________________________________________
    af                 = 0x0
    EIP                = @32[ESP]
    pf                 = 0x1
    IRDst              = @32[ESP]
    zf                 = 0x1
    ECX                = 0x1
    of                 = 0x0
    nf                 = 0x0
    cf                 = 0x0
    EBX                = EBX + 0x3
    ESP                = ESP + 0x4
    EAX                = EBX + 0x3
    ________________________________________________________________________________
    >>>
    

    How does it work?

    Miasm embeds its own disassembler, intermediate language and instruction semantic. It is written in Python.

    To emulate code, it uses LLVM, GCC, Clang or Python to JIT the intermediate representation. It can emulate shellcodes and all or parts of binaries. Python callbacks can be executed to interact with the execution, for instance to emulate library functions effects.

    Documentation

    Some documentation resources are available in the doc folder.

    An auto-generated documentation is available:

    Obtaining Miasm

    Software requirements

    Miasm uses:

    • Python >= 3.10
    • future
    • pyparsing >= 2.4.1

    Native jitter components are built when the local build environment supports them. If native extension compilation fails, installation continues and the jitter-dependent features are unavailable. Set MIASM_REQUIRE_JIT=1 when building release wheels or when native jitter support must be present.

    To enable non-Python JIT backends, one of the following is mandatory:

    • GCC
    • Clang
    • LLVM with Numba llvmlite (pip install miasm[llvm]), see below

    Optional Python features are grouped as extras:

    ExtraDependencyEnablesCode using it
    cparserpycparser>=2.17C type parsing and C-like expression access helpersmiasm/core/ctypesmngr.py, miasm/core/objc.py
    z3z3-solver==4.16.0.0Z3 expression translation, solver-backed dependency graph, DSE constraints, and range testsmiasm/ir/translators/z3_ir.py, miasm/analysis/depgraph.py, miasm/analysis/dse.py
    llvmllvmlite==0.50.0LLVM JIT backend and LLVM IR exportmiasm/jitter/jitcore_llvm.py, miasm/jitter/llvmconvert.py, example/expression/export_llvm.py
    graphgraphvizPython Graphviz object export from Miasm graphsmiasm/core/graph.py (DiGraph.graphviz)
    cryptopycryptodomeWindows API crypto/hash emulationmiasm/os_dep/win_api_x86_32.py
    allruntime extras aboveAll optional runtime featuresConvenience alias for users

    Development/test dependencies are not published as package extras. They live in [dependency-groups] in pyproject.toml:

    GroupDependencyEnablesCode using it
    devparameterized~=0.8.1Test runner parameterizationtest/test_all.py

    Configuration

    To use the jitter, GCC or LLVM is recommended

    • GCC (any version)
    • Clang (any version)
    • LLVM
      • Debian (testing/unstable): Not tested
      • Debian stable/Ubuntu/Kali/whatever: pip install llvmlite or install from llvmlite
      • Windows: Not tested
    • Build and install Miasm:
    $ cd miasm_directory
    $ python -m pip install .
    

    Optional dependencies can be installed with extras, for example:

    $ python -m pip install '.[cparser,z3,llvm]'
    $ python -m pip install '.[all]'
    $ python -m pip install --group dev '.[all]'  # local development/test runs
    

    If something goes wrong during native jitter compilation, Miasm will skip the failing extension and keep the rest of the package installable. Set MIASM_REQUIRE_JIT=1 to make native extension failures abort the build.

    Windows & IDA

    Most of Miasm's IDA plugins use a subset of Miasm functionality. A quick way to have them working is to add:

    • pyparsing.py to C:\...\IDA\python\ or pip install pyparsing
    • miasm/miasm directory to C:\...\IDA\python\

    All features excepting jitter related ones will be available. For a more complete installation, please refer to above paragraphs.

    Testing

    Miasm comes with a set of regression tests. Test-only dependencies are declared in the dev dependency group. uv sync installs this group by default; use --extra all when you also want all optional runtime backends for full test coverage. With pip, install the group explicitly.

    uv sync --extra all
    # or: python -m pip install --group dev '.[all]'
    cd miasm_directory/test
    
    # Run tests using our own test runner
    python test_all.py
    
    # Run tests using standard frameworks (slower, require 'parameterized')
    python -m unittest test_all.py        # sequential, requires 'unittest'
    python -m pytest test_all.py          # sequential, requires 'pytest'
    python -m pytest -n auto test_all.py  # parallel, requires 'pytest' and 'pytest-xdist'
    

    Some options can be specified:

    • Mono threading: -m
    • Code coverage instrumentation: -c
    • Only fast tests: -t long (excludes the long tests)

    They already use Miasm

    Tools

    • Sibyl: A function divination tool
    • R2M2: Use miasm as a radare2 plugin
    • CGrex: Targeted patcher for CGC binaries
    • ethRE: Reversing tool for Ethereum EVM (with corresponding Miasm2 architecture)

    Blog posts / papers / conferences

    Books