示例#1
0
 def __init__(self):
     super(AsmBase, self).__init__()
     # Initialize keystone and capstone as soon as an instance
     # of this plugin will be created.
     if not keystone:
         self.log.debug('Keystone is required for ' +
                        self.__class__.__name__)
         return
     if not capstone:
         self.log.debug('Capstone is required for ' +
                        self.__class__.__name__)
         return
     if getattr(self, 'args', None) and self.args and getattr(self.args, 'bigendian', None) \
             and self.args.bigendian:
         self.ks = keystone.Ks(
             self.keystone_arch,
             self.keystone_mode + keystone.KS_MODE_BIG_ENDIAN)
         self.cs = capstone.Cs(self.capstone_arch,
                               capstone.CS_MODE_BIG_ENDIAN)
     else:
         self.ks = keystone.Ks(
             self.keystone_arch,
             self.keystone_mode + keystone.KS_MODE_LITTLE_ENDIAN)
         self.cs = capstone.Cs(self.capstone_arch,
                               capstone.CS_MODE_LITTLE_ENDIAN)
 def __init__(self, is_thumb):
     self.__is_thumb = is_thumb
     if (is_thumb):
         self.__cs = capstone.Cs(capstone.CS_ARCH_ARM, capstone.CS_MODE_THUMB)
         self.__ks = keystone.Ks(keystone.KS_ARCH_ARM, keystone.KS_MODE_THUMB)
     else:
         self.__cs = capstone.Cs(capstone.CS_ARCH_ARM, capstone.CS_MODE_ARM)
         self.__ks = keystone.Ks(keystone.KS_ARCH_ARM, keystone.KS_MODE_ARM)
示例#3
0
def asm(asm_code, addr=0, arch=None):
    import keystone
    asm_code = Latin1_encode(asm_code)
    if arch is None:
        arch = context.arch
    if arch == 'i386':
        asmer = keystone.Ks(keystone.KS_ARCH_X86, keystone.KS_MODE_32)
    elif arch == "amd64":
        asmer = keystone.Ks(keystone.KS_ARCH_X86, keystone.KS_MODE_64)
    l = ""
    for i in asmer.asm(asm_code, addr)[0]:
        l += chr(i)
    return Latin1_decode(Latin1_encode(l.strip('\n')))
示例#4
0
 def keystone_thumb(self):
     if _keystone is None:
         l.warning("Keystone is not installed!")
         return None
     if self._ks_thumb is None:
         self._ks_thumb = _keystone.Ks(self.ks_arch, _keystone.KS_MODE_THUMB)
     return self._ks_thumb
示例#5
0
def assemble(asm_code, mode):
    """
    Helper function to assemble code receive in parameter `asm_code` using Keystone.

    @param asm_code : bytearray of N instructions, separated by ';'
    @param mode : defines the mode to use Keystone with
    @return a tuple of bytecodes as bytearray, along with the number of instruction compiled. If failed, the
    bytearray will be empty, the count of instruction will be the negative number for the faulty line.
    """
    arch, mode, endian = get_arch_mode("keystone", mode)
    ks = keystone.Ks(arch, mode | endian)
    if is_x86(mode) and mode.syntax == Syntax.ATT:
        ks.syntax = keystone.KS_OPT_SYNTAX_ATT

    bytecode = []
    insns = asm_code.split(b';')
    for i, insn in enumerate(insns):
        try:
            code, cnt = ks.asm(insn)
            if cnt == 0:
                return (b'', -(i + 1))
            bytecode.append(bytearray(code))
        except keystone.keystone.KsError as kse:
            return (b'', -(i + 1))

    return (b''.join(bytecode), i + 1)
