From 620c96e891d0ad356332713a23b39b9d2382470c Mon Sep 17 00:00:00 2001 From: Ajax Date: Fri, 31 Mar 2017 15:09:01 +0200 Subject: Introduce a naive "System V" calling convention --- test/arch/x86/qemu/testqemu.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'test') diff --git a/test/arch/x86/qemu/testqemu.py b/test/arch/x86/qemu/testqemu.py index 5f26d6f3..e6c487f2 100644 --- a/test/arch/x86/qemu/testqemu.py +++ b/test/arch/x86/qemu/testqemu.py @@ -40,7 +40,7 @@ nb_tests = 1 def xxx___printf_chk(jitter): """Tiny implementation of printf_chk""" global nb_tests - ret_ad, args = jitter.func_args_cdecl(["out", "format"]) + ret_ad, args = jitter.func_args_systemv(["out", "format"]) if args.out != 1: raise RuntimeError("Not implemented") fmt = jitter.get_str_ansi(args.format) @@ -89,7 +89,7 @@ def xxx___printf_chk(jitter): sys.stdout.write("[%d] %s" % (nb_tests, output)) nb_tests += 1 - jitter.func_ret_cdecl(ret_ad, 0) + jitter.func_ret_systemv(ret_ad, 0) def xxx_puts(jitter): ''' @@ -98,7 +98,7 @@ def xxx_puts(jitter): writes the string s and a trailing newline to stdout. ''' - ret_addr, args = jitter.func_args_cdecl(['target']) + ret_addr, args = jitter.func_args_systemv(['target']) output = jitter.get_str_ansi(args.target) # Check with expected result line = expected.next() @@ -106,7 +106,7 @@ def xxx_puts(jitter): print "Expected:", line print "Obtained:", output raise RuntimeError("Bad semantic") - return jitter.func_ret_cdecl(ret_addr, 1) + return jitter.func_ret_systemv(ret_addr, 1) # Parse arguments parser = Sandbox_Linux_x86_32.parser(description="ELF sandboxer") -- cgit 1.4.1 From f85d5e8f261db7b4c0fc519df056561ad9e45418 Mon Sep 17 00:00:00 2001 From: Ajax Date: Wed, 5 Apr 2017 15:54:52 +0200 Subject: Add regression test for command-line/env support in Sandbox --- test/os_dep/linux/test_env.aarch64l | Bin 0 -> 6168 bytes test/os_dep/linux/test_env.arml | Bin 0 -> 5608 bytes test/os_dep/linux/test_env.c | 10 ++++++++++ test/os_dep/linux/test_env.py | 36 ++++++++++++++++++++++++++++++++++++ test/os_dep/linux/test_env.x86_32 | Bin 0 -> 5588 bytes test/os_dep/linux/test_env.x86_64 | Bin 0 -> 6312 bytes test/test_all.py | 6 ++++++ 7 files changed, 52 insertions(+) create mode 100755 test/os_dep/linux/test_env.aarch64l create mode 100755 test/os_dep/linux/test_env.arml create mode 100644 test/os_dep/linux/test_env.c create mode 100644 test/os_dep/linux/test_env.py create mode 100755 test/os_dep/linux/test_env.x86_32 create mode 100755 test/os_dep/linux/test_env.x86_64 (limited to 'test') diff --git a/test/os_dep/linux/test_env.aarch64l b/test/os_dep/linux/test_env.aarch64l new file mode 100755 index 00000000..19e97780 Binary files /dev/null and b/test/os_dep/linux/test_env.aarch64l differ diff --git a/test/os_dep/linux/test_env.arml b/test/os_dep/linux/test_env.arml new file mode 100755 index 00000000..c24d061e Binary files /dev/null and b/test/os_dep/linux/test_env.arml differ diff --git a/test/os_dep/linux/test_env.c b/test/os_dep/linux/test_env.c new file mode 100644 index 00000000..7b265561 --- /dev/null +++ b/test/os_dep/linux/test_env.c @@ -0,0 +1,10 @@ +#include +#include + +int main(int argc, char** argv, char** envp) +{ + printf("argc %d\n", argc); + printf("argv[0] %s\n", argv[0]); + printf("argv[1] %s\n", argv[1]); + printf("envp[0] %s\n", envp[0]); +} diff --git a/test/os_dep/linux/test_env.py b/test/os_dep/linux/test_env.py new file mode 100644 index 00000000..a44d62c4 --- /dev/null +++ b/test/os_dep/linux/test_env.py @@ -0,0 +1,36 @@ +import os +import sys +from pdb import pm +from miasm2.analysis.binary import Container +from miasm2.analysis.sandbox import Sandbox_Linux_x86_32, Sandbox_Linux_x86_64,\ + Sandbox_Linux_arml, Sandbox_Linux_aarch64l + +if len(sys.argv) < 2: + print "Usage: %s ..." % sys.argv[0] + exit(0) + +arch = sys.argv[1] + +if arch == "x86_32": + sandbox = Sandbox_Linux_x86_32 +elif arch == "x86_64": + sandbox = Sandbox_Linux_x86_64 +elif arch == "arml": + sandbox = Sandbox_Linux_arml +elif arch == "aarch64l": + sandbox = Sandbox_Linux_aarch64l +else: + raise ValueError("Unsuported arch: %s" % arch) + +# Parse arguments +parser = sandbox.parser(description="ELF sandboxer") +parser.add_argument("filename", help="ELF Filename") +options = parser.parse_args(sys.argv[2:]) + +# Create sandbox +sb = sandbox(options.filename, options, globals()) + +# Run +sb.run() + +assert(sb.jitter.run is False) diff --git a/test/os_dep/linux/test_env.x86_32 b/test/os_dep/linux/test_env.x86_32 new file mode 100755 index 00000000..9f0f96bc Binary files /dev/null and b/test/os_dep/linux/test_env.x86_32 differ diff --git a/test/os_dep/linux/test_env.x86_64 b/test/os_dep/linux/test_env.x86_64 new file mode 100755 index 00000000..f9d78a1d Binary files /dev/null and b/test/os_dep/linux/test_env.x86_64 differ diff --git a/test/test_all.py b/test/test_all.py index 0a29d4d3..237f13c1 100755 --- a/test/test_all.py +++ b/test/test_all.py @@ -257,6 +257,12 @@ for script in ["win_api_x86_32.py", ]: testset += RegressionTest([script], base_dir="os_dep", tags=[TAGS['tcc']]) +for arch in ["x86_32", "x86_64", "arml", "aarch64l"]: + testset += RegressionTest(["test_env.py", arch, "test_env.%s" % arch, "-c", + "arg1", "-c", "arg2", "--environment-vars", + "TEST=TOTO", "--mimic-env"], + base_dir="os_dep/linux", tags=[TAGS['tcc']]) + ## Analysis testset += RegressionTest(["depgraph.py"], base_dir="analysis", products=[fname for fnames in ( -- cgit 1.4.1 From dc3a57fd1f0df922056edf087a9ac94c0005cd15 Mon Sep 17 00:00:00 2001 From: Ajax Date: Wed, 5 Apr 2017 15:55:46 +0200 Subject: MD5_arm: run from the very beginning --- example/jitter/arm.py | 3 --- test/test_all.py | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) (limited to 'test') diff --git a/example/jitter/arm.py b/example/jitter/arm.py index eac6c0e6..e475abeb 100755 --- a/example/jitter/arm.py +++ b/example/jitter/arm.py @@ -24,8 +24,5 @@ else: if options.verbose is True: print sb.jitter.vm -if options.address is None: - raise ValueError('Invalid address') - # Run the code sb.run() diff --git a/test/test_all.py b/test/test_all.py index 237f13c1..c4463339 100755 --- a/test/test_all.py +++ b/test/test_all.py @@ -614,7 +614,7 @@ for jitter in ExampleJitter.jitter_engines: 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"], + (["arm.py", Example.get_sample("md5_arm"), "--mimic-env"], []), (["sandbox_elf_aarch64l.py", Example.get_sample("md5_aarch64l"), "-a", "0x400A00"], []), -- cgit 1.4.1 From b535f6e26e354ca61307f8153b862385ba9d2a04 Mon Sep 17 00:00:00 2001 From: Ajax Date: Wed, 5 Apr 2017 16:28:54 +0200 Subject: Introduce Sandbox.call, for direct function calling --- example/jitter/sandbox_call.py | 23 ++++++++++++++ miasm2/analysis/sandbox.py | 71 ++++++++++++++++++++++++++++++++++++++++++ test/test_all.py | 1 + 3 files changed, 95 insertions(+) create mode 100644 example/jitter/sandbox_call.py (limited to 'test') diff --git a/example/jitter/sandbox_call.py b/example/jitter/sandbox_call.py new file mode 100644 index 00000000..49365004 --- /dev/null +++ b/example/jitter/sandbox_call.py @@ -0,0 +1,23 @@ +"""This example illustrate the Sandbox.call API, for direct call of a given +function""" + +from miasm2.analysis.sandbox import Sandbox_Linux_arml +from miasm2.analysis.binary import Container +from miasm2.os_dep.linux_stdlib import linobjs +from miasm2.core.utils import hexdump + +# Parse arguments +parser = Sandbox_Linux_arml.parser(description="ELF sandboxer") +parser.add_argument("filename", help="ELF Filename") +options = parser.parse_args() + +sb = Sandbox_Linux_arml(options.filename, options, globals()) + +with open(options.filename) as fdesc: + cont = Container.from_stream(fdesc) + addr_to_call = cont.symbol_pool.getby_name("md5_starts").offset + +# Calling md5_starts(malloc(0x64)) +addr = linobjs.heap.alloc(sb.jitter, 0x64) +sb.call(addr_to_call, addr) +hexdump(sb.jitter.vm.get_mem(addr, 0x64)) diff --git a/miasm2/analysis/sandbox.py b/miasm2/analysis/sandbox.py index 2b093338..3c29ace0 100644 --- a/miasm2/analysis/sandbox.py +++ b/miasm2/analysis/sandbox.py @@ -14,6 +14,8 @@ class Sandbox(object): Parent class for Sandbox abstraction """ + CALL_FINNISH_ADDR = 0x1337babe + @staticmethod def code_sentinelle(jitter): jitter.run = False @@ -126,6 +128,20 @@ class Sandbox(object): self.jitter.init_run(addr) self.jitter.continue_run() + def call(self, prepare_cb, addr, *args): + """ + Direct call of the function at @addr, with arguments @args prepare in + calling convention implemented by @prepare_cb + @prepare_cb: func(ret_addr, *args) + @addr: address of the target function + @args: arguments + """ + self.jitter.init_run(addr) + self.jitter.add_breakpoint(self.CALL_FINNISH_ADDR, self.code_sentinelle) + prepare_cb(self.CALL_FINNISH_ADDR, *args) + self.jitter.continue_run() + + class OS(object): @@ -449,6 +465,15 @@ class Sandbox_Win_x86_32(Sandbox, Arch_x86_32, OS_Win): addr = self.entry_point super(Sandbox_Win_x86_32, self).run(addr) + def call(self, addr, *args, **kwargs): + """ + Direct call of the function at @addr, with arguments @args + @addr: address of the target function + @args: arguments + """ + prepare_cb = kwargs.pop('prepare_cb', self.jitter.func_prepare_stdcall) + super(self.__class__, self).call(prepare_cb, addr, *args) + class Sandbox_Win_x86_64(Sandbox, Arch_x86_64, OS_Win): @@ -473,6 +498,15 @@ class Sandbox_Win_x86_64(Sandbox, Arch_x86_64, OS_Win): addr = self.entry_point super(Sandbox_Win_x86_64, self).run(addr) + def call(self, addr, *args, **kwargs): + """ + Direct call of the function at @addr, with arguments @args + @addr: address of the target function + @args: arguments + """ + prepare_cb = kwargs.pop('prepare_cb', self.jitter.func_prepare_stdcall) + super(self.__class__, self).call(prepare_cb, addr, *args) + class Sandbox_Linux_x86_32(Sandbox, Arch_x86_32, OS_Linux): @@ -518,6 +552,16 @@ class Sandbox_Linux_x86_32(Sandbox, Arch_x86_32, OS_Linux): addr = self.entry_point super(Sandbox_Linux_x86_32, self).run(addr) + def call(self, addr, *args, **kwargs): + """ + Direct call of the function at @addr, with arguments @args + @addr: address of the target function + @args: arguments + """ + prepare_cb = kwargs.pop('prepare_cb', self.jitter.func_prepare_systemv) + super(self.__class__, self).call(prepare_cb, addr, *args) + + class Sandbox_Linux_x86_64(Sandbox, Arch_x86_64, OS_Linux): @@ -563,6 +607,15 @@ class Sandbox_Linux_x86_64(Sandbox, Arch_x86_64, OS_Linux): addr = self.entry_point super(Sandbox_Linux_x86_64, self).run(addr) + def call(self, addr, *args, **kwargs): + """ + Direct call of the function at @addr, with arguments @args + @addr: address of the target function + @args: arguments + """ + prepare_cb = kwargs.pop('prepare_cb', self.jitter.func_prepare_systemv) + super(self.__class__, self).call(prepare_cb, addr, *args) + class Sandbox_Linux_arml(Sandbox, Arch_arml, OS_Linux): @@ -604,6 +657,15 @@ class Sandbox_Linux_arml(Sandbox, Arch_arml, OS_Linux): addr = self.entry_point super(Sandbox_Linux_arml, self).run(addr) + def call(self, addr, *args, **kwargs): + """ + Direct call of the function at @addr, with arguments @args + @addr: address of the target function + @args: arguments + """ + prepare_cb = kwargs.pop('prepare_cb', self.jitter.func_prepare_systemv) + super(self.__class__, self).call(prepare_cb, addr, *args) + class Sandbox_Linux_armb_str(Sandbox, Arch_armb, OS_Linux_str): @@ -676,3 +738,12 @@ class Sandbox_Linux_aarch64l(Sandbox, Arch_aarch64l, OS_Linux): if addr is None and self.options.address is None: addr = self.entry_point super(Sandbox_Linux_aarch64l, self).run(addr) + + def call(self, addr, *args, **kwargs): + """ + Direct call of the function at @addr, with arguments @args + @addr: address of the target function + @args: arguments + """ + prepare_cb = kwargs.pop('prepare_cb', self.jitter.func_prepare_systemv) + super(self.__class__, self).call(prepare_cb, addr, *args) diff --git a/test/test_all.py b/test/test_all.py index c4463339..f76019c4 100755 --- a/test/test_all.py +++ b/test/test_all.py @@ -626,6 +626,7 @@ for script, dep in [(["x86_32.py", Example.get_sample("x86_32_sc.bin")], []), "b", "-a", "0"], [test_armb]), (["arm_sc.py", "0", Example.get_sample("demo_arm_l.bin"), "l", "-a", "0"], [test_arml]), + (["sandbox_call.py", Example.get_sample("md5_arm")], []), ] + [(["sandbox_pe_x86_32.py", Example.get_sample("x86_32_" + name + ".bin")], [test_box[name]]) -- cgit 1.4.1