diff options
| author | serpilliere <serpilliere@users.noreply.github.com> | 2015-01-26 10:04:24 +0100 |
|---|---|---|
| committer | serpilliere <serpilliere@users.noreply.github.com> | 2015-01-26 10:04:24 +0100 |
| commit | b87f775c1a6a5c78c62beee925eaba6dc337577e (patch) | |
| tree | cf2650f575971bf8a23655a28c944e9e8a9da561 | |
| parent | c59591a779ac644d1b50a720aea93cd8b36a2ddf (diff) | |
| parent | 7b9bbe4754db4d1f5229cc5cc5769ad6cf2e0a84 (diff) | |
| download | miasm-b87f775c1a6a5c78c62beee925eaba6dc337577e.tar.gz miasm-b87f775c1a6a5c78c62beee925eaba6dc337577e.zip | |
Merge pull request #45 from commial/refactor-examples
Refactor examples
| -rw-r--r-- | example/asm/shellcode.py | 110 | ||||
| -rw-r--r-- | example/asm/simple.py | 37 | ||||
| -rw-r--r-- | example/asm_arm.py | 82 | ||||
| -rw-r--r-- | example/asm_arm_sc.py | 63 | ||||
| -rw-r--r-- | example/asm_armt.py | 88 | ||||
| -rw-r--r-- | example/asm_box_x86_32.py | 66 | ||||
| -rw-r--r-- | example/asm_box_x86_32_enc.py | 105 | ||||
| -rw-r--r-- | example/asm_box_x86_32_mod.py | 89 | ||||
| -rw-r--r-- | example/asm_box_x86_32_mod_self.py | 74 | ||||
| -rw-r--r-- | example/asm_box_x86_32_repmod.py | 103 | ||||
| -rw-r--r-- | example/asm_box_x86_64.py | 68 | ||||
| -rw-r--r-- | example/asm_mips32.py | 69 | ||||
| -rw-r--r-- | example/asm_msp430_sc.py | 54 | ||||
| -rw-r--r-- | example/asm_x86.py | 88 | ||||
| -rwxr-xr-x | example/box.exe | bin | 21827 -> 0 bytes | |||
| -rw-r--r-- | example/disasm/file.py (renamed from example/disasm_03.py) | 12 | ||||
| -rw-r--r-- | example/disasm/full.py (renamed from example/test_dis.py) | 136 | ||||
| -rw-r--r-- | example/disasm/function.py | 18 | ||||
| -rw-r--r-- | example/disasm/single_instr.py (renamed from example/disasm_01.py) | 2 | ||||
| -rw-r--r-- | example/disasm_02.py | 13 | ||||
| -rw-r--r-- | example/expression/expr_random.py | 4 | ||||
| -rw-r--r-- | example/expression/expr_translate.py | 1 | ||||
| -rw-r--r-- | example/ida/graph_ir.py (renamed from example/test_ida.py) | 0 | ||||
| -rw-r--r-- | example/jitter/arm.py (renamed from example/test_jit_arm.py) | 24 | ||||
| -rw-r--r-- | example/jitter/arm_sc.py (renamed from example/test_jit_arm_sc.py) | 2 | ||||
| -rw-r--r-- | example/jitter/mips32.py (renamed from example/test_jit_mips32.py) | 2 | ||||
| -rw-r--r-- | example/jitter/msp430.py (renamed from example/test_jit_msp430.py) | 2 | ||||
| -rw-r--r-- | example/jitter/sandbox_pe_x86_32.py (renamed from example/sandbox_pe_x86_32.py) | 0 | ||||
| -rw-r--r-- | example/jitter/unpack_upx.py (renamed from example/unpack_upx.py) | 0 | ||||
| -rw-r--r-- | example/jitter/x86_32.py (renamed from example/test_jit_x86_32.py) | 4 | ||||
| -rw-r--r-- | example/samples/arm_sc.S | 17 | ||||
| -rw-r--r-- | example/samples/arm_simple.S | 24 | ||||
| -rw-r--r-- | example/samples/armt.S | 27 | ||||
| -rwxr-xr-x | example/samples/box_upx.exe (renamed from example/box_upx.exe) | bin | 14659 -> 14659 bytes | |||
| -rwxr-xr-x | example/samples/md5_arm (renamed from example/md5_arm) | bin | 15381 -> 15381 bytes | |||
| -rw-r--r-- | example/samples/mips32.S | 12 | ||||
| -rw-r--r-- | example/samples/msp430.S | 8 | ||||
| -rw-r--r-- | example/samples/sc_connect_back.bin (renamed from example/expression/sc_connect_back.bin) | bin | 290 -> 290 bytes | |||
| -rw-r--r-- | example/samples/simple_test.bin (renamed from example/expression/simple_test.bin) | bin | 141 -> 141 bytes | |||
| -rw-r--r-- | example/samples/simple_test.c (renamed from example/expression/simple_test.c) | 0 | ||||
| -rw-r--r-- | example/samples/x86_32_enc.S | 38 | ||||
| -rw-r--r-- | example/samples/x86_32_manip_ptr.S | 50 | ||||
| -rw-r--r-- | example/samples/x86_32_mod.S | 35 | ||||
| -rw-r--r-- | example/samples/x86_32_mod_self.S | 20 | ||||
| -rw-r--r-- | example/samples/x86_32_repmod.S | 46 | ||||
| -rw-r--r-- | example/samples/x86_32_sc.bin (renamed from example/x86_32_sc.bin) | 0 | ||||
| -rw-r--r-- | example/samples/x86_32_simple.S | 12 | ||||
| -rw-r--r-- | example/samples/x86_64.S | 13 | ||||
| -rw-r--r-- | example/symbol_exec/single_instr.py (renamed from example/symbol_exec.py) | 0 | ||||
| -rw-r--r-- | miasm2/analysis/machine.py | 5 | ||||
| -rw-r--r-- | test/test_all.py | 298 |
51 files changed, 744 insertions, 1177 deletions
diff --git a/example/asm/shellcode.py b/example/asm/shellcode.py new file mode 100644 index 00000000..89914b6d --- /dev/null +++ b/example/asm/shellcode.py @@ -0,0 +1,110 @@ +#! /usr/bin/env python +from argparse import ArgumentParser +from pdb import pm + +from elfesteem import pe_init +from elfesteem.strpatchwork import StrPatchwork + +from miasm2.core.cpu import parse_ast +from miasm2.core import parse_asm, asmbloc +import miasm2.expression.expression as m2_expr +from miasm2.analysis.machine import Machine + +parser = ArgumentParser("Multi-arch (32 bits) assembler") +parser.add_argument('architecture', help="architecture: " + \ + ",".join(Machine.available_machine())) +parser.add_argument("source", help="Source file to assemble") +parser.add_argument("output", help="Output file") +parser.add_argument("--PE", help="Create a PE with a few imports", + action="store_true") +parser.add_argument("-e", "--encrypt", + help="Encrypt the code between <label_start> <label_stop>", + nargs=2) +args = parser.parse_args() + +# Get architecture-dependent parameters +machine = Machine(args.architecture) +try: + attrib = machine.dis_engine.attrib + size = int(attrib) +except AttributeError: + attrib = None + size = 32 +except ValueError: + size = 32 +reg_and_id = dict(machine.mn.regs.all_regs_ids_byname) +base_expr = machine.base_expr + +# Output format +if args.PE: + pe = pe_init.PE(wsize=size) + s_text = pe.SHList.add_section(name="text", addr=0x1000, rawsize=0x1000) + s_iat = pe.SHList.add_section(name="iat", rawsize=0x100) + new_dll = [({"name": "USER32.dll", + "firstthunk": s_iat.addr}, ["MessageBoxA"])] + pe.DirImport.add_dlldesc(new_dll) + s_myimp = pe.SHList.add_section(name="myimp", rawsize=len(pe.DirImport)) + pe.DirImport.set_rva(s_myimp.addr) + pe.Opthdr.AddressOfEntryPoint = s_text.addr + + addr_main = pe.rva2virt(s_text.addr) + virt = pe.virt + output = pe + +else: + st = StrPatchwork() + + addr_main = 0 + virt = st + output = st + +# Fix the AST parser +def my_ast_int2expr(a): + return m2_expr.ExprInt_fromsize(size, a) + +def my_ast_id2expr(t): + return reg_and_id.get(t, m2_expr.ExprId(t, size=size)) + +my_var_parser = parse_ast(my_ast_id2expr, my_ast_int2expr) +base_expr.setParseAction(my_var_parser) + +# Get and parse the source code +with open(args.source) as fstream: + source = fstream.read() + +blocs, symbol_pool = parse_asm.parse_txt(machine.mn, attrib, source) + +# Fix shellcode addrs +symbol_pool.set_offset(symbol_pool.getby_name("main"), addr_main) + +if args.PE: + symbol_pool.set_offset(symbol_pool.getby_name_create("MessageBoxA"), + pe.DirImport.get_funcvirt('MessageBoxA')) + +# Print and graph firsts blocs before patching it +for bloc in blocs[0]: + print bloc +graph = asmbloc.bloc2graph(blocs[0]) +open("graph.txt", "w").write(graph) + +# Apply patches +resolved_b, patches = asmbloc.asm_resolve_final(machine.mn, + blocs[0], + symbol_pool) +if args.encrypt: + # Encrypt code + ad_start = symbol_pool.getby_name_create(args.encrypt[0]).offset + ad_stop = symbol_pool.getby_name_create(args.encrypt[1]).offset + + new_patches = dict(patches) + for ad, val in patches.items(): + if ad_start <= ad < ad_stop: + new_patches[ad] = "".join([chr(ord(x) ^ 0x42) for x in val]) + patches = new_patches + +print patches +for offset, raw in patches.items(): + virt[offset] = raw + +# Produce output +open(args.output, 'wb').write(str(output)) diff --git a/example/asm/simple.py b/example/asm/simple.py new file mode 100644 index 00000000..1ae3ae05 --- /dev/null +++ b/example/asm/simple.py @@ -0,0 +1,37 @@ +from pdb import pm +from pprint import pprint + +from miasm2.arch.x86.arch import mn_x86 +from miasm2.core import parse_asm, asmbloc +import miasm2.expression.expression as m2_expr +from miasm2.core import asmbloc + + +# Assemble code +blocs, symbol_pool = parse_asm.parse_txt(mn_x86, 32, ''' +main: + MOV EAX, 1 + MOV EBX, 2 + MOV ECX, 2 + MOV DX, 2 + +loop: + INC EBX + CMOVZ EAX, EBX + ADD EAX, ECX + JZ loop + RET +''') + +# Set 'main' label's offset +symbol_pool.set_offset(symbol_pool.getby_name("main"), 0x0) + +# Spread information and resolve instructions offset +resolved_b, patches = asmbloc.asm_resolve_final(mn_x86, blocs[0], symbol_pool) + +# Show resolved blocs +for bloc, dummy in resolved_b: + print bloc + +# Print offset -> bytes +pprint(patches) diff --git a/example/asm_arm.py b/example/asm_arm.py deleted file mode 100644 index e9ffa330..00000000 --- a/example/asm_arm.py +++ /dev/null @@ -1,82 +0,0 @@ -#! /usr/bin/env python - -from miasm2.core.cpu import parse_ast -from miasm2.arch.arm.arch import mn_arm, base_expr, variable -from miasm2.core import parse_asm -from miasm2.expression.expression import * -from miasm2.core import asmbloc -from elfesteem.strpatchwork import StrPatchwork - -my_mn = mn_arm - -reg_and_id = dict(mn_arm.regs.all_regs_ids_byname) - - -def my_ast_int2expr(a): - return ExprInt32(a) - - -def my_ast_id2expr(t): - return reg_and_id.get(t, ExprId(t, size=32)) - -my_var_parser = parse_ast(my_ast_id2expr, my_ast_int2expr) -base_expr.setParseAction(my_var_parser) - -txt = ''' -main: - STMFD SP!, {R4, R5, LR} - MOV R0, mystr & 0xffff - ORR R0, R0, mystr & 0xffff0000 - MOV R4, R0 - MOV R1, mystrend & 0xffff - ORR R1, R1, mystrend & 0xffff0000 -xxx: - LDRB R2, [PC, key-$] -loop: - LDRB R3, [R0] - EOR R3, R3, R2 - STRB R3, [R0], 1 - CMP R0, R1 - BNE loop -end: - MOV R0, R4 - LDMFD SP!, {R4, R5, PC} -key: -.byte 0x11 -mystr: -.string "test string" -mystrend: -.long 0 -''' - -blocs_b, symbol_pool_b = parse_asm.parse_txt(my_mn, "b", txt) -blocs_l, symbol_pool_l = parse_asm.parse_txt(my_mn, "l", txt) - - -# fix shellcode addr -symbol_pool_b.set_offset(symbol_pool_b.getby_name("main"), 0x0) -symbol_pool_l.set_offset(symbol_pool_l.getby_name("main"), 0x0) - -# graph sc#### -g = asmbloc.bloc2graph(blocs_l[0]) -open("graph.txt", "w").write(g) - -s_b = StrPatchwork() -s_l = StrPatchwork() - -print "symbols" -print symbol_pool_l -# dont erase from start to shell code padading -resolved_b, patches_b = asmbloc.asm_resolve_final( - my_mn, blocs_b[0], symbol_pool_b) -resolved_l, patches_l = asmbloc.asm_resolve_final( - my_mn, blocs_l[0], symbol_pool_l) -print patches_b - -for offset, raw in patches_b.items(): - s_b[offset] = raw -for offset, raw in patches_l.items(): - s_l[offset] = raw - -open('demo_arm_b.bin', 'w').write(str(s_b)) -open('demo_arm_l.bin', 'w').write(str(s_l)) diff --git a/example/asm_arm_sc.py b/example/asm_arm_sc.py deleted file mode 100644 index 16bfa181..00000000 --- a/example/asm_arm_sc.py +++ /dev/null @@ -1,63 +0,0 @@ -#! /usr/bin/env python - -from miasm2.core.cpu import parse_ast -from miasm2.arch.arm.arch import mn_arm, base_expr, variable -from miasm2.core.bin_stream import bin_stream -from miasm2.core import parse_asm -from miasm2.expression.expression import * -from elfesteem.strpatchwork import StrPatchwork - -from pdb import pm -from miasm2.core import asmbloc -import struct - -reg_and_id = dict(mn_arm.regs.all_regs_ids_byname) - - -def my_ast_int2expr(a): - return ExprInt32(a) - - -def my_ast_id2expr(t): - return reg_and_id.get(t, ExprId(t, size=32)) - -my_var_parser = parse_ast(my_ast_id2expr, my_ast_int2expr) -base_expr.setParseAction(my_var_parser) - - -st = StrPatchwork() - -blocs, symbol_pool = parse_asm.parse_txt(mn_arm, 'l', ''' -main: - MOV R1, R0 - MOV R2, 0x100 - LDR R3, [PC, mykey1-$] -loop: - ADD R2, R1, R2 - ADD R1, R1, 1 - LDR R3, [PC, mykey2-$] - CMP R1, R3 - BEQ loop - - ADD R0, R1, R2 - BX LR -mykey1: -.long 0x1 -mykey2: -.long 0x2 -''') - -# fix shellcode addr -symbol_pool.set_offset(symbol_pool.getby_name("main"), 0) - -for b in blocs[0]: - print b - -resolved_b, patches = asmbloc.asm_resolve_final( - mn_arm, blocs[0], symbol_pool) -print patches - -for offset, raw in patches.items(): - st[offset] = raw - -open('arm_sc.bin', 'wb').write(str(st)) diff --git a/example/asm_armt.py b/example/asm_armt.py deleted file mode 100644 index 1c810e5b..00000000 --- a/example/asm_armt.py +++ /dev/null @@ -1,88 +0,0 @@ -#! /usr/bin/env python - -from miasm2.core.cpu import parse_ast -from miasm2.arch.arm.arch import mn_armt, base_expr, variable -from miasm2.core import parse_asm -from miasm2.expression.expression import * -from miasm2.core import asmbloc -from elfesteem.strpatchwork import StrPatchwork -from pdb import pm - -my_mn = mn_armt - -reg_and_id = dict(mn_armt.regs.all_regs_ids_byname) - - -def my_ast_int2expr(a): - return ExprInt32(a) - - -def my_ast_id2expr(t): - return reg_and_id.get(t, ExprId(t, size=32)) - -my_var_parser = parse_ast(my_ast_id2expr, my_ast_int2expr) -base_expr.setParseAction(my_var_parser) - -txt = ''' -memcpy: - PUSH {R0-R3, LR} - B test_end -loop: - LDRB R3, [R1] - STRB R3, [R0] - ADDS R0, R0, 1 - ADDS R1, R1, 1 - SUBS R2, R2, 1 -test_end: - CMP R2, 0 - BNE loop - POP {R0-R3, PC} -main: - PUSH {LR} - SUB SP, 0x100 - MOV R0, SP - ADD R1, PC, mystr-$+6 - MOV R0, R0 - EORS R2, R2 - ADDS R2, R2, 0x4 - BL memcpy - ADD SP, 0x100 - POP {PC} - -mystr: -.string "toto" -''' - -blocs_b, symbol_pool_b = parse_asm.parse_txt(my_mn, "b", txt) -blocs_l, symbol_pool_l = parse_asm.parse_txt(my_mn, "l", txt) - -# fix shellcode addr -symbol_pool_b.set_offset(symbol_pool_b.getby_name("main"), 0) -symbol_pool_l.set_offset(symbol_pool_l.getby_name("main"), 0) - -# graph sc#### -g = asmbloc.bloc2graph(blocs_b[0]) -open("graph.txt", "w").write(g) - -s_b = StrPatchwork() -s_l = StrPatchwork() - -print "symbols" -print symbol_pool_b -# dont erase from start to shell code padading -resolved_b, patches_b = asmbloc.asm_resolve_final( - my_mn, blocs_b[0], symbol_pool_b) -resolved__l, patches_l = asmbloc.asm_resolve_final( - my_mn, blocs_l[0], symbol_pool_l) -print patches_b -print patches_l - - - -for offset, raw in patches_b.items(): - s_b[offset] = raw -for offset, raw in patches_l.items(): - s_l[offset] = raw - -open('demo_armt_b.bin', 'wb').write(str(s_b)) -open('demo_armt_l.bin', 'wb').write(str(s_l)) diff --git a/example/asm_box_x86_32.py b/example/asm_box_x86_32.py deleted file mode 100644 index c11e645a..00000000 --- a/example/asm_box_x86_32.py +++ /dev/null @@ -1,66 +0,0 @@ -#! /usr/bin/env python - -from miasm2.core.cpu import parse_ast -from miasm2.arch.x86.arch import mn_x86, base_expr, variable -from miasm2.core.bin_stream import bin_stream -from miasm2.core import parse_asm -from miasm2.expression.expression import * -from elfesteem import * -from pdb import pm -from miasm2.core import asmbloc -import struct - -e = pe_init.PE() -s_text = e.SHList.add_section(name="text", addr=0x1000, rawsize=0x1000) -s_iat = e.SHList.add_section(name="iat", rawsize=0x100) -new_dll = [({"name": "USER32.dll", - "firstthunk": s_iat.addr}, ["MessageBoxA"])] -e.DirImport.add_dlldesc(new_dll) -s_myimp = e.SHList.add_section(name="myimp", rawsize=len(e.DirImport)) -e.DirImport.set_rva(s_myimp.addr) - -reg_and_id = dict(mn_x86.regs.all_regs_ids_byname) - - -def my_ast_int2expr(a): - return ExprInt32(a) - - -def my_ast_id2expr(t): - return reg_and_id.get(t, ExprId(t, size=32)) - -my_var_parser = parse_ast(my_ast_id2expr, my_ast_int2expr) -base_expr.setParseAction(my_var_parser) - -blocs, symbol_pool = parse_asm.parse_txt(mn_x86, 32, ''' -main: - PUSH 0 - PUSH title - PUSH msg - PUSH 0 - CALL DWORD PTR [ MessageBoxA ] - RET - -title: -.string "Hello!" -msg: -.string "World!" -''') - -# fix shellcode addr -symbol_pool.set_offset(symbol_pool.getby_name("main"), e.rva2virt(s_text.addr)) -symbol_pool.set_offset(symbol_pool.getby_name_create("MessageBoxA"), - e.DirImport.get_funcvirt('MessageBoxA')) -e.Opthdr.AddressOfEntryPoint = s_text.addr - -for b in blocs[0]: - print b - -resolved_b, patches = asmbloc.asm_resolve_final( - mn_x86, blocs[0], symbol_pool) -print patches - -for offset, raw in patches.items(): - e.virt[offset] = raw - -open('box_x86_32.bin', 'wb').write(str(e)) diff --git a/example/asm_box_x86_32_enc.py b/example/asm_box_x86_32_enc.py deleted file mode 100644 index b06fa1ea..00000000 --- a/example/asm_box_x86_32_enc.py +++ /dev/null @@ -1,105 +0,0 @@ -#! /usr/bin/env python - -from miasm2.core.cpu import parse_ast -from miasm2.arch.x86.arch import mn_x86, base_expr, variable -from miasm2.core.bin_stream import bin_stream -from miasm2.core import parse_asm -from miasm2.expression.expression import * -from elfesteem import * -from pdb import pm -from miasm2.core import asmbloc -import struct - -e = pe_init.PE() -s_text = e.SHList.add_section(name="text", addr=0x1000, rawsize=0x1000) -s_iat = e.SHList.add_section(name="iat", rawsize=0x100) -new_dll = [({"name": "USER32.dll", - "firstthunk": s_iat.addr}, ["MessageBoxA"])] -e.DirImport.add_dlldesc(new_dll) -s_myimp = e.SHList.add_section(name="myimp", rawsize=len(e.DirImport)) -e.DirImport.set_rva(s_myimp.addr) - -reg_and_id = dict(mn_x86.regs.all_regs_ids_byname) - - -def my_ast_int2expr(a): - return ExprInt32(a) - - -def my_ast_id2expr(t): - return reg_and_id.get(t, ExprId(t, size=32)) - -my_var_parser = parse_ast(my_ast_id2expr, my_ast_int2expr) -base_expr.setParseAction(my_var_parser) - -blocs, symbol_pool = parse_asm.parse_txt(mn_x86, 32, ''' -main: - CALL cipher_code - CALL msgbox_encrypted_start - CALL cipher_code - RET - -cipher_code: - PUSH EBP - MOV EBP, ESP - - LEA ESI, DWORD PTR [msgbox_encrypted_start] - LEA EDI, DWORD PTR [msgbox_encrypted_stop] - -loop: - XOR BYTE PTR [ESI], 0x42 - INC ESI - CMP ESI, EDI - JBE loop - - MOV ESP, EBP - POP EBP - RET - -msgbox_encrypted_start: - PUSH 0 - PUSH title - PUSH msg - PUSH 0 - CALL DWORD PTR [ MessageBoxA ] - RET -.dontsplit -msgbox_encrypted_stop: -.long 0 - -title: -.string "Hello!" -msg: -.string "World!" -''') - - -# fix shellcode addr -symbol_pool.set_offset(symbol_pool.getby_name("main"), e.rva2virt(s_text.addr)) -symbol_pool.set_offset(symbol_pool.getby_name_create( - "MessageBoxA"), e.DirImport.get_funcvirt('MessageBoxA')) -e.Opthdr.AddressOfEntryPoint = s_text.addr - -for b in blocs[0]: - print b - -print "symbols" -print symbol_pool - -resolved_b, patches = asmbloc.asm_resolve_final( - mn_x86, blocs[0], symbol_pool) -print patches - -ad_start = symbol_pool.getby_name_create("msgbox_encrypted_start").offset -ad_stop = symbol_pool.getby_name_create("msgbox_encrypted_stop").offset - -# cipher code -new_patches = dict(patches) -for ad, val in patches.items(): - if ad_start <= ad < ad_stop: - new_patches[ad] = "".join([chr(ord(x) ^ 0x42) for x in val]) - -for offset, raw in new_patches.items(): - e.virt[offset] = raw - -open('box_x86_32_enc.bin', 'wb').write(str(e)) diff --git a/example/asm_box_x86_32_mod.py b/example/asm_box_x86_32_mod.py deleted file mode 100644 index 5f90fe9c..00000000 --- a/example/asm_box_x86_32_mod.py +++ /dev/null @@ -1,89 +0,0 @@ -#! /usr/bin/env python - -from miasm2.core.cpu import parse_ast -from miasm2.arch.x86.arch import mn_x86, base_expr, variable -from miasm2.core.bin_stream import bin_stream -from miasm2.core import parse_asm -from miasm2.expression.expression import * -from elfesteem import * -from pdb import pm -from miasm2.core import asmbloc -import struct - -e = pe_init.PE() -s_text = e.SHList.add_section(name="text", addr=0x1000, rawsize=0x1000) -s_iat = e.SHList.add_section(name="iat", rawsize=0x100) -new_dll = [({"name": "USER32.dll", - "firstthunk": s_iat.addr}, ["MessageBoxA"])] -e.DirImport.add_dlldesc(new_dll) -s_myimp = e.SHList.add_section(name="myimp", rawsize=len(e.DirImport)) -e.DirImport.set_rva(s_myimp.addr) - -reg_and_id = dict(mn_x86.regs.all_regs_ids_byname) - - -def my_ast_int2expr(a): - return ExprInt32(a) - - -def my_ast_id2expr(t): - return reg_and_id.get(t, ExprId(t, size=32)) - -my_var_parser = parse_ast(my_ast_id2expr, my_ast_int2expr) -base_expr.setParseAction(my_var_parser) - -blocs, symbol_pool = parse_asm.parse_txt(mn_x86, 32, ''' -main: - CALL test_automod - CALL test_automod - RET - -test_automod: - PUSH EBP - MOV EBP, ESP - -loop: - MOV EAX, 0 - CMP EAX, 0 - JMP mod_addr -mod_addr: - JNZ end - - PUSH 0 - PUSH title - PUSH msg - PUSH 0 - CALL DWORD PTR [ MessageBoxA ] - - ; automodif code - MOV BYTE PTR [mod_addr], 0xEB - JMP loop -end: - MOV BYTE PTR [mod_addr], 0x75 - MOV ESP, EBP - POP EBP - RET - -title: -.string "Hello!" -msg: -.string "World!" -''') - -# fix shellcode addr -symbol_pool.set_offset(symbol_pool.getby_name("main"), e.rva2virt(s_text.addr)) -symbol_pool.set_offset(symbol_pool.getby_name_create("MessageBoxA"), - e.DirImport.get_funcvirt('MessageBoxA')) -e.Opthdr.AddressOfEntryPoint = s_text.addr - -for b in blocs[0]: - print b - -resolved_b, patches = asmbloc.asm_resolve_final( - mn_x86, blocs[0], symbol_pool) -print patches - -for offset, raw in patches.items(): - e.virt[offset] = raw - -open('box_x86_32_mod.bin', 'wb').write(str(e)) diff --git a/example/asm_box_x86_32_mod_self.py b/example/asm_box_x86_32_mod_self.py deleted file mode 100644 index 0efe4811..00000000 --- a/example/asm_box_x86_32_mod_self.py +++ /dev/null @@ -1,74 +0,0 @@ -#! /usr/bin/env python - -from miasm2.core.cpu import parse_ast -from miasm2.arch.x86.arch import mn_x86, base_expr, variable -from miasm2.core.bin_stream import bin_stream -from miasm2.core import parse_asm -from miasm2.expression.expression import * -from elfesteem import * -from pdb import pm -from miasm2.core import asmbloc -import struct - -e = pe_init.PE() -s_text = e.SHList.add_section(name="text", addr=0x1000, rawsize=0x1000) -s_iat = e.SHList.add_section(name="iat", rawsize=0x100) -new_dll = [({"name": "USER32.dll", - "firstthunk": s_iat.addr}, ["MessageBoxA"])] -e.DirImport.add_dlldesc(new_dll) -s_myimp = e.SHList.add_section(name="myimp", rawsize=len(e.DirImport)) -e.DirImport.set_rva(s_myimp.addr) - -reg_and_id = dict(mn_x86.regs.all_regs_ids_byname) - - -def my_ast_int2expr(a): - return ExprInt32(a) - - -def my_ast_id2expr(t): - return reg_and_id.get(t, ExprId(t, size=32)) - -my_var_parser = parse_ast(my_ast_id2expr, my_ast_int2expr) -base_expr.setParseAction(my_var_parser) - -blocs, symbol_pool = parse_asm.parse_txt(mn_x86, 32, ''' -main: - PUSH EBP - MOV EBP, ESP - MOV BYTE PTR [myint], 0x90 -myint: - INT 0x3 - - PUSH 0 - PUSH title - PUSH msg - PUSH 0 - CALL DWORD PTR [ MessageBoxA ] - MOV ESP, EBP - POP EBP - RET - -title: -.string "Hello!" -msg: -.string "World!" -''') - -# fix shellcode addr -symbol_pool.set_offset(symbol_pool.getby_name("main"), e.rva2virt(s_text.addr)) -symbol_pool.set_offset(symbol_pool.getby_name_create("MessageBoxA"), - e.DirImport.get_funcvirt('MessageBoxA')) -e.Opthdr.AddressOfEntryPoint = s_text.addr - -for b in blocs[0]: - print b - -resolved_b, patches = asmbloc.asm_resolve_final( - mn_x86, blocs[0], symbol_pool) -print patches - -for offset, raw in patches.items(): - e.virt[offset] = raw - -open('box_x86_32_mod_self.bin', 'wb').write(str(e)) diff --git a/example/asm_box_x86_32_repmod.py b/example/asm_box_x86_32_repmod.py deleted file mode 100644 index c46fedd5..00000000 --- a/example/asm_box_x86_32_repmod.py +++ /dev/null @@ -1,103 +0,0 @@ -#! /usr/bin/env python - -# test instruction caching - -from miasm2.core.cpu import parse_ast -from miasm2.arch.x86.arch import mn_x86, base_expr, variable -from miasm2.core.bin_stream import bin_stream -from miasm2.core import parse_asm -from miasm2.expression.expression import * -from elfesteem import * -from pdb import pm -from miasm2.core import asmbloc -import struct - -e = pe_init.PE() -s_text = e.SHList.add_section(name="text", addr=0x1000, rawsize=0x1000) -s_iat = e.SHList.add_section(name="iat", rawsize=0x100) -new_dll = [({"name": "USER32.dll", - "firstthunk": s_iat.addr}, ["MessageBoxA"])] -e.DirImport.add_dlldesc(new_dll) -s_myimp = e.SHList.add_section(name="myimp", rawsize=len(e.DirImport)) -e.DirImport.set_rva(s_myimp.addr) - -reg_and_id = dict(mn_x86.regs.all_regs_ids_byname) - - -def my_ast_int2expr(a): - return ExprInt32(a) - - -def my_ast_id2expr(t): - return reg_and_id.get(t, ExprId(t, size=32)) - -my_var_parser = parse_ast(my_ast_id2expr, my_ast_int2expr) -base_expr.setParseAction(my_var_parser) - - -blocs, symbol_pool = parse_asm.parse_txt(mn_x86, 32, ''' -main: - CALL test_automod - RET - -lbl_good: - NOP - NOP - NOP - NOP - NOP - NOP - NOP - NOP - NOP - -test_automod: - PUSH EBP - MOV EBP, ESP - - LEA EDI, DWORD PTR [lbl_mod] - LEA ESI, DWORD PTR [lbl_good] - - MOV ECX, 0x8 - REPE MOVSB -lbl_mod: - XOR EAX, EAX - MOV DWORD PTR [EAX], 0xDEADC0DE - - NOP - NOP - NOP - - PUSH 0 - PUSH title - PUSH msg - PUSH 0 - CALL DWORD PTR [ MessageBoxA ] - - MOV ESP, EBP - POP EBP - RET - -title: -.string "Hello!" -msg: -.string "World!" -''') - -# fix shellcode addr -symbol_pool.set_offset(symbol_pool.getby_name("main"), e.rva2virt(s_text.addr)) -symbol_pool.set_offset(symbol_pool.getby_name_create("MessageBoxA"), - e.DirImport.get_funcvirt('MessageBoxA')) -e.Opthdr.AddressOfEntryPoint = s_text.addr - -for b in blocs[0]: - print b - -resolved_b, patches = asmbloc.asm_resolve_final( - mn_x86, blocs[0], symbol_pool) -print patches - -for offset, raw in patches.items(): - e.virt[offset] = raw - -open('box_x86_32_repmod.bin', 'wb').write(str(e)) diff --git a/example/asm_box_x86_64.py b/example/asm_box_x86_64.py deleted file mode 100644 index d48a1729..00000000 --- a/example/asm_box_x86_64.py +++ /dev/null @@ -1,68 +0,0 @@ -#! /usr/bin/env python - -from miasm2.core.cpu import parse_ast -from miasm2.arch.x86.arch import mn_x86, base_expr, variable -from miasm2.core.bin_stream import bin_stream -from miasm2.core import parse_asm -from miasm2.expression.expression import * -from elfesteem import * -from pdb import pm -from miasm2.core import asmbloc -import struct - -e = pe_init.PE(wsize=64) -s_text = e.SHList.add_section(name="text", addr=0x1000, rawsize=0x1000) -s_iat = e.SHList.add_section(name="iat", rawsize=0x100) -new_dll = [({"name": "USER32.dll", - "firstthunk": s_iat.addr}, ["MessageBoxA"])] -e.DirImport.add_dlldesc(new_dll) -s_myimp = e.SHList.add_section(name="myimp", rawsize=len(e.DirImport)) -e.DirImport.set_rva(s_myimp.addr) - -reg_and_id = dict(mn_x86.regs.all_regs_ids_byname) - - -def my_ast_int2expr(a): - return ExprInt64(a) - - -def my_ast_id2expr(t): - return reg_and_id.get(t, ExprId(t, size=64)) - -my_var_parser = parse_ast(my_ast_id2expr, my_ast_int2expr) -base_expr.setParseAction(my_var_parser) - -blocs, symbol_pool = parse_asm.parse_txt(mn_x86, 64, ''' -main: - MOV R9, 0x0 - MOV R8, title - MOV RDX, msg - MOV RCX, 0x0 - MOV RAX, QWORD PTR [ MessageBoxA ] - CALL RAX - RET - -title: -.string "Hello!" -msg: -.string "World!" -''') - -# fix shellcode addr -symbol_pool.set_offset(symbol_pool.getby_name("main"), e.rva2virt(s_text.addr)) -symbol_pool.set_offset(symbol_pool.getby_name_create("MessageBoxA"), - e.DirImport.get_funcvirt('MessageBoxA')) -e.Opthdr.AddressOfEntryPoint = s_text.addr - -for b in blocs[0]: - print b - -resolved_b, patches = asmbloc.asm_resolve_final( - mn_x86, blocs[0], symbol_pool, - max_offset=0xFFFFFFFFFFFFFFFF) -print patches - -for offset, raw in patches.items(): - e.virt[offset] = raw - -open('box_x86_64.bin', 'wb').write(str(e)) diff --git a/example/asm_mips32.py b/example/asm_mips32.py deleted file mode 100644 index aec57886..00000000 --- a/example/asm_mips32.py +++ /dev/null @@ -1,69 +0,0 @@ -#! /usr/bin/env python - -from miasm2.core.cpu import parse_ast -from miasm2.arch.mips32.arch import mn_mips32, base_expr, variable -from miasm2.core.bin_stream import bin_stream -from miasm2.core import parse_asm -from miasm2.expression.expression import * -from elfesteem.strpatchwork import StrPatchwork - -from pdb import pm -from miasm2.core import asmbloc -import struct - -reg_and_id = dict(mn_mips32.regs.all_regs_ids_byname) - - -def my_ast_int2expr(a): - return ExprInt32(a) - - -def my_ast_id2expr(t): - return reg_and_id.get(t, ExprId(t, size=32)) - -my_var_parser = parse_ast(my_ast_id2expr, my_ast_int2expr) -base_expr.setParseAction(my_var_parser) - - -st_l = StrPatchwork() -st_b = StrPatchwork() - -txt = ''' -main: - ADDIU A0, ZERO, 0x10 - ADDIU A1, ZERO, 0 -loop: - ADDIU A1, A1, 0x1 - BNE A0, ZERO, loop - ADDIU A0, A0, 0xFFFFFFFF - - ADDIU A2, A2, 0x1 - MOVN A1, ZERO, ZERO - JR RA - ADDIU A2, A2, 0x1 -''' - -blocs_b, symbol_pool_b = parse_asm.parse_txt(mn_mips32, "b", txt) -blocs_l, symbol_pool_l = parse_asm.parse_txt(mn_mips32, "l", txt) - -# fix shellcode addr -symbol_pool_b.set_offset(symbol_pool_b.getby_name("main"), 0) -symbol_pool_l.set_offset(symbol_pool_l.getby_name("main"), 0) - -for b in blocs_b[0]: - print b - -resolved_b, patches_b = asmbloc.asm_resolve_final( - mn_mips32, blocs_b[0], symbol_pool_b) -resolved_l, patches_l = asmbloc.asm_resolve_final( - mn_mips32, blocs_l[0], symbol_pool_l) -print patches_b -print patches_l - -for offset, raw in patches_b.items(): - st_b[offset] = raw -for offset, raw in patches_l.items(): - st_l[offset] = raw - -open('mips32_sc_b.bin', 'wb').write(str(st_l)) -open('mips32_sc_l.bin', 'wb').write(str(st_l)) diff --git a/example/asm_msp430_sc.py b/example/asm_msp430_sc.py deleted file mode 100644 index c0bae929..00000000 --- a/example/asm_msp430_sc.py +++ /dev/null @@ -1,54 +0,0 @@ -#! /usr/bin/env python - -from miasm2.core.cpu import parse_ast -from miasm2.arch.msp430.arch import mn_msp430, base_expr, variable -from miasm2.core.bin_stream import bin_stream -from miasm2.core import parse_asm -from miasm2.expression.expression import * -from elfesteem.strpatchwork import StrPatchwork - -from pdb import pm -from miasm2.core import asmbloc -import struct - -reg_and_id = dict(mn_msp430.regs.all_regs_ids_byname) - - -def my_ast_int2expr(a): - return ExprInt32(a) - - -def my_ast_id2expr(t): - return reg_and_id.get(t, ExprId(t, size=32)) - -my_var_parser = parse_ast(my_ast_id2expr, my_ast_int2expr) -base_expr.setParseAction(my_var_parser) - - -st = StrPatchwork() - -blocs, symbol_pool = parse_asm.parse_txt(mn_msp430, None, ''' -main: - mov.w 0x10, R10 - mov.w 0x0, R11 -loop: - add.w 1, R11 - sub.w 1, R10 - jnz loop - mov.w @SP+, PC -''') - -# fix shellcode addr -symbol_pool.set_offset(symbol_pool.getby_name("main"), 0) - -for b in blocs[0]: - print b - -resolved_b, patches = asmbloc.asm_resolve_final( - mn_msp430, blocs[0], symbol_pool) -print patches - -for offset, raw in patches.items(): - st[offset] = raw - -open('msp430_sc.bin', 'wb').write(str(st)) diff --git a/example/asm_x86.py b/example/asm_x86.py deleted file mode 100644 index 77fc61dc..00000000 --- a/example/asm_x86.py +++ /dev/null @@ -1,88 +0,0 @@ -#! /usr/bin/env python - -from miasm2.core.cpu import parse_ast -from miasm2.arch.x86.arch import mn_x86, base_expr, variable -from miasm2.core import parse_asm -from miasm2.expression.expression import * -from miasm2.core import asmbloc -from elfesteem.strpatchwork import StrPatchwork - -reg_and_id = dict(mn_x86.regs.all_regs_ids_byname) - - -def my_ast_int2expr(a): - return ExprInt32(a) - - -def my_ast_id2expr(t): - return reg_and_id.get(t, ExprId(t, size=32)) - -my_var_parser = parse_ast(my_ast_id2expr, my_ast_int2expr) -base_expr.setParseAction(my_var_parser) - -blocs, symbol_pool = parse_asm.parse_txt(mn_x86, 32, ''' -main: - PUSH EBP - MOV EBP, ESP - SUB ESP, 0x100 - MOV EAX, 0x1337 - ; test ptr manip - LEA ESI, DWORD PTR [mystr^toto] - CALL toto -mystr: -.string "test string" - toto: - POP EDI - - PUSH EDI - ; test scasb - XOR EAX, EAX - XOR ECX, ECX - DEC ECX - REPNE SCASB - NOT ECX - DEC ECX - - ; test movsb - POP ESI - LEA EDI, DWORD PTR [EBP-0x100] - REPE MOVSB - - ; test float - PUSH 0 - FLD1 - FLD1 - FADD ST, ST(1) - FIST DWORD PTR [ESP] - POP EAX - - ; test cond mnemo - NOP - NOP - CMOVZ EAX, EBX - ; test shr - NOP - SHR EAX, 1 - NOP - NOP - SHR EAX, CL - NOP - - MOV ESP, EBP - POP EBP - RET - - -''') - -# fix shellcode addr -symbol_pool.set_offset(symbol_pool.getby_name("main"), 0x0) -s = StrPatchwork() -resolved_b, patches = asmbloc.asm_resolve_final( - mn_x86, blocs[0], symbol_pool) -for offset, raw in patches.items(): - s[offset] = raw - -print patches - -open('demo_x86_32.bin', 'wb').write(str(s)) diff --git a/example/box.exe b/example/box.exe deleted file mode 100755 index 1c11bcda..00000000 --- a/example/box.exe +++ /dev/null Binary files differdiff --git a/example/disasm_03.py b/example/disasm/file.py index 1141dc55..5bae0e89 100644 --- a/example/disasm_03.py +++ b/example/disasm/file.py @@ -5,15 +5,15 @@ from miasm2.analysis.binary import Container if len(sys.argv) != 3: print 'Example:' - print "%s box_upx.exe 0x410f90" % sys.argv[0] + print "%s samples/box_upx.exe 0x410f90" % sys.argv[0] sys.exit(0) -ad = int(sys.argv[2], 16) +addr = int(sys.argv[2], 16) cont = Container.from_stream(open(sys.argv[1])) mdis = dis_x86_32(cont.bin_stream) -# inform the engine not to disasm nul instructions +# Inform the engine to avoid disassembling null instructions mdis.dont_dis_nulstart_bloc = True -blocs = mdis.dis_multibloc(ad) +blocs = mdis.dis_multibloc(addr) -g = bloc2graph(blocs) -open('graph.txt', 'w').write(g) +graph = bloc2graph(blocs) +open('graph.txt', 'w').write(graph) diff --git a/example/test_dis.py b/example/disasm/full.py index 722e99c9..f7ca6780 100644 --- a/example/test_dis.py +++ b/example/disasm/full.py @@ -1,14 +1,13 @@ -import sys import os -import time +import logging +from argparse import ArgumentParser +from pdb import pm from miasm2.analysis.binary import Container -from miasm2.core.asmbloc import * -from optparse import OptionParser +from miasm2.core.asmbloc import log_asmbloc, asm_label, bloc2graph from miasm2.expression.expression import ExprId from miasm2.core.interval import interval from miasm2.analysis.machine import Machine -from pdb import pm log = logging.getLogger("dis") console_handler = logging.StreamHandler() @@ -21,80 +20,49 @@ if filename and os.path.isfile(filename): execfile(filename) -parser = OptionParser(usage="usage: %prog [options] file address") -parser.add_option('-m', "--architecture", dest="machine", metavar="MACHINE", - help="architecture: " + ",".join(Machine.available_machine())) -parser.add_option('-f', "--followcall", dest="followcall", action="store_true", - default=False, - help="follow call") - -parser.add_option('-b', "--blocwatchdog", dest="bw", - default=None, - help="address to disasemble") - -parser.add_option('-n', "--funcsnumwatchdog", dest="funcswd", - default=None, - help="max func to disasm") - -parser.add_option( - '-r', "--recurfunctions", dest="recurfunctions", action="store_true", - default=False, - help="disasm found functions") - -parser.add_option('-v', "--verbose", dest="verbose", action="store_true", - default=False, - help="verbose") - -parser.add_option('-g', "--gen_ir", dest="gen_ir", action="store_true", - default=False, - help="gen intermediate representation") - -parser.add_option('-z', "--dis_nulstart_bloc", dest="dis_nulstart_bloc", - action="store_true", default=False, - help="dont_dis_nulstart_bloc") -parser.add_option('-l', "--dontdis_retcall", dest="dontdis_retcall", - action="store_true", default=False, - help="only disasm call dst") - -parser.add_option('-s', "--simplify", dest="simplify", action="store_true", - default=False, - help="for test purpose") - -parser.add_option('-o', "--shiftoffset", dest="shiftoffset", - default=None, - help="shift input str by offset") - -parser.add_option( - '-a', "--trydisasmall", dest="trydisasmall", action="store_true", - default=False, - help="try disasm all binary") - -parser.add_option('-i', "--image", dest="image", action="store_true", - default=False, - help="display image representation of disasm") - -(options, args) = parser.parse_args(sys.argv[1:]) -if not args: - parser.print_help() - sys.exit(0) -fname = args[0] - -if options.verbose: +parser = ArgumentParser("Disassemble a binary") +parser.add_argument('architecture', help="architecture: " + \ + ",".join(Machine.available_machine())) +parser.add_argument('filename', help="File to disassemble") +parser.add_argument('address', help="Starting address for disassembly engine", + nargs="+") +parser.add_argument('-f', "--followcall", action="store_true", + help="Follow call instructions") +parser.add_argument('-b', "--blockwatchdog", default=None, type=int, + help="Maximum number of basic block to disassemble") +parser.add_argument('-n', "--funcswatchdog", default=None, type=int, + help="Maximum number of function to disassemble") +parser.add_argument('-r', "--recurfunctions", action="store_true", + help="Disassemble founded functions") +parser.add_argument('-v', "--verbose", action="store_true", help="Verbose mode") +parser.add_argument('-g', "--gen_ir", action="store_true", + help="Compute the intermediate representation") +parser.add_argument('-z', "--dis-nulstart-block", action="store_true", + help="Do not disassemble NULL starting block") +parser.add_argument('-l', "--dontdis-retcall", action="store_true", + help="If set, disassemble only call destinations") +parser.add_argument('-s', "--simplify", action="store_true", + help="Use the liveness analysis pass") +parser.add_argument('-o', "--shiftoffset", default=None, type=int, + help="Shift input binary by an offset") +parser.add_argument('-a', "--try-disasm-all", action="store_true", + help="Try to disassemble the whole binary") +parser.add_argument('-i', "--image", action="store_true", + help="Display image representation of disasm") + +args = parser.parse_args() + +if args.verbose: log_asmbloc.setLevel(logging.DEBUG) log.info("import machine...") -machine = Machine(options.machine) +machine = Machine(args.architecture) mn, dis_engine, ira = machine.mn, machine.dis_engine, machine.ira log.info('ok') -if options.bw != None: - options.bw = int(options.bw) -if options.funcswd != None: - options.funcswd = int(options.funcswd) - log.info('Load binary') -with open(fname) as fdesc: - cont = Container.from_stream(fdesc, addr=options.shiftoffset) +with open(args.filename) as fdesc: + cont = Container.from_stream(fdesc, addr=args.shiftoffset) default_addr = cont.entry_point bs = cont.bin_stream @@ -103,12 +71,12 @@ e = cont.executable log.info('ok') mdis = dis_engine(bs) # configure disasm engine -mdis.dontdis_retcall = options.dontdis_retcall -mdis.blocs_wd = options.bw -mdis.dont_dis_nulstart_bloc = not options.dis_nulstart_bloc +mdis.dontdis_retcall = args.dontdis_retcall +mdis.blocs_wd = args.blockwatchdog +mdis.dont_dis_nulstart_bloc = not args.dis_nulstart_block todo = [] -addrs = [int(a, 16) for a in args[1:]] +addrs = [int(a, 16) for a in args.address] if len(addrs) == 0 and default_addr is not None: addrs.append(default_addr) @@ -140,9 +108,9 @@ while not finish and todo: for l in b.lines: done_interval += interval([(l.offset, l.offset + l.l)]) - if options.funcswd is not None: - options.funcswd -= 1 - if options.recurfunctions: + if args.funcswatchdog is not None: + args.funcswatchdog -= 1 + if args.recurfunctions: for b in ab: i = b.get_subcall_instr() if not i: @@ -152,10 +120,10 @@ while not finish and todo: continue todo.append((mdis, i, d.name.offset)) - if options.funcswd is not None and options.funcswd <= 0: + if args.funcswatchdog is not None and args.funcswatchdog <= 0: finish = True - if options.trydisasmall: + if args.try_disasm_all: for a, b in done_interval.intervals: if b in done: continue @@ -180,7 +148,7 @@ all_lines = [] total_l = 0 print done_interval -if options.image: +if args.image: log.info('build img') done_interval.show() @@ -194,7 +162,7 @@ log.info('total lines %s' % total_l) # Bonus, generate IR graph -if options.gen_ir: +if args.gen_ir: log.info("generating IR") ir_arch = ira(mdis.symbol_pool) @@ -208,7 +176,7 @@ if options.gen_ir: ir_arch.gen_graph() - if options.simplify: + if args.simplify: ir_arch.dead_simp() out = ir_arch.graph() diff --git a/example/disasm/function.py b/example/disasm/function.py new file mode 100644 index 00000000..0d443c26 --- /dev/null +++ b/example/disasm/function.py @@ -0,0 +1,18 @@ +from miasm2.arch.x86.disasm import dis_x86_32 +from miasm2.core.asmbloc import bloc2graph + +# MOV EAX, 0x1337BEEF +# MOV ECX, 0x4 +# loop: +# ROL EAX, 0x8 +# LOOP loop +# RET +shellcode = '\xb8\xef\xbe7\x13\xb9\x04\x00\x00\x00\xc1\xc0\x08\xe2\xfb\xc3' +mdis = dis_x86_32(shellcode) +blocs = mdis.dis_multibloc(0) + +for bloc in blocs: + print bloc + +graph = bloc2graph(blocs) +open('graph.txt', 'w').write(graph) diff --git a/example/disasm_01.py b/example/disasm/single_instr.py index bc6a2fd6..0e29dcee 100644 --- a/example/disasm_01.py +++ b/example/disasm/single_instr.py @@ -1,5 +1,5 @@ from miasm2.arch.x86.arch import mn_x86 -from miasm2.arch.x86.regs import * +from miasm2.arch.x86.regs import EDX l = mn_x86.fromstring('MOV EAX, EBX', 32) print "instruction:", l diff --git a/example/disasm_02.py b/example/disasm_02.py deleted file mode 100644 index 5bfd77de..00000000 --- a/example/disasm_02.py +++ /dev/null @@ -1,13 +0,0 @@ -from miasm2.arch.x86.disasm import dis_x86_32 -from miasm2.core.asmbloc import bloc2graph - - -s = '\xb8\xef\xbe7\x13\xb9\x04\x00\x00\x00\xc1\xc0\x08\xe2\xfb\xc3' -mdis = dis_x86_32(s) -blocs = mdis.dis_multibloc(0) - -for b in blocs: - print b - -g = bloc2graph(blocs) -open('graph.txt', 'w').write(g) diff --git a/example/expression/expr_random.py b/example/expression/expr_random.py index 1d399091..66c09f2e 100644 --- a/example/expression/expr_random.py +++ b/example/expression/expr_random.py @@ -1,10 +1,14 @@ import string +import random from miasm2.expression.expression_helper import ExprRandom print "Simple expression generator\n" depth = 8 +seed = 0 +random.seed(seed) + print "- An ID:" print ExprRandom.identifier() print "- A number:" diff --git a/example/expression/expr_translate.py b/example/expression/expr_translate.py index aacb30c0..e1505dae 100644 --- a/example/expression/expr_translate.py +++ b/example/expression/expr_translate.py @@ -4,6 +4,7 @@ from miasm2.expression.expression import * from miasm2.expression.expression_helper import ExprRandom from miasm2.ir.translators import Translator +random.seed(0) class ExprRandom_OpSubRange(ExprRandom): operations_by_args_number = {1: ["-"], diff --git a/example/test_ida.py b/example/ida/graph_ir.py index 5f9aead6..5f9aead6 100644 --- a/example/test_ida.py +++ b/example/ida/graph_ir.py diff --git a/example/test_jit_arm.py b/example/jitter/arm.py index 12878a30..5342ee6d 100644 --- a/example/test_jit_arm.py +++ b/example/jitter/arm.py @@ -1,23 +1,21 @@ #!/usr/bin/env python #-*- coding:utf-8 -*- -from miasm2.analysis import debugging, gdbserver - -from miasm2.analysis.sandbox import Sandbox_Linux_arml -from miasm2.analysis.machine import Machine import logging - from pdb import pm -parser = Sandbox_Linux_arml.parser(description="""Sandbox an elf binary with arm engine -(ex: test_jit_arm.py example/md5_arm -a A684)""") -parser.add_argument("filename", help="PE Filename") -parser.add_argument('-v', "--verbose", - help="verbose mode", action="store_true") +from miasm2.analysis.sandbox import Sandbox_Linux_arml +# Get arguments +parser = Sandbox_Linux_arml.parser(description="""Sandbox an elf binary with arm + engine (ex: jit_arm.py samples/md5_arm -a A684)""") +parser.add_argument("filename", help="ELF Filename") +parser.add_argument('-v', "--verbose", help="verbose mode", action="store_true") options = parser.parse_args() -sb = Sandbox_Linux_arml(options.filename, options, globals()) +# Prepare the sandbox +sb = Sandbox_Linux_arml(options.filename, options, globals()) +# Handle 'verbose' option if options.verbose is True: logging.basicConfig(level=logging.INFO) else: @@ -27,7 +25,7 @@ if options.verbose is True: sb.jitter.vm.dump_memory_page_pool() if options.address is None: - raise ValueError('invalid address') + raise ValueError('Invalid address') +# Run the code sb.run() - diff --git a/example/test_jit_arm_sc.py b/example/jitter/arm_sc.py index 0ec2a5ee..80714641 100644 --- a/example/test_jit_arm_sc.py +++ b/example/jitter/arm_sc.py @@ -11,7 +11,7 @@ import logging from pdb import pm parser = Sandbox_Linux_arml_str.parser(description="""Sandbox an elf binary with arm engine -(ex: test_jit_arm_sc.py example/demo_arm_l.bin)""") +(ex: jit_arm_sc.py example/demo_arm_l.bin)""") parser.add_argument("filename", help="string Filename") parser.add_argument("endianess", help="endianness [b/l]") parser.add_argument('-v', "--verbose", diff --git a/example/test_jit_mips32.py b/example/jitter/mips32.py index d027ec50..e41096cc 100644 --- a/example/test_jit_mips32.py +++ b/example/jitter/mips32.py @@ -9,7 +9,7 @@ from pdb import pm parser = ArgumentParser( description="""Sandbox raw binary with mips32 engine -(ex: test_jit_mips32.py example/mips32_sc_l.bin 0)""") +(ex: jit_mips32.py example/mips32_sc_l.bin 0)""") parser.add_argument("-r", "--log-regs", help="Log registers value for each instruction", action="store_true") diff --git a/example/test_jit_msp430.py b/example/jitter/msp430.py index 5aa1f340..d752ef8c 100644 --- a/example/test_jit_msp430.py +++ b/example/jitter/msp430.py @@ -7,7 +7,7 @@ from miasm2.analysis.machine import Machine parser = ArgumentParser( description="""Sandbox raw binary with msp430 engine -(ex: test_jit_msp430.py example/msp430_sc.bin 0)""") +(ex: jit_msp430.py example/msp430_sc.bin 0)""") parser.add_argument("-r", "--log-regs", help="Log registers value for each instruction", action="store_true") diff --git a/example/sandbox_pe_x86_32.py b/example/jitter/sandbox_pe_x86_32.py index 738e0778..738e0778 100644 --- a/example/sandbox_pe_x86_32.py +++ b/example/jitter/sandbox_pe_x86_32.py diff --git a/example/unpack_upx.py b/example/jitter/unpack_upx.py index 313f75a2..313f75a2 100644 --- a/example/unpack_upx.py +++ b/example/jitter/unpack_upx.py diff --git a/example/test_jit_x86_32.py b/example/jitter/x86_32.py index 8ba39bb3..1b2aa012 100644 --- a/example/test_jit_x86_32.py +++ b/example/jitter/x86_32.py @@ -1,8 +1,6 @@ -import sys import os from argparse import ArgumentParser -from miasm2.jitter.jitload import bin_stream_vm -from miasm2.jitter.csts import * +from miasm2.jitter.csts import PAGE_READ, PAGE_WRITE from miasm2.analysis.machine import Machine from pdb import pm diff --git a/example/samples/arm_sc.S b/example/samples/arm_sc.S new file mode 100644 index 00000000..e9a0787f --- /dev/null +++ b/example/samples/arm_sc.S @@ -0,0 +1,17 @@ +main: + MOV R1, R0 + MOV R2, 0x100 + LDR R3, [PC, mykey1-$] +loop: + ADD R2, R1, R2 + ADD R1, R1, 1 + LDR R3, [PC, mykey2-$] + CMP R1, R3 + BEQ loop + + ADD R0, R1, R2 + BX LR +mykey1: +.long 0x1 +mykey2: +.long 0x2 diff --git a/example/samples/arm_simple.S b/example/samples/arm_simple.S new file mode 100644 index 00000000..f6dcf81e --- /dev/null +++ b/example/samples/arm_simple.S @@ -0,0 +1,24 @@ +main: + STMFD SP!, {R4, R5, LR} + MOV R0, mystr & 0xffff + ORR R0, R0, mystr & 0xffff0000 + MOV R4, R0 + MOV R1, mystrend & 0xffff + ORR R1, R1, mystrend & 0xffff0000 +xxx: + LDRB R2, [PC, key-$] +loop: + LDRB R3, [R0] + EOR R3, R3, R2 + STRB R3, [R0], 1 + CMP R0, R1 + BNE loop +end: + MOV R0, R4 + LDMFD SP!, {R4, R5, PC} +key: +.byte 0x11 +mystr: +.string "test string" +mystrend: +.long 0 diff --git a/example/samples/armt.S b/example/samples/armt.S new file mode 100644 index 00000000..c50075a6 --- /dev/null +++ b/example/samples/armt.S @@ -0,0 +1,27 @@ +memcpy: + PUSH {R0-R3, LR} + B test_end +loop: + LDRB R3, [R1] + STRB R3, [R0] + ADDS R0, R0, 1 + ADDS R1, R1, 1 + SUBS R2, R2, 1 +test_end: + CMP R2, 0 + BNE loop + POP {R0-R3, PC} +main: + PUSH {LR} + SUB SP, 0x100 + MOV R0, SP + ADD R1, PC, mystr-$+6 + MOV R0, R0 + EORS R2, R2 + ADDS R2, R2, 0x4 + BL memcpy + ADD SP, 0x100 + POP {PC} + +mystr: +.string "toto" diff --git a/example/box_upx.exe b/example/samples/box_upx.exe index d0776ec2..d0776ec2 100755 --- a/example/box_upx.exe +++ b/example/samples/box_upx.exe Binary files differdiff --git a/example/md5_arm b/example/samples/md5_arm index 148e0611..148e0611 100755 --- a/example/md5_arm +++ b/example/samples/md5_arm Binary files differdiff --git a/example/samples/mips32.S b/example/samples/mips32.S new file mode 100644 index 00000000..ae44d52f --- /dev/null +++ b/example/samples/mips32.S @@ -0,0 +1,12 @@ +main: + ADDIU A0, ZERO, 0x10 + ADDIU A1, ZERO, 0 +loop: + ADDIU A1, A1, 0x1 + BNE A0, ZERO, loop + ADDIU A0, A0, 0xFFFFFFFF + + ADDIU A2, A2, 0x1 + MOVN A1, ZERO, ZERO + JR RA + ADDIU A2, A2, 0x1 diff --git a/example/samples/msp430.S b/example/samples/msp430.S new file mode 100644 index 00000000..77f4b448 --- /dev/null +++ b/example/samples/msp430.S @@ -0,0 +1,8 @@ +main: + mov.w 0x10, R10 + mov.w 0x0, R11 +loop: + add.w 1, R11 + sub.w 1, R10 + jnz loop + mov.w @SP+, PC diff --git a/example/expression/sc_connect_back.bin b/example/samples/sc_connect_back.bin index 9e9c80a5..9e9c80a5 100644 --- a/example/expression/sc_connect_back.bin +++ b/example/samples/sc_connect_back.bin Binary files differdiff --git a/example/expression/simple_test.bin b/example/samples/simple_test.bin index 60f4e768..60f4e768 100644 --- a/example/expression/simple_test.bin +++ b/example/samples/simple_test.bin Binary files differdiff --git a/example/expression/simple_test.c b/example/samples/simple_test.c index 8e344f18..8e344f18 100644 --- a/example/expression/simple_test.c +++ b/example/samples/simple_test.c diff --git a/example/samples/x86_32_enc.S b/example/samples/x86_32_enc.S new file mode 100644 index 00000000..92379838 --- /dev/null +++ b/example/samples/x86_32_enc.S @@ -0,0 +1,38 @@ +main: + CALL cipher_code + CALL msgbox_encrypted_start + CALL cipher_code + RET + +cipher_code: + PUSH EBP + MOV EBP, ESP + + LEA ESI, DWORD PTR [msgbox_encrypted_start] + LEA EDI, DWORD PTR [msgbox_encrypted_stop] + +loop: + XOR BYTE PTR [ESI], 0x42 + INC ESI + CMP ESI, EDI + JBE loop + + MOV ESP, EBP + POP EBP + RET + +msgbox_encrypted_start: + PUSH 0 + PUSH title + PUSH msg + PUSH 0 + CALL DWORD PTR [ MessageBoxA ] + RET +.dontsplit +msgbox_encrypted_stop: +.long 0 + +title: +.string "Hello!" +msg: +.string "World!" diff --git a/example/samples/x86_32_manip_ptr.S b/example/samples/x86_32_manip_ptr.S new file mode 100644 index 00000000..43e4ed73 --- /dev/null +++ b/example/samples/x86_32_manip_ptr.S @@ -0,0 +1,50 @@ +main: + PUSH EBP + MOV EBP, ESP + SUB ESP, 0x100 + MOV EAX, 0x1337 + ; test ptr manip + LEA ESI, DWORD PTR [mystr^toto] + CALL toto +mystr: +.string "test string" + toto: + POP EDI + + PUSH EDI + ; test scasb + XOR EAX, EAX + XOR ECX, ECX + DEC ECX + REPNE SCASB + NOT ECX + DEC ECX + + ; test movsb + POP ESI + LEA EDI, DWORD PTR [EBP-0x100] + REPE MOVSB + + ; test float + PUSH 0 + FLD1 + FLD1 + FADD ST, ST(1) + FIST DWORD PTR [ESP] + POP EAX + + ; test cond mnemo + NOP + NOP + CMOVZ EAX, EBX + ; test shr + NOP + SHR EAX, 1 + NOP + NOP + SHR EAX, CL + NOP + + MOV ESP, EBP + POP EBP + RET diff --git a/example/samples/x86_32_mod.S b/example/samples/x86_32_mod.S new file mode 100644 index 00000000..df7792af --- /dev/null +++ b/example/samples/x86_32_mod.S @@ -0,0 +1,35 @@ +main: + CALL test_automod + CALL test_automod + RET + +test_automod: + PUSH EBP + MOV EBP, ESP + +loop: + MOV EAX, 0 + CMP EAX, 0 + JMP mod_addr +mod_addr: + JNZ end + + PUSH 0 + PUSH title + PUSH msg + PUSH 0 + CALL DWORD PTR [ MessageBoxA ] + + ; automodif code + MOV BYTE PTR [mod_addr], 0xEB + JMP loop +end: + MOV BYTE PTR [mod_addr], 0x75 + MOV ESP, EBP + POP EBP + RET + +title: +.string "Hello!" +msg: +.string "World!" diff --git a/example/samples/x86_32_mod_self.S b/example/samples/x86_32_mod_self.S new file mode 100644 index 00000000..398438ec --- /dev/null +++ b/example/samples/x86_32_mod_self.S @@ -0,0 +1,20 @@ +main: + PUSH EBP + MOV EBP, ESP + MOV BYTE PTR [myint], 0x90 +myint: + INT 0x3 + + PUSH 0 + PUSH title + PUSH msg + PUSH 0 + CALL DWORD PTR [ MessageBoxA ] + MOV ESP, EBP + POP EBP + RET + +title: +.string "Hello!" +msg: +.string "World!" diff --git a/example/samples/x86_32_repmod.S b/example/samples/x86_32_repmod.S new file mode 100644 index 00000000..332a876c --- /dev/null +++ b/example/samples/x86_32_repmod.S @@ -0,0 +1,46 @@ +main: + CALL test_automod + RET + +lbl_good: + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + +test_automod: + PUSH EBP + MOV EBP, ESP + + LEA EDI, DWORD PTR [lbl_mod] + LEA ESI, DWORD PTR [lbl_good] + + MOV ECX, 0x8 + REPE MOVSB +lbl_mod: + XOR EAX, EAX + MOV DWORD PTR [EAX], 0xDEADC0DE + + NOP + NOP + NOP + + PUSH 0 + PUSH title + PUSH msg + PUSH 0 + CALL DWORD PTR [ MessageBoxA ] + + MOV ESP, EBP + POP EBP + RET + +title: +.string "Hello!" +msg: +.string "World!" diff --git a/example/x86_32_sc.bin b/example/samples/x86_32_sc.bin index c1931ce0..c1931ce0 100644 --- a/example/x86_32_sc.bin +++ b/example/samples/x86_32_sc.bin diff --git a/example/samples/x86_32_simple.S b/example/samples/x86_32_simple.S new file mode 100644 index 00000000..f38c232f --- /dev/null +++ b/example/samples/x86_32_simple.S @@ -0,0 +1,12 @@ +main: + PUSH 0 + PUSH title + PUSH msg + PUSH 0 + CALL DWORD PTR [ MessageBoxA ] + RET + +title: +.string "Hello!" +msg: +.string "World!" diff --git a/example/samples/x86_64.S b/example/samples/x86_64.S new file mode 100644 index 00000000..d090a01b --- /dev/null +++ b/example/samples/x86_64.S @@ -0,0 +1,13 @@ +main: + MOV R9, 0x0 + MOV R8, title + MOV RDX, msg + MOV RCX, 0x0 + MOV RAX, QWORD PTR [ MessageBoxA ] + CALL RAX + RET + +title: +.string "Hello!" +msg: +.string "World!" diff --git a/example/symbol_exec.py b/example/symbol_exec/single_instr.py index 416909f2..416909f2 100644 --- a/example/symbol_exec.py +++ b/example/symbol_exec/single_instr.py diff --git a/miasm2/analysis/machine.py b/miasm2/analysis/machine.py index 872eccbc..d714dbb9 100644 --- a/miasm2/analysis/machine.py +++ b/miasm2/analysis/machine.py @@ -108,6 +108,7 @@ class Machine(object): self.__gdbserver = gdbserver self.__log_jit = log_jit self.__log_arch = log_arch + self.__base_expr = arch.base_expr @property def dis_engine(self): @@ -137,6 +138,10 @@ class Machine(object): def log_arch(self): return self.__log_arch + @property + def base_expr(self): + return self.__base_expr + @classmethod def available_machine(cls): "Return a list of supported machines" diff --git a/test/test_all.py b/test/test_all.py index 5e43ce3f..5de12bf4 100644 --- a/test/test_all.py +++ b/test/test_all.py @@ -73,129 +73,217 @@ class Example(Test): - @base_dir: example/@base_dir - @tags: TAGS["example"]""" + # Directory containing samples for examples + sample_dir = os.path.join("..", "samples") + example_dir = "" + def __init__(self, *args, **kwargs): + if not self.example_dir: + raise NotImplementedError("ExampleDir should be inherited") super(Example, self).__init__(*args, **kwargs) - self.base_dir = os.path.join("example", self.base_dir) + self.base_dir = os.path.join(self.base_dir, "example", self.example_dir) self.tags.append(TAGS["example"]) + @classmethod + def get_sample(cls, sample_name): + "Return the relative path of @sample_name" + return os.path.join(cls.sample_dir, sample_name) + + ## Assembler -testset += Example(['asm_x86.py'], products=["demo_x86_32.bin"]) -test_arm = Example(["asm_arm.py"], products=["demo_arm_l.bin", "demo_arm_b.bin"]) -test_armt = Example(["asm_armt.py"], products=["demo_armt_l.bin", - "demo_armt_b.bin"]) -test_box = Example(["asm_box_x86_32.py"], products=["box_x86_32.bin"]) -test_box_enc = Example(["asm_box_x86_32_enc.py"], - products=["box_x86_32_enc.bin"]) -test_box_mod = Example(["asm_box_x86_32_mod.py"], - products=["box_x86_32_mod.bin"]) -test_box_mod_self = Example(["asm_box_x86_32_mod_self.py"], - products=["box_x86_32_mod_self.bin"]) -test_box_repmod = Example(["asm_box_x86_32_repmod.py"], - products=["box_x86_32_repmod.bin"]) -test_msp430 = Example(["asm_msp430_sc.py"], products=["msp430_sc.bin"]) -test_mips32 = Example(["asm_mips32.py"], products=["mips32_sc_b.bin", - "mips32_sc_l.bin"]) - -testset += test_arm -testset += test_armt -testset += test_box -testset += test_box_enc -testset += test_box_mod -testset += test_box_mod_self -testset += test_box_repmod +class ExampleAssembler(Example): + """Assembler examples specificities: + - script path begins with "asm/" + """ + example_dir = "asm" + + +testset += ExampleAssembler(["simple.py"]) + +class ExampleShellcode(ExampleAssembler): + """Specificities: + - script: asm/shellcode.py + - @products: graph.txt + 3rd arg + - apply get_sample on each products (!= graph.txt) + - apply get_sample on the 2nd and 3rd arg (source, output) + """ + + def __init__(self, *args, **kwargs): + super(ExampleShellcode, self).__init__(*args, **kwargs) + self.command_line = ["shellcode.py", + self.command_line[0]] + \ + map(Example.get_sample, self.command_line[1:3]) + \ + self.command_line[3:] + self.products = [self.command_line[3], "graph.txt"] + + +testset += ExampleShellcode(['x86_32', 'x86_32_manip_ptr.S', "demo_x86_32.bin"]) + +test_box = {} +test_box_names = ["mod", "mod_self", "repmod", "simple", "enc"] +for source in test_box_names: + sample_base = "x86_32_" + source + args = ["x86_32", sample_base + ".S", sample_base + ".bin", "--PE"] + if source == "enc": + args += ["--encrypt","msgbox_encrypted_start", "msgbox_encrypted_stop"] + test_box[source] = ExampleShellcode(args) + testset += test_box[source] + +test_armb = ExampleShellcode(["armb", "arm_simple.S", "demo_arm_b.bin"]) +test_arml = ExampleShellcode(["arml", "arm_simple.S", "demo_arm_l.bin"]) +test_armb_sc = ExampleShellcode(["armb", "arm_sc.S", "demo_arm2_b.bin"]) +test_arml_sc = ExampleShellcode(["arml", "arm_sc.S", "demo_arm2_l.bin"]) +test_armtb = ExampleShellcode(["armtb", "armt.S", "demo_armt_b.bin"]) +test_armtl = ExampleShellcode(["armtl", "armt.S", "demo_armt_l.bin"]) +test_msp430 = ExampleShellcode(["msp430", "msp430.S", "msp430_sc.bin"]) +test_mips32b = ExampleShellcode(["mips32b", "mips32.S", "mips32_sc_b.bin"]) +test_mips32l = ExampleShellcode(["mips32l", "mips32.S", "mips32_sc_l.bin"]) +test_x86_64 = ExampleShellcode(["x86_64", "x86_64.S", "demo_x86_64.bin", + "--PE"]) + +testset += test_armb +testset += test_arml +testset += test_armb_sc +testset += test_arml_sc +testset += test_armtb +testset += test_armtl testset += test_msp430 -testset += test_mips32 -for script in [["disasm_01.py"], - ["disasm_02.py"], - ["disasm_03.py", "box_upx.exe", "0x410f90"], - ]: - testset += Example(script) -## Expression -class ExampleTestDis(Example): - """TestDis specificities: - - script: test_dis.py - - flags: -g -s -m +testset += test_mips32b +testset += test_mips32l +testset += test_x86_64 + +class ExampleDisassembler(Example): + """Disassembler examples specificities: + - script path begins with "disasm/" + """ + example_dir = "disasm" + + +for script, prods in [(["single_instr.py"], []), + (["function.py"], ["graph.txt"]), + (["file.py", Example.get_sample("box_upx.exe"), + "0x410f90"], ["graph.txt"]), + ]: + testset += ExampleDisassembler(script, products=prods) + + +class ExampleDisasmFull(ExampleDisassembler): + """DisasmFull specificities: + - script: disasm/full.py + - flags: -g -s - @products: graph_execflow.txt, graph_irflow.txt, lines.txt, out.txt """ def __init__(self, *args, **kwargs): - super(ExampleTestDis, self).__init__(*args, **kwargs) - self.command_line = ["test_dis.py", "-g", "-s", "-m"] + \ - self.command_line - self.products += ["graph_execflow.txt", "graph_irflow.txt", "lines.txt", - "out.txt"] - -testset += ExampleTestDis(["arml", "demo_arm_l.bin", "0"], depends=[test_arm]) -testset += ExampleTestDis(["armb", "demo_arm_b.bin", "0"], depends=[test_arm]) -testset += ExampleTestDis(["armtl", "demo_armt_l.bin", "0"], - depends=[test_armt]) -testset += ExampleTestDis(["armtb", "demo_armt_b.bin", "0"], - depends=[test_armt]) -testset += ExampleTestDis(["x86_32", "box_x86_32.bin", "0x401000"], - depends=[test_box]) -testset += ExampleTestDis(["msp430", "msp430_sc.bin", "0"], - depends=[test_msp430]) -testset += ExampleTestDis(["mips32l", "mips32_sc_l.bin", "0"], - depends=[test_mips32]) -testset += ExampleTestDis(["mips32b", "mips32_sc_b.bin", "0"], - depends=[test_mips32]) - -testset += Example(["expression/graph_dataflow.py", - "expression/sc_connect_back.bin", "0x2e"], - products=["data.txt"]) -testset += Example(["expression/asm_to_ir.py"], - products=["graph.txt", "graph2.txt"]) -testset += Example(["expression/get_read_write.py"], - products=["graph_instr.txt"]) -testset += Example(["expression/solve_condition_stp.py", - "expression/simple_test.bin"], - products=["graph_instr.txt"]) - -for script in [["symbol_exec.py"], - ["expression/basic_op.py"], - ["expression/basic_simplification.py"], - ["expression/simplification_tools.py"], - ["expression/expr_grapher.py"], - ["expression/simplification_add.py"], - ["expression/expr_random.py"], - ["expression/expr_translate.py"], + super(ExampleDisasmFull, self).__init__(*args, **kwargs) + self.command_line = ["full.py", "-g", "-s"] + self.command_line + self.products += ["graph_execflow.txt", "graph_irflow.txt", "lines.txt"] + + +testset += ExampleDisasmFull(["arml", Example.get_sample("demo_arm_l.bin"), + "0"], depends=[test_arml]) +testset += ExampleDisasmFull(["armb", Example.get_sample("demo_arm_b.bin"), + "0"], depends=[test_armb]) +testset += ExampleDisasmFull(["arml", Example.get_sample("demo_arm2_l.bin"), + "0"], depends=[test_arml_sc]) +testset += ExampleDisasmFull(["armb", Example.get_sample("demo_arm2_b.bin"), + "0"], depends=[test_armb_sc]) +testset += ExampleDisasmFull(["armtl", Example.get_sample("demo_armt_l.bin"), + "0"], depends=[test_armtl]) +testset += ExampleDisasmFull(["armtb", Example.get_sample("demo_armt_b.bin"), + "0"], depends=[test_armtb]) +testset += ExampleDisasmFull(["x86_32", Example.get_sample("x86_32_simple.bin"), + "0x401000"], depends=[test_box["simple"]]) +testset += ExampleDisasmFull(["msp430", Example.get_sample("msp430_sc.bin"), + "0"], depends=[test_msp430]) +testset += ExampleDisasmFull(["mips32l", Example.get_sample("mips32_sc_l.bin"), + "0"], depends=[test_mips32l]) +testset += ExampleDisasmFull(["mips32b", Example.get_sample("mips32_sc_b.bin"), + "0"], depends=[test_mips32b]) +testset += ExampleDisasmFull(["x86_64", Example.get_sample("demo_x86_64.bin"), + "0x401000"], depends=[test_x86_64]) + + +## Expression +class ExampleExpression(Example): + """Expression examples specificities: + - script path begins with "expression/" + """ + example_dir = "expression" + + +testset += ExampleExpression(["graph_dataflow.py", + Example.get_sample("sc_connect_back.bin"), + "0x2e"], + products=["data.txt"]) +testset += ExampleExpression(["asm_to_ir.py"], + products=["graph.txt", "graph2.txt"]) +testset += ExampleExpression(["get_read_write.py"], + products=["graph_instr.txt"]) +testset += ExampleExpression(["solve_condition_stp.py", + Example.get_sample("simple_test.bin")], + products=["graph_instr.txt", "out.txt"]) + +for script in [["basic_op.py"], + ["basic_simplification.py"], + ["simplification_tools.py"], + ["expr_grapher.py"], + ["simplification_add.py"], + ["expr_random.py"], + ["expr_translate.py"], ]: - testset += Example(script) + testset += ExampleExpression(script) + +## Symbolic Execution +class ExampleSymbolExec(Example): + """Symbol Exec examples specificities: + - script path begins with "symbol_exec/" + """ + + example_dir = "symbol_exec" + + +testset += ExampleSymbolExec(["single_instr.py"]) + ## Jitter +class ExampleJitter(Example): + """Jitter examples specificities: + - script path begins with "jitter/" + """ + example_dir = "jitter" + jitter_engines = ["tcc", "llvm", "python"] + -for jitter in ["tcc", "llvm", "python"]: +for jitter in ExampleJitter.jitter_engines: # Take 5 min on a Core i5 tags = {"python": [TAGS["long"]], "llvm": [TAGS["llvm"]], } - testset += Example(["unpack_upx.py", "box_upx.exe"] + ["--jitter", jitter], - products=["box_upx_exe_unupx.bin"], - tags=tags.get(jitter, [])) - -for script, dep in [(["test_jit_x86_32.py", "x86_32_sc.bin"], []), - (["test_jit_arm.py", "md5_arm", "-a", "A684"], []), - (["test_jit_msp430.py", "msp430_sc.bin", "0"], + testset += ExampleJitter(["unpack_upx.py", + Example.get_sample("box_upx.exe")] + + ["--jitter", jitter], + products=[Example.get_sample("box_upx_exe_unupx.bin")], + tags=tags.get(jitter, [])) + +for script, dep in [(["x86_32.py", Example.get_sample("x86_32_sc.bin")], []), + (["arm.py", Example.get_sample("md5_arm"), "-a", "A684"], + []), + (["msp430.py", Example.get_sample("msp430_sc.bin"), "0"], [test_msp430]), - (["test_jit_mips32.py", "mips32_sc_l.bin", "0"], - [test_mips32]), - (["test_jit_arm_sc.py", "0", "demo_arm_b.bin", "b", "-a", - "0"], [test_arm]), - (["test_jit_arm_sc.py", "0", "demo_arm_l.bin", "l", "-a", - "0"], [test_arm]), - (["sandbox_pe_x86_32.py", "box_x86_32.bin"], [test_box]), - (["sandbox_pe_x86_32.py", "box_x86_32_enc.bin"], - [test_box_enc]), - (["sandbox_pe_x86_32.py", "box_x86_32_mod.bin"], - [test_box_mod]), - (["sandbox_pe_x86_32.py", "box_x86_32_repmod.bin"], - [test_box_repmod]), - (["sandbox_pe_x86_32.py", "box_x86_32_mod_self.bin"], - [test_box_mod_self]), - ]: - for jitter in ["tcc", "llvm", "python"]: + (["mips32.py", Example.get_sample("mips32_sc_l.bin"), "0"], + [test_mips32l]), + (["arm_sc.py", "0", Example.get_sample("demo_arm_b.bin"), + "b", "-a", "0"], [test_armb]), + (["arm_sc.py", "0", Example.get_sample("demo_arm_l.bin"), + "l", "-a", "0"], [test_arml]), + ] + [(["sandbox_pe_x86_32.py", + Example.get_sample("x86_32_" + name + ".bin")], + [test_box[name]]) + for name in test_box_names]: + for jitter in ExampleJitter.jitter_engines: tags = [TAGS["llvm"]] if jitter == "llvm" else [] - testset += Example(script + ["--jitter", jitter], - depends=dep, tags=tags) + testset += ExampleJitter(script + ["--jitter", jitter], depends=dep, + tags=tags) if __name__ == "__main__": @@ -287,7 +375,7 @@ By default, no tag is ommited." % ", ".join(TAGS.keys()), default="") try: import z3 except ImportError: - print "%(red)s[Z3]%(end)s" % cosmetics.colors + \ + print "%(red)s[Z3]%(end)s " % cosmetics.colors + \ "Z3 and its python binding are necessary for TranslatorZ3." if TAGS["z3"] not in exclude_tags: exclude_tags.append(TAGS["z3"]) |