diff options
Diffstat (limited to '')
| -rw-r--r-- | miasm2/analysis/machine.py | 13 | ||||
| -rw-r--r-- | miasm2/analysis/sandbox.py | 85 |
2 files changed, 97 insertions, 1 deletions
diff --git a/miasm2/analysis/machine.py b/miasm2/analysis/machine.py index 7a6069c0..f361b412 100644 --- a/miasm2/analysis/machine.py +++ b/miasm2/analysis/machine.py @@ -12,7 +12,7 @@ class Machine(object): __available = ["arml", "armb", "armtl", "armtb", "sh4", "x86_16", "x86_32", "x86_64", "msp430", "mips32b", "mips32l", - "aarch64l", "aarch64b"] + "aarch64l", "aarch64b", "ppc32b"] def __init__(self, machine_name): @@ -162,6 +162,17 @@ class Machine(object): mn = arch.mn_mips32 from miasm2.arch.mips32.ira import ir_a_mips32l as ira from miasm2.arch.mips32.sem import ir_mips32l as ir + elif machine_name == "ppc32b": + from miasm2.arch.ppc.disasm import dis_ppc32b as dis_engine + from miasm2.arch.ppc import arch + try: + from miasm2.arch.ppc import jit + jitter = jit.jitter_ppc32b + except ImportError: + pass + mn = arch.mn_ppc + from miasm2.arch.ppc.ira import ir_a_ppc32b as ira + from miasm2.arch.ppc.sem import ir_ppc32b as ir else: raise ValueError('Unknown machine: %s' % machine_name) 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) |