Exemplo n.º 1
0
    def asm(self, string, addr=0, as_bytes=True, thumb=False):
        """
        Compile the assembly instruction represented by string using Keystone

        :param string:      The textual assembly instructions, separated by semicolons
        :param addr:        The address at which the text should be assembled, to deal with PC-relative access. Default 0
        :param as_bytes:    Set to False to return a list of integers instead of a python byte string
        :param thumb:       If working with an ARM processor, set to True to assemble in thumb mode.
        :return:            The assembled bytecode
        """
        if thumb is True:
            l.warning("Specified thumb=True on non-ARM architecture")
        if _keystone is None:
            l.warning("Keystone is not found!")
            return None
        if self.ks_arch is None:
            raise ArchError("Arch %s does not support assembly with Keystone" %
                            self.name)
        if self._ks is None:
            self._ks = _keystone.Ks(self.ks_arch, self.ks_mode)
        try:
            encoding, _ = self._ks.asm(string, addr, as_bytes)  # pylint: disable=too-many-function-args
        except TypeError:
            bytelist, _ = self._ks.asm(string, addr)
            if as_bytes:
                encoding = ''.join(chr(c) for c in bytelist)
                if not isinstance(encoding, bytes):
                    l.warning("Cheap hack to create bytestring from Keystone!")
                    encoding = encoding.encode()
            else:
                encoding = bytelist

        return encoding
Exemplo n.º 2
0
 def unicorn(self):
     """
     A Unicorn engine instance for this arch
     """
     if _unicorn is None or self.uc_arch is None:
         raise ArchError("Arch %s does not support with Unicorn" % self.name)
     # always create a new Unicorn instance
     return _unicorn.Uc(self.uc_arch, self.uc_mode)
Exemplo n.º 3
0
 def capstone(self):
     """
     A capstone instance for this arch
     """
     if self.cs_arch is None:
         raise ArchError("Arch %s does not support disassembly with capstone" % self.name)
     if self._cs is None:
         self._cs = _capstone.Cs(self.cs_arch, self.cs_mode)
         self._cs.detail = True
     return self._cs
Exemplo n.º 4
0
    def __init__(self, endness, instruction_endness=None):

        if endness not in (Endness.LE, Endness.BE, Endness.ME):
            raise ArchError(
                'Must pass a valid endness: Endness.LE, Endness.BE, or Endness.ME'
            )

        if instruction_endness is not None:
            self.instruction_endness = instruction_endness

        if self.vex_support:
            if _pyvex:
                self.vex_archinfo = _pyvex.default_vex_archinfo()
        else:
            self._vex_archinfo = None

        if endness == Endness.BE:
            if self.vex_archinfo:
                self.vex_archinfo['endness'] = _pyvex.vex_endness_from_string(
                    'VexEndnessBE')
            self.memory_endness = Endness.BE
            self.register_endness = Endness.BE
            if _capstone and self.cs_mode is not None:
                self.cs_mode -= _capstone.CS_MODE_LITTLE_ENDIAN
                self.cs_mode += _capstone.CS_MODE_BIG_ENDIAN
            if _keystone and self.ks_mode is not None:
                self.ks_mode -= _keystone.KS_MODE_LITTLE_ENDIAN
                self.ks_mode += _keystone.KS_MODE_BIG_ENDIAN
            self.ret_instruction = reverse_ends(self.ret_instruction)
            self.nop_instruction = reverse_ends(self.nop_instruction)

        # generate register mapping (offset, size): name
        self.register_size_names = {}
        for k in self.registers:
            v = self.registers[k]

            # special hacks for X86 and AMD64 - don't translate register names to bp, sp, etc.
            if self.name in {'X86', 'AMD64'} and k in {'bp', 'sp', 'ip'}:
                continue

            if v in self.register_size_names and k not in self.register_names:
                continue
            self.register_size_names[v] = k

        # Unicorn specific stuff
        if self.uc_mode is not None:
            if endness == Endness.BE:
                self.uc_mode -= _unicorn.UC_MODE_LITTLE_ENDIAN
                self.uc_mode += _unicorn.UC_MODE_BIG_ENDIAN
            self.uc_regs = {}
            # map register names to Unicorn const
            for r in self.register_names.values():
                reg_name = self.uc_prefix + 'REG_' + r.upper()
                if hasattr(self.uc_const, reg_name):
                    self.uc_regs[r] = getattr(self.uc_const, reg_name)
