about summary refs log tree commit diff stats
path: root/miasm/analysis/sandbox.py
diff options
context:
space:
mode:
Diffstat (limited to 'miasm/analysis/sandbox.py')
-rw-r--r--miasm/analysis/sandbox.py1033
1 files changed, 0 insertions, 1033 deletions
diff --git a/miasm/analysis/sandbox.py b/miasm/analysis/sandbox.py
deleted file mode 100644
index e51fd45a..00000000
--- a/miasm/analysis/sandbox.py
+++ /dev/null
@@ -1,1033 +0,0 @@
-from __future__ import print_function
-from builtins import range
-
-import os
-import logging
-from argparse import ArgumentParser
-
-from future.utils import viewitems, viewvalues
-from past.builtins import basestring
-
-from miasm.analysis.machine import Machine
-from miasm.jitter.csts import PAGE_READ, PAGE_WRITE
-from miasm.analysis import debugging
-from miasm.jitter.jitload import log_func
-from miasm.core.utils import force_bytes
-
-
-class Sandbox(object):
-
-    """
-    Parent class for Sandbox abstraction
-    """
-
-    CALL_FINISH_ADDR = 0x13371acc
-
-    @staticmethod
-    def code_sentinelle(jitter):
-        jitter.running = False
-        return False
-
-    @classmethod
-    def _classes_(cls):
-        """
-        Iterator on parent classes except Sanbox
-        """
-        for base_cls in cls.__bases__:
-            # Avoid infinite loop
-            if base_cls == Sandbox:
-                continue
-
-            yield base_cls
-
-    classes = property(lambda x: x.__class__._classes_())
-
-    def __init__(self, loc_db, fname, options, custom_methods=None, **kwargs):
-        """
-        Initialize a sandbox
-        @fname: str file name
-        @options: namespace instance of specific options
-        @custom_methods: { str => func } for custom API implementations
-        """
-
-        # Initialize
-        assert isinstance(fname, basestring)
-        self.fname = fname
-        self.options = options
-        self.loc_db = loc_db
-        if custom_methods is None:
-            custom_methods = {}
-        kwargs["loc_db"] = loc_db
-        for cls in self.classes:
-            if cls == Sandbox:
-                continue
-            if issubclass(cls, OS):
-                cls.__init__(self, custom_methods, **kwargs)
-            else:
-                cls.__init__(self, **kwargs)
-
-        # Logging options
-        self.jitter.set_trace_log(
-            trace_instr=self.options.singlestep,
-            trace_regs=self.options.singlestep,
-            trace_new_blocks=self.options.dumpblocs
-        )
-
-        if not self.options.quiet_function_calls:
-            log_func.setLevel(logging.INFO)
-
-    @classmethod
-    def parser(cls, *args, **kwargs):
-        """
-        Return instance of instance parser with expecting options.
-        Extra parameters are passed to parser initialisation.
-        """
-
-        parser = ArgumentParser(*args, **kwargs)
-        parser.add_argument('-a', "--address",
-                            help="Force entry point address", default=None)
-        parser.add_argument('-b', "--dumpblocs", action="store_true",
-                            help="Log disasm blocks")
-        parser.add_argument('-z', "--singlestep", action="store_true",
-                            help="Log single step")
-        parser.add_argument('-d', "--debugging", action="store_true",
-                            help="Debug shell")
-        parser.add_argument('-g', "--gdbserver", type=int,
-                            help="Listen on port @port")
-        parser.add_argument("-j", "--jitter",
-                            help="Jitter engine. Possible values are: gcc (default), llvm, python",
-                            default="gcc")
-        parser.add_argument(
-            '-q', "--quiet-function-calls", action="store_true",
-                            help="Don't log function calls")
-        parser.add_argument('-i', "--dependencies", action="store_true",
-                            help="Load PE and its dependencies")
-
-        for base_cls in cls._classes_():
-            base_cls.update_parser(parser)
-        return parser
-
-    def run(self, addr=None):
-        """
-        Launch emulation (gdbserver, debugging, basic JIT).
-        @addr: (int) start address
-        """
-        if addr is None and self.options.address is not None:
-            addr = int(self.options.address, 0)
-
-        if any([self.options.debugging, self.options.gdbserver]):
-            dbg = debugging.Debugguer(self.jitter)
-            self.dbg = dbg
-            dbg.init_run(addr)
-
-            if self.options.gdbserver:
-                port = self.options.gdbserver
-                print("Listen on port %d" % port)
-                gdb = self.machine.gdbserver(dbg, port)
-                self.gdb = gdb
-                gdb.run()
-            else:
-                cmd = debugging.DebugCmd(dbg)
-                self.cmd = cmd
-                cmd.cmdloop()
-
-        else:
-            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_FINISH_ADDR, self.code_sentinelle)
-        prepare_cb(self.CALL_FINISH_ADDR, *args)
-        self.jitter.continue_run()
-
-
-
-class OS(object):
-
-    """
-    Parent class for OS abstraction
-    """
-
-    def __init__(self, custom_methods, **kwargs):
-        pass
-
-    @classmethod
-    def update_parser(cls, parser):
-        pass
-
-
-class Arch(object):
-
-    """
-    Parent class for Arch abstraction
-    """
-
-    # Architecture name
-    _ARCH_ = None
-
-    def __init__(self, loc_db, **kwargs):
-        self.machine = Machine(self._ARCH_)
-        self.jitter = self.machine.jitter(loc_db, self.options.jitter)
-
-    @classmethod
-    def update_parser(cls, parser):
-        pass
-
-
-class OS_Win(OS):
-    # DLL to import
-    ALL_IMP_DLL = [
-        "ntdll.dll", "kernel32.dll", "user32.dll",
-        "ole32.dll", "urlmon.dll",
-        "ws2_32.dll", 'advapi32.dll', "psapi.dll",
-    ]
-    modules_path = "win_dll"
-
-    def __init__(self, custom_methods, *args, **kwargs):
-        from miasm.jitter.loader.pe import vm_load_pe, vm_load_pe_libs,\
-            preload_pe, libimp_pe, vm_load_pe_and_dependencies
-        from miasm.os_dep import win_api_x86_32, win_api_x86_32_seh
-        methods = dict((name, func) for name, func in viewitems(win_api_x86_32.__dict__))
-        methods.update(custom_methods)
-
-        super(OS_Win, self).__init__(methods, *args, **kwargs)
-
-        # Import manager
-        libs = libimp_pe()
-        self.libs = libs
-        win_api_x86_32.winobjs.runtime_dll = libs
-
-        self.name2module = {}
-        fname_basename = os.path.basename(self.fname).lower()
-
-        # Load main pe
-        with open(self.fname, "rb") as fstream:
-            self.pe = vm_load_pe(
-                self.jitter.vm,
-                fstream.read(),
-                load_hdr=self.options.load_hdr,
-                name=self.fname,
-                winobjs=win_api_x86_32.winobjs,
-                **kwargs
-            )
-            self.name2module[fname_basename] = self.pe
-
-        # Load library
-        if self.options.loadbasedll:
-
-            # Load libs in memory
-            self.name2module.update(
-                vm_load_pe_libs(
-                    self.jitter.vm,
-                    self.ALL_IMP_DLL,
-                    libs,
-                    self.modules_path,
-                    winobjs=win_api_x86_32.winobjs,
-                    **kwargs
-                )
-            )
-
-            # Patch libs imports
-            for pe in viewvalues(self.name2module):
-                preload_pe(self.jitter.vm, pe, libs)
-
-        if self.options.dependencies:
-            vm_load_pe_and_dependencies(
-                self.jitter.vm,
-                fname_basename,
-                self.name2module,
-                libs,
-                self.modules_path,
-                winobjs=win_api_x86_32.winobjs,
-                **kwargs
-            )
-
-        win_api_x86_32.winobjs.current_pe = self.pe
-
-        # Fix pe imports
-        preload_pe(self.jitter.vm, self.pe, libs)
-
-        # Library calls handler
-        self.jitter.add_lib_handler(libs, methods)
-
-        # Manage SEH
-        if self.options.use_windows_structs:
-            win_api_x86_32_seh.main_pe_name = fname_basename
-            win_api_x86_32_seh.main_pe = self.pe
-            win_api_x86_32.winobjs.hcurmodule = self.pe.NThdr.ImageBase
-            win_api_x86_32_seh.name2module = self.name2module
-            win_api_x86_32_seh.set_win_fs_0(self.jitter)
-            win_api_x86_32_seh.init_seh(self.jitter)
-
-        self.entry_point = self.pe.rva2virt(
-            self.pe.Opthdr.AddressOfEntryPoint)
-
-    @classmethod
-    def update_parser(cls, parser):
-        parser.add_argument('-o', "--load-hdr", action="store_true",
-                            help="Load pe hdr")
-        parser.add_argument('-y', "--use-windows-structs", action="store_true",
-                            help="Create and use windows structures (peb, ldr, seh, ...)")
-        parser.add_argument('-l', "--loadbasedll", action="store_true",
-                            help="Load base dll (path './win_dll')")
-        parser.add_argument('-r', "--parse-resources",
-                            action="store_true", help="Load resources")
-
-
-class OS_Linux(OS):
-
-    PROGRAM_PATH = "./program"
-
-    def __init__(self, custom_methods, *args, **kwargs):
-        from miasm.jitter.loader.elf import vm_load_elf, preload_elf, libimp_elf
-        from miasm.os_dep import linux_stdlib
-        methods = linux_stdlib.__dict__
-        methods.update(custom_methods)
-
-        super(OS_Linux, self).__init__(methods, *args, **kwargs)
-
-        # Import manager
-        self.libs = libimp_elf()
-
-        with open(self.fname, "rb") as fstream:
-            self.elf = vm_load_elf(
-                self.jitter.vm,
-                fstream.read(),
-                name=self.fname,
-                **kwargs
-            )
-        preload_elf(self.jitter.vm, self.elf, self.libs)
-
-        self.entry_point = self.elf.Ehdr.entry
-
-        # Library calls handler
-        self.jitter.add_lib_handler(self.libs, methods)
-        linux_stdlib.ABORT_ADDR = self.CALL_FINISH_ADDR
-
-        # Arguments
-        self.argv = [self.PROGRAM_PATH]
-        if self.options.command_line:
-             self.argv += self.options.command_line
-        self.envp = self.options.environment_vars
-
-    @classmethod
-    def update_parser(cls, parser):
-        parser.add_argument('-c', '--command-line',
-                            action="append",
-                            default=[],
-                            help="Command line arguments")
-        parser.add_argument('--environment-vars',
-                            action="append",
-                            default=[],
-                            help="Environment variables arguments")
-        parser.add_argument('--mimic-env',
-                            action="store_true",
-                            help="Mimic the environment of a starting executable")
-
-class OS_Linux_str(OS):
-
-    PROGRAM_PATH = "./program"
-
-    def __init__(self, custom_methods, *args, **kwargs):
-        from miasm.jitter.loader.elf import libimp_elf
-        from miasm.os_dep import linux_stdlib
-        methods = linux_stdlib.__dict__
-        methods.update(custom_methods)
-
-        super(OS_Linux_str, self).__init__(methods, *args, **kwargs)
-
-        # Import manager
-        libs = libimp_elf()
-        self.libs = libs
-
-        data = open(self.fname, "rb").read()
-        self.options.load_base_addr = int(self.options.load_base_addr, 0)
-        self.jitter.vm.add_memory_page(
-            self.options.load_base_addr, PAGE_READ | PAGE_WRITE, data,
-            "Initial Str"
-        )
-
-        # Library calls handler
-        self.jitter.add_lib_handler(libs, methods)
-        linux_stdlib.ABORT_ADDR = self.CALL_FINISH_ADDR
-
-        # Arguments
-        self.argv = [self.PROGRAM_PATH]
-        if self.options.command_line:
-             self.argv += self.options.command_line
-        self.envp = self.options.environment_vars
-
-    @classmethod
-    def update_parser(cls, parser):
-        parser.add_argument('-c', '--command-line',
-                            action="append",
-                            default=[],
-                            help="Command line arguments")
-        parser.add_argument('--environment-vars',
-                            action="append",
-                            default=[],
-                            help="Environment variables arguments")
-        parser.add_argument('--mimic-env',
-                            action="store_true",
-                            help="Mimic the environment of a starting executable")
-        parser.add_argument("load_base_addr", help="load base address")
-
-
-class Arch_x86(Arch):
-    _ARCH_ = None  # Arch name
-    STACK_SIZE = 0x10000
-    STACK_BASE = 0x130000
-
-    def __init__(self, loc_db, **kwargs):
-        super(Arch_x86, self).__init__(loc_db, **kwargs)
-
-        if self.options.usesegm:
-            self.jitter.lifter.do_stk_segm = True
-            self.jitter.lifter.do_ds_segm = True
-            self.jitter.lifter.do_str_segm = True
-            self.jitter.lifter.do_all_segm = True
-
-        # Init stack
-        self.jitter.stack_size = self.STACK_SIZE
-        self.jitter.stack_base = self.STACK_BASE
-        self.jitter.init_stack()
-
-    @classmethod
-    def update_parser(cls, parser):
-        parser.add_argument('-s', "--usesegm", action="store_true",
-                            help="Use segments")
-
-
-class Arch_x86_32(Arch_x86):
-    _ARCH_ = "x86_32"
-
-
-class Arch_x86_64(Arch_x86):
-    _ARCH_ = "x86_64"
-
-
-class Arch_arml(Arch):
-    _ARCH_ = "arml"
-    STACK_SIZE = 0x100000
-    STACK_BASE = 0x100000
-
-    def __init__(self, loc_db, **kwargs):
-        super(Arch_arml, self).__init__(loc_db, **kwargs)
-
-        # Init stack
-        self.jitter.stack_size = self.STACK_SIZE
-        self.jitter.stack_base = self.STACK_BASE
-        self.jitter.init_stack()
-
-
-class Arch_armb(Arch):
-    _ARCH_ = "armb"
-    STACK_SIZE = 0x100000
-    STACK_BASE = 0x100000
-
-    def __init__(self, loc_db, **kwargs):
-        super(Arch_armb, self).__init__(loc_db, **kwargs)
-
-        # Init stack
-        self.jitter.stack_size = self.STACK_SIZE
-        self.jitter.stack_base = self.STACK_BASE
-        self.jitter.init_stack()
-
-
-class Arch_armtl(Arch):
-    _ARCH_ = "armtl"
-    STACK_SIZE = 0x100000
-    STACK_BASE = 0x100000
-
-    def __init__(self, loc_db, **kwargs):
-        super(Arch_armtl, self).__init__(loc_db, **kwargs)
-
-        # Init stack
-        self.jitter.stack_size = self.STACK_SIZE
-        self.jitter.stack_base = self.STACK_BASE
-        self.jitter.init_stack()
-
-
-class Arch_mips32b(Arch):
-    _ARCH_ = "mips32b"
-    STACK_SIZE = 0x100000
-    STACK_BASE = 0x100000
-
-    def __init__(self, loc_db, **kwargs):
-        super(Arch_mips32b, self).__init__(loc_db, **kwargs)
-
-        # Init stack
-        self.jitter.stack_size = self.STACK_SIZE
-        self.jitter.stack_base = self.STACK_BASE
-        self.jitter.init_stack()
-
-
-class Arch_aarch64l(Arch):
-    _ARCH_ = "aarch64l"
-    STACK_SIZE = 0x100000
-    STACK_BASE = 0x100000
-
-    def __init__(self, loc_db, **kwargs):
-        super(Arch_aarch64l, self).__init__(loc_db, **kwargs)
-
-        # Init stack
-        self.jitter.stack_size = self.STACK_SIZE
-        self.jitter.stack_base = self.STACK_BASE
-        self.jitter.init_stack()
-
-
-class Arch_aarch64b(Arch):
-    _ARCH_ = "aarch64b"
-    STACK_SIZE = 0x100000
-    STACK_BASE = 0x100000
-
-    def __init__(self, loc_db, **kwargs):
-        super(Arch_aarch64b, self).__init__(loc_db, **kwargs)
-
-        # Init stack
-        self.jitter.stack_size = self.STACK_SIZE
-        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):
-
-    def __init__(self, loc_db, *args, **kwargs):
-        Sandbox.__init__(self, loc_db, *args, **kwargs)
-
-        # Pre-stack some arguments
-        self.jitter.push_uint32_t(2)
-        self.jitter.push_uint32_t(1)
-        self.jitter.push_uint32_t(0)
-        self.jitter.push_uint32_t(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_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):
-
-    def __init__(self, loc_db, *args, **kwargs):
-        Sandbox.__init__(self, loc_db, *args, **kwargs)
-
-        # reserve stack for local reg
-        for _ in range(0x4):
-            self.jitter.push_uint64_t(0)
-
-        # Pre-stack return address
-        self.jitter.push_uint64_t(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_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):
-
-    def __init__(self, loc_db, *args, **kwargs):
-        Sandbox.__init__(self, loc_db, *args, **kwargs)
-
-        # Pre-stack some arguments
-        if self.options.mimic_env:
-            env_ptrs = []
-            for env in self.envp:
-                env = force_bytes(env)
-                env += b"\x00"
-                self.jitter.cpu.ESP -= len(env)
-                ptr = self.jitter.cpu.ESP
-                self.jitter.vm.set_mem(ptr, env)
-                env_ptrs.append(ptr)
-            argv_ptrs = []
-            for arg in self.argv:
-                arg = force_bytes(arg)
-                arg += b"\x00"
-                self.jitter.cpu.ESP -= len(arg)
-                ptr = self.jitter.cpu.ESP
-                self.jitter.vm.set_mem(ptr, arg)
-                argv_ptrs.append(ptr)
-
-            self.jitter.push_uint32_t(self.CALL_FINISH_ADDR)
-            self.jitter.push_uint32_t(0)
-            for ptr in reversed(env_ptrs):
-                self.jitter.push_uint32_t(ptr)
-            self.jitter.push_uint32_t(0)
-            for ptr in reversed(argv_ptrs):
-                self.jitter.push_uint32_t(ptr)
-            self.jitter.push_uint32_t(len(self.argv))
-        else:
-            self.jitter.push_uint32_t(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_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):
-
-    def __init__(self, loc_db, *args, **kwargs):
-        Sandbox.__init__(self, loc_db, *args, **kwargs)
-
-        # Pre-stack some arguments
-        if self.options.mimic_env:
-            env_ptrs = []
-            for env in self.envp:
-                env = force_bytes(env)
-                env += b"\x00"
-                self.jitter.cpu.RSP -= len(env)
-                ptr = self.jitter.cpu.RSP
-                self.jitter.vm.set_mem(ptr, env)
-                env_ptrs.append(ptr)
-            argv_ptrs = []
-            for arg in self.argv:
-                arg = force_bytes(arg)
-                arg += b"\x00"
-                self.jitter.cpu.RSP -= len(arg)
-                ptr = self.jitter.cpu.RSP
-                self.jitter.vm.set_mem(ptr, arg)
-                argv_ptrs.append(ptr)
-
-            self.jitter.push_uint64_t(self.CALL_FINISH_ADDR)
-            self.jitter.push_uint64_t(0)
-            for ptr in reversed(env_ptrs):
-                self.jitter.push_uint64_t(ptr)
-            self.jitter.push_uint64_t(0)
-            for ptr in reversed(argv_ptrs):
-                self.jitter.push_uint64_t(ptr)
-            self.jitter.push_uint64_t(len(self.argv))
-        else:
-            self.jitter.push_uint64_t(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_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):
-
-    def __init__(self, loc_db, *args, **kwargs):
-        Sandbox.__init__(self, loc_db, *args, **kwargs)
-
-        # Pre-stack some arguments
-        if self.options.mimic_env:
-            env_ptrs = []
-            for env in self.envp:
-                env = force_bytes(env)
-                env += b"\x00"
-                self.jitter.cpu.SP -= len(env)
-                ptr = self.jitter.cpu.SP
-                self.jitter.vm.set_mem(ptr, env)
-                env_ptrs.append(ptr)
-            argv_ptrs = []
-            for arg in self.argv:
-                arg = force_bytes(arg)
-                arg += b"\x00"
-                self.jitter.cpu.SP -= len(arg)
-                ptr = self.jitter.cpu.SP
-                self.jitter.vm.set_mem(ptr, arg)
-                argv_ptrs.append(ptr)
-
-            # Round SP to 4
-            self.jitter.cpu.SP = self.jitter.cpu.SP & ~ 3
-
-            self.jitter.push_uint32_t(0)
-            for ptr in reversed(env_ptrs):
-                self.jitter.push_uint32_t(ptr)
-            self.jitter.push_uint32_t(0)
-            for ptr in reversed(argv_ptrs):
-                self.jitter.push_uint32_t(ptr)
-            self.jitter.push_uint32_t(len(self.argv))
-
-        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 None and self.options.address is None:
-            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_armtl(Sandbox, Arch_armtl, OS_Linux):
-
-    def __init__(self, loc_db, *args, **kwargs):
-        Sandbox.__init__(self, loc_db, *args, **kwargs)
-
-        # Pre-stack some arguments
-        if self.options.mimic_env:
-            env_ptrs = []
-            for env in self.envp:
-                env = force_bytes(env)
-                env += b"\x00"
-                self.jitter.cpu.SP -= len(env)
-                ptr = self.jitter.cpu.SP
-                self.jitter.vm.set_mem(ptr, env)
-                env_ptrs.append(ptr)
-            argv_ptrs = []
-            for arg in self.argv:
-                arg = force_bytes(arg)
-                arg += b"\x00"
-                self.jitter.cpu.SP -= len(arg)
-                ptr = self.jitter.cpu.SP
-                self.jitter.vm.set_mem(ptr, arg)
-                argv_ptrs.append(ptr)
-
-            # Round SP to 4
-            self.jitter.cpu.SP = self.jitter.cpu.SP & ~ 3
-
-            self.jitter.push_uint32_t(0)
-            for ptr in reversed(env_ptrs):
-                self.jitter.push_uint32_t(ptr)
-            self.jitter.push_uint32_t(0)
-            for ptr in reversed(argv_ptrs):
-                self.jitter.push_uint32_t(ptr)
-            self.jitter.push_uint32_t(len(self.argv))
-
-        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 None and self.options.address is None:
-            addr = self.entry_point
-        super(Sandbox_Linux_armtl, 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_mips32b(Sandbox, Arch_mips32b, OS_Linux):
-
-    def __init__(self, loc_db, *args, **kwargs):
-        Sandbox.__init__(self, loc_db, *args, **kwargs)
-
-        # Pre-stack some arguments
-        if self.options.mimic_env:
-            env_ptrs = []
-            for env in self.envp:
-                env = force_bytes(env)
-                env += b"\x00"
-                self.jitter.cpu.SP -= len(env)
-                ptr = self.jitter.cpu.SP
-                self.jitter.vm.set_mem(ptr, env)
-                env_ptrs.append(ptr)
-            argv_ptrs = []
-            for arg in self.argv:
-                arg = force_bytes(arg)
-                arg += b"\x00"
-                self.jitter.cpu.SP -= len(arg)
-                ptr = self.jitter.cpu.SP
-                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.push_uint32_t(0)
-            for ptr in reversed(argv_ptrs):
-                self.jitter.push_uint32_t(ptr)
-            self.jitter.push_uint32_t(len(self.argv))
-
-        self.jitter.cpu.RA = 0x1337beef
-
-        # Set the runtime guard
-        self.jitter.add_breakpoint(
-            0x1337beef,
-            self.__class__.code_sentinelle
-        )
-
-    def run(self, addr=None):
-        if addr is None and self.options.address is None:
-            addr = self.entry_point
-        super(Sandbox_Linux_mips32b, 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):
-
-    def __init__(self, loc_db, *args, **kwargs):
-        Sandbox.__init__(self, loc_db, *args, **kwargs)
-
-        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 None and self.options.address is not None:
-            addr = int(self.options.address, 0)
-        super(Sandbox_Linux_armb_str, self).run(addr)
-
-
-class Sandbox_Linux_arml_str(Sandbox, Arch_arml, OS_Linux_str):
-
-    def __init__(self, loc_db, *args, **kwargs):
-        Sandbox.__init__(self, loc_db, *args, **kwargs)
-
-        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 None and self.options.address is not None:
-            addr = int(self.options.address, 0)
-        super(Sandbox_Linux_arml_str, self).run(addr)
-
-
-class Sandbox_Linux_aarch64l(Sandbox, Arch_aarch64l, OS_Linux):
-
-    def __init__(self, loc_db, *args, **kwargs):
-        Sandbox.__init__(self, loc_db, *args, **kwargs)
-
-        # Pre-stack some arguments
-        if self.options.mimic_env:
-            env_ptrs = []
-            for env in self.envp:
-                env = force_bytes(env)
-                env += b"\x00"
-                self.jitter.cpu.SP -= len(env)
-                ptr = self.jitter.cpu.SP
-                self.jitter.vm.set_mem(ptr, env)
-                env_ptrs.append(ptr)
-            argv_ptrs = []
-            for arg in self.argv:
-                arg = force_bytes(arg)
-                arg += b"\x00"
-                self.jitter.cpu.SP -= len(arg)
-                ptr = self.jitter.cpu.SP
-                self.jitter.vm.set_mem(ptr, arg)
-                argv_ptrs.append(ptr)
-
-            self.jitter.push_uint64_t(0)
-            for ptr in reversed(env_ptrs):
-                self.jitter.push_uint64_t(ptr)
-            self.jitter.push_uint64_t(0)
-            for ptr in reversed(argv_ptrs):
-                self.jitter.push_uint64_t(ptr)
-            self.jitter.push_uint64_t(len(self.argv))
-
-        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 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)
-
-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, loc_db, *args, **kwargs):
-        super(Sandbox_Linux_ppc32b, self).__init__(loc_db, *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 = force_bytes(env)
-                env += b"\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 = force_bytes(arg)
-                arg += b"\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)