about summary refs log tree commit diff stats
path: root/miasm2/analysis/sandbox.py
diff options
context:
space:
mode:
authorAymeric Vincent <aymeric.vincent@cea.fr>2018-02-22 16:02:57 +0100
committerAymeric Vincent <aymeric.vincent@cea.fr>2018-02-26 11:34:41 +0100
commitcc2ee2c61dd4719bd7f9a85193590dffcda46991 (patch)
tree8d6b3e6077c97f368dab884b8a889bba75e74f5a /miasm2/analysis/sandbox.py
parent0606dd974a5ff0c3d6fb58e002b9319235a2dfbd (diff)
downloadmiasm-cc2ee2c61dd4719bd7f9a85193590dffcda46991.tar.gz
miasm-cc2ee2c61dd4719bd7f9a85193590dffcda46991.zip
Add support for PowerPC 32bit big-endian processors: "ppc32b"
Diffstat (limited to 'miasm2/analysis/sandbox.py')
-rw-r--r--miasm2/analysis/sandbox.py85
1 files changed, 85 insertions, 0 deletions
diff --git a/miasm2/analysis/sandbox.py b/miasm2/analysis/sandbox.py
index 086473b0..5bdccddd 100644
--- a/miasm2/analysis/sandbox.py
+++ b/miasm2/analysis/sandbox.py
@@ -440,6 +440,14 @@ class Arch_aarch64b(Arch):
         self.jitter.stack_base = self.STACK_BASE
         self.jitter.init_stack()
 
+class Arch_ppc(Arch):
+    _ARCH_ = None
+
+class Arch_ppc32(Arch):
+    _ARCH_ = None
+
+class Arch_ppc32b(Arch_ppc32):
+    _ARCH_ = "ppc32b"
 
 class Sandbox_Win_x86_32(Sandbox, Arch_x86_32, OS_Win):
 
@@ -745,3 +753,80 @@ class Sandbox_Linux_aarch64l(Sandbox, Arch_aarch64l, OS_Linux):
         """
         prepare_cb = kwargs.pop('prepare_cb', self.jitter.func_prepare_systemv)
         super(self.__class__, self).call(prepare_cb, addr, *args)
+
+class Sandbox_Linux_ppc32b(Sandbox, Arch_ppc32b, OS_Linux):
+
+    STACK_SIZE = 0x10000
+    STACK_BASE = 0xbfce0000
+
+    # The glue between the kernel and the ELF ABI on Linux/PowerPC is
+    # implemented in glibc/sysdeps/powerpc/powerpc32/dl-start.S, so we
+    # have to play the role of ld.so here.
+    def __init__(self, *args, **kwargs):
+        super(Sandbox_Linux_ppc32b, self).__init__(*args, **kwargs)
+
+        # Init stack
+        self.jitter.stack_size = self.STACK_SIZE
+        self.jitter.stack_base = self.STACK_BASE
+        self.jitter.init_stack()
+        self.jitter.cpu.R1 -= 8
+
+        # Pre-stack some arguments
+        if self.options.mimic_env:
+            env_ptrs = []
+            for env in self.envp:
+                env += "\x00"
+                self.jitter.cpu.R1 -= len(env)
+                ptr = self.jitter.cpu.R1
+                self.jitter.vm.set_mem(ptr, env)
+                env_ptrs.append(ptr)
+            argv_ptrs = []
+            for arg in self.argv:
+                arg += "\x00"
+                self.jitter.cpu.R1 -= len(arg)
+                ptr = self.jitter.cpu.R1
+                self.jitter.vm.set_mem(ptr, arg)
+                argv_ptrs.append(ptr)
+
+            self.jitter.push_uint32_t(0)
+            for ptr in reversed(env_ptrs):
+                self.jitter.push_uint32_t(ptr)
+            self.jitter.cpu.R5 = self.jitter.cpu.R1	# envp
+            self.jitter.push_uint32_t(0)
+            for ptr in reversed(argv_ptrs):
+                self.jitter.push_uint32_t(ptr)
+            self.jitter.cpu.R4 = self.jitter.cpu.R1	# argv
+            self.jitter.cpu.R3 = len(self.argv)		# argc
+            self.jitter.push_uint32_t(self.jitter.cpu.R3)
+
+            self.jitter.cpu.R6 = 0			# auxp
+            self.jitter.cpu.R7 = 0			# termination function
+
+            # From the glibc, we should push a 0 here to distinguish a
+            # dynamically linked executable from a statically linked one.
+            # We actually do not do it and attempt to be somehow compatible
+            # with both types of executables.
+            #self.jitter.push_uint32_t(0)
+
+        self.jitter.cpu.LR = self.CALL_FINISH_ADDR
+
+        # Set the runtime guard
+        self.jitter.add_breakpoint(self.CALL_FINISH_ADDR,
+                                   self.__class__.code_sentinelle)
+
+    def run(self, addr=None):
+        """
+        If addr is not set, use entrypoint
+        """
+        if addr is None and self.options.address is None:
+            addr = self.entry_point
+        super(Sandbox_Linux_ppc32b, 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)