Exemplo n.º 5
0
 def keystone(self):
     """
     A Keystone instance for this arch
     """
     if self._ks is None:
         if _keystone is None:
             l.warning("Keystone is not installed!")
             return None
         if self.ks_arch is None:
             raise ArchError("Arch %s does not support disassembly with Keystone" % self.name)
         self._ks = _keystone.Ks(self.ks_arch, self.ks_mode)
         self._configure_keystone()
     return self._ks
Exemplo n.º 6
0
 def capstone(self):
     """
     A Capstone instance for this arch
     """
     if _capstone is None:
         l.warning("Capstone is not installed!")
         return None
     if self.cs_arch is None:
         raise ArchError("Arch %s does not support disassembly with Capstone" % self.name)
     if self._cs is None:
         self._cs = _capstone.Cs(self.cs_arch, self.cs_mode)
         self._configure_capstone()
         self._cs.detail = True
     return self._cs
Exemplo n.º 7
0
    def __init__(self, endness):
        if endness not in ('Iend_LE', 'Iend_BE'):
            raise ArchError('Must pass a valid VEX endness: "Iend_LE" or "Iend_BE"')

        if _pyvex:
            self.vex_archinfo = _pyvex.default_vex_archinfo()
        if endness == 'Iend_BE':
            if self.vex_archinfo:
                self.vex_archinfo['endness'] = _pyvex.vex_endness_from_string('VexEndnessBE')
            self.memory_endness = 'Iend_BE'
            self.register_endness = 'Iend_BE'
            if _capstone:
                self.cs_mode -= _capstone.CS_MODE_LITTLE_ENDIAN
                self.cs_mode += _capstone.CS_MODE_BIG_ENDIAN
            self.ret_instruction = reverse_ends(self.ret_instruction)
            self.nop_instruction = reverse_ends(self.nop_instruction)

        # generate regitster mapping (offset, size): name
        self.register_size_names = {}
        for k, v in self.registers.iteritems():

            # special hacks for X86 and AMD64 - don't translate register names to bp, sp, etc.
            if self.name in {'X86', 'AMD64'} and k in {'bp', 'sp', 'ip'}:
                continue

            if v in self.register_size_names and k not in self.register_names:
                continue
            self.register_size_names[v] = k

        # unicorn specific stuff
        if self.uc_mode is not None:
            if endness == 'Iend_BE':
                self.uc_mode -= _unicorn.UC_MODE_LITTLE_ENDIAN
                self.uc_mode += _unicorn.UC_MODE_BIG_ENDIAN
            self.uc_regs = { }
            # map register names to unicorn const
            for r in self.register_names.itervalues():
                reg_name = self.uc_prefix + 'REG_' + r.upper()
                if hasattr(self.uc_const, reg_name):
                    self.uc_regs[r] = getattr(self.uc_const, reg_name)
