From fc814adc2c5ee28e282b4212fefa187a59ccf46d Mon Sep 17 00:00:00 2001 From: Camille Mougey Date: Tue, 6 Jan 2015 17:37:39 +0100 Subject: TestAll: Use only asm_box_x86_32 and .S files, to reduce copy/paste errors --- test/test_all.py | 34 +++++++++++++--------------------- 1 file changed, 13 insertions(+), 21 deletions(-) (limited to 'test') diff --git a/test/test_all.py b/test/test_all.py index 5e43ce3f..a1b081cc 100644 --- a/test/test_all.py +++ b/test/test_all.py @@ -83,26 +83,23 @@ 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 = {} +test_box_names = ["mod", "mod_self", "repmod", "simple"] +for source in test_box_names: + test_box[source] = Example(["asm_box_x86_32.py", "x86_32_" + source + ".S"], + products=["x86_32_" + source + ".bin"]) + testset += test_box[source] + 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 testset += test_msp430 testset += test_mips32 for script in [["disasm_01.py"], @@ -131,8 +128,8 @@ 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(["x86_32", "x86_32_simple.bin", "0x401000"], + depends=[test_box["simple"]]) testset += ExampleTestDis(["msp430", "msp430_sc.bin", "0"], depends=[test_msp430]) testset += ExampleTestDis(["mips32l", "mips32_sc_l.bin", "0"], @@ -182,16 +179,11 @@ for script, dep in [(["test_jit_x86_32.py", "x86_32_sc.bin"], []), "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]), - ]: + ] + [(["sandbox_pe_x86_32.py", "x86_32_" + name + ".bin"], + [test_box[name]]) + for name in test_box_names]: for jitter in ["tcc", "llvm", "python"]: tags = [TAGS["llvm"]] if jitter == "llvm" else [] testset += Example(script + ["--jitter", jitter], -- cgit 1.4.1 From 2e876ebdbc9bdb504f72c7af5492dc20985e3973 Mon Sep 17 00:00:00 2001 From: Camille Mougey Date: Tue, 6 Jan 2015 18:04:25 +0100 Subject: Examples: Update box_upx.exe location --- example/disasm_03.py | 2 +- test/test_all.py | 16 +++++++++++++--- 2 files changed, 14 insertions(+), 4 deletions(-) (limited to 'test') diff --git a/example/disasm_03.py b/example/disasm_03.py index 1141dc55..f86a485e 100644 --- a/example/disasm_03.py +++ b/example/disasm_03.py @@ -5,7 +5,7 @@ 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) diff --git a/test/test_all.py b/test/test_all.py index a1b081cc..ffbca63c 100644 --- a/test/test_all.py +++ b/test/test_all.py @@ -73,11 +73,20 @@ class Example(Test): - @base_dir: example/@base_dir - @tags: TAGS["example"]""" + # Directory containing samples for examples + sample_dir = "samples" + def __init__(self, *args, **kwargs): super(Example, self).__init__(*args, **kwargs) self.base_dir = os.path.join("example", self.base_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"]) @@ -104,7 +113,7 @@ testset += test_msp430 testset += test_mips32 for script in [["disasm_01.py"], ["disasm_02.py"], - ["disasm_03.py", "box_upx.exe", "0x410f90"], + ["disasm_03.py", Example.get_sample("box_upx.exe"), "0x410f90"], ]: testset += Example(script) ## Expression @@ -165,8 +174,9 @@ for jitter in ["tcc", "llvm", "python"]: tags = {"python": [TAGS["long"]], "llvm": [TAGS["llvm"]], } - testset += Example(["unpack_upx.py", "box_upx.exe"] + ["--jitter", jitter], - products=["box_upx_exe_unupx.bin"], + testset += Example(["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 [(["test_jit_x86_32.py", "x86_32_sc.bin"], []), -- cgit 1.4.1 From db40b0755027e37ef57403ac10d3b7b0a3879221 Mon Sep 17 00:00:00 2001 From: Camille Mougey Date: Tue, 6 Jan 2015 18:05:58 +0100 Subject: Examples: Update md5_arm location --- example/test_jit_arm.py | 2 +- test/test_all.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/example/test_jit_arm.py b/example/test_jit_arm.py index 12878a30..7df4461c 100644 --- a/example/test_jit_arm.py +++ b/example/test_jit_arm.py @@ -9,7 +9,7 @@ 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)""") +(ex: test_jit_arm.py samples/md5_arm -a A684)""") parser.add_argument("filename", help="PE Filename") parser.add_argument('-v', "--verbose", help="verbose mode", action="store_true") diff --git a/test/test_all.py b/test/test_all.py index ffbca63c..19f26641 100644 --- a/test/test_all.py +++ b/test/test_all.py @@ -180,7 +180,8 @@ for jitter in ["tcc", "llvm", "python"]: 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_arm.py", Example.get_sample("md5_arm"), "-a", + "A684"], []), (["test_jit_msp430.py", "msp430_sc.bin", "0"], [test_msp430]), (["test_jit_mips32.py", "mips32_sc_l.bin", "0"], -- cgit 1.4.1 From c7209f8d8a5dfac3cd1bf5152a32f860f888550e Mon Sep 17 00:00:00 2001 From: Camille Mougey Date: Wed, 7 Jan 2015 17:09:00 +0100 Subject: Examples: Update *.S location --- test/test_all.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'test') diff --git a/test/test_all.py b/test/test_all.py index 19f26641..0d39b029 100644 --- a/test/test_all.py +++ b/test/test_all.py @@ -96,8 +96,10 @@ test_armt = Example(["asm_armt.py"], products=["demo_armt_l.bin", test_box = {} test_box_names = ["mod", "mod_self", "repmod", "simple"] for source in test_box_names: - test_box[source] = Example(["asm_box_x86_32.py", "x86_32_" + source + ".S"], - products=["x86_32_" + source + ".bin"]) + test_box[source] = Example(["asm_box_x86_32.py", + Example.get_sample("x86_32_" + source + ".S")], + products=[Example.get_sample("x86_32_" + source + + ".bin")]) testset += test_box[source] test_box_enc = Example(["asm_box_x86_32_enc.py"], @@ -137,7 +139,8 @@ 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", "x86_32_simple.bin", "0x401000"], +testset += ExampleTestDis(["x86_32", Example.get_sample("x86_32_simple.bin"), + "0x401000"], depends=[test_box["simple"]]) testset += ExampleTestDis(["msp430", "msp430_sc.bin", "0"], depends=[test_msp430]) @@ -192,7 +195,8 @@ for script, dep in [(["test_jit_x86_32.py", "x86_32_sc.bin"], []), "0"], [test_arm]), (["sandbox_pe_x86_32.py", "box_x86_32_enc.bin"], [test_box_enc]), - ] + [(["sandbox_pe_x86_32.py", "x86_32_" + name + ".bin"], + ] + [(["sandbox_pe_x86_32.py", + Example.get_sample("x86_32_" + name + ".bin")], [test_box[name]]) for name in test_box_names]: for jitter in ["tcc", "llvm", "python"]: -- cgit 1.4.1 From ca47e84732659a7898419ca570fa7885b8b93a20 Mon Sep 17 00:00:00 2001 From: Camille Mougey Date: Wed, 7 Jan 2015 17:10:48 +0100 Subject: Examples: Update x86_32_sc.bin location --- test/test_all.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/test_all.py b/test/test_all.py index 0d39b029..10cd4b66 100644 --- a/test/test_all.py +++ b/test/test_all.py @@ -182,7 +182,8 @@ for jitter in ["tcc", "llvm", "python"]: products=[Example.get_sample("box_upx_exe_unupx.bin")], tags=tags.get(jitter, [])) -for script, dep in [(["test_jit_x86_32.py", "x86_32_sc.bin"], []), +for script, dep in [(["test_jit_x86_32.py", + Example.get_sample("x86_32_sc.bin")], []), (["test_jit_arm.py", Example.get_sample("md5_arm"), "-a", "A684"], []), (["test_jit_msp430.py", "msp430_sc.bin", "0"], -- cgit 1.4.1 From c0a74599627ed01c6e799d41905d449ba44b098b Mon Sep 17 00:00:00 2001 From: Camille Mougey Date: Wed, 7 Jan 2015 17:17:42 +0100 Subject: Example: Rename test_jit_* to jit_* --- example/jit_arm.py | 31 +++++++++++++++++++ example/jit_arm_sc.py | 46 ++++++++++++++++++++++++++++ example/jit_mips32.py | 76 ++++++++++++++++++++++++++++++++++++++++++++++ example/jit_msp430.py | 69 +++++++++++++++++++++++++++++++++++++++++ example/jit_x86_32.py | 41 +++++++++++++++++++++++++ example/test_jit_arm.py | 31 ------------------- example/test_jit_arm_sc.py | 46 ---------------------------- example/test_jit_mips32.py | 76 ---------------------------------------------- example/test_jit_msp430.py | 69 ----------------------------------------- example/test_jit_x86_32.py | 41 ------------------------- test/test_all.py | 12 ++++---- 11 files changed, 269 insertions(+), 269 deletions(-) create mode 100644 example/jit_arm.py create mode 100644 example/jit_arm_sc.py create mode 100644 example/jit_mips32.py create mode 100644 example/jit_msp430.py create mode 100644 example/jit_x86_32.py delete mode 100644 example/test_jit_arm.py delete mode 100644 example/test_jit_arm_sc.py delete mode 100644 example/test_jit_mips32.py delete mode 100644 example/test_jit_msp430.py delete mode 100644 example/test_jit_x86_32.py (limited to 'test') diff --git a/example/jit_arm.py b/example/jit_arm.py new file mode 100644 index 00000000..2699c345 --- /dev/null +++ b/example/jit_arm.py @@ -0,0 +1,31 @@ +#!/usr/bin/env python +#-*- coding:utf-8 -*- +import logging +from pdb import pm + +from miasm2.analysis.sandbox import Sandbox_Linux_arml + +# Get arguments +parser = Sandbox_Linux_arml.parser(description="""Sandbox an elf binary with arm + engine (ex: test_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() + +# 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: + logging.basicConfig(level=logging.WARNING) + +if options.verbose is True: + sb.jitter.vm.dump_memory_page_pool() + +if options.address is None: + raise ValueError('Invalid address') + +# Run the code +sb.run() diff --git a/example/jit_arm_sc.py b/example/jit_arm_sc.py new file mode 100644 index 00000000..0ec2a5ee --- /dev/null +++ b/example/jit_arm_sc.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python +#-*- coding:utf-8 -*- +from miasm2.analysis import debugging, gdbserver + +from miasm2.analysis.sandbox import Sandbox_Linux_armb_str +from miasm2.analysis.sandbox import Sandbox_Linux_arml_str +from miasm2.analysis.machine import Machine +from elfesteem.strpatchwork import StrPatchwork +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)""") +parser.add_argument("filename", help="string Filename") +parser.add_argument("endianess", help="endianness [b/l]") +parser.add_argument('-v', "--verbose", + help="verbose mode", action="store_true") + +options = parser.parse_args() + +if options.endianess == 'b': + sandbox = Sandbox_Linux_armb_str +elif options.endianess == 'l': + sandbox = Sandbox_Linux_arml_str +else: + raise ValueError("Bad endianess!") + +sb = sandbox(options.filename, options, globals()) + +if options.address is None: + raise ValueError('invalid address') + +sb.run() + +# test correct de xor +start = sb.jitter.cpu.R0 +stop = sb.jitter.cpu.R1 +s = sb.jitter.vm.get_mem(start, stop-start) +s = StrPatchwork(s) +for i, c in enumerate(s): + s[i] = chr(ord(c)^0x11) +s = str(s) +assert(s == "test string\x00") + + diff --git a/example/jit_mips32.py b/example/jit_mips32.py new file mode 100644 index 00000000..d027ec50 --- /dev/null +++ b/example/jit_mips32.py @@ -0,0 +1,76 @@ +#!/usr/bin/env python +#-*- coding:utf-8 -*- +from argparse import ArgumentParser +from miasm2.analysis import debugging, gdbserver +from miasm2.jitter.csts import * +from miasm2.analysis.machine import Machine + +from pdb import pm + +parser = ArgumentParser( + description="""Sandbox raw binary with mips32 engine +(ex: test_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") +parser.add_argument("-m", "--log-mn", + help="Log desassembly conversion for each instruction", + action="store_true") +parser.add_argument("-n", "--log-newbloc", + help="Log basic blocks processed by the Jitter", + action="store_true") +parser.add_argument("-j", "--jitter", + help="Jitter engine. Possible values are : tcc (default), llvm", + default="tcc") +parser.add_argument("-d", "--debugging", + help="Attach a CLI debugguer to the sandboxed programm", + action="store_true") +parser.add_argument("binary", + help="binary to run") +parser.add_argument("addr", + help="start exec on addr") + +machine = Machine("mips32l") + +def code_sentinelle(jitter): + jitter.run = False + jitter.pc = 0 + return True + +def jit_mips32_binary(args): + filepath, entryp = args.binary, int(args.addr, 16) + myjit = machine.jitter(jit_type = args.jitter) + myjit.init_stack() + + # Log level (if available with jitter engine) + myjit.jit.log_regs = args.log_regs + myjit.jit.log_mn = args.log_mn + myjit.jit.log_newbloc = args.log_newbloc + + myjit.vm.add_memory_page(0, PAGE_READ | PAGE_WRITE, open(filepath).read()) + myjit.add_breakpoint(0x1337BEEF, code_sentinelle) + + + # for stack + myjit.vm.add_memory_page(0xF000, PAGE_READ | PAGE_WRITE, "\x00"*0x1000) + + myjit.cpu.SP = 0xF800 + + myjit.cpu.RA = 0x1337BEEF + myjit.init_run(entryp) + + + + # Handle debugging + if args.debugging is True: + dbg = debugging.Debugguer(myjit) + cmd = debugging.DebugCmd(dbg) + cmd.cmdloop() + + else: + print(myjit.continue_run()) + return myjit +if __name__ == '__main__': + from sys import stderr + args = parser.parse_args() + myjit = jit_mips32_binary(args) diff --git a/example/jit_msp430.py b/example/jit_msp430.py new file mode 100644 index 00000000..5aa1f340 --- /dev/null +++ b/example/jit_msp430.py @@ -0,0 +1,69 @@ +#!/usr/bin/env python +#-*- coding:utf-8 -*- +from argparse import ArgumentParser +from miasm2.analysis import debugging, gdbserver +from miasm2.jitter.csts import * +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)""") +parser.add_argument("-r", "--log-regs", + help="Log registers value for each instruction", + action="store_true") +parser.add_argument("-m", "--log-mn", + help="Log desassembly conversion for each instruction", + action="store_true") +parser.add_argument("-n", "--log-newbloc", + help="Log basic blocks processed by the Jitter", + action="store_true") +parser.add_argument("-j", "--jitter", + help="Jitter engine. Possible values are : tcc (default), llvm", + default="tcc") +parser.add_argument("-d", "--debugging", + help="Attach a CLI debugguer to the sandboxed programm", + action="store_true") +parser.add_argument("binary", + help="binary to run") +parser.add_argument("addr", + help="start exec on addr") + +machine = Machine("msp430") + +def jit_msp430_binary(args): + filepath, entryp = args.binary, int(args.addr, 16) + myjit = machine.jitter(jit_type = args.jitter) + myjit.init_stack() + + # Log level (if available with jitter engine) + myjit.jit.log_regs = args.log_regs + myjit.jit.log_mn = args.log_mn + myjit.jit.log_newbloc = args.log_newbloc + + myjit.vm.add_memory_page(0, PAGE_READ | PAGE_WRITE, open(filepath).read()) + myjit.add_breakpoint(0x1337, lambda _: exit(0)) + + + # for stack + myjit.vm.add_memory_page(0xF000, PAGE_READ | PAGE_WRITE, "\x00"*0x1000) + + myjit.cpu.SP = 0xF800 + + myjit.push_uint16_t(0x1337) + myjit.init_run(entryp) + + + + # Handle debugging + if args.debugging is True: + dbg = debugging.Debugguer(myjit) + cmd = debugging.DebugCmd(dbg) + cmd.cmdloop() + + else: + print(myjit.continue_run()) + +if __name__ == '__main__': + from sys import stderr + args = parser.parse_args() + jit_msp430_binary(args) diff --git a/example/jit_x86_32.py b/example/jit_x86_32.py new file mode 100644 index 00000000..1b2aa012 --- /dev/null +++ b/example/jit_x86_32.py @@ -0,0 +1,41 @@ +import os +from argparse import ArgumentParser +from miasm2.jitter.csts import PAGE_READ, PAGE_WRITE +from miasm2.analysis.machine import Machine + +from pdb import pm + + +filename = os.environ.get('PYTHONSTARTUP') +if filename and os.path.isfile(filename): + execfile(filename) + +parser = ArgumentParser(description="x86 32 basic Jitter") +parser.add_argument("filename", help="x86 32 shellcode filename") +parser.add_argument("-j", "--jitter", + help="Jitter engine. Possible values are : tcc (default), llvm", + default="tcc") +args = parser.parse_args() + +def code_sentinelle(jitter): + jitter.run = False + jitter.pc = 0 + return True + + +myjit = Machine("x86_32").jitter(args.jitter) +myjit.init_stack() + +data = open(args.filename).read() +run_addr = 0x40000000 +myjit.vm.add_memory_page(run_addr, PAGE_READ | PAGE_WRITE, data) + +myjit.jit.log_regs = True +myjit.jit.log_mn = True +myjit.push_uint32_t(0x1337beef) + +myjit.add_breakpoint(0x1337beef, code_sentinelle) + +myjit.init_run(run_addr) +myjit.continue_run() +del(myjit) diff --git a/example/test_jit_arm.py b/example/test_jit_arm.py deleted file mode 100644 index 2699c345..00000000 --- a/example/test_jit_arm.py +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/env python -#-*- coding:utf-8 -*- -import logging -from pdb import pm - -from miasm2.analysis.sandbox import Sandbox_Linux_arml - -# Get arguments -parser = Sandbox_Linux_arml.parser(description="""Sandbox an elf binary with arm - engine (ex: test_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() - -# 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: - logging.basicConfig(level=logging.WARNING) - -if options.verbose is True: - sb.jitter.vm.dump_memory_page_pool() - -if options.address is None: - raise ValueError('Invalid address') - -# Run the code -sb.run() diff --git a/example/test_jit_arm_sc.py b/example/test_jit_arm_sc.py deleted file mode 100644 index 0ec2a5ee..00000000 --- a/example/test_jit_arm_sc.py +++ /dev/null @@ -1,46 +0,0 @@ -#!/usr/bin/env python -#-*- coding:utf-8 -*- -from miasm2.analysis import debugging, gdbserver - -from miasm2.analysis.sandbox import Sandbox_Linux_armb_str -from miasm2.analysis.sandbox import Sandbox_Linux_arml_str -from miasm2.analysis.machine import Machine -from elfesteem.strpatchwork import StrPatchwork -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)""") -parser.add_argument("filename", help="string Filename") -parser.add_argument("endianess", help="endianness [b/l]") -parser.add_argument('-v', "--verbose", - help="verbose mode", action="store_true") - -options = parser.parse_args() - -if options.endianess == 'b': - sandbox = Sandbox_Linux_armb_str -elif options.endianess == 'l': - sandbox = Sandbox_Linux_arml_str -else: - raise ValueError("Bad endianess!") - -sb = sandbox(options.filename, options, globals()) - -if options.address is None: - raise ValueError('invalid address') - -sb.run() - -# test correct de xor -start = sb.jitter.cpu.R0 -stop = sb.jitter.cpu.R1 -s = sb.jitter.vm.get_mem(start, stop-start) -s = StrPatchwork(s) -for i, c in enumerate(s): - s[i] = chr(ord(c)^0x11) -s = str(s) -assert(s == "test string\x00") - - diff --git a/example/test_jit_mips32.py b/example/test_jit_mips32.py deleted file mode 100644 index d027ec50..00000000 --- a/example/test_jit_mips32.py +++ /dev/null @@ -1,76 +0,0 @@ -#!/usr/bin/env python -#-*- coding:utf-8 -*- -from argparse import ArgumentParser -from miasm2.analysis import debugging, gdbserver -from miasm2.jitter.csts import * -from miasm2.analysis.machine import Machine - -from pdb import pm - -parser = ArgumentParser( - description="""Sandbox raw binary with mips32 engine -(ex: test_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") -parser.add_argument("-m", "--log-mn", - help="Log desassembly conversion for each instruction", - action="store_true") -parser.add_argument("-n", "--log-newbloc", - help="Log basic blocks processed by the Jitter", - action="store_true") -parser.add_argument("-j", "--jitter", - help="Jitter engine. Possible values are : tcc (default), llvm", - default="tcc") -parser.add_argument("-d", "--debugging", - help="Attach a CLI debugguer to the sandboxed programm", - action="store_true") -parser.add_argument("binary", - help="binary to run") -parser.add_argument("addr", - help="start exec on addr") - -machine = Machine("mips32l") - -def code_sentinelle(jitter): - jitter.run = False - jitter.pc = 0 - return True - -def jit_mips32_binary(args): - filepath, entryp = args.binary, int(args.addr, 16) - myjit = machine.jitter(jit_type = args.jitter) - myjit.init_stack() - - # Log level (if available with jitter engine) - myjit.jit.log_regs = args.log_regs - myjit.jit.log_mn = args.log_mn - myjit.jit.log_newbloc = args.log_newbloc - - myjit.vm.add_memory_page(0, PAGE_READ | PAGE_WRITE, open(filepath).read()) - myjit.add_breakpoint(0x1337BEEF, code_sentinelle) - - - # for stack - myjit.vm.add_memory_page(0xF000, PAGE_READ | PAGE_WRITE, "\x00"*0x1000) - - myjit.cpu.SP = 0xF800 - - myjit.cpu.RA = 0x1337BEEF - myjit.init_run(entryp) - - - - # Handle debugging - if args.debugging is True: - dbg = debugging.Debugguer(myjit) - cmd = debugging.DebugCmd(dbg) - cmd.cmdloop() - - else: - print(myjit.continue_run()) - return myjit -if __name__ == '__main__': - from sys import stderr - args = parser.parse_args() - myjit = jit_mips32_binary(args) diff --git a/example/test_jit_msp430.py b/example/test_jit_msp430.py deleted file mode 100644 index 5aa1f340..00000000 --- a/example/test_jit_msp430.py +++ /dev/null @@ -1,69 +0,0 @@ -#!/usr/bin/env python -#-*- coding:utf-8 -*- -from argparse import ArgumentParser -from miasm2.analysis import debugging, gdbserver -from miasm2.jitter.csts import * -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)""") -parser.add_argument("-r", "--log-regs", - help="Log registers value for each instruction", - action="store_true") -parser.add_argument("-m", "--log-mn", - help="Log desassembly conversion for each instruction", - action="store_true") -parser.add_argument("-n", "--log-newbloc", - help="Log basic blocks processed by the Jitter", - action="store_true") -parser.add_argument("-j", "--jitter", - help="Jitter engine. Possible values are : tcc (default), llvm", - default="tcc") -parser.add_argument("-d", "--debugging", - help="Attach a CLI debugguer to the sandboxed programm", - action="store_true") -parser.add_argument("binary", - help="binary to run") -parser.add_argument("addr", - help="start exec on addr") - -machine = Machine("msp430") - -def jit_msp430_binary(args): - filepath, entryp = args.binary, int(args.addr, 16) - myjit = machine.jitter(jit_type = args.jitter) - myjit.init_stack() - - # Log level (if available with jitter engine) - myjit.jit.log_regs = args.log_regs - myjit.jit.log_mn = args.log_mn - myjit.jit.log_newbloc = args.log_newbloc - - myjit.vm.add_memory_page(0, PAGE_READ | PAGE_WRITE, open(filepath).read()) - myjit.add_breakpoint(0x1337, lambda _: exit(0)) - - - # for stack - myjit.vm.add_memory_page(0xF000, PAGE_READ | PAGE_WRITE, "\x00"*0x1000) - - myjit.cpu.SP = 0xF800 - - myjit.push_uint16_t(0x1337) - myjit.init_run(entryp) - - - - # Handle debugging - if args.debugging is True: - dbg = debugging.Debugguer(myjit) - cmd = debugging.DebugCmd(dbg) - cmd.cmdloop() - - else: - print(myjit.continue_run()) - -if __name__ == '__main__': - from sys import stderr - args = parser.parse_args() - jit_msp430_binary(args) diff --git a/example/test_jit_x86_32.py b/example/test_jit_x86_32.py deleted file mode 100644 index 1b2aa012..00000000 --- a/example/test_jit_x86_32.py +++ /dev/null @@ -1,41 +0,0 @@ -import os -from argparse import ArgumentParser -from miasm2.jitter.csts import PAGE_READ, PAGE_WRITE -from miasm2.analysis.machine import Machine - -from pdb import pm - - -filename = os.environ.get('PYTHONSTARTUP') -if filename and os.path.isfile(filename): - execfile(filename) - -parser = ArgumentParser(description="x86 32 basic Jitter") -parser.add_argument("filename", help="x86 32 shellcode filename") -parser.add_argument("-j", "--jitter", - help="Jitter engine. Possible values are : tcc (default), llvm", - default="tcc") -args = parser.parse_args() - -def code_sentinelle(jitter): - jitter.run = False - jitter.pc = 0 - return True - - -myjit = Machine("x86_32").jitter(args.jitter) -myjit.init_stack() - -data = open(args.filename).read() -run_addr = 0x40000000 -myjit.vm.add_memory_page(run_addr, PAGE_READ | PAGE_WRITE, data) - -myjit.jit.log_regs = True -myjit.jit.log_mn = True -myjit.push_uint32_t(0x1337beef) - -myjit.add_breakpoint(0x1337beef, code_sentinelle) - -myjit.init_run(run_addr) -myjit.continue_run() -del(myjit) diff --git a/test/test_all.py b/test/test_all.py index 10cd4b66..9de73da0 100644 --- a/test/test_all.py +++ b/test/test_all.py @@ -182,17 +182,17 @@ for jitter in ["tcc", "llvm", "python"]: products=[Example.get_sample("box_upx_exe_unupx.bin")], tags=tags.get(jitter, [])) -for script, dep in [(["test_jit_x86_32.py", +for script, dep in [(["jit_x86_32.py", Example.get_sample("x86_32_sc.bin")], []), - (["test_jit_arm.py", Example.get_sample("md5_arm"), "-a", + (["jit_arm.py", Example.get_sample("md5_arm"), "-a", "A684"], []), - (["test_jit_msp430.py", "msp430_sc.bin", "0"], + (["jit_msp430.py", "msp430_sc.bin", "0"], [test_msp430]), - (["test_jit_mips32.py", "mips32_sc_l.bin", "0"], + (["jit_mips32.py", "mips32_sc_l.bin", "0"], [test_mips32]), - (["test_jit_arm_sc.py", "0", "demo_arm_b.bin", "b", "-a", + (["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", + (["jit_arm_sc.py", "0", "demo_arm_l.bin", "l", "-a", "0"], [test_arm]), (["sandbox_pe_x86_32.py", "box_x86_32_enc.bin"], [test_box_enc]), -- cgit 1.4.1 From b139ca5b454f442eeffe2bc18cb6aa0f3391049b Mon Sep 17 00:00:00 2001 From: Camille Mougey Date: Thu, 8 Jan 2015 17:06:23 +0100 Subject: Example: Rename Disasm_01 to Disasm_Single_Instr --- example/disasm_01.py | 12 ------------ example/disasm_single_instr.py | 12 ++++++++++++ test/test_all.py | 2 +- 3 files changed, 13 insertions(+), 13 deletions(-) delete mode 100644 example/disasm_01.py create mode 100644 example/disasm_single_instr.py (limited to 'test') diff --git a/example/disasm_01.py b/example/disasm_01.py deleted file mode 100644 index 0e29dcee..00000000 --- a/example/disasm_01.py +++ /dev/null @@ -1,12 +0,0 @@ -from miasm2.arch.x86.arch import mn_x86 -from miasm2.arch.x86.regs import EDX - -l = mn_x86.fromstring('MOV EAX, EBX', 32) -print "instruction:", l -print "arg:", l.args[0] -x = mn_x86.asm(l) -print x -l.args[0] = EDX -y = mn_x86.asm(l) -print y -print mn_x86.dis(y[0], 32) diff --git a/example/disasm_single_instr.py b/example/disasm_single_instr.py new file mode 100644 index 00000000..0e29dcee --- /dev/null +++ b/example/disasm_single_instr.py @@ -0,0 +1,12 @@ +from miasm2.arch.x86.arch import mn_x86 +from miasm2.arch.x86.regs import EDX + +l = mn_x86.fromstring('MOV EAX, EBX', 32) +print "instruction:", l +print "arg:", l.args[0] +x = mn_x86.asm(l) +print x +l.args[0] = EDX +y = mn_x86.asm(l) +print y +print mn_x86.dis(y[0], 32) diff --git a/test/test_all.py b/test/test_all.py index 9de73da0..7802bf1c 100644 --- a/test/test_all.py +++ b/test/test_all.py @@ -113,7 +113,7 @@ testset += test_armt testset += test_box_enc testset += test_msp430 testset += test_mips32 -for script in [["disasm_01.py"], +for script in [["disasm_single_instr.py"], ["disasm_02.py"], ["disasm_03.py", Example.get_sample("box_upx.exe"), "0x410f90"], ]: -- cgit 1.4.1 From 17258a346c5ecf423b0758f5de6cf56f423b9e88 Mon Sep 17 00:00:00 2001 From: Camille Mougey Date: Thu, 8 Jan 2015 17:11:11 +0100 Subject: Example: Rename Disasm_02 to Disasm Function --- example/disasm_02.py | 18 ------------------ example/disasm_function.py | 18 ++++++++++++++++++ test/test_all.py | 2 +- 3 files changed, 19 insertions(+), 19 deletions(-) delete mode 100644 example/disasm_02.py create mode 100644 example/disasm_function.py (limited to 'test') diff --git a/example/disasm_02.py b/example/disasm_02.py deleted file mode 100644 index 0d443c26..00000000 --- a/example/disasm_02.py +++ /dev/null @@ -1,18 +0,0 @@ -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_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/test/test_all.py b/test/test_all.py index 7802bf1c..c2b3387b 100644 --- a/test/test_all.py +++ b/test/test_all.py @@ -114,7 +114,7 @@ testset += test_box_enc testset += test_msp430 testset += test_mips32 for script in [["disasm_single_instr.py"], - ["disasm_02.py"], + ["disasm_function.py"], ["disasm_03.py", Example.get_sample("box_upx.exe"), "0x410f90"], ]: testset += Example(script) -- cgit 1.4.1 From 5bc92753be1c0b20b8ad224c7a75ae77bf025151 Mon Sep 17 00:00:00 2001 From: Camille Mougey Date: Thu, 8 Jan 2015 17:22:08 +0100 Subject: Example: Rename Disasm_03 to Disasm_File --- example/disasm_03.py | 19 ------------------- example/disasm_file.py | 19 +++++++++++++++++++ test/test_all.py | 3 ++- 3 files changed, 21 insertions(+), 20 deletions(-) delete mode 100644 example/disasm_03.py create mode 100644 example/disasm_file.py (limited to 'test') diff --git a/example/disasm_03.py b/example/disasm_03.py deleted file mode 100644 index 5bae0e89..00000000 --- a/example/disasm_03.py +++ /dev/null @@ -1,19 +0,0 @@ -import sys -from miasm2.arch.x86.disasm import dis_x86_32 -from miasm2.core.asmbloc import bloc2graph -from miasm2.analysis.binary import Container - -if len(sys.argv) != 3: - print 'Example:' - print "%s samples/box_upx.exe 0x410f90" % sys.argv[0] - sys.exit(0) - -addr = int(sys.argv[2], 16) -cont = Container.from_stream(open(sys.argv[1])) -mdis = dis_x86_32(cont.bin_stream) -# Inform the engine to avoid disassembling null instructions -mdis.dont_dis_nulstart_bloc = True -blocs = mdis.dis_multibloc(addr) - -graph = bloc2graph(blocs) -open('graph.txt', 'w').write(graph) diff --git a/example/disasm_file.py b/example/disasm_file.py new file mode 100644 index 00000000..5bae0e89 --- /dev/null +++ b/example/disasm_file.py @@ -0,0 +1,19 @@ +import sys +from miasm2.arch.x86.disasm import dis_x86_32 +from miasm2.core.asmbloc import bloc2graph +from miasm2.analysis.binary import Container + +if len(sys.argv) != 3: + print 'Example:' + print "%s samples/box_upx.exe 0x410f90" % sys.argv[0] + sys.exit(0) + +addr = int(sys.argv[2], 16) +cont = Container.from_stream(open(sys.argv[1])) +mdis = dis_x86_32(cont.bin_stream) +# Inform the engine to avoid disassembling null instructions +mdis.dont_dis_nulstart_bloc = True +blocs = mdis.dis_multibloc(addr) + +graph = bloc2graph(blocs) +open('graph.txt', 'w').write(graph) diff --git a/test/test_all.py b/test/test_all.py index c2b3387b..3f25dab2 100644 --- a/test/test_all.py +++ b/test/test_all.py @@ -115,7 +115,8 @@ testset += test_msp430 testset += test_mips32 for script in [["disasm_single_instr.py"], ["disasm_function.py"], - ["disasm_03.py", Example.get_sample("box_upx.exe"), "0x410f90"], + ["disasm_file.py", Example.get_sample("box_upx.exe"), + "0x410f90"], ]: testset += Example(script) ## Expression -- cgit 1.4.1 From dfc2f102e8848c15d7a87a3fc000396eb347bbc4 Mon Sep 17 00:00:00 2001 From: Camille Mougey Date: Thu, 8 Jan 2015 18:09:29 +0100 Subject: Example/Test_Dis: OptParse to ArgParse --- example/test_dis.py | 130 ++++++++++++++++++++-------------------------------- test/test_all.py | 5 +- 2 files changed, 51 insertions(+), 84 deletions(-) (limited to 'test') diff --git a/example/test_dis.py b/example/test_dis.py index b200b6ac..f7ca6780 100644 --- a/example/test_dis.py +++ b/example/test_dis.py @@ -1,7 +1,6 @@ -import sys import os import logging -from optparse import OptionParser +from argparse import ArgumentParser from pdb import pm from miasm2.analysis.binary import Container @@ -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/test/test_all.py b/test/test_all.py index 3f25dab2..11de10b2 100644 --- a/test/test_all.py +++ b/test/test_all.py @@ -123,14 +123,13 @@ for script in [["disasm_single_instr.py"], class ExampleTestDis(Example): """TestDis specificities: - script: test_dis.py - - flags: -g -s -m + - 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.command_line = ["test_dis.py", "-g", "-s"] + self.command_line self.products += ["graph_execflow.txt", "graph_irflow.txt", "lines.txt", "out.txt"] -- cgit 1.4.1 From 2694784814818ab61efcb5711a8bd2649532f014 Mon Sep 17 00:00:00 2001 From: Camille Mougey Date: Fri, 9 Jan 2015 17:45:21 +0100 Subject: Example: Rename Test Dis to Disasm Full --- example/disasm_full.py | 183 +++++++++++++++++++++++++++++++++++++++++++++++++ example/test_dis.py | 183 ------------------------------------------------- test/test_all.py | 26 +++---- 3 files changed, 197 insertions(+), 195 deletions(-) create mode 100644 example/disasm_full.py delete mode 100644 example/test_dis.py (limited to 'test') diff --git a/example/disasm_full.py b/example/disasm_full.py new file mode 100644 index 00000000..f7ca6780 --- /dev/null +++ b/example/disasm_full.py @@ -0,0 +1,183 @@ +import os +import logging +from argparse import ArgumentParser +from pdb import pm + +from miasm2.analysis.binary import Container +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 + +log = logging.getLogger("dis") +console_handler = logging.StreamHandler() +console_handler.setFormatter(logging.Formatter("%(levelname)-5s: %(message)s")) +log.addHandler(console_handler) +log.setLevel(logging.INFO) + +filename = os.environ.get('PYTHONSTARTUP') +if filename and os.path.isfile(filename): + execfile(filename) + + +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(args.architecture) +mn, dis_engine, ira = machine.mn, machine.dis_engine, machine.ira +log.info('ok') + +log.info('Load binary') +with open(args.filename) as fdesc: + cont = Container.from_stream(fdesc, addr=args.shiftoffset) + +default_addr = cont.entry_point +bs = cont.bin_stream +e = cont.executable + +log.info('ok') +mdis = dis_engine(bs) +# configure disasm engine +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.address] + +if len(addrs) == 0 and default_addr is not None: + addrs.append(default_addr) +for ad in addrs: + todo = [(mdis, None, ad)] + +done = set() +all_funcs = set() +all_funcs_blocs = {} + + +done_interval = interval() +finish = False + +# Main disasm loop +while not finish and todo: + while not finish and todo: + mdis, caller, ad = todo.pop(0) + if ad in done: + continue + done.add(ad) + ab = mdis.dis_multibloc(ad) + + log.info('func ok %.16x (%d)' % (ad, len(all_funcs))) + + all_funcs.add(ad) + all_funcs_blocs[ad] = ab + for b in ab: + for l in b.lines: + done_interval += interval([(l.offset, l.offset + l.l)]) + + if args.funcswatchdog is not None: + args.funcswatchdog -= 1 + if args.recurfunctions: + for b in ab: + i = b.get_subcall_instr() + if not i: + continue + for d in i.getdstflow(mdis.symbol_pool): + if not (isinstance(d, ExprId) and isinstance(d.name, asm_label)): + continue + todo.append((mdis, i, d.name.offset)) + + if args.funcswatchdog is not None and args.funcswatchdog <= 0: + finish = True + + if args.try_disasm_all: + for a, b in done_interval.intervals: + if b in done: + continue + log.debug('add func %s' % hex(b)) + todo.append((mdis, None, b)) + + +# Generate dotty graph +all_blocs = [] +for blocs in all_funcs_blocs.values(): + all_blocs += blocs + # for b in blocs: + # print b + +log.info('generate graph file') +g = bloc2graph(all_blocs, True) +open('graph_execflow.txt', 'w').write(g) + +log.info('generate intervals') + +all_lines = [] +total_l = 0 + +print done_interval +if args.image: + log.info('build img') + done_interval.show() + +for i, j in done_interval.intervals: + log.debug((hex(i), "->", hex(j))) + + +all_lines.sort(key=lambda x: x.offset) +open('lines.txt', 'w').write('\n'.join([str(l) for l in all_lines])) +log.info('total lines %s' % total_l) + + +# Bonus, generate IR graph +if args.gen_ir: + log.info("generating IR") + + ir_arch = ira(mdis.symbol_pool) + ir_arch.blocs = {} + for ad, all_bloc in all_funcs_blocs.items(): + log.info("generating IR... %x" % ad) + for b in all_bloc: + ir_arch.add_bloc(b) + + log.info("Gen Graph... %x" % ad) + + ir_arch.gen_graph() + + if args.simplify: + ir_arch.dead_simp() + + out = ir_arch.graph() + open('graph_irflow.txt', 'w').write(out) diff --git a/example/test_dis.py b/example/test_dis.py deleted file mode 100644 index f7ca6780..00000000 --- a/example/test_dis.py +++ /dev/null @@ -1,183 +0,0 @@ -import os -import logging -from argparse import ArgumentParser -from pdb import pm - -from miasm2.analysis.binary import Container -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 - -log = logging.getLogger("dis") -console_handler = logging.StreamHandler() -console_handler.setFormatter(logging.Formatter("%(levelname)-5s: %(message)s")) -log.addHandler(console_handler) -log.setLevel(logging.INFO) - -filename = os.environ.get('PYTHONSTARTUP') -if filename and os.path.isfile(filename): - execfile(filename) - - -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(args.architecture) -mn, dis_engine, ira = machine.mn, machine.dis_engine, machine.ira -log.info('ok') - -log.info('Load binary') -with open(args.filename) as fdesc: - cont = Container.from_stream(fdesc, addr=args.shiftoffset) - -default_addr = cont.entry_point -bs = cont.bin_stream -e = cont.executable - -log.info('ok') -mdis = dis_engine(bs) -# configure disasm engine -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.address] - -if len(addrs) == 0 and default_addr is not None: - addrs.append(default_addr) -for ad in addrs: - todo = [(mdis, None, ad)] - -done = set() -all_funcs = set() -all_funcs_blocs = {} - - -done_interval = interval() -finish = False - -# Main disasm loop -while not finish and todo: - while not finish and todo: - mdis, caller, ad = todo.pop(0) - if ad in done: - continue - done.add(ad) - ab = mdis.dis_multibloc(ad) - - log.info('func ok %.16x (%d)' % (ad, len(all_funcs))) - - all_funcs.add(ad) - all_funcs_blocs[ad] = ab - for b in ab: - for l in b.lines: - done_interval += interval([(l.offset, l.offset + l.l)]) - - if args.funcswatchdog is not None: - args.funcswatchdog -= 1 - if args.recurfunctions: - for b in ab: - i = b.get_subcall_instr() - if not i: - continue - for d in i.getdstflow(mdis.symbol_pool): - if not (isinstance(d, ExprId) and isinstance(d.name, asm_label)): - continue - todo.append((mdis, i, d.name.offset)) - - if args.funcswatchdog is not None and args.funcswatchdog <= 0: - finish = True - - if args.try_disasm_all: - for a, b in done_interval.intervals: - if b in done: - continue - log.debug('add func %s' % hex(b)) - todo.append((mdis, None, b)) - - -# Generate dotty graph -all_blocs = [] -for blocs in all_funcs_blocs.values(): - all_blocs += blocs - # for b in blocs: - # print b - -log.info('generate graph file') -g = bloc2graph(all_blocs, True) -open('graph_execflow.txt', 'w').write(g) - -log.info('generate intervals') - -all_lines = [] -total_l = 0 - -print done_interval -if args.image: - log.info('build img') - done_interval.show() - -for i, j in done_interval.intervals: - log.debug((hex(i), "->", hex(j))) - - -all_lines.sort(key=lambda x: x.offset) -open('lines.txt', 'w').write('\n'.join([str(l) for l in all_lines])) -log.info('total lines %s' % total_l) - - -# Bonus, generate IR graph -if args.gen_ir: - log.info("generating IR") - - ir_arch = ira(mdis.symbol_pool) - ir_arch.blocs = {} - for ad, all_bloc in all_funcs_blocs.items(): - log.info("generating IR... %x" % ad) - for b in all_bloc: - ir_arch.add_bloc(b) - - log.info("Gen Graph... %x" % ad) - - ir_arch.gen_graph() - - if args.simplify: - ir_arch.dead_simp() - - out = ir_arch.graph() - open('graph_irflow.txt', 'w').write(out) diff --git a/test/test_all.py b/test/test_all.py index 11de10b2..aea5b885 100644 --- a/test/test_all.py +++ b/test/test_all.py @@ -120,33 +120,35 @@ for script in [["disasm_single_instr.py"], ]: testset += Example(script) ## Expression -class ExampleTestDis(Example): +class ExampleDisasmFull(Example): """TestDis specificities: - - script: test_dis.py + - 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"] + self.command_line + super(ExampleDisasmFull, self).__init__(*args, **kwargs) + self.command_line = ["disasm_full.py", "-g", "-s"] + 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"], +testset += ExampleDisasmFull(["arml", "demo_arm_l.bin", "0"], + depends=[test_arm]) +testset += ExampleDisasmFull(["armb", "demo_arm_b.bin", "0"], + depends=[test_arm]) +testset += ExampleDisasmFull(["armtl", "demo_armt_l.bin", "0"], depends=[test_armt]) -testset += ExampleTestDis(["armtb", "demo_armt_b.bin", "0"], +testset += ExampleDisasmFull(["armtb", "demo_armt_b.bin", "0"], depends=[test_armt]) -testset += ExampleTestDis(["x86_32", Example.get_sample("x86_32_simple.bin"), +testset += ExampleDisasmFull(["x86_32", Example.get_sample("x86_32_simple.bin"), "0x401000"], depends=[test_box["simple"]]) -testset += ExampleTestDis(["msp430", "msp430_sc.bin", "0"], +testset += ExampleDisasmFull(["msp430", "msp430_sc.bin", "0"], depends=[test_msp430]) -testset += ExampleTestDis(["mips32l", "mips32_sc_l.bin", "0"], +testset += ExampleDisasmFull(["mips32l", "mips32_sc_l.bin", "0"], depends=[test_mips32]) -testset += ExampleTestDis(["mips32b", "mips32_sc_b.bin", "0"], +testset += ExampleDisasmFull(["mips32b", "mips32_sc_b.bin", "0"], depends=[test_mips32]) testset += Example(["expression/graph_dataflow.py", -- cgit 1.4.1 From d4606461786632e4771c7b16dcab2dbb01132ee1 Mon Sep 17 00:00:00 2001 From: Camille Mougey Date: Fri, 9 Jan 2015 17:56:54 +0100 Subject: Example: Rename symbol_exec to single_instr in a specific symbol_exec directory --- example/symbol_exec.py | 31 ------------------------------- example/symbol_exec/single_instr.py | 31 +++++++++++++++++++++++++++++++ test/test_all.py | 8 +++++--- 3 files changed, 36 insertions(+), 34 deletions(-) delete mode 100644 example/symbol_exec.py create mode 100644 example/symbol_exec/single_instr.py (limited to 'test') diff --git a/example/symbol_exec.py b/example/symbol_exec.py deleted file mode 100644 index 416909f2..00000000 --- a/example/symbol_exec.py +++ /dev/null @@ -1,31 +0,0 @@ -# Minimalist Symbol Exec example -from miasm2.core.bin_stream import bin_stream_str -from miasm2.arch.x86.arch import mn_x86 -from miasm2.arch.x86.ira import ir_a_x86_32 -from miasm2.arch.x86.regs import all_regs_ids, all_regs_ids_init -from miasm2.ir.symbexec import symbexec -from miasm2.arch.x86.disasm import dis_x86_32 as dis_engine -import miasm2.expression.expression as m2_expr - -l = mn_x86.fromstring("MOV EAX, EBX", 32) -asm = mn_x86.asm(l)[0] - -bin_stream = bin_stream_str(asm) - -mdis = dis_engine(bin_stream) -disasm = mdis.dis_multibloc(0) - -ir = ir_a_x86_32(mdis.symbol_pool) -for bbl in disasm: ir.add_bloc(bbl) - -symbols_init = {} -for i, r in enumerate(all_regs_ids): - symbols_init[r] = all_regs_ids_init[i] -symb = symbexec(ir, symbols_init) - -block = ir.get_bloc(0) - -cur_addr = symb.emulbloc(block) -assert(symb.symbols[m2_expr.ExprId("EAX")] == symbols_init[m2_expr.ExprId("EBX")]) -print 'modified registers:' -symb.dump_id() diff --git a/example/symbol_exec/single_instr.py b/example/symbol_exec/single_instr.py new file mode 100644 index 00000000..416909f2 --- /dev/null +++ b/example/symbol_exec/single_instr.py @@ -0,0 +1,31 @@ +# Minimalist Symbol Exec example +from miasm2.core.bin_stream import bin_stream_str +from miasm2.arch.x86.arch import mn_x86 +from miasm2.arch.x86.ira import ir_a_x86_32 +from miasm2.arch.x86.regs import all_regs_ids, all_regs_ids_init +from miasm2.ir.symbexec import symbexec +from miasm2.arch.x86.disasm import dis_x86_32 as dis_engine +import miasm2.expression.expression as m2_expr + +l = mn_x86.fromstring("MOV EAX, EBX", 32) +asm = mn_x86.asm(l)[0] + +bin_stream = bin_stream_str(asm) + +mdis = dis_engine(bin_stream) +disasm = mdis.dis_multibloc(0) + +ir = ir_a_x86_32(mdis.symbol_pool) +for bbl in disasm: ir.add_bloc(bbl) + +symbols_init = {} +for i, r in enumerate(all_regs_ids): + symbols_init[r] = all_regs_ids_init[i] +symb = symbexec(ir, symbols_init) + +block = ir.get_bloc(0) + +cur_addr = symb.emulbloc(block) +assert(symb.symbols[m2_expr.ExprId("EAX")] == symbols_init[m2_expr.ExprId("EBX")]) +print 'modified registers:' +symb.dump_id() diff --git a/test/test_all.py b/test/test_all.py index aea5b885..f4df9967 100644 --- a/test/test_all.py +++ b/test/test_all.py @@ -162,8 +162,7 @@ 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"], +for script in [["expression/basic_op.py"], ["expression/basic_simplification.py"], ["expression/simplification_tools.py"], ["expression/expr_grapher.py"], @@ -172,8 +171,11 @@ for script in [["symbol_exec.py"], ["expression/expr_translate.py"], ]: testset += Example(script) -## Jitter +## Symbolic Execution +testset += Example(["symbol_exec/single_instr.py"]) + +## Jitter for jitter in ["tcc", "llvm", "python"]: # Take 5 min on a Core i5 tags = {"python": [TAGS["long"]], -- cgit 1.4.1 From 42d91afa7441f62c77febc7d3dbc3e43d4a31218 Mon Sep 17 00:00:00 2001 From: Camille Mougey Date: Fri, 9 Jan 2015 18:05:07 +0100 Subject: Example: Move expression samples to sample directory --- example/expression/sc_connect_back.bin | Bin 290 -> 0 bytes example/expression/simple_test.bin | Bin 141 -> 0 bytes example/expression/simple_test.c | 26 -------------------------- example/samples/sc_connect_back.bin | Bin 0 -> 290 bytes example/samples/simple_test.bin | Bin 0 -> 141 bytes example/samples/simple_test.c | 26 ++++++++++++++++++++++++++ test/test_all.py | 7 ++++--- 7 files changed, 30 insertions(+), 29 deletions(-) delete mode 100644 example/expression/sc_connect_back.bin delete mode 100644 example/expression/simple_test.bin delete mode 100644 example/expression/simple_test.c create mode 100644 example/samples/sc_connect_back.bin create mode 100644 example/samples/simple_test.bin create mode 100644 example/samples/simple_test.c (limited to 'test') diff --git a/example/expression/sc_connect_back.bin b/example/expression/sc_connect_back.bin deleted file mode 100644 index 9e9c80a5..00000000 Binary files a/example/expression/sc_connect_back.bin and /dev/null differ diff --git a/example/expression/simple_test.bin b/example/expression/simple_test.bin deleted file mode 100644 index 60f4e768..00000000 Binary files a/example/expression/simple_test.bin and /dev/null differ diff --git a/example/expression/simple_test.c b/example/expression/simple_test.c deleted file mode 100644 index 8e344f18..00000000 --- a/example/expression/simple_test.c +++ /dev/null @@ -1,26 +0,0 @@ -int test(unsigned int argc, char** argv) -{ - unsigned int ret; - if (argc == 0) - ret = 0x1001; - else if (argc < 2) - ret = 0x1002; - else if (argc <= 5) - ret = 0x1003; - else if (argc != 7 && argc*2 == 14) - ret = 0x1004; - else if (argc*2 == 14) - ret = 0x1005; - else if (argc & 0x30) - ret = 0x1006; - else if (argc + 3 == 0x45) - ret = 0x1007; - else - ret = 0x1008; - return ret; -} - -int main(int argc, char** argv) -{ - return test(argc, argv); -} diff --git a/example/samples/sc_connect_back.bin b/example/samples/sc_connect_back.bin new file mode 100644 index 00000000..9e9c80a5 Binary files /dev/null and b/example/samples/sc_connect_back.bin differ diff --git a/example/samples/simple_test.bin b/example/samples/simple_test.bin new file mode 100644 index 00000000..60f4e768 Binary files /dev/null and b/example/samples/simple_test.bin differ diff --git a/example/samples/simple_test.c b/example/samples/simple_test.c new file mode 100644 index 00000000..8e344f18 --- /dev/null +++ b/example/samples/simple_test.c @@ -0,0 +1,26 @@ +int test(unsigned int argc, char** argv) +{ + unsigned int ret; + if (argc == 0) + ret = 0x1001; + else if (argc < 2) + ret = 0x1002; + else if (argc <= 5) + ret = 0x1003; + else if (argc != 7 && argc*2 == 14) + ret = 0x1004; + else if (argc*2 == 14) + ret = 0x1005; + else if (argc & 0x30) + ret = 0x1006; + else if (argc + 3 == 0x45) + ret = 0x1007; + else + ret = 0x1008; + return ret; +} + +int main(int argc, char** argv) +{ + return test(argc, argv); +} diff --git a/test/test_all.py b/test/test_all.py index f4df9967..61ad701a 100644 --- a/test/test_all.py +++ b/test/test_all.py @@ -119,7 +119,7 @@ for script in [["disasm_single_instr.py"], "0x410f90"], ]: testset += Example(script) -## Expression + class ExampleDisasmFull(Example): """TestDis specificities: - script: disasm_full.py @@ -151,15 +151,16 @@ testset += ExampleDisasmFull(["mips32l", "mips32_sc_l.bin", "0"], testset += ExampleDisasmFull(["mips32b", "mips32_sc_b.bin", "0"], depends=[test_mips32]) +## Expression testset += Example(["expression/graph_dataflow.py", - "expression/sc_connect_back.bin", "0x2e"], + Example.get_sample("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"], + Example.get_sample("simple_test.bin")], products=["graph_instr.txt"]) for script in [["expression/basic_op.py"], -- cgit 1.4.1 From 829f8b98a658532b40382640223c0c3ea12ab15c Mon Sep 17 00:00:00 2001 From: Camille Mougey Date: Sun, 18 Jan 2015 17:14:45 +0100 Subject: TestAll: Introduce ExampleDir, and use it for expressions (ExampleExpression) --- test/test_all.py | 60 ++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 41 insertions(+), 19 deletions(-) (limited to 'test') diff --git a/test/test_all.py b/test/test_all.py index 61ad701a..1a80cf46 100644 --- a/test/test_all.py +++ b/test/test_all.py @@ -87,6 +87,20 @@ class Example(Test): return os.path.join(cls.sample_dir, sample_name) +class ExampleDir(Example): + "Launch examples from a given directory" + + example_dir = "" + + def __init__(self, *args, **kwargs): + if not self.example_dir: + raise NotImplementedError("ExampleDir should be inherited") + + super(ExampleDir, self).__init__(*args, **kwargs) + self.command_line[0] = os.path.join(self.example_dir, + self.command_line[0]) + + ## 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"]) @@ -152,26 +166,34 @@ testset += ExampleDisasmFull(["mips32b", "mips32_sc_b.bin", "0"], depends=[test_mips32]) ## Expression -testset += Example(["expression/graph_dataflow.py", - Example.get_sample("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", - Example.get_sample("simple_test.bin")], - products=["graph_instr.txt"]) - -for script in [["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"], +class ExampleExpression(ExampleDir): + """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"]) + +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 testset += Example(["symbol_exec/single_instr.py"]) -- cgit 1.4.1 From 488cb99d4d61a0b3b176f7e3c53431872fc234ef Mon Sep 17 00:00:00 2001 From: Camille Mougey Date: Sun, 18 Jan 2015 18:24:13 +0100 Subject: Example: Move jitter's examples to a `jitter` directory --- example/jit_arm.py | 31 ---------- example/jit_arm_sc.py | 46 -------------- example/jit_mips32.py | 76 ----------------------- example/jit_msp430.py | 69 --------------------- example/jit_x86_32.py | 41 ------------- example/jitter/arm.py | 31 ++++++++++ example/jitter/arm_sc.py | 46 ++++++++++++++ example/jitter/mips32.py | 76 +++++++++++++++++++++++ example/jitter/msp430.py | 69 +++++++++++++++++++++ example/jitter/sandbox_pe_x86_32.py | 23 +++++++ example/jitter/unpack_upx.py | 117 ++++++++++++++++++++++++++++++++++++ example/jitter/x86_32.py | 41 +++++++++++++ example/sandbox_pe_x86_32.py | 23 ------- example/unpack_upx.py | 117 ------------------------------------ test/test_all.py | 47 ++++++++------- 15 files changed, 429 insertions(+), 424 deletions(-) delete mode 100644 example/jit_arm.py delete mode 100644 example/jit_arm_sc.py delete mode 100644 example/jit_mips32.py delete mode 100644 example/jit_msp430.py delete mode 100644 example/jit_x86_32.py create mode 100644 example/jitter/arm.py create mode 100644 example/jitter/arm_sc.py create mode 100644 example/jitter/mips32.py create mode 100644 example/jitter/msp430.py create mode 100644 example/jitter/sandbox_pe_x86_32.py create mode 100644 example/jitter/unpack_upx.py create mode 100644 example/jitter/x86_32.py delete mode 100644 example/sandbox_pe_x86_32.py delete mode 100644 example/unpack_upx.py (limited to 'test') diff --git a/example/jit_arm.py b/example/jit_arm.py deleted file mode 100644 index 5342ee6d..00000000 --- a/example/jit_arm.py +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/env python -#-*- coding:utf-8 -*- -import logging -from pdb import pm - -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() - -# 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: - logging.basicConfig(level=logging.WARNING) - -if options.verbose is True: - sb.jitter.vm.dump_memory_page_pool() - -if options.address is None: - raise ValueError('Invalid address') - -# Run the code -sb.run() diff --git a/example/jit_arm_sc.py b/example/jit_arm_sc.py deleted file mode 100644 index 80714641..00000000 --- a/example/jit_arm_sc.py +++ /dev/null @@ -1,46 +0,0 @@ -#!/usr/bin/env python -#-*- coding:utf-8 -*- -from miasm2.analysis import debugging, gdbserver - -from miasm2.analysis.sandbox import Sandbox_Linux_armb_str -from miasm2.analysis.sandbox import Sandbox_Linux_arml_str -from miasm2.analysis.machine import Machine -from elfesteem.strpatchwork import StrPatchwork -import logging - -from pdb import pm - -parser = Sandbox_Linux_arml_str.parser(description="""Sandbox an elf binary with arm engine -(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", - help="verbose mode", action="store_true") - -options = parser.parse_args() - -if options.endianess == 'b': - sandbox = Sandbox_Linux_armb_str -elif options.endianess == 'l': - sandbox = Sandbox_Linux_arml_str -else: - raise ValueError("Bad endianess!") - -sb = sandbox(options.filename, options, globals()) - -if options.address is None: - raise ValueError('invalid address') - -sb.run() - -# test correct de xor -start = sb.jitter.cpu.R0 -stop = sb.jitter.cpu.R1 -s = sb.jitter.vm.get_mem(start, stop-start) -s = StrPatchwork(s) -for i, c in enumerate(s): - s[i] = chr(ord(c)^0x11) -s = str(s) -assert(s == "test string\x00") - - diff --git a/example/jit_mips32.py b/example/jit_mips32.py deleted file mode 100644 index e41096cc..00000000 --- a/example/jit_mips32.py +++ /dev/null @@ -1,76 +0,0 @@ -#!/usr/bin/env python -#-*- coding:utf-8 -*- -from argparse import ArgumentParser -from miasm2.analysis import debugging, gdbserver -from miasm2.jitter.csts import * -from miasm2.analysis.machine import Machine - -from pdb import pm - -parser = ArgumentParser( - description="""Sandbox raw binary with mips32 engine -(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") -parser.add_argument("-m", "--log-mn", - help="Log desassembly conversion for each instruction", - action="store_true") -parser.add_argument("-n", "--log-newbloc", - help="Log basic blocks processed by the Jitter", - action="store_true") -parser.add_argument("-j", "--jitter", - help="Jitter engine. Possible values are : tcc (default), llvm", - default="tcc") -parser.add_argument("-d", "--debugging", - help="Attach a CLI debugguer to the sandboxed programm", - action="store_true") -parser.add_argument("binary", - help="binary to run") -parser.add_argument("addr", - help="start exec on addr") - -machine = Machine("mips32l") - -def code_sentinelle(jitter): - jitter.run = False - jitter.pc = 0 - return True - -def jit_mips32_binary(args): - filepath, entryp = args.binary, int(args.addr, 16) - myjit = machine.jitter(jit_type = args.jitter) - myjit.init_stack() - - # Log level (if available with jitter engine) - myjit.jit.log_regs = args.log_regs - myjit.jit.log_mn = args.log_mn - myjit.jit.log_newbloc = args.log_newbloc - - myjit.vm.add_memory_page(0, PAGE_READ | PAGE_WRITE, open(filepath).read()) - myjit.add_breakpoint(0x1337BEEF, code_sentinelle) - - - # for stack - myjit.vm.add_memory_page(0xF000, PAGE_READ | PAGE_WRITE, "\x00"*0x1000) - - myjit.cpu.SP = 0xF800 - - myjit.cpu.RA = 0x1337BEEF - myjit.init_run(entryp) - - - - # Handle debugging - if args.debugging is True: - dbg = debugging.Debugguer(myjit) - cmd = debugging.DebugCmd(dbg) - cmd.cmdloop() - - else: - print(myjit.continue_run()) - return myjit -if __name__ == '__main__': - from sys import stderr - args = parser.parse_args() - myjit = jit_mips32_binary(args) diff --git a/example/jit_msp430.py b/example/jit_msp430.py deleted file mode 100644 index d752ef8c..00000000 --- a/example/jit_msp430.py +++ /dev/null @@ -1,69 +0,0 @@ -#!/usr/bin/env python -#-*- coding:utf-8 -*- -from argparse import ArgumentParser -from miasm2.analysis import debugging, gdbserver -from miasm2.jitter.csts import * -from miasm2.analysis.machine import Machine - -parser = ArgumentParser( - description="""Sandbox raw binary with msp430 engine -(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") -parser.add_argument("-m", "--log-mn", - help="Log desassembly conversion for each instruction", - action="store_true") -parser.add_argument("-n", "--log-newbloc", - help="Log basic blocks processed by the Jitter", - action="store_true") -parser.add_argument("-j", "--jitter", - help="Jitter engine. Possible values are : tcc (default), llvm", - default="tcc") -parser.add_argument("-d", "--debugging", - help="Attach a CLI debugguer to the sandboxed programm", - action="store_true") -parser.add_argument("binary", - help="binary to run") -parser.add_argument("addr", - help="start exec on addr") - -machine = Machine("msp430") - -def jit_msp430_binary(args): - filepath, entryp = args.binary, int(args.addr, 16) - myjit = machine.jitter(jit_type = args.jitter) - myjit.init_stack() - - # Log level (if available with jitter engine) - myjit.jit.log_regs = args.log_regs - myjit.jit.log_mn = args.log_mn - myjit.jit.log_newbloc = args.log_newbloc - - myjit.vm.add_memory_page(0, PAGE_READ | PAGE_WRITE, open(filepath).read()) - myjit.add_breakpoint(0x1337, lambda _: exit(0)) - - - # for stack - myjit.vm.add_memory_page(0xF000, PAGE_READ | PAGE_WRITE, "\x00"*0x1000) - - myjit.cpu.SP = 0xF800 - - myjit.push_uint16_t(0x1337) - myjit.init_run(entryp) - - - - # Handle debugging - if args.debugging is True: - dbg = debugging.Debugguer(myjit) - cmd = debugging.DebugCmd(dbg) - cmd.cmdloop() - - else: - print(myjit.continue_run()) - -if __name__ == '__main__': - from sys import stderr - args = parser.parse_args() - jit_msp430_binary(args) diff --git a/example/jit_x86_32.py b/example/jit_x86_32.py deleted file mode 100644 index 1b2aa012..00000000 --- a/example/jit_x86_32.py +++ /dev/null @@ -1,41 +0,0 @@ -import os -from argparse import ArgumentParser -from miasm2.jitter.csts import PAGE_READ, PAGE_WRITE -from miasm2.analysis.machine import Machine - -from pdb import pm - - -filename = os.environ.get('PYTHONSTARTUP') -if filename and os.path.isfile(filename): - execfile(filename) - -parser = ArgumentParser(description="x86 32 basic Jitter") -parser.add_argument("filename", help="x86 32 shellcode filename") -parser.add_argument("-j", "--jitter", - help="Jitter engine. Possible values are : tcc (default), llvm", - default="tcc") -args = parser.parse_args() - -def code_sentinelle(jitter): - jitter.run = False - jitter.pc = 0 - return True - - -myjit = Machine("x86_32").jitter(args.jitter) -myjit.init_stack() - -data = open(args.filename).read() -run_addr = 0x40000000 -myjit.vm.add_memory_page(run_addr, PAGE_READ | PAGE_WRITE, data) - -myjit.jit.log_regs = True -myjit.jit.log_mn = True -myjit.push_uint32_t(0x1337beef) - -myjit.add_breakpoint(0x1337beef, code_sentinelle) - -myjit.init_run(run_addr) -myjit.continue_run() -del(myjit) diff --git a/example/jitter/arm.py b/example/jitter/arm.py new file mode 100644 index 00000000..5342ee6d --- /dev/null +++ b/example/jitter/arm.py @@ -0,0 +1,31 @@ +#!/usr/bin/env python +#-*- coding:utf-8 -*- +import logging +from pdb import pm + +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() + +# 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: + logging.basicConfig(level=logging.WARNING) + +if options.verbose is True: + sb.jitter.vm.dump_memory_page_pool() + +if options.address is None: + raise ValueError('Invalid address') + +# Run the code +sb.run() diff --git a/example/jitter/arm_sc.py b/example/jitter/arm_sc.py new file mode 100644 index 00000000..80714641 --- /dev/null +++ b/example/jitter/arm_sc.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python +#-*- coding:utf-8 -*- +from miasm2.analysis import debugging, gdbserver + +from miasm2.analysis.sandbox import Sandbox_Linux_armb_str +from miasm2.analysis.sandbox import Sandbox_Linux_arml_str +from miasm2.analysis.machine import Machine +from elfesteem.strpatchwork import StrPatchwork +import logging + +from pdb import pm + +parser = Sandbox_Linux_arml_str.parser(description="""Sandbox an elf binary with arm engine +(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", + help="verbose mode", action="store_true") + +options = parser.parse_args() + +if options.endianess == 'b': + sandbox = Sandbox_Linux_armb_str +elif options.endianess == 'l': + sandbox = Sandbox_Linux_arml_str +else: + raise ValueError("Bad endianess!") + +sb = sandbox(options.filename, options, globals()) + +if options.address is None: + raise ValueError('invalid address') + +sb.run() + +# test correct de xor +start = sb.jitter.cpu.R0 +stop = sb.jitter.cpu.R1 +s = sb.jitter.vm.get_mem(start, stop-start) +s = StrPatchwork(s) +for i, c in enumerate(s): + s[i] = chr(ord(c)^0x11) +s = str(s) +assert(s == "test string\x00") + + diff --git a/example/jitter/mips32.py b/example/jitter/mips32.py new file mode 100644 index 00000000..e41096cc --- /dev/null +++ b/example/jitter/mips32.py @@ -0,0 +1,76 @@ +#!/usr/bin/env python +#-*- coding:utf-8 -*- +from argparse import ArgumentParser +from miasm2.analysis import debugging, gdbserver +from miasm2.jitter.csts import * +from miasm2.analysis.machine import Machine + +from pdb import pm + +parser = ArgumentParser( + description="""Sandbox raw binary with mips32 engine +(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") +parser.add_argument("-m", "--log-mn", + help="Log desassembly conversion for each instruction", + action="store_true") +parser.add_argument("-n", "--log-newbloc", + help="Log basic blocks processed by the Jitter", + action="store_true") +parser.add_argument("-j", "--jitter", + help="Jitter engine. Possible values are : tcc (default), llvm", + default="tcc") +parser.add_argument("-d", "--debugging", + help="Attach a CLI debugguer to the sandboxed programm", + action="store_true") +parser.add_argument("binary", + help="binary to run") +parser.add_argument("addr", + help="start exec on addr") + +machine = Machine("mips32l") + +def code_sentinelle(jitter): + jitter.run = False + jitter.pc = 0 + return True + +def jit_mips32_binary(args): + filepath, entryp = args.binary, int(args.addr, 16) + myjit = machine.jitter(jit_type = args.jitter) + myjit.init_stack() + + # Log level (if available with jitter engine) + myjit.jit.log_regs = args.log_regs + myjit.jit.log_mn = args.log_mn + myjit.jit.log_newbloc = args.log_newbloc + + myjit.vm.add_memory_page(0, PAGE_READ | PAGE_WRITE, open(filepath).read()) + myjit.add_breakpoint(0x1337BEEF, code_sentinelle) + + + # for stack + myjit.vm.add_memory_page(0xF000, PAGE_READ | PAGE_WRITE, "\x00"*0x1000) + + myjit.cpu.SP = 0xF800 + + myjit.cpu.RA = 0x1337BEEF + myjit.init_run(entryp) + + + + # Handle debugging + if args.debugging is True: + dbg = debugging.Debugguer(myjit) + cmd = debugging.DebugCmd(dbg) + cmd.cmdloop() + + else: + print(myjit.continue_run()) + return myjit +if __name__ == '__main__': + from sys import stderr + args = parser.parse_args() + myjit = jit_mips32_binary(args) diff --git a/example/jitter/msp430.py b/example/jitter/msp430.py new file mode 100644 index 00000000..d752ef8c --- /dev/null +++ b/example/jitter/msp430.py @@ -0,0 +1,69 @@ +#!/usr/bin/env python +#-*- coding:utf-8 -*- +from argparse import ArgumentParser +from miasm2.analysis import debugging, gdbserver +from miasm2.jitter.csts import * +from miasm2.analysis.machine import Machine + +parser = ArgumentParser( + description="""Sandbox raw binary with msp430 engine +(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") +parser.add_argument("-m", "--log-mn", + help="Log desassembly conversion for each instruction", + action="store_true") +parser.add_argument("-n", "--log-newbloc", + help="Log basic blocks processed by the Jitter", + action="store_true") +parser.add_argument("-j", "--jitter", + help="Jitter engine. Possible values are : tcc (default), llvm", + default="tcc") +parser.add_argument("-d", "--debugging", + help="Attach a CLI debugguer to the sandboxed programm", + action="store_true") +parser.add_argument("binary", + help="binary to run") +parser.add_argument("addr", + help="start exec on addr") + +machine = Machine("msp430") + +def jit_msp430_binary(args): + filepath, entryp = args.binary, int(args.addr, 16) + myjit = machine.jitter(jit_type = args.jitter) + myjit.init_stack() + + # Log level (if available with jitter engine) + myjit.jit.log_regs = args.log_regs + myjit.jit.log_mn = args.log_mn + myjit.jit.log_newbloc = args.log_newbloc + + myjit.vm.add_memory_page(0, PAGE_READ | PAGE_WRITE, open(filepath).read()) + myjit.add_breakpoint(0x1337, lambda _: exit(0)) + + + # for stack + myjit.vm.add_memory_page(0xF000, PAGE_READ | PAGE_WRITE, "\x00"*0x1000) + + myjit.cpu.SP = 0xF800 + + myjit.push_uint16_t(0x1337) + myjit.init_run(entryp) + + + + # Handle debugging + if args.debugging is True: + dbg = debugging.Debugguer(myjit) + cmd = debugging.DebugCmd(dbg) + cmd.cmdloop() + + else: + print(myjit.continue_run()) + +if __name__ == '__main__': + from sys import stderr + args = parser.parse_args() + jit_msp430_binary(args) diff --git a/example/jitter/sandbox_pe_x86_32.py b/example/jitter/sandbox_pe_x86_32.py new file mode 100644 index 00000000..738e0778 --- /dev/null +++ b/example/jitter/sandbox_pe_x86_32.py @@ -0,0 +1,23 @@ +import os +from pdb import pm +from miasm2.analysis.sandbox import Sandbox_Win_x86_32 + +# Python auto completion +filename = os.environ.get('PYTHONSTARTUP') +if filename and os.path.isfile(filename): + execfile(filename) + +# Insert here user defined methods + +# Parse arguments +parser = Sandbox_Win_x86_32.parser(description="PE sandboxer") +parser.add_argument("filename", help="PE Filename") +options = parser.parse_args() + +# Create sandbox +sb = Sandbox_Win_x86_32(options.filename, options, globals()) + +# Run +sb.run() + +assert(sb.jitter.run is False) diff --git a/example/jitter/unpack_upx.py b/example/jitter/unpack_upx.py new file mode 100644 index 00000000..313f75a2 --- /dev/null +++ b/example/jitter/unpack_upx.py @@ -0,0 +1,117 @@ +import os +import logging +from pdb import pm +from elfesteem import pe +from miasm2.analysis.sandbox import Sandbox_Win_x86_32 +from miasm2.core import asmbloc + +filename = os.environ.get('PYTHONSTARTUP') +if filename and os.path.isfile(filename): + execfile(filename) + + +# User defined methods + +def kernel32_GetProcAddress(jitter): + ret_ad, args = jitter.func_args_stdcall(2) + libbase, fname = args + + dst_ad = jitter.cpu.EBX + logging.info('EBX ' + hex(dst_ad)) + + if fname < 0x10000: + fname = fname + else: + fname = jitter.get_str_ansi(fname) + logging.info(fname) + + ad = sb.libs.lib_get_add_func(libbase, fname, dst_ad) + jitter.func_ret_stdcall(ret_ad, ad) + + + +parser = Sandbox_Win_x86_32.parser(description="Generic UPX unpacker") +parser.add_argument("filename", help="PE Filename") +parser.add_argument('-v', "--verbose", + help="verbose mode", action="store_true") +parser.add_argument("--graph", + help="Export the CFG graph in graph.txt", + action="store_true") +options = parser.parse_args() +sb = Sandbox_Win_x86_32(options.filename, options, globals()) + + +if options.verbose is True: + logging.basicConfig(level=logging.INFO) +else: + logging.basicConfig(level=logging.WARNING) + +if options.verbose is True: + sb.jitter.vm.dump_memory_page_pool() + + +ep = sb.entry_point + +# Ensure there is one and only one leave (for OEP discovering) +mdis = sb.machine.dis_engine(sb.jitter.bs) +mdis.dont_dis_nulstart_bloc = True +ab = mdis.dis_multibloc(ep) + +bb = asmbloc.basicblocs(ab) +leaves = bb.get_bad_dst() +assert(len(leaves) == 1) +l = leaves.pop() +logging.info(l) +end_label = l.label.offset + +logging.info('final label') +logging.info(end_label) + +# Export CFG graph (dot format) +if options.graph is True: + g = asmbloc.bloc2graph(ab) + open("graph.txt", "w").write(g) + + +if options.verbose is True: + sb.jitter.vm.dump_memory_page_pool() + + +def update_binary(jitter): + sb.pe.Opthdr.AddressOfEntryPoint = sb.pe.virt2rva(jitter.pc) + logging.info('updating binary') + for s in sb.pe.SHList: + sdata = sb.jitter.vm.get_mem(sb.pe.rva2virt(s.addr), s.rawsize) + sb.pe.virt[sb.pe.rva2virt(s.addr)] = sdata + + +# Set callbacks +sb.jitter.add_breakpoint(end_label, update_binary) + +# Run +sb.run() + +# Rebuild PE +new_dll = [] + +sb.pe.SHList.align_sections(0x1000, 0x1000) +logging.info(repr(sb.pe.SHList)) + +sb.pe.DirRes = pe.DirRes(sb.pe) +sb.pe.DirImport.impdesc = None +logging.info(repr(sb.pe.DirImport.impdesc)) +new_dll = sb.libs.gen_new_lib(sb.pe) +logging.info(new_dll) +sb.pe.DirImport.impdesc = [] +sb.pe.DirImport.add_dlldesc(new_dll) +s_myimp = sb.pe.SHList.add_section(name="myimp", rawsize=len(sb.pe.DirImport)) +logging.info(repr(sb.pe.SHList)) +sb.pe.DirImport.set_rva(s_myimp.addr) + +# XXXX TODO +sb.pe.NThdr.optentries[pe.DIRECTORY_ENTRY_DELAY_IMPORT].rva = 0 + +sb.pe.Opthdr.AddressOfEntryPoint = sb.pe.virt2rva(end_label) +bname, fname = os.path.split(options.filename) +fname = os.path.join(bname, fname.replace('.', '_')) +open(fname + '_unupx.bin', 'w').write(str(sb.pe)) diff --git a/example/jitter/x86_32.py b/example/jitter/x86_32.py new file mode 100644 index 00000000..1b2aa012 --- /dev/null +++ b/example/jitter/x86_32.py @@ -0,0 +1,41 @@ +import os +from argparse import ArgumentParser +from miasm2.jitter.csts import PAGE_READ, PAGE_WRITE +from miasm2.analysis.machine import Machine + +from pdb import pm + + +filename = os.environ.get('PYTHONSTARTUP') +if filename and os.path.isfile(filename): + execfile(filename) + +parser = ArgumentParser(description="x86 32 basic Jitter") +parser.add_argument("filename", help="x86 32 shellcode filename") +parser.add_argument("-j", "--jitter", + help="Jitter engine. Possible values are : tcc (default), llvm", + default="tcc") +args = parser.parse_args() + +def code_sentinelle(jitter): + jitter.run = False + jitter.pc = 0 + return True + + +myjit = Machine("x86_32").jitter(args.jitter) +myjit.init_stack() + +data = open(args.filename).read() +run_addr = 0x40000000 +myjit.vm.add_memory_page(run_addr, PAGE_READ | PAGE_WRITE, data) + +myjit.jit.log_regs = True +myjit.jit.log_mn = True +myjit.push_uint32_t(0x1337beef) + +myjit.add_breakpoint(0x1337beef, code_sentinelle) + +myjit.init_run(run_addr) +myjit.continue_run() +del(myjit) diff --git a/example/sandbox_pe_x86_32.py b/example/sandbox_pe_x86_32.py deleted file mode 100644 index 738e0778..00000000 --- a/example/sandbox_pe_x86_32.py +++ /dev/null @@ -1,23 +0,0 @@ -import os -from pdb import pm -from miasm2.analysis.sandbox import Sandbox_Win_x86_32 - -# Python auto completion -filename = os.environ.get('PYTHONSTARTUP') -if filename and os.path.isfile(filename): - execfile(filename) - -# Insert here user defined methods - -# Parse arguments -parser = Sandbox_Win_x86_32.parser(description="PE sandboxer") -parser.add_argument("filename", help="PE Filename") -options = parser.parse_args() - -# Create sandbox -sb = Sandbox_Win_x86_32(options.filename, options, globals()) - -# Run -sb.run() - -assert(sb.jitter.run is False) diff --git a/example/unpack_upx.py b/example/unpack_upx.py deleted file mode 100644 index 313f75a2..00000000 --- a/example/unpack_upx.py +++ /dev/null @@ -1,117 +0,0 @@ -import os -import logging -from pdb import pm -from elfesteem import pe -from miasm2.analysis.sandbox import Sandbox_Win_x86_32 -from miasm2.core import asmbloc - -filename = os.environ.get('PYTHONSTARTUP') -if filename and os.path.isfile(filename): - execfile(filename) - - -# User defined methods - -def kernel32_GetProcAddress(jitter): - ret_ad, args = jitter.func_args_stdcall(2) - libbase, fname = args - - dst_ad = jitter.cpu.EBX - logging.info('EBX ' + hex(dst_ad)) - - if fname < 0x10000: - fname = fname - else: - fname = jitter.get_str_ansi(fname) - logging.info(fname) - - ad = sb.libs.lib_get_add_func(libbase, fname, dst_ad) - jitter.func_ret_stdcall(ret_ad, ad) - - - -parser = Sandbox_Win_x86_32.parser(description="Generic UPX unpacker") -parser.add_argument("filename", help="PE Filename") -parser.add_argument('-v', "--verbose", - help="verbose mode", action="store_true") -parser.add_argument("--graph", - help="Export the CFG graph in graph.txt", - action="store_true") -options = parser.parse_args() -sb = Sandbox_Win_x86_32(options.filename, options, globals()) - - -if options.verbose is True: - logging.basicConfig(level=logging.INFO) -else: - logging.basicConfig(level=logging.WARNING) - -if options.verbose is True: - sb.jitter.vm.dump_memory_page_pool() - - -ep = sb.entry_point - -# Ensure there is one and only one leave (for OEP discovering) -mdis = sb.machine.dis_engine(sb.jitter.bs) -mdis.dont_dis_nulstart_bloc = True -ab = mdis.dis_multibloc(ep) - -bb = asmbloc.basicblocs(ab) -leaves = bb.get_bad_dst() -assert(len(leaves) == 1) -l = leaves.pop() -logging.info(l) -end_label = l.label.offset - -logging.info('final label') -logging.info(end_label) - -# Export CFG graph (dot format) -if options.graph is True: - g = asmbloc.bloc2graph(ab) - open("graph.txt", "w").write(g) - - -if options.verbose is True: - sb.jitter.vm.dump_memory_page_pool() - - -def update_binary(jitter): - sb.pe.Opthdr.AddressOfEntryPoint = sb.pe.virt2rva(jitter.pc) - logging.info('updating binary') - for s in sb.pe.SHList: - sdata = sb.jitter.vm.get_mem(sb.pe.rva2virt(s.addr), s.rawsize) - sb.pe.virt[sb.pe.rva2virt(s.addr)] = sdata - - -# Set callbacks -sb.jitter.add_breakpoint(end_label, update_binary) - -# Run -sb.run() - -# Rebuild PE -new_dll = [] - -sb.pe.SHList.align_sections(0x1000, 0x1000) -logging.info(repr(sb.pe.SHList)) - -sb.pe.DirRes = pe.DirRes(sb.pe) -sb.pe.DirImport.impdesc = None -logging.info(repr(sb.pe.DirImport.impdesc)) -new_dll = sb.libs.gen_new_lib(sb.pe) -logging.info(new_dll) -sb.pe.DirImport.impdesc = [] -sb.pe.DirImport.add_dlldesc(new_dll) -s_myimp = sb.pe.SHList.add_section(name="myimp", rawsize=len(sb.pe.DirImport)) -logging.info(repr(sb.pe.SHList)) -sb.pe.DirImport.set_rva(s_myimp.addr) - -# XXXX TODO -sb.pe.NThdr.optentries[pe.DIRECTORY_ENTRY_DELAY_IMPORT].rva = 0 - -sb.pe.Opthdr.AddressOfEntryPoint = sb.pe.virt2rva(end_label) -bname, fname = os.path.split(options.filename) -fname = os.path.join(bname, fname.replace('.', '_')) -open(fname + '_unupx.bin', 'w').write(str(sb.pe)) diff --git a/test/test_all.py b/test/test_all.py index 1a80cf46..55eead73 100644 --- a/test/test_all.py +++ b/test/test_all.py @@ -199,38 +199,43 @@ for script in [["basic_op.py"], testset += Example(["symbol_exec/single_instr.py"]) ## Jitter -for jitter in ["tcc", "llvm", "python"]: +class ExampleJitter(ExampleDir): + """Jitter examples specificities: + - script path begins with "jitter/" + """ + example_dir = "jitter" + jitter_engines = ["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", 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 [(["jit_x86_32.py", - Example.get_sample("x86_32_sc.bin")], []), - (["jit_arm.py", Example.get_sample("md5_arm"), "-a", - "A684"], []), - (["jit_msp430.py", "msp430_sc.bin", "0"], - [test_msp430]), - (["jit_mips32.py", "mips32_sc_l.bin", "0"], - [test_mips32]), - (["jit_arm_sc.py", "0", "demo_arm_b.bin", "b", "-a", - "0"], [test_arm]), - (["jit_arm_sc.py", "0", "demo_arm_l.bin", "l", "-a", - "0"], [test_arm]), + 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", "msp430_sc.bin", "0"], [test_msp430]), + (["mips32.py", "mips32_sc_l.bin", "0"], [test_mips32]), + (["arm_sc.py", "0", "demo_arm_b.bin", "b", "-a", "0"], + [test_arm]), + (["arm_sc.py", "0", "demo_arm_l.bin", "l", "-a", "0"], + [test_arm]), (["sandbox_pe_x86_32.py", "box_x86_32_enc.bin"], [test_box_enc]), ] + [(["sandbox_pe_x86_32.py", Example.get_sample("x86_32_" + name + ".bin")], [test_box[name]]) for name in test_box_names]: - for jitter in ["tcc", "llvm", "python"]: + 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__": -- cgit 1.4.1 From 663b49b712b4309d44e2ae77e37f26861c4906b7 Mon Sep 17 00:00:00 2001 From: Camille Mougey Date: Sun, 18 Jan 2015 18:36:23 +0100 Subject: Example: Move asm's examples to a `asm` directory --- example/asm/arm.py | 82 +++++++++++++++++++++++++++++++++ example/asm/arm_sc.py | 62 +++++++++++++++++++++++++ example/asm/armt.py | 90 ++++++++++++++++++++++++++++++++++++ example/asm/box_x86_32.py | 61 +++++++++++++++++++++++++ example/asm/box_x86_32_enc.py | 104 ++++++++++++++++++++++++++++++++++++++++++ example/asm/box_x86_64.py | 67 +++++++++++++++++++++++++++ example/asm/mips32.py | 67 +++++++++++++++++++++++++++ example/asm/msp430_sc.py | 52 +++++++++++++++++++++ example/asm/x86.py | 88 +++++++++++++++++++++++++++++++++++ example/asm_arm.py | 82 --------------------------------- example/asm_arm_sc.py | 62 ------------------------- example/asm_armt.py | 90 ------------------------------------ example/asm_box_x86_32.py | 61 ------------------------- example/asm_box_x86_32_enc.py | 104 ------------------------------------------ example/asm_box_x86_64.py | 67 --------------------------- example/asm_mips32.py | 67 --------------------------- example/asm_msp430_sc.py | 52 --------------------- example/asm_x86.py | 88 ----------------------------------- test/test_all.py | 33 ++++++++------ 19 files changed, 693 insertions(+), 686 deletions(-) create mode 100644 example/asm/arm.py create mode 100644 example/asm/arm_sc.py create mode 100644 example/asm/armt.py create mode 100644 example/asm/box_x86_32.py create mode 100644 example/asm/box_x86_32_enc.py create mode 100644 example/asm/box_x86_64.py create mode 100644 example/asm/mips32.py create mode 100644 example/asm/msp430_sc.py create mode 100644 example/asm/x86.py delete mode 100644 example/asm_arm.py delete mode 100644 example/asm_arm_sc.py delete mode 100644 example/asm_armt.py delete mode 100644 example/asm_box_x86_32.py delete mode 100644 example/asm_box_x86_32_enc.py delete mode 100644 example/asm_box_x86_64.py delete mode 100644 example/asm_mips32.py delete mode 100644 example/asm_msp430_sc.py delete mode 100644 example/asm_x86.py (limited to 'test') diff --git a/example/asm/arm.py b/example/asm/arm.py new file mode 100644 index 00000000..28af59fb --- /dev/null +++ b/example/asm/arm.py @@ -0,0 +1,82 @@ +#! /usr/bin/env python +from elfesteem.strpatchwork import StrPatchwork + +from miasm2.core.cpu import parse_ast +from miasm2.arch.arm.arch import mn_arm, base_expr +from miasm2.core import parse_asm +import miasm2.expression.expression as m2_expr +from miasm2.core import asmbloc + +my_mn = mn_arm + +reg_and_id = dict(mn_arm.regs.all_regs_ids_byname) + + +def my_ast_int2expr(a): + return m2_expr.ExprInt32(a) + + +def my_ast_id2expr(t): + return reg_and_id.get(t, m2_expr.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 new file mode 100644 index 00000000..83787f02 --- /dev/null +++ b/example/asm/arm_sc.py @@ -0,0 +1,62 @@ +#! /usr/bin/env python + +from pdb import pm + +from elfesteem.strpatchwork import StrPatchwork + +from miasm2.core import asmbloc +from miasm2.core.cpu import parse_ast +from miasm2.arch.arm.arch import mn_arm, base_expr +from miasm2.core import parse_asm +import miasm2.expression.expression as m2_expr + +reg_and_id = dict(mn_arm.regs.all_regs_ids_byname) + + +def my_ast_int2expr(a): + return m2_expr.ExprInt32(a) + + +def my_ast_id2expr(t): + return reg_and_id.get(t, m2_expr.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 new file mode 100644 index 00000000..f4ce6d2d --- /dev/null +++ b/example/asm/armt.py @@ -0,0 +1,90 @@ +#! /usr/bin/env python + +from pdb import pm + +from elfesteem.strpatchwork import StrPatchwork + +from miasm2.core.cpu import parse_ast +from miasm2.arch.arm.arch import mn_armt, base_expr +from miasm2.core import parse_asm +import miasm2.expression.expression as m2_expr +from miasm2.core import asmbloc + +my_mn = mn_armt + +reg_and_id = dict(mn_armt.regs.all_regs_ids_byname) + + +def my_ast_int2expr(a): + return m2_expr.ExprInt32(a) + + +def my_ast_id2expr(t): + return reg_and_id.get(t, m2_expr.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 new file mode 100644 index 00000000..def7af99 --- /dev/null +++ b/example/asm/box_x86_32.py @@ -0,0 +1,61 @@ +#! /usr/bin/env python +from argparse import ArgumentParser +from pdb import pm + +from elfesteem import pe_init + +from miasm2.core.cpu import parse_ast +from miasm2.arch.x86.arch import mn_x86, base_expr +from miasm2.core import parse_asm +import miasm2.expression.expression as m2_expr +from miasm2.core import asmbloc + +parser = ArgumentParser("x86 32bits assembler") +parser.add_argument("source", help="Source to assemble") +args = parser.parse_args() + +pe = pe_init.PE() +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) + +reg_and_id = dict(mn_x86.regs.all_regs_ids_byname) + + +def my_ast_int2expr(a): + return m2_expr.ExprInt32(a) + + +def my_ast_id2expr(t): + return reg_and_id.get(t, m2_expr.ExprId(t, size=32)) + +my_var_parser = parse_ast(my_ast_id2expr, my_ast_int2expr) +base_expr.setParseAction(my_var_parser) + +with open(args.source) as fstream: + source = fstream.read() + +blocs, symbol_pool = parse_asm.parse_txt(mn_x86, 32, source) + +# fix shellcode addr +symbol_pool.set_offset(symbol_pool.getby_name("main"), pe.rva2virt(s_text.addr)) +symbol_pool.set_offset(symbol_pool.getby_name_create("MessageBoxA"), + pe.DirImport.get_funcvirt('MessageBoxA')) +pe.Opthdr.AddressOfEntryPoint = s_text.addr + +for bloc in blocs[0]: + print bloc + +resolved_b, patches = asmbloc.asm_resolve_final( + mn_x86, blocs[0], symbol_pool) +print patches + +for offset, raw in patches.items(): + pe.virt[offset] = raw + +output = args.source.replace(".S", ".bin") +open(output, 'wb').write(str(pe)) diff --git a/example/asm/box_x86_32_enc.py b/example/asm/box_x86_32_enc.py new file mode 100644 index 00000000..ec4d70ea --- /dev/null +++ b/example/asm/box_x86_32_enc.py @@ -0,0 +1,104 @@ +#! /usr/bin/env python +from pdb import pm + +from elfesteem import pe_init + +from miasm2.core import asmbloc +from miasm2.core.cpu import parse_ast +from miasm2.arch.x86.arch import mn_x86, base_expr +from miasm2.core import parse_asm +import miasm2.expression.expression as m2_expr + +pe = pe_init.PE() +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) + +reg_and_id = dict(mn_x86.regs.all_regs_ids_byname) + + +def my_ast_int2expr(a): + return m2_expr.ExprInt32(a) + + +def my_ast_id2expr(t): + return reg_and_id.get(t, m2_expr.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"), pe.rva2virt(s_text.addr)) +symbol_pool.set_offset(symbol_pool.getby_name_create( + "MessageBoxA"), pe.DirImport.get_funcvirt('MessageBoxA')) +pe.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(): + pe.virt[offset] = raw + +open('box_x86_32_enc.bin', 'wb').write(str(pe)) diff --git a/example/asm/box_x86_64.py b/example/asm/box_x86_64.py new file mode 100644 index 00000000..44aca56e --- /dev/null +++ b/example/asm/box_x86_64.py @@ -0,0 +1,67 @@ +#! /usr/bin/env python +from pdb import pm + +from elfesteem import pe_init + +from miasm2.core import asmbloc +from miasm2.core.cpu import parse_ast +from miasm2.arch.x86.arch import mn_x86, base_expr +from miasm2.core import parse_asm +import miasm2.expression.expression as m2_expr + +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 m2_expr.ExprInt64(a) + + +def my_ast_id2expr(t): + return reg_and_id.get(t, m2_expr.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 new file mode 100644 index 00000000..fc050f1f --- /dev/null +++ b/example/asm/mips32.py @@ -0,0 +1,67 @@ +#! /usr/bin/env python +from pdb import pm + +from elfesteem.strpatchwork import StrPatchwork + +from miasm2.core.cpu import parse_ast +from miasm2.arch.mips32.arch import mn_mips32, base_expr +from miasm2.core import parse_asm +import miasm2.expression.expression as m2_expr +from miasm2.core import asmbloc + +reg_and_id = dict(mn_mips32.regs.all_regs_ids_byname) + + +def my_ast_int2expr(a): + return m2_expr.ExprInt32(a) + + +def my_ast_id2expr(t): + return reg_and_id.get(t, m2_expr.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 new file mode 100644 index 00000000..de488803 --- /dev/null +++ b/example/asm/msp430_sc.py @@ -0,0 +1,52 @@ +#! /usr/bin/env python +from pdb import pm + +from elfesteem.strpatchwork import StrPatchwork + +from miasm2.core import asmbloc +from miasm2.core.cpu import parse_ast +from miasm2.arch.msp430.arch import mn_msp430, base_expr +from miasm2.core import parse_asm +import miasm2.expression.expression as m2_expr + +reg_and_id = dict(mn_msp430.regs.all_regs_ids_byname) + + +def my_ast_int2expr(a): + return m2_expr.ExprInt32(a) + + +def my_ast_id2expr(t): + return reg_and_id.get(t, m2_expr.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 new file mode 100644 index 00000000..d877ceaa --- /dev/null +++ b/example/asm/x86.py @@ -0,0 +1,88 @@ +#! /usr/bin/env python + +from miasm2.core.cpu import parse_ast +from miasm2.arch.x86.arch import mn_x86, base_expr +from miasm2.core import parse_asm +import miasm2.expression.expression as m2_expr +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 m2_expr.ExprInt32(a) + + +def my_ast_id2expr(t): + return reg_and_id.get(t, m2_expr.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/asm_arm.py b/example/asm_arm.py deleted file mode 100644 index 28af59fb..00000000 --- a/example/asm_arm.py +++ /dev/null @@ -1,82 +0,0 @@ -#! /usr/bin/env python -from elfesteem.strpatchwork import StrPatchwork - -from miasm2.core.cpu import parse_ast -from miasm2.arch.arm.arch import mn_arm, base_expr -from miasm2.core import parse_asm -import miasm2.expression.expression as m2_expr -from miasm2.core import asmbloc - -my_mn = mn_arm - -reg_and_id = dict(mn_arm.regs.all_regs_ids_byname) - - -def my_ast_int2expr(a): - return m2_expr.ExprInt32(a) - - -def my_ast_id2expr(t): - return reg_and_id.get(t, m2_expr.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 83787f02..00000000 --- a/example/asm_arm_sc.py +++ /dev/null @@ -1,62 +0,0 @@ -#! /usr/bin/env python - -from pdb import pm - -from elfesteem.strpatchwork import StrPatchwork - -from miasm2.core import asmbloc -from miasm2.core.cpu import parse_ast -from miasm2.arch.arm.arch import mn_arm, base_expr -from miasm2.core import parse_asm -import miasm2.expression.expression as m2_expr - -reg_and_id = dict(mn_arm.regs.all_regs_ids_byname) - - -def my_ast_int2expr(a): - return m2_expr.ExprInt32(a) - - -def my_ast_id2expr(t): - return reg_and_id.get(t, m2_expr.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 f4ce6d2d..00000000 --- a/example/asm_armt.py +++ /dev/null @@ -1,90 +0,0 @@ -#! /usr/bin/env python - -from pdb import pm - -from elfesteem.strpatchwork import StrPatchwork - -from miasm2.core.cpu import parse_ast -from miasm2.arch.arm.arch import mn_armt, base_expr -from miasm2.core import parse_asm -import miasm2.expression.expression as m2_expr -from miasm2.core import asmbloc - -my_mn = mn_armt - -reg_and_id = dict(mn_armt.regs.all_regs_ids_byname) - - -def my_ast_int2expr(a): - return m2_expr.ExprInt32(a) - - -def my_ast_id2expr(t): - return reg_and_id.get(t, m2_expr.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 def7af99..00000000 --- a/example/asm_box_x86_32.py +++ /dev/null @@ -1,61 +0,0 @@ -#! /usr/bin/env python -from argparse import ArgumentParser -from pdb import pm - -from elfesteem import pe_init - -from miasm2.core.cpu import parse_ast -from miasm2.arch.x86.arch import mn_x86, base_expr -from miasm2.core import parse_asm -import miasm2.expression.expression as m2_expr -from miasm2.core import asmbloc - -parser = ArgumentParser("x86 32bits assembler") -parser.add_argument("source", help="Source to assemble") -args = parser.parse_args() - -pe = pe_init.PE() -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) - -reg_and_id = dict(mn_x86.regs.all_regs_ids_byname) - - -def my_ast_int2expr(a): - return m2_expr.ExprInt32(a) - - -def my_ast_id2expr(t): - return reg_and_id.get(t, m2_expr.ExprId(t, size=32)) - -my_var_parser = parse_ast(my_ast_id2expr, my_ast_int2expr) -base_expr.setParseAction(my_var_parser) - -with open(args.source) as fstream: - source = fstream.read() - -blocs, symbol_pool = parse_asm.parse_txt(mn_x86, 32, source) - -# fix shellcode addr -symbol_pool.set_offset(symbol_pool.getby_name("main"), pe.rva2virt(s_text.addr)) -symbol_pool.set_offset(symbol_pool.getby_name_create("MessageBoxA"), - pe.DirImport.get_funcvirt('MessageBoxA')) -pe.Opthdr.AddressOfEntryPoint = s_text.addr - -for bloc in blocs[0]: - print bloc - -resolved_b, patches = asmbloc.asm_resolve_final( - mn_x86, blocs[0], symbol_pool) -print patches - -for offset, raw in patches.items(): - pe.virt[offset] = raw - -output = args.source.replace(".S", ".bin") -open(output, 'wb').write(str(pe)) diff --git a/example/asm_box_x86_32_enc.py b/example/asm_box_x86_32_enc.py deleted file mode 100644 index ec4d70ea..00000000 --- a/example/asm_box_x86_32_enc.py +++ /dev/null @@ -1,104 +0,0 @@ -#! /usr/bin/env python -from pdb import pm - -from elfesteem import pe_init - -from miasm2.core import asmbloc -from miasm2.core.cpu import parse_ast -from miasm2.arch.x86.arch import mn_x86, base_expr -from miasm2.core import parse_asm -import miasm2.expression.expression as m2_expr - -pe = pe_init.PE() -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) - -reg_and_id = dict(mn_x86.regs.all_regs_ids_byname) - - -def my_ast_int2expr(a): - return m2_expr.ExprInt32(a) - - -def my_ast_id2expr(t): - return reg_and_id.get(t, m2_expr.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"), pe.rva2virt(s_text.addr)) -symbol_pool.set_offset(symbol_pool.getby_name_create( - "MessageBoxA"), pe.DirImport.get_funcvirt('MessageBoxA')) -pe.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(): - pe.virt[offset] = raw - -open('box_x86_32_enc.bin', 'wb').write(str(pe)) diff --git a/example/asm_box_x86_64.py b/example/asm_box_x86_64.py deleted file mode 100644 index 44aca56e..00000000 --- a/example/asm_box_x86_64.py +++ /dev/null @@ -1,67 +0,0 @@ -#! /usr/bin/env python -from pdb import pm - -from elfesteem import pe_init - -from miasm2.core import asmbloc -from miasm2.core.cpu import parse_ast -from miasm2.arch.x86.arch import mn_x86, base_expr -from miasm2.core import parse_asm -import miasm2.expression.expression as m2_expr - -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 m2_expr.ExprInt64(a) - - -def my_ast_id2expr(t): - return reg_and_id.get(t, m2_expr.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 fc050f1f..00000000 --- a/example/asm_mips32.py +++ /dev/null @@ -1,67 +0,0 @@ -#! /usr/bin/env python -from pdb import pm - -from elfesteem.strpatchwork import StrPatchwork - -from miasm2.core.cpu import parse_ast -from miasm2.arch.mips32.arch import mn_mips32, base_expr -from miasm2.core import parse_asm -import miasm2.expression.expression as m2_expr -from miasm2.core import asmbloc - -reg_and_id = dict(mn_mips32.regs.all_regs_ids_byname) - - -def my_ast_int2expr(a): - return m2_expr.ExprInt32(a) - - -def my_ast_id2expr(t): - return reg_and_id.get(t, m2_expr.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 de488803..00000000 --- a/example/asm_msp430_sc.py +++ /dev/null @@ -1,52 +0,0 @@ -#! /usr/bin/env python -from pdb import pm - -from elfesteem.strpatchwork import StrPatchwork - -from miasm2.core import asmbloc -from miasm2.core.cpu import parse_ast -from miasm2.arch.msp430.arch import mn_msp430, base_expr -from miasm2.core import parse_asm -import miasm2.expression.expression as m2_expr - -reg_and_id = dict(mn_msp430.regs.all_regs_ids_byname) - - -def my_ast_int2expr(a): - return m2_expr.ExprInt32(a) - - -def my_ast_id2expr(t): - return reg_and_id.get(t, m2_expr.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 d877ceaa..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 -from miasm2.core import parse_asm -import miasm2.expression.expression as m2_expr -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 m2_expr.ExprInt32(a) - - -def my_ast_id2expr(t): - return reg_and_id.get(t, m2_expr.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/test/test_all.py b/test/test_all.py index 55eead73..0bd6ccb3 100644 --- a/test/test_all.py +++ b/test/test_all.py @@ -102,25 +102,32 @@ class ExampleDir(Example): ## 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"]) +class ExampleAssembler(ExampleDir): + """Assembler examples specificities: + - script path begins with "asm/" + """ + example_dir = "asm" + + +testset += ExampleAssembler(['x86.py'], products=["demo_x86_32.bin"]) +test_arm = ExampleAssembler(["arm.py"], + products=["demo_arm_l.bin", "demo_arm_b.bin"]) +test_armt = ExampleAssembler(["armt.py"], products=["demo_armt_l.bin", + "demo_armt_b.bin"]) test_box = {} test_box_names = ["mod", "mod_self", "repmod", "simple"] for source in test_box_names: - test_box[source] = Example(["asm_box_x86_32.py", - Example.get_sample("x86_32_" + source + ".S")], - products=[Example.get_sample("x86_32_" + source + - ".bin")]) + sample_base = Example.get_sample("x86_32_" + source) + test_box[source] = ExampleAssembler(["box_x86_32.py", sample_base + ".S"], + products=[sample_base + ".bin"]) testset += test_box[source] -test_box_enc = Example(["asm_box_x86_32_enc.py"], - products=["box_x86_32_enc.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"]) +test_box_enc = ExampleAssembler(["box_x86_32_enc.py"], + products=["box_x86_32_enc.bin"]) +test_msp430 = ExampleAssembler(["msp430_sc.py"], products=["msp430_sc.bin"]) +test_mips32 = ExampleAssembler(["mips32.py"], products=["mips32_sc_b.bin", + "mips32_sc_l.bin"]) testset += test_arm testset += test_armt -- cgit 1.4.1 From 9206458e0f4b815e4af68f8978d96d14632a087f Mon Sep 17 00:00:00 2001 From: Camille Mougey Date: Sun, 18 Jan 2015 18:44:44 +0100 Subject: Example: Move disasm's examples to a `disasm` directory --- example/disasm/file.py | 19 +++++ example/disasm/full.py | 183 +++++++++++++++++++++++++++++++++++++++++ example/disasm/function.py | 18 ++++ example/disasm/single_instr.py | 12 +++ example/disasm_file.py | 19 ----- example/disasm_full.py | 183 ----------------------------------------- example/disasm_function.py | 18 ---- example/disasm_single_instr.py | 12 --- test/test_all.py | 29 +++++-- 9 files changed, 253 insertions(+), 240 deletions(-) create mode 100644 example/disasm/file.py create mode 100644 example/disasm/full.py create mode 100644 example/disasm/function.py create mode 100644 example/disasm/single_instr.py delete mode 100644 example/disasm_file.py delete mode 100644 example/disasm_full.py delete mode 100644 example/disasm_function.py delete mode 100644 example/disasm_single_instr.py (limited to 'test') diff --git a/example/disasm/file.py b/example/disasm/file.py new file mode 100644 index 00000000..5bae0e89 --- /dev/null +++ b/example/disasm/file.py @@ -0,0 +1,19 @@ +import sys +from miasm2.arch.x86.disasm import dis_x86_32 +from miasm2.core.asmbloc import bloc2graph +from miasm2.analysis.binary import Container + +if len(sys.argv) != 3: + print 'Example:' + print "%s samples/box_upx.exe 0x410f90" % sys.argv[0] + sys.exit(0) + +addr = int(sys.argv[2], 16) +cont = Container.from_stream(open(sys.argv[1])) +mdis = dis_x86_32(cont.bin_stream) +# Inform the engine to avoid disassembling null instructions +mdis.dont_dis_nulstart_bloc = True +blocs = mdis.dis_multibloc(addr) + +graph = bloc2graph(blocs) +open('graph.txt', 'w').write(graph) diff --git a/example/disasm/full.py b/example/disasm/full.py new file mode 100644 index 00000000..f7ca6780 --- /dev/null +++ b/example/disasm/full.py @@ -0,0 +1,183 @@ +import os +import logging +from argparse import ArgumentParser +from pdb import pm + +from miasm2.analysis.binary import Container +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 + +log = logging.getLogger("dis") +console_handler = logging.StreamHandler() +console_handler.setFormatter(logging.Formatter("%(levelname)-5s: %(message)s")) +log.addHandler(console_handler) +log.setLevel(logging.INFO) + +filename = os.environ.get('PYTHONSTARTUP') +if filename and os.path.isfile(filename): + execfile(filename) + + +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(args.architecture) +mn, dis_engine, ira = machine.mn, machine.dis_engine, machine.ira +log.info('ok') + +log.info('Load binary') +with open(args.filename) as fdesc: + cont = Container.from_stream(fdesc, addr=args.shiftoffset) + +default_addr = cont.entry_point +bs = cont.bin_stream +e = cont.executable + +log.info('ok') +mdis = dis_engine(bs) +# configure disasm engine +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.address] + +if len(addrs) == 0 and default_addr is not None: + addrs.append(default_addr) +for ad in addrs: + todo = [(mdis, None, ad)] + +done = set() +all_funcs = set() +all_funcs_blocs = {} + + +done_interval = interval() +finish = False + +# Main disasm loop +while not finish and todo: + while not finish and todo: + mdis, caller, ad = todo.pop(0) + if ad in done: + continue + done.add(ad) + ab = mdis.dis_multibloc(ad) + + log.info('func ok %.16x (%d)' % (ad, len(all_funcs))) + + all_funcs.add(ad) + all_funcs_blocs[ad] = ab + for b in ab: + for l in b.lines: + done_interval += interval([(l.offset, l.offset + l.l)]) + + if args.funcswatchdog is not None: + args.funcswatchdog -= 1 + if args.recurfunctions: + for b in ab: + i = b.get_subcall_instr() + if not i: + continue + for d in i.getdstflow(mdis.symbol_pool): + if not (isinstance(d, ExprId) and isinstance(d.name, asm_label)): + continue + todo.append((mdis, i, d.name.offset)) + + if args.funcswatchdog is not None and args.funcswatchdog <= 0: + finish = True + + if args.try_disasm_all: + for a, b in done_interval.intervals: + if b in done: + continue + log.debug('add func %s' % hex(b)) + todo.append((mdis, None, b)) + + +# Generate dotty graph +all_blocs = [] +for blocs in all_funcs_blocs.values(): + all_blocs += blocs + # for b in blocs: + # print b + +log.info('generate graph file') +g = bloc2graph(all_blocs, True) +open('graph_execflow.txt', 'w').write(g) + +log.info('generate intervals') + +all_lines = [] +total_l = 0 + +print done_interval +if args.image: + log.info('build img') + done_interval.show() + +for i, j in done_interval.intervals: + log.debug((hex(i), "->", hex(j))) + + +all_lines.sort(key=lambda x: x.offset) +open('lines.txt', 'w').write('\n'.join([str(l) for l in all_lines])) +log.info('total lines %s' % total_l) + + +# Bonus, generate IR graph +if args.gen_ir: + log.info("generating IR") + + ir_arch = ira(mdis.symbol_pool) + ir_arch.blocs = {} + for ad, all_bloc in all_funcs_blocs.items(): + log.info("generating IR... %x" % ad) + for b in all_bloc: + ir_arch.add_bloc(b) + + log.info("Gen Graph... %x" % ad) + + ir_arch.gen_graph() + + if args.simplify: + ir_arch.dead_simp() + + out = ir_arch.graph() + open('graph_irflow.txt', 'w').write(out) 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/single_instr.py b/example/disasm/single_instr.py new file mode 100644 index 00000000..0e29dcee --- /dev/null +++ b/example/disasm/single_instr.py @@ -0,0 +1,12 @@ +from miasm2.arch.x86.arch import mn_x86 +from miasm2.arch.x86.regs import EDX + +l = mn_x86.fromstring('MOV EAX, EBX', 32) +print "instruction:", l +print "arg:", l.args[0] +x = mn_x86.asm(l) +print x +l.args[0] = EDX +y = mn_x86.asm(l) +print y +print mn_x86.dis(y[0], 32) diff --git a/example/disasm_file.py b/example/disasm_file.py deleted file mode 100644 index 5bae0e89..00000000 --- a/example/disasm_file.py +++ /dev/null @@ -1,19 +0,0 @@ -import sys -from miasm2.arch.x86.disasm import dis_x86_32 -from miasm2.core.asmbloc import bloc2graph -from miasm2.analysis.binary import Container - -if len(sys.argv) != 3: - print 'Example:' - print "%s samples/box_upx.exe 0x410f90" % sys.argv[0] - sys.exit(0) - -addr = int(sys.argv[2], 16) -cont = Container.from_stream(open(sys.argv[1])) -mdis = dis_x86_32(cont.bin_stream) -# Inform the engine to avoid disassembling null instructions -mdis.dont_dis_nulstart_bloc = True -blocs = mdis.dis_multibloc(addr) - -graph = bloc2graph(blocs) -open('graph.txt', 'w').write(graph) diff --git a/example/disasm_full.py b/example/disasm_full.py deleted file mode 100644 index f7ca6780..00000000 --- a/example/disasm_full.py +++ /dev/null @@ -1,183 +0,0 @@ -import os -import logging -from argparse import ArgumentParser -from pdb import pm - -from miasm2.analysis.binary import Container -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 - -log = logging.getLogger("dis") -console_handler = logging.StreamHandler() -console_handler.setFormatter(logging.Formatter("%(levelname)-5s: %(message)s")) -log.addHandler(console_handler) -log.setLevel(logging.INFO) - -filename = os.environ.get('PYTHONSTARTUP') -if filename and os.path.isfile(filename): - execfile(filename) - - -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(args.architecture) -mn, dis_engine, ira = machine.mn, machine.dis_engine, machine.ira -log.info('ok') - -log.info('Load binary') -with open(args.filename) as fdesc: - cont = Container.from_stream(fdesc, addr=args.shiftoffset) - -default_addr = cont.entry_point -bs = cont.bin_stream -e = cont.executable - -log.info('ok') -mdis = dis_engine(bs) -# configure disasm engine -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.address] - -if len(addrs) == 0 and default_addr is not None: - addrs.append(default_addr) -for ad in addrs: - todo = [(mdis, None, ad)] - -done = set() -all_funcs = set() -all_funcs_blocs = {} - - -done_interval = interval() -finish = False - -# Main disasm loop -while not finish and todo: - while not finish and todo: - mdis, caller, ad = todo.pop(0) - if ad in done: - continue - done.add(ad) - ab = mdis.dis_multibloc(ad) - - log.info('func ok %.16x (%d)' % (ad, len(all_funcs))) - - all_funcs.add(ad) - all_funcs_blocs[ad] = ab - for b in ab: - for l in b.lines: - done_interval += interval([(l.offset, l.offset + l.l)]) - - if args.funcswatchdog is not None: - args.funcswatchdog -= 1 - if args.recurfunctions: - for b in ab: - i = b.get_subcall_instr() - if not i: - continue - for d in i.getdstflow(mdis.symbol_pool): - if not (isinstance(d, ExprId) and isinstance(d.name, asm_label)): - continue - todo.append((mdis, i, d.name.offset)) - - if args.funcswatchdog is not None and args.funcswatchdog <= 0: - finish = True - - if args.try_disasm_all: - for a, b in done_interval.intervals: - if b in done: - continue - log.debug('add func %s' % hex(b)) - todo.append((mdis, None, b)) - - -# Generate dotty graph -all_blocs = [] -for blocs in all_funcs_blocs.values(): - all_blocs += blocs - # for b in blocs: - # print b - -log.info('generate graph file') -g = bloc2graph(all_blocs, True) -open('graph_execflow.txt', 'w').write(g) - -log.info('generate intervals') - -all_lines = [] -total_l = 0 - -print done_interval -if args.image: - log.info('build img') - done_interval.show() - -for i, j in done_interval.intervals: - log.debug((hex(i), "->", hex(j))) - - -all_lines.sort(key=lambda x: x.offset) -open('lines.txt', 'w').write('\n'.join([str(l) for l in all_lines])) -log.info('total lines %s' % total_l) - - -# Bonus, generate IR graph -if args.gen_ir: - log.info("generating IR") - - ir_arch = ira(mdis.symbol_pool) - ir_arch.blocs = {} - for ad, all_bloc in all_funcs_blocs.items(): - log.info("generating IR... %x" % ad) - for b in all_bloc: - ir_arch.add_bloc(b) - - log.info("Gen Graph... %x" % ad) - - ir_arch.gen_graph() - - if args.simplify: - ir_arch.dead_simp() - - out = ir_arch.graph() - open('graph_irflow.txt', 'w').write(out) diff --git a/example/disasm_function.py b/example/disasm_function.py deleted file mode 100644 index 0d443c26..00000000 --- a/example/disasm_function.py +++ /dev/null @@ -1,18 +0,0 @@ -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_single_instr.py b/example/disasm_single_instr.py deleted file mode 100644 index 0e29dcee..00000000 --- a/example/disasm_single_instr.py +++ /dev/null @@ -1,12 +0,0 @@ -from miasm2.arch.x86.arch import mn_x86 -from miasm2.arch.x86.regs import EDX - -l = mn_x86.fromstring('MOV EAX, EBX', 32) -print "instruction:", l -print "arg:", l.args[0] -x = mn_x86.asm(l) -print x -l.args[0] = EDX -y = mn_x86.asm(l) -print y -print mn_x86.dis(y[0], 32) diff --git a/test/test_all.py b/test/test_all.py index 0bd6ccb3..65172a2d 100644 --- a/test/test_all.py +++ b/test/test_all.py @@ -134,26 +134,38 @@ testset += test_armt testset += test_box_enc testset += test_msp430 testset += test_mips32 -for script in [["disasm_single_instr.py"], - ["disasm_function.py"], - ["disasm_file.py", Example.get_sample("box_upx.exe"), - "0x410f90"], + + +class ExampleDisassembler(ExampleDir): + """Disassembler examples specificities: + - script path begins with "disasm/" + """ + example_dir = "disasm" + + +for script in [["single_instr.py"], + ["function.py"], + ["file.py", Example.get_sample("box_upx.exe"), "0x410f90"], ]: - testset += Example(script) + testset += ExampleDisassembler(script) + class ExampleDisasmFull(Example): - """TestDis specificities: - - script: disasm_full.py + """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(ExampleDisasmFull, self).__init__(*args, **kwargs) - self.command_line = ["disasm_full.py", "-g", "-s"] + self.command_line + self.command_line = [os.path.join(ExampleDisassembler.example_dir, + "full.py"), + "-g", "-s"] + self.command_line self.products += ["graph_execflow.txt", "graph_irflow.txt", "lines.txt", "out.txt"] + testset += ExampleDisasmFull(["arml", "demo_arm_l.bin", "0"], depends=[test_arm]) testset += ExampleDisasmFull(["armb", "demo_arm_b.bin", "0"], @@ -172,6 +184,7 @@ testset += ExampleDisasmFull(["mips32l", "mips32_sc_l.bin", "0"], testset += ExampleDisasmFull(["mips32b", "mips32_sc_b.bin", "0"], depends=[test_mips32]) + ## Expression class ExampleExpression(ExampleDir): """Expression examples specificities: -- cgit 1.4.1 From 8b9047402913c46a545aadeea10fce1011ddd6bd Mon Sep 17 00:00:00 2001 From: Camille Mougey Date: Thu, 22 Jan 2015 17:59:11 +0100 Subject: Example/ASM: Avoid duplicating code by using a common script shellcode.py --- example/asm/arm.py | 82 ------------------------------- example/asm/armt.py | 90 ---------------------------------- example/asm/box_x86_32.py | 61 ----------------------- example/asm/box_x86_32_enc.py | 104 --------------------------------------- example/asm/mips32.py | 67 ------------------------- example/asm/msp430_sc.py | 52 -------------------- example/asm/shellcode.py | 110 ++++++++++++++++++++++++++++++++++++++++++ example/asm/x86.py | 88 --------------------------------- test/test_all.py | 103 +++++++++++++++++++++++---------------- 9 files changed, 171 insertions(+), 586 deletions(-) delete mode 100644 example/asm/arm.py delete mode 100644 example/asm/armt.py delete mode 100644 example/asm/box_x86_32.py delete mode 100644 example/asm/box_x86_32_enc.py delete mode 100644 example/asm/mips32.py delete mode 100644 example/asm/msp430_sc.py create mode 100644 example/asm/shellcode.py delete mode 100644 example/asm/x86.py (limited to 'test') diff --git a/example/asm/arm.py b/example/asm/arm.py deleted file mode 100644 index 28af59fb..00000000 --- a/example/asm/arm.py +++ /dev/null @@ -1,82 +0,0 @@ -#! /usr/bin/env python -from elfesteem.strpatchwork import StrPatchwork - -from miasm2.core.cpu import parse_ast -from miasm2.arch.arm.arch import mn_arm, base_expr -from miasm2.core import parse_asm -import miasm2.expression.expression as m2_expr -from miasm2.core import asmbloc - -my_mn = mn_arm - -reg_and_id = dict(mn_arm.regs.all_regs_ids_byname) - - -def my_ast_int2expr(a): - return m2_expr.ExprInt32(a) - - -def my_ast_id2expr(t): - return reg_and_id.get(t, m2_expr.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/armt.py b/example/asm/armt.py deleted file mode 100644 index f4ce6d2d..00000000 --- a/example/asm/armt.py +++ /dev/null @@ -1,90 +0,0 @@ -#! /usr/bin/env python - -from pdb import pm - -from elfesteem.strpatchwork import StrPatchwork - -from miasm2.core.cpu import parse_ast -from miasm2.arch.arm.arch import mn_armt, base_expr -from miasm2.core import parse_asm -import miasm2.expression.expression as m2_expr -from miasm2.core import asmbloc - -my_mn = mn_armt - -reg_and_id = dict(mn_armt.regs.all_regs_ids_byname) - - -def my_ast_int2expr(a): - return m2_expr.ExprInt32(a) - - -def my_ast_id2expr(t): - return reg_and_id.get(t, m2_expr.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 def7af99..00000000 --- a/example/asm/box_x86_32.py +++ /dev/null @@ -1,61 +0,0 @@ -#! /usr/bin/env python -from argparse import ArgumentParser -from pdb import pm - -from elfesteem import pe_init - -from miasm2.core.cpu import parse_ast -from miasm2.arch.x86.arch import mn_x86, base_expr -from miasm2.core import parse_asm -import miasm2.expression.expression as m2_expr -from miasm2.core import asmbloc - -parser = ArgumentParser("x86 32bits assembler") -parser.add_argument("source", help="Source to assemble") -args = parser.parse_args() - -pe = pe_init.PE() -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) - -reg_and_id = dict(mn_x86.regs.all_regs_ids_byname) - - -def my_ast_int2expr(a): - return m2_expr.ExprInt32(a) - - -def my_ast_id2expr(t): - return reg_and_id.get(t, m2_expr.ExprId(t, size=32)) - -my_var_parser = parse_ast(my_ast_id2expr, my_ast_int2expr) -base_expr.setParseAction(my_var_parser) - -with open(args.source) as fstream: - source = fstream.read() - -blocs, symbol_pool = parse_asm.parse_txt(mn_x86, 32, source) - -# fix shellcode addr -symbol_pool.set_offset(symbol_pool.getby_name("main"), pe.rva2virt(s_text.addr)) -symbol_pool.set_offset(symbol_pool.getby_name_create("MessageBoxA"), - pe.DirImport.get_funcvirt('MessageBoxA')) -pe.Opthdr.AddressOfEntryPoint = s_text.addr - -for bloc in blocs[0]: - print bloc - -resolved_b, patches = asmbloc.asm_resolve_final( - mn_x86, blocs[0], symbol_pool) -print patches - -for offset, raw in patches.items(): - pe.virt[offset] = raw - -output = args.source.replace(".S", ".bin") -open(output, 'wb').write(str(pe)) diff --git a/example/asm/box_x86_32_enc.py b/example/asm/box_x86_32_enc.py deleted file mode 100644 index ec4d70ea..00000000 --- a/example/asm/box_x86_32_enc.py +++ /dev/null @@ -1,104 +0,0 @@ -#! /usr/bin/env python -from pdb import pm - -from elfesteem import pe_init - -from miasm2.core import asmbloc -from miasm2.core.cpu import parse_ast -from miasm2.arch.x86.arch import mn_x86, base_expr -from miasm2.core import parse_asm -import miasm2.expression.expression as m2_expr - -pe = pe_init.PE() -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) - -reg_and_id = dict(mn_x86.regs.all_regs_ids_byname) - - -def my_ast_int2expr(a): - return m2_expr.ExprInt32(a) - - -def my_ast_id2expr(t): - return reg_and_id.get(t, m2_expr.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"), pe.rva2virt(s_text.addr)) -symbol_pool.set_offset(symbol_pool.getby_name_create( - "MessageBoxA"), pe.DirImport.get_funcvirt('MessageBoxA')) -pe.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(): - pe.virt[offset] = raw - -open('box_x86_32_enc.bin', 'wb').write(str(pe)) diff --git a/example/asm/mips32.py b/example/asm/mips32.py deleted file mode 100644 index fc050f1f..00000000 --- a/example/asm/mips32.py +++ /dev/null @@ -1,67 +0,0 @@ -#! /usr/bin/env python -from pdb import pm - -from elfesteem.strpatchwork import StrPatchwork - -from miasm2.core.cpu import parse_ast -from miasm2.arch.mips32.arch import mn_mips32, base_expr -from miasm2.core import parse_asm -import miasm2.expression.expression as m2_expr -from miasm2.core import asmbloc - -reg_and_id = dict(mn_mips32.regs.all_regs_ids_byname) - - -def my_ast_int2expr(a): - return m2_expr.ExprInt32(a) - - -def my_ast_id2expr(t): - return reg_and_id.get(t, m2_expr.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 de488803..00000000 --- a/example/asm/msp430_sc.py +++ /dev/null @@ -1,52 +0,0 @@ -#! /usr/bin/env python -from pdb import pm - -from elfesteem.strpatchwork import StrPatchwork - -from miasm2.core import asmbloc -from miasm2.core.cpu import parse_ast -from miasm2.arch.msp430.arch import mn_msp430, base_expr -from miasm2.core import parse_asm -import miasm2.expression.expression as m2_expr - -reg_and_id = dict(mn_msp430.regs.all_regs_ids_byname) - - -def my_ast_int2expr(a): - return m2_expr.ExprInt32(a) - - -def my_ast_id2expr(t): - return reg_and_id.get(t, m2_expr.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/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 ", + 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/x86.py b/example/asm/x86.py deleted file mode 100644 index d877ceaa..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 -from miasm2.core import parse_asm -import miasm2.expression.expression as m2_expr -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 m2_expr.ExprInt32(a) - - -def my_ast_id2expr(t): - return reg_and_id.get(t, m2_expr.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/test/test_all.py b/test/test_all.py index 65172a2d..38793b9b 100644 --- a/test/test_all.py +++ b/test/test_all.py @@ -108,32 +108,52 @@ class ExampleAssembler(ExampleDir): """ example_dir = "asm" +class ExampleShellcode(Example): + """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 = [os.path.join(ExampleAssembler.example_dir, + "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"]) -testset += ExampleAssembler(['x86.py'], products=["demo_x86_32.bin"]) -test_arm = ExampleAssembler(["arm.py"], - products=["demo_arm_l.bin", "demo_arm_b.bin"]) -test_armt = ExampleAssembler(["armt.py"], products=["demo_armt_l.bin", - "demo_armt_b.bin"]) +test_armb = ExampleShellcode(["armb", "arm_simple.S", "demo_arm_b.bin"]) +test_arml = ExampleShellcode(["arml", "arm_simple.S", "demo_arm_l.bin"]) +test_armtb = ExampleShellcode(["armtb", "armt.S", "demo_armt_b.bin"]) +test_armtl = ExampleShellcode(["armtl", "armt.S", "demo_armt_l.bin"]) test_box = {} -test_box_names = ["mod", "mod_self", "repmod", "simple"] +test_box_names = ["mod", "mod_self", "repmod", "simple", "enc"] for source in test_box_names: - sample_base = Example.get_sample("x86_32_" + source) - test_box[source] = ExampleAssembler(["box_x86_32.py", sample_base + ".S"], - products=[sample_base + ".bin"]) + 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_box_enc = ExampleAssembler(["box_x86_32_enc.py"], - products=["box_x86_32_enc.bin"]) -test_msp430 = ExampleAssembler(["msp430_sc.py"], products=["msp430_sc.bin"]) -test_mips32 = ExampleAssembler(["mips32.py"], products=["mips32_sc_b.bin", - "mips32_sc_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"]) -testset += test_arm -testset += test_armt -testset += test_box_enc +testset += test_armb +testset += test_arml +testset += test_armtb +testset += test_armtl testset += test_msp430 -testset += test_mips32 +testset += test_mips32b +testset += test_mips32l class ExampleDisassembler(ExampleDir): @@ -166,23 +186,22 @@ class ExampleDisasmFull(Example): "out.txt"] -testset += ExampleDisasmFull(["arml", "demo_arm_l.bin", "0"], - depends=[test_arm]) -testset += ExampleDisasmFull(["armb", "demo_arm_b.bin", "0"], - depends=[test_arm]) -testset += ExampleDisasmFull(["armtl", "demo_armt_l.bin", "0"], - depends=[test_armt]) -testset += ExampleDisasmFull(["armtb", "demo_armt_b.bin", "0"], - depends=[test_armt]) +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(["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", "msp430_sc.bin", "0"], - depends=[test_msp430]) -testset += ExampleDisasmFull(["mips32l", "mips32_sc_l.bin", "0"], - depends=[test_mips32]) -testset += ExampleDisasmFull(["mips32b", "mips32_sc_b.bin", "0"], - depends=[test_mips32]) + "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]) ## Expression @@ -240,14 +259,14 @@ for jitter in ExampleJitter.jitter_engines: 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", "msp430_sc.bin", "0"], [test_msp430]), - (["mips32.py", "mips32_sc_l.bin", "0"], [test_mips32]), - (["arm_sc.py", "0", "demo_arm_b.bin", "b", "-a", "0"], - [test_arm]), - (["arm_sc.py", "0", "demo_arm_l.bin", "l", "-a", "0"], - [test_arm]), - (["sandbox_pe_x86_32.py", "box_x86_32_enc.bin"], - [test_box_enc]), + (["msp430.py", Example.get_sample("msp430_sc.bin"), "0"], + [test_msp430]), + (["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]]) -- cgit 1.4.1 From 5306f0ea5baba77df35f1ce27664502c294ca025 Mon Sep 17 00:00:00 2001 From: Camille Mougey Date: Fri, 23 Jan 2015 11:25:51 +0100 Subject: TestAll: Launch examples from their subdir, merge ExampleDir into Example --- test/test_all.py | 54 ++++++++++++++++++++++++------------------------------ 1 file changed, 24 insertions(+), 30 deletions(-) (limited to 'test') diff --git a/test/test_all.py b/test/test_all.py index 38793b9b..dbdb3a44 100644 --- a/test/test_all.py +++ b/test/test_all.py @@ -74,11 +74,14 @@ class Example(Test): - @tags: TAGS["example"]""" # Directory containing samples for examples - sample_dir = "samples" + 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 @@ -87,28 +90,14 @@ class Example(Test): return os.path.join(cls.sample_dir, sample_name) -class ExampleDir(Example): - "Launch examples from a given directory" - - example_dir = "" - - def __init__(self, *args, **kwargs): - if not self.example_dir: - raise NotImplementedError("ExampleDir should be inherited") - - super(ExampleDir, self).__init__(*args, **kwargs) - self.command_line[0] = os.path.join(self.example_dir, - self.command_line[0]) - - ## Assembler -class ExampleAssembler(ExampleDir): +class ExampleAssembler(Example): """Assembler examples specificities: - script path begins with "asm/" """ example_dir = "asm" -class ExampleShellcode(Example): +class ExampleShellcode(ExampleAssembler): """Specificities: - script: asm/shellcode.py - @products: graph.txt + 3rd arg @@ -118,8 +107,7 @@ class ExampleShellcode(Example): def __init__(self, *args, **kwargs): super(ExampleShellcode, self).__init__(*args, **kwargs) - self.command_line = [os.path.join(ExampleAssembler.example_dir, - "shellcode.py"), + self.command_line = ["shellcode.py", self.command_line[0]] + \ map(Example.get_sample, self.command_line[1:3]) + \ self.command_line[3:] @@ -156,7 +144,7 @@ testset += test_mips32b testset += test_mips32l -class ExampleDisassembler(ExampleDir): +class ExampleDisassembler(Example): """Disassembler examples specificities: - script path begins with "disasm/" """ @@ -170,7 +158,7 @@ for script in [["single_instr.py"], testset += ExampleDisassembler(script) -class ExampleDisasmFull(Example): +class ExampleDisasmFull(ExampleDisassembler): """DisasmFull specificities: - script: disasm/full.py - flags: -g -s @@ -179,11 +167,8 @@ class ExampleDisasmFull(Example): def __init__(self, *args, **kwargs): super(ExampleDisasmFull, self).__init__(*args, **kwargs) - self.command_line = [os.path.join(ExampleDisassembler.example_dir, - "full.py"), - "-g", "-s"] + self.command_line - self.products += ["graph_execflow.txt", "graph_irflow.txt", "lines.txt", - "out.txt"] + 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"), @@ -205,7 +190,7 @@ testset += ExampleDisasmFull(["mips32b", Example.get_sample("mips32_sc_b.bin"), ## Expression -class ExampleExpression(ExampleDir): +class ExampleExpression(Example): """Expression examples specificities: - script path begins with "expression/" """ @@ -235,16 +220,25 @@ for script in [["basic_op.py"], testset += ExampleExpression(script) ## Symbolic Execution -testset += Example(["symbol_exec/single_instr.py"]) +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(ExampleDir): +class ExampleJitter(Example): """Jitter examples specificities: - script path begins with "jitter/" """ example_dir = "jitter" jitter_engines = ["tcc", "llvm", "python"] + for jitter in ExampleJitter.jitter_engines: # Take 5 min on a Core i5 tags = {"python": [TAGS["long"]], -- cgit 1.4.1 From c98879f0c1df3554fb16110f4b0b49e57da29a1b Mon Sep 17 00:00:00 2001 From: Camille Mougey Date: Fri, 23 Jan 2015 11:29:57 +0100 Subject: TestAll: Add missing products --- test/test_all.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'test') diff --git a/test/test_all.py b/test/test_all.py index dbdb3a44..87a60994 100644 --- a/test/test_all.py +++ b/test/test_all.py @@ -151,11 +151,12 @@ class ExampleDisassembler(Example): example_dir = "disasm" -for script in [["single_instr.py"], - ["function.py"], - ["file.py", Example.get_sample("box_upx.exe"), "0x410f90"], - ]: - testset += ExampleDisassembler(script) +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): @@ -207,7 +208,7 @@ 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"]) + products=["graph_instr.txt", "out.txt"]) for script in [["basic_op.py"], ["basic_simplification.py"], -- cgit 1.4.1 From a5f035142ce772f7868c0a67cb60d876dedfc0dc Mon Sep 17 00:00:00 2001 From: Camille Mougey Date: Fri, 23 Jan 2015 12:33:38 +0100 Subject: Example/ASM: Test the x86_64 example --- example/asm/box_x86_64.py | 67 ----------------------------------------------- test/test_all.py | 15 ++++++----- 2 files changed, 9 insertions(+), 73 deletions(-) delete mode 100644 example/asm/box_x86_64.py (limited to 'test') diff --git a/example/asm/box_x86_64.py b/example/asm/box_x86_64.py deleted file mode 100644 index 44aca56e..00000000 --- a/example/asm/box_x86_64.py +++ /dev/null @@ -1,67 +0,0 @@ -#! /usr/bin/env python -from pdb import pm - -from elfesteem import pe_init - -from miasm2.core import asmbloc -from miasm2.core.cpu import parse_ast -from miasm2.arch.x86.arch import mn_x86, base_expr -from miasm2.core import parse_asm -import miasm2.expression.expression as m2_expr - -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 m2_expr.ExprInt64(a) - - -def my_ast_id2expr(t): - return reg_and_id.get(t, m2_expr.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/test/test_all.py b/test/test_all.py index 87a60994..86c8241a 100644 --- a/test/test_all.py +++ b/test/test_all.py @@ -116,11 +116,6 @@ class ExampleShellcode(ExampleAssembler): testset += ExampleShellcode(['x86_32', 'x86_32_manip_ptr.S', "demo_x86_32.bin"]) -test_armb = ExampleShellcode(["armb", "arm_simple.S", "demo_arm_b.bin"]) -test_arml = ExampleShellcode(["arml", "arm_simple.S", "demo_arm_l.bin"]) -test_armtb = ExampleShellcode(["armtb", "armt.S", "demo_armt_b.bin"]) -test_armtl = ExampleShellcode(["armtl", "armt.S", "demo_armt_l.bin"]) - test_box = {} test_box_names = ["mod", "mod_self", "repmod", "simple", "enc"] for source in test_box_names: @@ -131,9 +126,15 @@ for source in test_box_names: 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_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 @@ -142,7 +143,7 @@ testset += test_armtl testset += test_msp430 testset += test_mips32b testset += test_mips32l - +testset += test_x86_64 class ExampleDisassembler(Example): """Disassembler examples specificities: @@ -188,6 +189,8 @@ 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 -- cgit 1.4.1 From 29a65d37ba8cc3c1e4b06807d4dee3ef32bb2e8f Mon Sep 17 00:00:00 2001 From: Camille Mougey Date: Fri, 23 Jan 2015 12:39:48 +0100 Subject: Example/ASM: Test the second ARM (arm_sc.S) example --- example/asm/arm_sc.py | 62 --------------------------------------------------- test/test_all.py | 8 +++++++ 2 files changed, 8 insertions(+), 62 deletions(-) delete mode 100644 example/asm/arm_sc.py (limited to 'test') diff --git a/example/asm/arm_sc.py b/example/asm/arm_sc.py deleted file mode 100644 index 83787f02..00000000 --- a/example/asm/arm_sc.py +++ /dev/null @@ -1,62 +0,0 @@ -#! /usr/bin/env python - -from pdb import pm - -from elfesteem.strpatchwork import StrPatchwork - -from miasm2.core import asmbloc -from miasm2.core.cpu import parse_ast -from miasm2.arch.arm.arch import mn_arm, base_expr -from miasm2.core import parse_asm -import miasm2.expression.expression as m2_expr - -reg_and_id = dict(mn_arm.regs.all_regs_ids_byname) - - -def my_ast_int2expr(a): - return m2_expr.ExprInt32(a) - - -def my_ast_id2expr(t): - return reg_and_id.get(t, m2_expr.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/test/test_all.py b/test/test_all.py index 86c8241a..cb0adf64 100644 --- a/test/test_all.py +++ b/test/test_all.py @@ -128,6 +128,8 @@ for source in test_box_names: 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"]) @@ -138,6 +140,8 @@ test_x86_64 = ExampleShellcode(["x86_64", "x86_64.S", "demo_x86_64.bin", testset += test_armb testset += test_arml +testset += test_armb_sc +testset += test_arml_sc testset += test_armtb testset += test_armtl testset += test_msp430 @@ -177,6 +181,10 @@ 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"), -- cgit 1.4.1 From 4ed9736a17347662a89997f6e2afa1d09af7d3ab Mon Sep 17 00:00:00 2001 From: Camille Mougey Date: Fri, 23 Jan 2015 17:26:35 +0100 Subject: TestAll: Add an empty space between ']' and z3 warning message --- test/test_all.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test') diff --git a/test/test_all.py b/test/test_all.py index cb0adf64..70ab8e66 100644 --- a/test/test_all.py +++ b/test/test_all.py @@ -372,7 +372,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"]) -- cgit 1.4.1 From 7b9bbe4754db4d1f5229cc5cc5769ad6cf2e0a84 Mon Sep 17 00:00:00 2001 From: Camille Mougey Date: Mon, 26 Jan 2015 09:53:30 +0100 Subject: Example/ASM: Add a minimalist example --- example/asm/simple.py | 37 +++++++++++++++++++++++++++++++++++++ test/test_all.py | 3 +++ 2 files changed, 40 insertions(+) create mode 100644 example/asm/simple.py (limited to 'test') 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/test/test_all.py b/test/test_all.py index 70ab8e66..5de12bf4 100644 --- a/test/test_all.py +++ b/test/test_all.py @@ -97,6 +97,9 @@ class ExampleAssembler(Example): """ example_dir = "asm" + +testset += ExampleAssembler(["simple.py"]) + class ExampleShellcode(ExampleAssembler): """Specificities: - script: asm/shellcode.py -- cgit 1.4.1