Miasm 是一个免费开源的(GPLv2)逆向工程框架。 Miasm 旨在分析/修改/生成二进制程序。以下是 一个非详尽的功能列表:
访问官方 博客 获取更多示例和演示。
导入 Miasm x86 架构:```pycon
from miasm.arch.x86.arch import mn_x86 from miasm.core.locationdb import LocationDB
获取位置数据库:```pycon
>>> loc_db = LocationDB()
组装一行:```pycon
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']
修改一个操作数:```pycon
>>> 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']
对结果进行反汇编:```pycon
print(mn_x86.dis(a[0], 32)) XOR EAX, ECX
使用 `Machine` 抽象:```pycon
>>> from miasm.analysis.machine import Machine
>>> mn = Machine('x86_32').mn
>>> print(mn.dis('\x33\x30', 32))
XOR ESI, DWORD PTR [EAX]
对于 MIPS:```pycon
mn = Machine('mips32b').mn print(mn.dis(b'\x97\xa3\x00 ', "b")) LHU V1, 0x20(SP)
中间表示
---------------------------
创建一条指令:```pycon
>>> machine = Machine('arml')
>>> instr = machine.mn.dis('\x00 \x88\xe0', 'l')
>>> print(instr)
ADD R2, R8, R0
创建一个中间表示对象:```pycon
lifter = machine.lifter_model_call(loc_db)
创建一个空的ircfg:```pycon
>>> ircfg = lifter.new_ircfg()
添加指令到池中:```pycon
lifter.add_instr_to_ircfg(instr, ircfg)
打印当前池:```pycon
>>> for lbl, irblock in ircfg.blocks.items():
... print(irblock)
loc_0:
R2 = R8 + R0
IRDst = loc_4
处理 IR,例如通过获取副作用:```pycon
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
更多关于Miasm IR的信息见[对应的Jupyter Notebook](https://github.com/cea-sec/miasm/blob/master/doc/expression/expression.ipynb)。
模拟
---------
给出一个shellcode:```pycon
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'
使用 Container 抽象来导入 shellcode:```pycon
from miasm.analysis.binary import Container c = Container.from_string(s, loc_db) c <miasm.analysis.binary.ContainerUnknown object at 0x7f34cefe6090>
将位于地址 `0` 处的 shellcode 进行反汇编:```pycon
>>> 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
使用栈初始化 JIT 引擎:```pycon
jitter = machine.jitter(loc_db, jit_type='python') jitter.init_stack()
将shellcode添加到一个任意内存位置:```pycon
>>> run_addr = 0x40000000
>>> from miasm.jitter.csts import PAGE_READ, PAGE_WRITE
>>> jitter.vm.add_memory_page(run_addr, PAGE_READ | PAGE_WRITE, s)
创建一个哨兵来捕获shellcode的返回:```Python def code_sentinelle(jitter): jitter.running = False jitter.pc = 0 return True
jitter.add_breakpoint(0x1337beef, code_sentinelle) jitter.push_uint32_t(0x1337beef)
活动日志:```pycon
>>> jitter.set_trace_log()
在任意地址运行:```pycon
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
与 jitter 交互:```pycon
>>> 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