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
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)
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
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)
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
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
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)
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)
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)