about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--example/jitter/sandbox_call.py23
-rw-r--r--miasm2/analysis/sandbox.py71
-rwxr-xr-xtest/test_all.py1
3 files changed, 95 insertions, 0 deletions
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]])