diff options
Diffstat (limited to 'README.md')
| -rw-r--r-- | README.md | 416 |
1 files changed, 245 insertions, 171 deletions
diff --git a/README.md b/README.md index 118051df..9be3bdc6 100644 --- a/README.md +++ b/README.md @@ -45,19 +45,25 @@ Assembling / Disassembling -------------------------- Import Miasm x86 architecture: -``` +```pycon >>> from miasm2.arch.x86.arch import mn_x86 +>>> from miasm2.core.locationdb import LocationDB ``` -Assemble a line: +Get a location db: + +```pycon +>>> loc_db = LocationDB() ``` ->>> l = mn_x86.fromstring('XOR ECX, ECX', 32) +Assemble a line: +```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'] ``` Modify an operand: -``` +```pycon >>> l.args[0] = mn_x86.regs.EAX >>> print l XOR EAX, ECX @@ -66,13 +72,13 @@ XOR EAX, ECX ['1\xc8', '3\xc1', 'g1\xc8', 'g3\xc1'] ``` Disassemble the result: -``` +```pycon >>> print mn_x86.dis(a[0], 32) XOR EAX, ECX ``` Using `Machine` abstraction: -``` +```pycon >>> from miasm2.analysis.machine import Machine >>> mn = Machine('x86_32').mn >>> print mn.dis('\x33\x30', 32) @@ -80,7 +86,7 @@ XOR ESI, DWORD PTR [EAX] ``` For Mips: -``` +```pycon >>> mn = Machine('mips32b').mn >>> print mn.dis('97A30020'.decode('hex'), "b") LHU V1, 0x20(SP) @@ -90,36 +96,39 @@ Intermediate representation Create an instruction: -``` +```pycon >>> machine = Machine('arml') ->>> l = machine.mn.dis('002088e0'.decode('hex'), 'l') ->>> print l +>>> instr = machine.mn.dis('002088e0'.decode('hex'), 'l') +>>> print instr ADD R2, R8, R0 ``` -Create an intermediate representation (IR) object: +Create an intermediate representation object: +```pycon +>>> ira = machine.ira(loc_db) ``` ->>> ira = machine.ira() +Create an empty ircfg +```pycon +>>> ircfg = ira.new_ircfg() ``` Add instruction to the pool: -``` ->>> ira.add_instr(l) +```pycon +>>> ira.add_instr_to_ircfg(instr, ircfg) ``` Print current pool: -``` ->>> for lbl, irblock in ira.blocks.items(): -... print irblock -... -loc_0000000000000000:0x00000000 +```pycon +>>> for lbl, irblock in ircfg.blocks.items(): +... print irblock.to_string(loc_db) +loc_0: +R2 = R8 + R0 - R2 = (R8+R0) +IRDst = loc_4 - IRDst = loc_0000000000000004:0x00000004 ``` Working with IR, for instance by getting side effects: -``` ->>> for lbl, irblock in ira.blocks.iteritems(): +```pycon +>>> for lbl, irblock in ircfg.blocks.iteritems(): ... for assignblk in irblock: ... rw = assignblk.get_rw() ... for dst, reads in rw.iteritems(): @@ -130,15 +139,16 @@ Working with IR, for instance by getting side effects: read: ['R8', 'R0'] written: R2 -read: ['loc_0000000000000004:0x00000004'] +read: [] written: IRDst + ``` Emulation --------- Giving a shellcode: -``` +```pycon 00000000 8d4904 lea ecx, [ecx+0x4] 00000003 8d5b01 lea ebx, [ebx+0x1] 00000006 80f901 cmp cl, 0x1 @@ -152,7 +162,7 @@ Giving a shellcode: ``` Import the shellcode thanks to the `Container` abstraction: -``` +```pycon >>> from miasm2.analysis.binary import Container >>> c = Container.from_string(s) >>> c @@ -161,42 +171,41 @@ Import the shellcode thanks to the `Container` abstraction: Disassembling the shellcode at address `0`: -``` +```pycon >>> from miasm2.analysis.machine import Machine >>> machine = Machine('x86_32') >>> mdis = machine.dis_engine(c.bin_stream) ->>> blocks = mdis.dis_multiblock(0) ->>> for block in blocks: -... print block +>>> asmcfg = mdis.dis_multiblock(0) +>>> for block in asmcfg.blocks: +... print block.to_string(asmcfg.loc_db) ... -loc_0000000000000000:0x00000000 -LEA ECX, DWORD PTR [ECX+0x4] -LEA EBX, DWORD PTR [EBX+0x1] +loc_0 +LEA ECX, DWORD PTR [ECX + 0x4] +LEA EBX, DWORD PTR [EBX + 0x1] CMP CL, 0x1 -JZ loc_0000000000000010:0x00000010 --> c_next:loc_000000000000000B:0x0000000b c_to:loc_0000000000000010:0x00000010 -loc_0000000000000010:0x00000010 -LEA EBX, DWORD PTR [EBX+0x1] --> c_next:loc_0000000000000013:0x00000013 -loc_000000000000000B:0x0000000b -LEA EBX, DWORD PTR [EBX+0xFFFFFFFF] -JMP loc_0000000000000013:0x00000013 --> c_to:loc_0000000000000013:0x00000013 -loc_0000000000000013:0x00000013 +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: -``` +```pycon >>> jitter = machine.jitter(jit_type='python') >>> jitter.init_stack() ``` Add the shellcode in an arbitrary memory location: -``` +```pycon >>> run_addr = 0x40000000 >>> from miasm2.jitter.csts import PAGE_READ, PAGE_WRITE >>> jitter.vm.add_memory_page(run_addr, PAGE_READ | PAGE_WRITE, s) @@ -204,7 +213,7 @@ Add the shellcode in an arbitrary memory location: Create a sentinelle to catch the return of the shellcode: -``` +```Python def code_sentinelle(jitter): jitter.run = False jitter.pc = 0 @@ -216,14 +225,13 @@ def code_sentinelle(jitter): Active logs: -``` ->>> jitter.jit.log_regs = True ->>> jitter.jit.log_mn = True +```pycon +>>> jitter.set_trace_log() ``` Run at arbitrary address: -``` +```pycon >>> jitter.init_run(run_addr) >>> jitter.continue_run() RAX 0000000000000000 RBX 0000000000000000 RCX 0000000000000000 RDX 0000000000000000 @@ -252,7 +260,7 @@ RIP 0000000040000013 Interacting with the jitter: -``` +```pycon >>> jitter.vm ad 1230000 size 10000 RW_ hpad 0x2854b40 ad 40000000 size 16 RW_ hpad 0x25e0ed0 @@ -267,154 +275,220 @@ Symbolic execution Initializing the IR pool: -``` +```pycon >>> ira = machine.ira() ->>> for block in blocks: -... ira.add_block(block) -... +>>> ircfg = ira.new_ircfg_from_asmcfg(asmcfg) ``` Initializing the engine with default symbolic values: -``` +```pycon >>> from miasm2.ir.symbexec import SymbolicExecutionEngine ->>> sb = SymbolicExecutionEngine(ira, machine.mn.regs.regs_init) +>>> sb = SymbolicExecutionEngine(ira) ``` Launching the execution: -``` ->>> symbolic_pc = sb.run_at(0) +```pycon +>>> symbolic_pc = sb.run_at(ircfg, 0) >>> print symbolic_pc -((ECX_init+0x4)[0:8]+0xFF)?(0xB,0x10) +((ECX + 0x4)[0:8] + 0xFF)?(0xB,0x10) ``` Same, with step logs (only changes are displayed): -``` +```pycon >>> sb = SymbolicExecutionEngine(ira, machine.mn.regs.regs_init) ->>> symbolic_pc = sb.run_at(0, step=True) +>>> symbolic_pc = sb.run_at(ircfg, 0, step=True) +Instr LEA ECX, DWORD PTR [ECX + 0x4] +Assignblk: +ECX = ECX + 0x4 +________________________________________________________________________________ +ECX = ECX + 0x4 ________________________________________________________________________________ -ECX (ECX_init+0x4) +Instr LEA EBX, DWORD PTR [EBX + 0x1] +Assignblk: +EBX = EBX + 0x1 ________________________________________________________________________________ -ECX (ECX_init+0x4) -EBX (EBX_init+0x1) +EBX = EBX + 0x1 +ECX = ECX + 0x4 ________________________________________________________________________________ -zf ((ECX_init+0x4)[0:8]+0xFF)?(0x0,0x1) -nf ((ECX_init+0x4)[0:8]+0xFF)[7:8] -pf (parity ((ECX_init+0x4)[0:8]+0xFF)) -of ((((ECX_init+0x4)[0:8]+0xFF)^(ECX_init+0x4)[0:8])&((ECX_init+0x4)[0:8]^0x1))[7:8] -cf (((((ECX_init+0x4)[0:8]+0xFF)^(ECX_init+0x4)[0:8])&((ECX_init+0x4)[0:8]^0x1))^((ECX_init+0x4)[0:8]+0xFF)^(ECX_init+0x4)[0:8]^0x1)[7:8] -af (((ECX_init+0x4)[0:8]+0xFF)&0x10)?(0x1,0x0) -ECX (ECX_init+0x4) -EBX (EBX_init+0x1) +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] ________________________________________________________________________________ -IRDst ((ECX_init+0x4)[0:8]+0xFF)?(0xB,0x10) -zf ((ECX_init+0x4)[0:8]+0xFF)?(0x0,0x1) -nf ((ECX_init+0x4)[0:8]+0xFF)[7:8] -pf (parity ((ECX_init+0x4)[0:8]+0xFF)) -of ((((ECX_init+0x4)[0:8]+0xFF)^(ECX_init+0x4)[0:8])&((ECX_init+0x4)[0:8]^0x1))[7:8] -cf (((((ECX_init+0x4)[0:8]+0xFF)^(ECX_init+0x4)[0:8])&((ECX_init+0x4)[0:8]^0x1))^((ECX_init+0x4)[0:8]+0xFF)^(ECX_init+0x4)[0:8]^0x1)[7:8] -af (((ECX_init+0x4)[0:8]+0xFF)&0x10)?(0x1,0x0) -EIP ((ECX_init+0x4)[0:8]+0xFF)?(0xB,0x10) -ECX (ECX_init+0x4) -EBX (EBX_init+0x1) +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 miasm2.expression.expression import ExprInt32 ->>> sb.symbols[machine.mn.regs.ECX] = ExprInt32(-3) ->>> symbolic_pc = sb.run_at(0, step=True) +```pycon +>>> from miasm2.expression.expression import ExprInt +>>> sb.symbols[machine.mn.regs.ECX] = ExprInt(-3) +>>> symbolic_pc = sb.run_at(ircfg, 0, step=True) +Instr LEA ECX, DWORD PTR [ECX + 0x4] +Assignblk: +ECX = ECX + 0x4 ________________________________________________________________________________ -ECX 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 + 0x1 ________________________________________________________________________________ -ECX 0x1 -EBX (EBX_init+0x1) +Instr LEA EBX, DWORD PTR [EBX + 0x1] +Assignblk: +EBX = EBX + 0x1 ________________________________________________________________________________ -zf 0x1 -nf 0x0 -pf 0x1 -of 0x0 -cf 0x0 -af 0x0 -ECX 0x1 -EBX (EBX_init+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 ________________________________________________________________________________ -IRDst 0x10 -zf 0x1 -nf 0x0 -pf 0x1 -of 0x0 -cf 0x0 -af 0x0 -EIP 0x10 -ECX 0x1 -EBX (EBX_init+0x1) +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] ________________________________________________________________________________ -IRDst 0x10 -zf 0x1 -nf 0x0 -pf 0x1 -of 0x0 -cf 0x0 -af 0x0 -EIP 0x10 -ECX 0x1 -EBX (EBX_init+0x2) +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 ________________________________________________________________________________ -IRDst 0x13 -zf 0x1 -nf 0x0 -pf 0x1 -of 0x0 -cf 0x0 -af 0x0 -EIP 0x10 -ECX 0x1 -EBX (EBX_init+0x2) +Instr JZ loc_key_1 +Assignblk: +IRDst = zf?(loc_key_1,loc_key_2) +EIP = zf?(loc_key_1,loc_key_2) ________________________________________________________________________________ -IRDst 0x13 -zf 0x1 -nf 0x0 -pf 0x1 -of 0x0 -cf 0x0 -af 0x0 -EIP 0x10 -EAX (EBX_init+0x2) -ECX 0x1 -EBX (EBX_init+0x2) +af = 0x0 +EIP = 0x10 +pf = 0x1 +IRDst = 0x10 +zf = 0x1 +ECX = 0x1 +of = 0x0 +nf = 0x0 +cf = 0x0 +EBX = EBX + 0x2 ________________________________________________________________________________ -IRDst @32[ESP_init] -zf 0x1 -nf 0x0 -pf 0x1 -of 0x0 -cf 0x0 -af 0x0 -EIP @32[ESP_init] -EAX (EBX_init+0x2) -ECX 0x1 -EBX (EBX_init+0x2) -ESP (ESP_init+0x4) ->>> print symbolic_pc -@32[ESP_init] ->>> sb.dump_id() -IRDst @32[ESP_init] -zf 0x1 -nf 0x0 -pf 0x1 -of 0x0 -cf 0x0 -af 0x0 -EIP @32[ESP_init] -EAX (EBX_init+0x2) -ECX 0x1 -EBX (EBX_init+0x2) -ESP (ESP_init+0x4) +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 +________________________________________________________________________________ +>>> ``` @@ -440,7 +514,7 @@ An auto-generated documentation is available [here](http://miasmdoc.ajax.re). Obtaining Miasm =============== -* Clone the repository: [Miasm on GitHub](https://github.com/serpilliere/miasm) +* Clone the repository: [Miasm on GitHub](https://github.com/cea-sec/miasm/) * Get one of the Docker images at [Docker Hub](https://registry.hub.docker.com/u/miasm/) Software requirements @@ -465,7 +539,7 @@ Configuration ------------- * Install elfesteem -``` +```pycon git clone https://github.com/serpilliere/elfesteem.git elfesteem cd elfesteem python setup.py build @@ -480,7 +554,7 @@ To use the jitter, GCC or LLVM is recommended * Debian stable/Ubuntu/Kali/whatever: `pip install llvmlite` or install from [llvmlite](https://github.com/numba/llvmlite) * Windows: Not tested * Build and install Miasm: -``` +```pycon $ cd miasm_directory $ python setup.py build $ sudo python setup.py install @@ -505,7 +579,7 @@ Testing Miasm comes with a set of regression tests. To run all of them: -``` +```pycon cd miasm_directory/test python test_all.py ``` |