Exemplo n.º 8
0
    def __init__(self, endness, instruction_endness=None):

        self.bytes = self.bits // self.byte_width

        if endness not in (Endness.LE, Endness.BE, Endness.ME):
            raise ArchError('Must pass a valid endness: Endness.LE, Endness.BE, or Endness.ME')

        if instruction_endness is not None:
            self.instruction_endness = instruction_endness

        if self.vex_support:
            if _pyvex:
                self.vex_archinfo = _pyvex.default_vex_archinfo()
        else:
            self._vex_archinfo = None

        if endness == Endness.BE:
            if self.vex_archinfo:
                self.vex_archinfo['endness'] = _pyvex.vex_endness_from_string('VexEndnessBE')
            self.memory_endness = Endness.BE
            self.register_endness = Endness.BE
            if _capstone and self.cs_mode is not None:
                self.cs_mode -= _capstone.CS_MODE_LITTLE_ENDIAN
                self.cs_mode += _capstone.CS_MODE_BIG_ENDIAN
            if _keystone and self.ks_mode is not None:
                self.ks_mode -= _keystone.KS_MODE_LITTLE_ENDIAN
                self.ks_mode += _keystone.KS_MODE_BIG_ENDIAN
            self.ret_instruction = reverse_ends(self.ret_instruction)
            self.nop_instruction = reverse_ends(self.nop_instruction)

        if self.register_list and _pyvex is not None:
            (_, _), max_offset = max(_pyvex.vex_ffi.guest_offsets.items(), key=lambda x: x[1])
            max_offset += self.bits
            # Register collections
            if type(self.vex_arch) is str:
                va = self.vex_arch[7:].lower() # pylint: disable=unsubscriptable-object
                for r in self.register_list:
                    if r.vex_offset is None:
                        for name in (r.vex_name, r.name) + r.alias_names:
                            try:
                                r.vex_offset = _pyvex.vex_ffi.guest_offsets[(va, name)]
                            except KeyError:
                                r.vex_offset = max_offset
                                max_offset += r.size
                            else:
                                break

            self.default_register_values = [(r.name,) + r.default_value for r in self.register_list if r.default_value is not None]
            self.entry_register_values = {r.name: r.linux_entry_value for r in self.register_list if r.linux_entry_value is not None}
            self.default_symbolic_registers = [r.name for r in self.register_list if r.general_purpose]
            self.register_names = {r.vex_offset: r.name for r in self.register_list}
            self.registers = self._get_register_dict()
            self.argument_registers = set(r.vex_offset for r in self.register_list if r.argument)
            self.persistent_regs = [r.name for r in self.register_list if r.persistent]
            self.concretize_unique_registers = set(r.vex_offset for r in self.register_list if r.concretize_unique)
            self.artificial_registers = set(r.name for r in self.register_list if r.artificial)

            # Register offsets
            try:
                self.ip_offset = self.registers['ip'][0]
                self.sp_offset = self.registers['sp'][0]
                self.bp_offset = self.registers['bp'][0]
                self.lr_offset = self.registers.get('lr', (None, None))[0]
            except KeyError:
                pass

        # generate register mapping (offset, size): name
        self.register_size_names = {}
        for reg in self.register_list:
            if reg.vex_offset is None:
                continue
            self.register_size_names[(reg.vex_offset, reg.size)] = reg.name
            for name, off, sz in reg.subregisters:
                # special hacks for X86 and AMD64 - don't translate register names to bp, sp, etc.
                if self.name in {'X86', 'AMD64'} and name in {'bp', 'sp', 'ip'}:
                    continue
                self.register_size_names[(reg.vex_offset + off, sz)] = name

        # allow mapping a sub-register to its base register
        self.subregister_map = { }
        for reg in self.register_list:
            if reg.vex_offset is None:
                continue
            base_reg = reg.vex_offset, reg.size
            self.subregister_map[(reg.vex_offset, reg.size)] = base_reg
            self.subregister_map[reg.vex_offset] = base_reg
            for name, off, sz in reg.subregisters:
                if self.name in {'X86', 'AMD64'} and name in {'bp', 'sp', 'ip'}:
                    continue
                subreg_offset = reg.vex_offset + off
                self.subregister_map[(subreg_offset, sz)] = base_reg
                if subreg_offset not in self.subregister_map:
                    self.subregister_map[subreg_offset] = base_reg

        # Unicorn specific stuff
        if self.uc_mode is not None:
            if endness == Endness.BE:
                self.uc_mode -= _unicorn.UC_MODE_LITTLE_ENDIAN
                self.uc_mode += _unicorn.UC_MODE_BIG_ENDIAN
            self.uc_regs = { }
            # map register names to Unicorn const
            for r in self.register_names.values():
                reg_name = self.uc_prefix + 'REG_' + r.upper()
                if hasattr(self.uc_const, reg_name):
                    self.uc_regs[r] = getattr(self.uc_const, reg_name)