示例#6
0
    def __init__(self, archstring, debug=False):
        self.debug = debug
        self.arch = globals()[archstring]()
        self.ks = keystone.Ks(self.arch.ks_arch[0], self.arch.ks_arch[1])
        self.mu = unicorn.Uc(self.arch.uc_arch[0], self.arch.uc_arch[1])
        self.md = capstone.Cs(self.arch.cs_arch[0], self.arch.cs_arch[1])

        self.pc_reg = self.arch.pc_reg
        self.state_reg = self.arch.state_reg
        self.cpu_regs = self.arch.cpu_regs
        self.mem_regs = {}
        self.mem_addrs = {}

        self.mu.mem_map(self.arch.code_addr, self.arch.code_mem)
        self._mem_invalid_hook = self.mu.hook_add(
            UC_HOOK_MEM_READ_UNMAPPED | UC_HOOK_MEM_WRITE_UNMAPPED,
            self._invalid_mem)
        #self._mem_invalid_hook2 = self.mu.hook_add(UC_HOOK_MEM_FETCH_UNMAPPED, self._invalid_mem_fetch)
        self._code_hook = self.mu.hook_add(
            UC_HOOK_CODE, self._code_hook, None, self.arch.code_addr,
            self.arch.code_addr + self.arch.code_mem)

        self.pages = set()

        # TODO: have to figure out how to remove this state... :(
        self.rw_struct = [[0, 0], [None, None, None], False]
        self._mem_rw_hook = self.mu.hook_add(
            UC_HOOK_MEM_WRITE | UC_HOOK_MEM_READ, self._mem_hook,
            self.rw_struct)
        pass
示例#7
0
 def asm(code, bitness=64, vma=0):
     """asm(code, bitness = 64, vma = 0) assembles the assembly code at vma"""
     ks = keystone.Ks(
         keystone.KS_ARCH_X86,
         keystone.KS_MODE_64 if bitness == 64 else keystone.KS_MODE_32)
     encoding, count = ks.asm(code, vma)
     return encoding
示例#8
0
 def asm(self, arch, mode):
     try:
         ks = keystone.Ks(self._arch(arch), self._mode(mode))
         return ks.asm("\n".join(self.pcode))
     except keystone.KsError as e:
         print("ERROR: %s" % e)
         sys.exit(1)
示例#9
0
def main(args):

    egghunter = ntaccess_hunter(args.tag) if not args.seh else seh_hunter(
        args.tag)

    eng = ks.Ks(ks.KS_ARCH_X86, ks.KS_MODE_32)
    encoding, count = eng.asm(egghunter)

    final = ""

    final += 'egghunter = b"'

    for enc in encoding:
        final += "\\x{0:02x}".format(enc)

    final += '"'

    sentry = False

    for bad in args.bad_chars:
        if bad in final:
            print(f"[!] Found 0x{bad}")
            sentry = True

    if sentry:
        print(f'[=] {final[14:-1]}', file=sys.stderr)
        raise SystemExit("[!] Remove bad characters and try again")

    print(f"[+] egghunter created!")
    print(f"[=]   len: {len(encoding)} bytes")
    print(f"[=]   tag: {args.tag * 2}")
    print(f"[=]   ver: {['NtAccessCheckAndAuditAlarm', 'SEH'][args.seh]}\n")
    print(final)
示例#10
0
文件: rop.py 项目: sinmygit/Ropper
    def assemble(self, code, arch=x86, format=Format.HEX):
        if 'keystone' not in globals():
            raise RopperError('Keystone is not installed! Please install Keystone. \nLook at http://keystone-engine.org')

        ks = keystone.Ks(arch.ksarch[0], arch.ksarch[1])
        try:
            byte_list =  ks.asm(code.encode('ascii'))[0]
        except BaseException as e:
            raise RopperError(e)

        if not byte_list:
            return "invalid"
        to_return = byte_list

        if format == Format.STRING:
            to_return = '"'
            for byte in byte_list:
                to_return += '\\x%02x' % byte

            to_return += '"'
        elif format == Format.HEX:
            to_return = ''
            for byte in byte_list:
                to_return += '%02x' % byte
        elif format == Format.RAW:
            to_return = ''
            for byte in byte_list:
                to_return += '%s' % chr(byte)

        return to_return