Exemplo n.º 9
0
    def __init__(self, endness, instruction_endness=None):

        if endness not in (Endness.LE, Endness.BE, Endness.ME):
            raise ArchError(
                'Must pass a valid endness: Endness.LE, Endness.BE, or Endness.ME'
            )

        if instruction_endness is not None:
            self.instruction_endness = instruction_endness

        if self.vex_support:
            if _pyvex:
                self.vex_archinfo = _pyvex.default_vex_archinfo()
        else:
            self._vex_archinfo = None

        if endness == Endness.BE:
            if self.vex_archinfo:
                self.vex_archinfo['endness'] = _pyvex.vex_endness_from_string(
                    'VexEndnessBE')
            self.memory_endness = Endness.BE
            self.register_endness = Endness.BE
            if _capstone and self.cs_mode is not None:
                self.cs_mode -= _capstone.CS_MODE_LITTLE_ENDIAN
                self.cs_mode += _capstone.CS_MODE_BIG_ENDIAN
            if _keystone and self.ks_mode is not None:
                self.ks_mode -= _keystone.KS_MODE_LITTLE_ENDIAN
                self.ks_mode += _keystone.KS_MODE_BIG_ENDIAN
            self.ret_instruction = reverse_ends(self.ret_instruction)
            self.nop_instruction = reverse_ends(self.nop_instruction)

        # Register collections
        if self.register_list:
            if self.vex_arch is not None and _pyvex is not None:
                va = self.vex_arch[7:].lower()
                for r in self.register_list:
                    if r.vex_offset is None:
                        for name in (r.vex_name, r.name) + r.alias_names:
                            try:
                                r.vex_offset = _pyvex.vex_ffi.guest_offsets[(
                                    va, name)]
                            except KeyError:
                                pass
                            else:
                                break

            self.default_register_values = [(r.name, ) + r.default_value
                                            for r in self.register_list
                                            if r.default_value is not None]
            #           print 'default_register_values'
            #           for i in self.default_register_values:
            #               print i
            self.entry_register_values = {
                r.name: r.linux_entry_value
                for r in self.register_list if r.linux_entry_value is not None
            }
            #           print 'entry_register_values'
            #           for i in self.entry_register_values:
            #               print i
            self.default_symbolic_registers = [
                r.name for r in self.register_list if r.general_purpose
            ]
            #           print 'default_symbolic_registers'
            #           for i in self.default_symbolic_registers:
            #               print i
            self.register_names = {
                r.vex_offset: r.name
                for r in self.register_list
            }
            #           print 'register_names'
            #           for k, v in self.register_names.iteritems():
            #               print k, v
            self.registers = self._get_register_dict()
            #           print 'registers'
            #           for k, v in self.registers.iteritems():
            #               print k, v
            self.argument_registers = set(r.vex_offset
                                          for r in self.register_list
                                          if r.argument)
            #           print 'argument_registers'
            #           for i in self.argument_registers:
            #               print i
            self.persistent_regs = [
                r.name for r in self.register_list if r.persistent
            ]
            #           print 'persistent_regs'
            #           for i in self.persistent_regs:
            #               print i
            self.concretize_unique_registers = set(r.vex_offset
                                                   for r in self.register_list
                                                   if r.concretize_unique)


#           print 'concretize_unique_registers'
#           for i in self.concretize_unique_registers:
#               print i

# generate register mapping (offset, size): name
        self.register_size_names = {}
        for k in self.registers:
            v = self.registers[k]

            # special hacks for X86 and AMD64 - don't translate register names to bp, sp, etc.
            if self.name in {'X86', 'AMD64'} and k in {'bp', 'sp', 'ip'}:
                continue

            if v in self.register_size_names and k not in self.register_names:
                continue
            self.register_size_names[v] = k

        # Unicorn specific stuff
        if self.uc_mode is not None:
            if endness == Endness.BE:
                self.uc_mode -= _unicorn.UC_MODE_LITTLE_ENDIAN
                self.uc_mode += _unicorn.UC_MODE_BIG_ENDIAN
            self.uc_regs = {}
            # map register names to Unicorn const
            for r in self.register_names.values():
                reg_name = self.uc_prefix + 'REG_' + r.upper()
                if hasattr(self.uc_const, reg_name):
                    self.uc_regs[r] = getattr(self.uc_const, reg_name)