示例#11
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 _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 or self._ks_thumb != thumb:
            self._ks_thumb = thumb
            mode = _keystone.KS_MODE_THUMB if thumb else _keystone.KS_MODE_ARM
            self._ks = _keystone.Ks(self.ks_arch, self.ks_mode + 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
示例#12
0
    def __init__(self):
        '''初始化 instance 初始化模拟器参数 only x86'''
        # Initialize emulator in X86-32bit mode
        self.vm = unicorn.Uc(unicorn.UC_ARCH_X86, unicorn.UC_MODE_32 | unicorn.UC_MODE_LITTLE_ENDIAN)
        self.asb = keystone.Ks(keystone.KS_ARCH_X86, keystone.KS_MODE_32 | keystone.KS_MODE_LITTLE_ENDIAN)
        self.disas = capstone.Cs(capstone.CS_ARCH_X86, capstone.CS_MODE_32 | capstone.CS_MODE_LITTLE_ENDIAN)
		self.__reinit__()
示例#13
0
    def load_library(self, arch, libso, libc_time_offset, libc_dlopen_offset):
        """
        Load library by hooking time() to a stub that calls dlopen to load library
        :param arch: currently arm64 only
        :param libso: so filename or path to load.
        :param libc_time_offset: time function offset to libc
        :param libc_dlopen_offset: dlopen function offset to libc
        """
        try:
            import keystone
            asm = keystone.Ks(keystone.KS_ARCH_ARM64,
                              keystone.KS_MODE_LITTLE_ENDIAN)

            has_runned_flag_addr = self.find_code_cave(4, perm='rw')
            if has_runned_flag_addr == 0:
                raise Exception('failed to find data cave')
            # print(f'has_runned_flag_addr: {has_runned_flag_addr:x}, {victim.get_ptr_info(has_runned_flag_addr)}')

            #### get the payload length with random address
            shellcode_len = 0
            if arch == 'arm64':
                shellcode_len = len(
                    asm.asm(self.get_dlopen_payload_arm64(0, 0, 0, libso),
                            addr=0,
                            as_bytes=True)[0])
            else:
                raise Exception('load library only support arm64 currently')

            if shellcode_len == 0:
                raise Exception('failed to generate payload')
            #### now find a code cave
            shellcode_addr = self.find_code_cave(
                shellcode_len, not_addrs=(has_runned_flag_addr, ))
            if shellcode_addr == 0:
                raise Exception('failed to find code cave')
            # print(f'shellcode_addr: {shellcode_addr:x}, {victim.get_ptr_info(shellcode_addr)}')

            #### get the real payload
            time_addr = self.find('/libc.so')[0].addr + libc_time_offset
            dlopen_addr = self.mem.readptr(
                self.find('/libc.so')[0].addr + libc_dlopen_offset)
            shellcode = asm.asm(self.get_dlopen_payload_arm64(
                time_addr, has_runned_flag_addr, dlopen_addr, libso),
                                addr=shellcode_addr,
                                as_bytes=True)[0]

            trampoline = asm.asm(f"""
            b #{shellcode_addr}
            """,
                                 addr=time_addr,
                                 as_bytes=True)[0]
            # prepare stub
            self.mem.writebuf(shellcode_addr, shellcode)
            # detour
            self.mem.writebuf(time_addr, trampoline)
            return True
        except ImportError:
            print('python dependency keystone is required')
            return False
示例#14
0
文件: tarch.py 项目: kamou/poseidon
    def __init__(self):
        self.simplifications = set()
        self.tc = triton.TritonContext()
        self.tc.setArchitecture(triton.ARCH.X86_64)
        self.tc.setMode(triton.MODE.ALIGNED_MEMORY, True)
        self.ks = keystone.Ks(keystone.KS_ARCH_X86, keystone.KS_MODE_64)
        self.tc.addCallback(self.simplify, triton.CALLBACK.SYMBOLIC_SIMPLIFICATION)
        self.tc.setMode(triton.MODE.SYMBOLIZE_INDEX_ROTATION, True)
        self.pc = self.tc.registers.rip
        self.sp = self.tc.registers.rsp
        self.psize = triton.CPUSIZE.QWORD
        self.ret = self.tc.registers.rax
        self.tc.setAstRepresentationMode(triton.AST_REPRESENTATION.PYTHON)

        self.regs = [
            self.tc.registers.rdi,
            self.tc.registers.rsi,
            self.tc.registers.rdx,
            self.tc.registers.rcx,
            self.tc.registers.r8,
            self.tc.registers.r9
        ]

        self.syscall_regs = [
            self.tc.registers.rax,
            self.tc.registers.rbx,
            self.tc.registers.rcx,
            self.tc.registers.rdx,
            self.tc.registers.rsi,
            self.tc.registers.rdi,
        ]

        self.ret_types = set([triton.OPCODE.X86.RET])
        self.call_types = set([triton.OPCODE.X86.CALL, triton.OPCODE.X86.LCALL])
        self.conditional_branch_types = set([
            triton.OPCODE.X86.JA,
            triton.OPCODE.X86.JBE,
            triton.OPCODE.X86.JECXZ,
            triton.OPCODE.X86.JL,
            triton.OPCODE.X86.JNE,
            triton.OPCODE.X86.JNS,
            triton.OPCODE.X86.JRCXZ,
            triton.OPCODE.X86.JAE,
            triton.OPCODE.X86.JCXZ,
            triton.OPCODE.X86.JG,
            triton.OPCODE.X86.JLE,
            triton.OPCODE.X86.JNO,
            triton.OPCODE.X86.JO,
            triton.OPCODE.X86.JS,
            triton.OPCODE.X86.JB,
            triton.OPCODE.X86.JE,
            triton.OPCODE.X86.JGE,
            triton.OPCODE.X86.JNP,
            triton.OPCODE.X86.JP
        ])

        self.branch_types = set()
        self.branch_types.update(self.conditional_branch_types)
        self.branch_types.add(triton.OPCODE.X86.JMP)
示例#15
0
def assemble(code, addr=0, mode=keystone.KS_MODE_32):
    """
    assemble asm code for inline hook
    """

    ks = keystone.Ks(keystone.KS_ARCH_X86, mode)
    encoding, count = ks.asm(code, addr)
    buf = ''.join(chr(c) for c in encoding)
    return buf, count
示例#16
0
def create_assembler():
    '''
    create an assembler using some standard options.
    '''
    try:
        return keystone.Ks(keystone.KS_ARCH_X86, keystone.KS_MODE_32)
    except AttributeError:
        # DANGER
        logger.warning('failed to load keystone-engine')
        return None
示例#17
0
    def __init__(self, program, flags=None):
        self.program = program

        # if flags == None:
        #     flags = ['-w']

        # if '-w' not in flags:
        #     flags.append('-w')

        if flags != None and isinstance(flags, list):
            self.r2 = r2pipe.open(self.program, flags=flags)
        else:
            self.r2 = r2pipe.open(self.program)
        # self.r2.cmd("aa")

        i_json = self.r2.cmdj('ij')
        self.os = i_json['bin']['os']
        self.arch = i_json['bin']['arch']
        self.bits = i_json['bin']['bits']
        self.pic = i_json['bin']['pic']
        self.endian = i_json['bin']['endian']

        if self.arch == 'x86':
            if self.bits == 64:
                self.archinfo = archinfo.ArchAMD64
            else:
                self.archinfo = archinfo.ArchX86
        elif self.arch == 'mips':
            if self.bits == 32:
                self.archinfo = archinfo.ArchMIPS32
            elif self.bits == 64:
                self.archinfo = archinfo.ArchMIPS64
        elif self.arch == 'arm':
            self.archinfo = archinfo.ArchARM
        elif self.arch == 'ppc':
            if self.bits == 32:
                self.archinfo = archinfo.ArchPPC32
            elif self.bits == 64:
                self.archinfo = archinfo.ArchPPC64
        elif self.arch == 'aarch64':
            self.archinfo = archinfo.AArch64
        else:
            self.archinfo = None

        if self.archinfo is not None:
            if self.endian == "little":
                self.archinfo.memory_endess = archinfo.Endness.LE
            else:
                self.archinfo.memory_endess = archinfo.Endness.BE

        if self.archinfo != None:
            self.md = capstone.Cs(self.archinfo.cs_arch, self.archinfo.cs_mode)
            self.cs = keystone.Ks(self.archinfo.ks_arch, self.archinfo.ks_mode)
        else:
            self.md = None
示例#18
0
def get_ks(arch, arch_bits):  # TODO: What architectures are supported by KS?
    if arch == "x86":
        ks_arch = ks.KS_ARCH_X86
        if arch_bits == 32:
            ks_mode = ks.KS_MODE_32
        else:
            ks_mode = ks.KS_MODE_64
    else:
        return None

    return ks.Ks(ks_arch, ks_mode)
示例#19
0
def assemble_x86_64(code):
    try:
        ks = keystone.Ks(keystone.KS_ARCH_X86,
                         keystone.KS_MODE_64)
        encoding, count = ks.asm(code)
        print("%s = %s (number of statements: %u)" %(code, encoding, count))

        return encoding
    except keystone.KsError as e:
        print("ERROR: %s" %e)

        return None
示例#20
0
文件: arch.py 项目: AOS002/archinfo
 def keystone(self):
     """
     A Keystone instance for this arch
     """
     if self._ks is None:
         if _keystone is None:
             raise Exception("Keystone is not installed!")
         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
示例#21
0
    def patch_code(self, instructions='ret;', va=0):
        """ put instruction(s), at the end of the basic block specified"""
        #TODO: get capstone instruction at the end of the basic_block
        try:
            k = ks.Ks(ks.KS_ARCH_X86, ks.KS_MODE_32)
            encoding, count = k.asm(instructions)
        except ks.KsError as e:
            l.error("Error! %s", e)
            raise

        if not self.set_bytes_at_rva(va, ''.join(map(chr, encoding))):
            raise Exception('Cannot patch bytes at %x!', va)
示例#22
0
    def __init__(self, ir, ks=None):
        self.ir = ir
        self.cp = capstone.Cs(capstone.CS_ARCH_X86, capstone.CS_MODE_64)

        if ks is None:
            # Setup keystone
            self.ks = keystone.Ks(keystone.KS_ARCH_X86, keystone.KS_MODE_64)
            self.ks.syntax = keystone.KS_OPT_SYNTAX_ATT
        else:
            self.ks = ks

        self.prepare_for_rewriting()
示例#23
0
文件: utils.py 项目: wflk/cemu
def assemble(asm_code, mode):
    arch, mode, endian = get_arch_mode("keystone", mode)
    ks = keystone.Ks(arch, mode | endian)
    if mode in (Architecture.X86_16_ATT, Architecture.X86_32_ATT,
                Architecture.X86_64_ATT):
        ks.syntax = keystone.KS_OPT_SYNTAX_ATT

    try:
        code, cnt = ks.asm(asm_code)
        code = bytes(bytearray(code))
    except keystone.keystone.KsError:
        code, cnt = (b"", -1)

    return (code, cnt)
示例#24
0
def assemble(asm_code, mode):
    arch, mode, endian = get_arch_mode("keystone", mode)
    ks = keystone.Ks(arch, mode | endian)
    if is_x86(mode) and mode.syntax == Syntax.ATT:
        ks.syntax = keystone.KS_OPT_SYNTAX_ATT

    try:
        code, cnt = ks.asm(asm_code)
        if cnt == 0:
            code = b""
        code = bytes(bytearray(code))
    except keystone.keystone.KsError:
        code, cnt = (b"", -1)

    return (code, cnt)
示例#25
0
    def load(fp, _isa, base=0, offset=0):
        """load a single executable extent from a file"""
        _isa = isa.correlate(copy.deepcopy(_isa))

        # first, assemble

        fp.seek(offset, os.SEEK_CUR)
        assembled = bytes(
            keystone.Ks(
                _isa["keystone"]["arch"], _isa["keystone"]["endianness"] +
                _isa["keystone"]["mode"]).asm(fp.read())[0])

        # disassemble

        return MachineCodeIO.load(io.BytesIO(assembled), _isa, base)
def get_function(code):
    import keystone as ks

    ksa = ks.Ks(ks.KS_ARCH_X86, ks.KS_MODE_64)
    ksa.syntax = ks.KS_OPT_SYNTAX_ATT
    asm, count = ksa.asm(code)

    asm = bytes(asm)

    func = Function("DYNCODE", 0x1000, len(asm), asm)

    container = Container()
    container.add_function(func)

    return container
示例#27
0
    def dump(fp, extent):
        """load a single executable extent to a file"""
        _isa = isa.correlate(copy.deepcopy(extent["isa"]))

        # dump assembly

        b = io.BytesIO()
        AssemblyIO.dump(b, extent)

        # assemble

        fp.write(
            bytes(
                keystone.Ks(
                    _isa["keystone"]["arch"], _isa["keystone"]["endianness"] +
                    _isa["keystone"]["mode"]).asm(b.getvalue())[0]))
示例#28
0
def main(args):

    egghunter = ntaccess_hunter(args.tag) if not args.seh else seh_hunter(
        args.tag)

    eng = ks.Ks(ks.KS_ARCH_X86, ks.KS_MODE_32)
    if args.seh:
        encoding, count = eng.asm(egghunter)
    else:
        print("[+] Egghunter assembly code + coresponding bytes")
        asm_blocks = ""
        prev_size = 0
        for line in egghunter.splitlines():
            asm_blocks += line + "\n"
            encoding, count = eng.asm(asm_blocks)
            if encoding:
                enc_opcode = ""
                for byte in encoding[prev_size:]:
                    enc_opcode += "0x{0:02x} ".format(byte)
                    prev_size += 1
                spacer = 30 - len(line)
                print("%s %s %s" % (line, (" " * spacer), enc_opcode))

    final = ""
    final += 'egghunter = b"'

    for enc in encoding:
        final += "\\x{0:02x}".format(enc)

    final += '"'

    sentry = False

    for bad in args.bad_chars:
        if bad in final:
            print(f"[!] Found 0x{bad}")
            sentry = True

    if sentry:
        print(f"[=] {final[14:-1]}", file=sys.stderr)
        raise SystemExit("[!] Remove bad characters and try again")

    print(f"[+] egghunter created!")
    print(f"[=]   len: {len(encoding)} bytes")
    print(f"[=]   tag: {args.tag * 2}")
    print(f"[=]   ver: {['NtAccessCheckAndAuditAlarm', 'SEH'][args.seh]}\n")
    print(final)
示例#29
0
文件: asm.py 项目: domenukk/uDdbg
    def assemble(self, func_name, *args):
        sp = bytes(' ', 'utf8')
        instr = bytes()

        i = 0
        while i < len(args):
            a = str(args[i])
            if i == 0 and (not a.startswith("'") or not a.startswith('"')):
                raise Exception('provide a valid instruction set')
            if a.startswith("'") or a.startswith('"'):
                a = a[1:]
            b = False
            if a.endswith("'") or a.endswith('"'):
                a = a[:len(a) - 1]
                b = True
            instr += bytes(a, 'utf8')
            if not b:
                instr += sp
            i += 1
            if b:
                break

        if str(args[i]) == '!':
            self.keystone_instance = None

        if self.keystone_instance is None:
            self.ks_arch = getattr(keystone, self.prompt_ks_arch())
            self.ks_mode = getattr(keystone, self.prompt_ks_mode())

            self.core_instance.get_module('configs_module').push_config(
                'ks_arch', self.ks_arch)
            self.core_instance.get_module('configs_module').push_config(
                'ks_mode', self.ks_mode)

            self.keystone_instance = keystone.Ks(self.ks_arch, self.ks_mode)
        try:
            encoding, count = self.keystone_instance.asm(instr)
            h = ''
            for i in range(0, len(encoding)):
                h += hex(encoding[i])[2:]
            print("%s = %s (number of statements: %u)" %
                  (str(instr), h, count))
        except keystone.KsError as e:
            print("ERROR: %s" % e)
示例#30
0
文件: panel_asm.py 项目: zbx91/Dwarf
    def trigger_write_instruction(self, item):
        if not self.dwarf.keystone_installed:
            details = ''
            try:
                import keystone.keystone_const
            except Exception as e:
                details = str(e)
            utils.show_message_box(
                'keystone-engine not found. Install it to enable instructions patching',
                details=details)
            return

        accept, inst, arch, mode = WriteInstructionDialog().show_dialog(
            input_content='%s %s' %
            (self.item(item.row(), 1).text(), self.item(item.row(), 2).text()),
            arch=self.ks_arch,
            mode=self.ks_mode)

        self.ks_arch = 'KS_ARCH_' + arch.upper()
        self.ks_mode = 'KS_MODE_' + mode.upper()

        if accept and len(inst) > 0:
            import keystone
            try:
                ks = keystone.Ks(
                    getattr(keystone.keystone_const, self.ks_arch),
                    getattr(keystone.keystone_const, self.ks_mode))
                encoding, count = ks.asm(inst)
                asm_widget = self.item(item.row(), 0)
                offset = asm_widget.get_offset()
                if self.dwarf.dwarf_api('writeBytes',
                                        [asm_widget.get_address(), encoding]):
                    new_data = bytearray(self.range.data)
                    for i in range(0, len(encoding)):
                        try:
                            new_data[self.asm_data_start + offset +
                                     i] = encoding[i]
                        except Exception as e:
                            if isinstance(e, IndexError):
                                break
                    self.range.data = bytes(new_data)
                    self.disa()
            except Exception as e:
                self.dwarf.log(e)