示例#1
0
    def btn_save_on_click(self):
        flags = 0
        if self.f_prev_inuse.isChecked():
            flags |= PREV_INUSE
        if self.f_is_mmaped.isChecked():
            flags |= IS_MMAPPED
        if self.f_non_main_arena.isChecked():
            flags |= NON_MAIN_ARENA

        try:
            size = eval(self.t_size.text())
            size |= flags

            fd = eval(self.t_fd.text())
            bk = eval(self.t_bk.text())
            fd_nextsize = eval(self.t_fd_nextsize.text())
            bk_nextsize = eval(self.t_bk_nextsize.text())

            self.chunk.size = size
            self.chunk.fd = fd
            self.chunk.bk = bk
            self.chunk.fd_nextsize = fd_nextsize
            self.chunk.bk_nextsize = bk_nextsize

            idaapi.patch_bytes(self.addr, self.chunk.data)
            idaapi.info("Chunk saved")
            self.done(1)

        except Exception as e:
            idaapi.warning("ERROR: " + str(e))
示例#2
0
    def patch(self, fill_char=b'\x00', define=True):
        """
        Patches the original encoded string with the decoded string.

        :param str fill_char:
            Character to use to fill left over space if decoded data
            is shorter than its encoded data.
            Set to None leaving the original data.
        :param bool define: Whether to define the string after patching.
        """
        if not self.decoded_data or self.string_location is None:
            return
        decoded_data = self.decoded_data
        if fill_char:
            decoded_data += fill_char * (len(self.encoded_data) - len(decoded_data))
        try:
            idaapi.patch_bytes(self.start_ea, decoded_data)
            if define:
                self.define()
        except TypeError:
            logger.debug(
                "String type for decoded string from location 0x{:08x}.".format(
                    self.start_ea
                )
            )
        finally:
            return self
示例#3
0
 def add_stub_func(va, sc, nm):
     idaapi.patch_bytes(va, binascii.unhexlify(sc))
     idc.create_insn(va)
     idc.add_func(va)
     mykutils.makename_safe(va, self._stubname(nm))
     cmt = ('%s implementation generated by FLARE Code Grafter' % (nm))
     idc.set_cmt(va, cmt, 1)
示例#4
0
def __create_load_data_segment(data, seg_addr, seg_name):
    # This function creates a data segment located in a pre-specified address
    # and fills this new segment with data

    seglen = len(data)
    if seglen % 0x1000 != 0:
        seglen = seglen + (0x1000 - (seglen % 0x1000))

    if not idc.AddSeg(seg_addr, seg_addr + seglen, 0, 1, 0, idaapi.scPub):
        logger.error('failed to add segment: 0x%x', seg_addr)
        return False

    if not idc.set_segm_name(seg_addr, seg_name):
        logger.warning('failed to rename segment: %s', seg_name)
        return False

    if not idc.set_segm_class(seg_addr, 'DATA'):
        logger.warning('failed to set segment class DATA: %s', seg_name)
        return False

    if not idc.set_segm_attr(seg_addr, idc.SEGATTR_ALIGN, idc.saRelPara):
        logger.warning('failed to align segment: %s', seg_name)
        return False

    if data:
        idaapi.patch_bytes(seg_addr, data)

    return True
示例#5
0
    def hook(self, hook_addr=0):
        """
        Args:
            hook_addr(int): address for inline hook code, 0 indicates bpt hook.

        Returns:
            memory size in bytes used for inline hook.
        """

        self.hook_addr = hook_addr
        self.func_addr = idc.get_name_ea_simple(self.name)

        if self.func_addr == 0:
            return 0

        print("Hooking %s at 0x%x" % (self.name, self.func_addr))
        if self.hook_addr == 0:
            idc.add_bpt(self.func_addr)
            idc.set_bpt_cond(self.func_addr, self.bpt_cond_hook_code)
            return 0
        else:
            # assemble jmp code
            jmp_code = "jmp 0x%x" % self.hook_addr
            jmp_buf, _ = assemble(jmp_code, self.func_addr)

            # read function prologue according to jmp code length
            # NOTE: instructions like 'call $+5' in prologue will
            # cause problems.
            insn = idaapi.insn_t()
            move_length = 0
            while move_length < len(jmp_buf):
                idaapi.decode_insn(insn, self.func_addr + move_length)
                move_length += insn.size
            prologue = idaapi.get_bytes(self.func_addr, move_length)

            # write jmp code
            idaapi.patch_bytes(self.func_addr, jmp_buf)

            # assmble hook code
            hook_buf, _ = assemble(self.inline_hook_code, self.hook_addr)
            hook_buf += prologue
            jmp_back_code = 'jmp 0x%x' % (self.func_addr + move_length)
            jmp_back_buf, _ = assemble(jmp_back_code,
                                       self.hook_addr + len(hook_buf))
            hook_buf += jmp_back_buf

            # wirte hook code
            idaapi.patch_bytes(self.hook_addr, hook_buf)
            return len(hook_buf)
示例#6
0
def patch_call(va, new_nm):
    """Patch the call at @va to target @new_nm.

    Args:
        va (numbers.Integral): Address of the call site
        new_nm (str): Name of the new call destination

    Returns:
        bool: True if successful
    """
    is_call = idc.print_insn_mnem(va) == 'call'

    if is_call:
        opno = 0
        new_asm = 'call %s' % (new_nm)
    else:
        logger.warn('Not a call instruction at %s' % (phex(va)))
        return False

    # Already done?
    if idc.print_operand(va, opno) == new_nm:
        return True

    ok, code = idautils.Assemble(va, new_asm)

    if not ok:
        logger.warn('Failed assembling %s: %s' % (phex(va), new_asm))
        return False

    orig_opcode_len = idc.get_item_size(va)
    new_code_len = len(code)

    if orig_opcode_len < new_code_len:
        logger.warn('Not enough room or wrong opcode type to patch %s: %s' %
                    (phex(va), new_asm))
        return False

    # If we actually have too much room, then add filler
    if orig_opcode_len > new_code_len:
        delta = orig_opcode_len - new_code_len
        code += '\x90' * delta

    idaapi.patch_bytes(va, code)

    return True
示例#7
0
def write_memory(start, data, destructive=False):
    if destructive:
        idaapi.put_bytes(start, data)

    else:
        idaapi.patch_bytes(start, data)
示例#8
0
    def activate(self, ctx):
        if self.action in ACTION_CONVERT:
            # convert
            t0, t1, view = idaapi.twinpos_t(), idaapi.twinpos_t(
            ), idaapi.get_current_viewer()
            if idaapi.read_selection(view, t0, t1):
                start, end = t0.place(view).toea(), t1.place(view).toea()
                size = end - start
            elif idc.get_item_size(idc.get_screen_ea()) > 1:
                start = idc.get_screen_ea()
                size = idc.get_item_size(start)
                end = start + size
            else:
                return False

            data = idc.get_bytes(start, size)
            if isinstance(data, str):  # python2 compatibility
                data = bytearray(data)
            name = idc.get_name(start, idc.GN_VISIBLE)
            if not name:
                name = "data"
            if data:
                print("\n[+] Dump 0x%X - 0x%X (%u bytes) :" %
                      (start, end, size))
                if self.action == ACTION_CONVERT[0]:
                    # escaped string
                    print('"%s"' % "".join("\\x%02X" % b for b in data))
                elif self.action == ACTION_CONVERT[1]:
                    # hex string
                    print("".join("%02X" % b for b in data))
                elif self.action == ACTION_CONVERT[2]:
                    # C array
                    output = "unsigned char %s[%d] = {" % (name, size)
                    for i in range(size):
                        if i % 16 == 0:
                            output += "\n    "
                        output += "0x%02X, " % data[i]
                    output = output[:-2] + "\n};"
                    print(output)
                elif self.action == ACTION_CONVERT[3]:
                    # C array word
                    data += b"\x00"
                    array_size = (size + 1) // 2
                    output = "unsigned short %s[%d] = {" % (name, array_size)
                    for i in range(0, size, 2):
                        if i % 16 == 0:
                            output += "\n    "
                        output += "0x%04X, " % u16(data[i:i + 2])
                    output = output[:-2] + "\n};"
                    print(output)
                elif self.action == ACTION_CONVERT[4]:
                    # C array dword
                    data += b"\x00" * 3
                    array_size = (size + 3) // 4
                    output = "unsigned int %s[%d] = {" % (name, array_size)
                    for i in range(0, size, 4):
                        if i % 32 == 0:
                            output += "\n    "
                        output += "0x%08X, " % u32(data[i:i + 4])
                    output = output[:-2] + "\n};"
                    print(output)
                elif self.action == ACTION_CONVERT[5]:
                    # C array qword
                    data += b"\x00" * 7
                    array_size = (size + 7) // 8
                    output = "unsigned long %s[%d] = {" % (name, array_size)
                    for i in range(0, size, 8):
                        if i % 32 == 0:
                            output += "\n    "
                        output += "%#018X, " % u64(data[i:i + 8])
                    output = output[:-2] + "\n};"
                    print(output.replace("0X", "0x"))
                elif self.action == ACTION_CONVERT[6]:
                    # python list
                    print("[%s]" % ", ".join("0x%02X" % b for b in data))
                elif self.action == ACTION_CONVERT[7]:
                    # python list word
                    data += b"\x00"
                    print("[%s]" % ", ".join("0x%04X" % u16(data[i:i + 2])
                                             for i in range(0, size, 2)))
                elif self.action == ACTION_CONVERT[8]:
                    # python list dword
                    data += b"\x00" * 3
                    print("[%s]" % ", ".join("0x%08X" % u32(data[i:i + 4])
                                             for i in range(0, size, 4)))
                elif self.action == ACTION_CONVERT[9]:
                    # python list qword
                    data += b"\x00" * 7
                    print("[%s]" % ", ".join(
                        "%#018X" % u64(data[i:i + 8])
                        for i in range(0, size, 8)).replace("0X", "0x"))
        elif self.action == ACTION_XORDATA:
            t0, t1, view = idaapi.twinpos_t(), idaapi.twinpos_t(
            ), idaapi.get_current_viewer()
            if idaapi.read_selection(view, t0, t1):
                start, end = t0.place(view).toea(), t1.place(view).toea()
            else:
                if idc.get_item_size(idc.get_screen_ea()) > 1:
                    start = idc.get_screen_ea()
                    end = start + idc.get_item_size(start)
                else:
                    return False

            data = idc.get_bytes(start, end - start)
            if isinstance(data, str):  # python2 compatibility
                data = bytearray(data)
            x = idaapi.ask_long(0, "Xor with...")
            if x:
                x &= 0xFF
                print("\n[+] Xor 0x%X - 0x%X (%u bytes) with 0x%02X:" %
                      (start, end, end - start, x))
                print(repr("".join(chr(b ^ x) for b in data)))
        elif self.action == ACTION_FILLNOP:
            t0, t1, view = idaapi.twinpos_t(), idaapi.twinpos_t(
            ), idaapi.get_current_viewer()
            if idaapi.read_selection(view, t0, t1):
                start, end = t0.place(view).toea(), t1.place(view).toea()
                idaapi.patch_bytes(start, b"\x90" * (end - start))
                print("\n[+] Fill 0x%X - 0x%X (%u bytes) with NOPs" %
                      (start, end, end - start))
        elif self.action == ACTION_SCANVUL:
            print("\n[+] Finding Format String Vulnerability...")
            found = []
            for addr in idautils.Functions():
                name = idc.get_func_name(addr)
                if "printf" in name and "v" not in name and idc.get_segm_name(
                        addr) in (".text", ".plt", ".idata"):
                    xrefs = idautils.CodeRefsTo(addr, False)
                    for xref in xrefs:
                        vul = self.check_fmt_function(name, xref)
                        if vul:
                            found.append(vul)
            if found:
                print("[!] Done! %d possible vulnerabilities found." %
                      len(found))
                ch = VulnChoose("Vulnerability", found, None, False)
                ch.Show()
            else:
                print("[-] No format string vulnerabilities found.")
        else:
            return 0

        return 1
示例#9
0
    def activate(self, ctx):
        if self.action in ACTION_MENU_CONVERT:
            sel, start, end = lazy_read_selection()
            if not sel:
                idc.msg("[LazyIDA] Nothing to convert.")
                return False

            size = end - start
            data = idc.get_bytes(start, size)
            if isinstance(data, str):  # python2 compatibility
                data = bytearray(data)
            assert size == len(data)

            name = idc.get_name(start, idc.GN_VISIBLE)
            if not name:
                name = "data"
            if data:
                output = None
                plg_print("Dump from 0x%X to 0x%X (%u bytes):" % (start, end - 1, size))
                if self.action == ACTION_MENU_CONVERT[0]:
                    # escaped string
                    output = '"%s"' % "".join("\\x%02X" % b for b in data)

                elif self.action == ACTION_MENU_CONVERT[1]:
                    # hex string, space
                    output = " ".join("%02X" % b for b in data)

                elif self.action == ACTION_MENU_CONVERT[2]:
                    # C array
                    output = "unsigned char %s[%d] = {" % (name, size)
                    for i in range(size):
                        if i % 16 == 0:
                            output += "\n    "
                        output += "0x%02X, " % data[i]
                    output = output[:-2] + "\n};"

                elif self.action == ACTION_MENU_CONVERT[3]:
                    # C array word
                    data += b"\x00"
                    array_size = (size + 1) // 2
                    output = "unsigned short %s[%d] = {" % (name, array_size)
                    for i in range(0, size, 2):
                        if i % 16 == 0:
                            output += "\n    "
                        output += "0x%04X, " % u16(data[i:i+2])
                    output = output[:-2] + "\n};"

                elif self.action == ACTION_MENU_CONVERT[4]:
                    # C array dword
                    data += b"\x00" * 3
                    array_size = (size + 3) // 4
                    output = "unsigned int %s[%d] = {" % (name, array_size)
                    for i in range(0, size, 4):
                        if i % 32 == 0:
                            output += "\n    "
                        output += "0x%08X, " % u32(data[i:i+4])
                    output = output[:-2] + "\n};"

                elif self.action == ACTION_MENU_CONVERT[5]:
                    # C array qword
                    data += b"\x00" * 7
                    array_size = (size + 7) // 8
                    output = "unsigned long %s[%d] = {" % (name, array_size)
                    for i in range(0, size, 8):
                        if i % 32 == 0:
                            output += "\n    "
                        output += "%#018X, " % u64(data[i:i+8])
                    output = output[:-2] + "\n};"
                    output = output.replace("0X", "0x")

                elif self.action == ACTION_MENU_CONVERT[6]:
                    # python list
                    output = "[%s]" % ", ".join("0x%02X" % b for b in data)

                elif self.action == ACTION_MENU_CONVERT[7]:
                    # python list word
                    data += b"\x00"
                    output = "[%s]" % ", ".join("0x%04X" % u16(data[i:i+2]) for i in range(0, size, 2))

                elif self.action == ACTION_MENU_CONVERT[8]:
                    # python list dword
                    data += b"\x00" * 3
                    output = "[%s]" % ", ".join("0x%08X" % u32(data[i:i+4]) for i in range(0, size, 4))

                elif self.action == ACTION_MENU_CONVERT[9]:
                    # python list qword
                    data += b"\x00" * 7
                    output = "[%s]" %  ", ".join("%#018X" % u64(data[i:i+8]) for i in range(0, size, 8)).replace("0X", "0x")

                elif self.action == ACTION_MENU_CONVERT[10]:
                    # MASM byte array
                    header = "%s db " % name
                    output = header
                    for i in range(size):
                        if i and i % 16 == 0:
                            output += "\n"
                            output += " " * len(header)
                        output += "0%02Xh, " % data[i]
                    output = output[:-2]

                elif self.action == ACTION_MENU_CONVERT[11]:
                    # GNU ASM byte array
                    header = "%s: .byte " % name
                    output = header
                    for i in range(size):
                        if i and i % 16 == 0:
                            output += "\n"
                            output += " " * len(header)
                        output += "0x%02X, " % data[i]
                    output = output[:-2]

                if output:
                    print(output)
                    copy_to_clip(output)
                    output = None

        elif self.action == ACTION_MENU_COPY_DATA:
            # added by merc, modified by HTC
            sel, start, end = lazy_read_selection()
            if not sel:
                return 0

            data = idaapi.get_bytes(start, end - start)
            if isinstance(data, str):
                data = bytearray(data)
            output = "".join("%02X" % b for b in data)
            copy_to_clip(output)
            plg_print("Hex string '%s' copied" % output)

        elif self.action == ACTION_MENU_DUMP_DATA:
            # add by HTC
            sel, start, end = lazy_read_selection()
            if not sel:
                return 0

            size = end - start
            data = idaapi.get_bytes(start, size)
            assert len(data) == size
            if data and len(data) == size:
                dump_data_to_file("Dump_At_%X_Size_%d.dump" % (start, size), data)
            else:
                plg_print("0x%X: unable to get %d bytes" % (start, size))

        elif self.action == ACTION_MENU_XOR_DATA:
            sel, start, end = lazy_read_selection()
            if not sel:
                return 0

            size = end - start

            key = idaapi.ask_str("AA BB CC DD", 0, "Xor with hex values (or a string begin and end with\" or ')...")
            if not key:
                return 0

            bytes_key = bytearray()
            if is_str(key):
                bytes_key = str_to_bytes(key)
            else:
                bytes_key = hex_to_bytes(key)

            if not bytes_key:
                return 0

            data = idc.get_bytes(start, end - start)
            if isinstance(data, str):  # python2 compatibility
                data = bytearray(data)

            output = xor_data(data, bytes_key)
            if not output:
                plg_print("Sorry, error occurred. My bug :( Please report.")
                return 0

            assert size == len(output)

            plg_print("Xor result from 0x%X to 0x%X (%d bytes) with %s:" % (start, end, end - start, key))
            process_data_result(start, output)

        elif self.action == ACTION_MENU_FILL_NOP:
            sel, start, end = lazy_read_selection()
            if not sel:
                return 0

            idaapi.patch_bytes(start, b"\x90" * (end - start))
            idc.create_insn(start)
            plg_print("Fill 0x%X to 0x%X (%u bytes) with NOPs" % (start, end, end - start))

        elif self.action == ACTION_MENU_B64STD:
            base64_decode(True)

        elif self.action == ACTION_MENU_B64URL:
            base64_decode(False)

        elif self.action == ACTION_MENU_SCAN_VUL:
            plg_print("Finding Format String Vulnerability...")
            found = []
            for addr in idautils.Functions():
                name = idc.get_func_name(addr)
                if "printf" in name and "v" not in name and idc.get_segm_name(addr) in (".text", ".plt", ".idata"):
                    xrefs = idautils.CodeRefsTo(addr, False)
                    for xref in xrefs:
                        vul = self.check_fmt_function(name, xref)
                        if vul:
                            found.append(vul)
            if found:
                plg_print("Done! %d possible vulnerabilities found." % len(found))
                ch = VulnChoose("Vulnerability", found, None, False)
                ch.Show()
            else:
                plg_print("No format string vulnerabilities found.")

        else:
            return 0

        return 1
示例#10
0
def process_data_result(start, data):
    # 16 bytes on a line
    # one byte take 4 char: 2 hex char, a space and a char if isalnum
    # one line take 3 char addtion: two space and \n, and ea hex address

    BYTES_PER_LINE = 16
    MAX_BYTES_HEX_DUMP = BYTES_PER_LINE * 64    # 64 lines

    printLen = len(data)
    if printLen > MAX_BYTES_HEX_DUMP:
        printLen = MAX_BYTES_HEX_DUMP
        plg_print("Only hexdump first %d bytes" % MAX_BYTES_HEX_DUMP)

    nLines = printLen // BYTES_PER_LINE     # Number of lines
    nOdd = printLen % BYTES_PER_LINE    # Number of bytes at last line
    isStr = True
    sHex = str()
    for i in range(printLen):
        if isStr and chr(data[i]) not in string.printable:
            isStr = False

        if i % BYTES_PER_LINE == 0:
            sHex += "%s: " % idaapi.ea2str(start + i)

        sHex += "%02X " % data[i]

        if (i % BYTES_PER_LINE == BYTES_PER_LINE - 1) or (i == printLen - 1):
            # add the end of data or end of a line
            if nLines:
                lineIdx = i // BYTES_PER_LINE   # current line number
                low = lineIdx * BYTES_PER_LINE
                high = i + 1
            else:
                low = 0
                high = printLen

            sHex += " "

            # Padding last line
            if i == printLen - 1 and nLines and nOdd:
                sHex += " " * (BYTES_PER_LINE - nOdd) * 3

            for j in range(low, high):
                ch = chr(data[j])
                sHex += ch if ch.isalnum() else "."

            sHex += "\n"

    # Print out the hexdump string
    print(sHex)

    if isStr:
        txt = str(data)
        print("String result: '%s'" % txt)
        idaapi.set_cmt(start, txt, 1)

    if idaapi.ask_yn(idaapi.ASKBTN_NO, "Do you want to patch selected range with result data ?") == idaapi.ASKBTN_YES:
        idaapi.patch_bytes(start, bytes(data))

    if idaapi.ask_yn(idaapi.ASKBTN_YES, "Do you want to dump result data to file ?") == idaapi.ASKBTN_YES:
        dump_data_to_file("Dump_At_0x%X_Size_%d.dump" % (start, len(data)), data)
示例#11
0
    def activate(self, ctx):
        if self.action in ACTION_CONVERT:
            sel, start, end = lazy_read_selection()
            if not sel:
                idc.msg("[LazyIDA] Nothing to convert.")
                return False

            size = end - start
            data = idc.get_bytes(start, size)
            if isinstance(data, str):  # python2 compatibility
                data = bytearray(data)
            assert size == len(data)

            name = idc.get_name(start, idc.GN_VISIBLE)
            if not name:
                name = "data"
            if data:
                print("\n[+] Dump 0x%X - 0x%X (%u bytes) :" % (start, end, size))
                if self.action == ACTION_CONVERT[0]:
                    # escaped string
                    print('"%s"' % "".join("\\x%02X" % b for b in data))
                elif self.action == ACTION_CONVERT[1]:
                    # hex string
                    print("".join("%02X" % b for b in data))
                elif self.action == ACTION_CONVERT[2]:
                    # C array
                    output = "unsigned char %s[%d] = {" % (name, size)
                    for i in range(size):
                        if i % 16 == 0:
                            output += "\n    "
                        output += "0x%02X, " % data[i]
                    output = output[:-2] + "\n};"
                    print(output)
                elif self.action == ACTION_CONVERT[3]:
                    # C array word
                    data += b"\x00"
                    array_size = (size + 1) // 2
                    output = "unsigned short %s[%d] = {" % (name, array_size)
                    for i in range(0, size, 2):
                        if i % 16 == 0:
                            output += "\n    "
                        output += "0x%04X, " % u16(data[i:i+2])
                    output = output[:-2] + "\n};"
                    print(output)
                elif self.action == ACTION_CONVERT[4]:
                    # C array dword
                    data += b"\x00" * 3
                    array_size = (size + 3) // 4
                    output = "unsigned int %s[%d] = {" % (name, array_size)
                    for i in range(0, size, 4):
                        if i % 32 == 0:
                            output += "\n    "
                        output += "0x%08X, " % u32(data[i:i+4])
                    output = output[:-2] + "\n};"
                    print(output)
                elif self.action == ACTION_CONVERT[5]:
                    # C array qword
                    data += b"\x00" * 7
                    array_size = (size + 7) // 8
                    output = "unsigned long %s[%d] = {" % (name, array_size)
                    for i in range(0, size, 8):
                        if i % 32 == 0:
                            output += "\n    "
                        output += "%#018X, " % u64(data[i:i+8])
                    output = output[:-2] + "\n};"
                    print(output.replace("0X", "0x"))
                elif self.action == ACTION_CONVERT[6]:
                    # python list
                    print("[%s]" % ", ".join("0x%02X" % b for b in data))
                elif self.action == ACTION_CONVERT[7]:
                    # python list word
                    data += b"\x00"
                    print("[%s]" % ", ".join("0x%04X" % u16(data[i:i+2]) for i in range(0, size, 2)))
                elif self.action == ACTION_CONVERT[8]:
                    # python list dword
                    data += b"\x00" * 3
                    print("[%s]" % ", ".join("0x%08X" % u32(data[i:i+4]) for i in range(0, size, 4)))
                elif self.action == ACTION_CONVERT[9]:
                    # python list qword
                    data += b"\x00" * 7
                    print("[%s]" %  ", ".join("%#018X" % u64(data[i:i+8]) for i in range(0, size, 8)).replace("0X", "0x"))
        elif self.action == ACTION_COPYDATA:
            # added by merc, modfiy by HTC
            sel, start, end = lazy_read_selection()
            if not sel:
                return 0

            data = idaapi.get_bytes(start, end - start)
            data = data.encode('hex')
            copy_to_clip(data)
            print("[LazyIDA] copied hex string '%s'" % data)
        elif self.action == ACTION_XORDATA:
            sel, start, end = lazy_read_selection()
            if not sel:
                return 0

            data = idc.get_bytes(start, end - start)
            if isinstance(data, str):  # python2 compatibility
                data = bytearray(data)
            x = idaapi.ask_long(0, "Xor with...")
            if x:
                x &= 0xFF
                print("\n[+] Xor 0x%X - 0x%X (%u bytes) with 0x%02X:" % (start, end, end - start, x))
                print(repr("".join(chr(b ^ x) for b in data)))
        elif self.action == ACTION_FILLNOP:
            sel, start, end = lazy_read_selection()
            if not sel:
                return 0
            idaapi.patch_bytes(start, b"\x90" * (end - start))
            print("\n[+] Fill 0x%X - 0x%X (%u bytes) with NOPs" % (start, end, end - start))
        elif self.action == ACTION_SCANVUL:
            print("\n[+] Finding Format String Vulnerability...")
            found = []
            for addr in idautils.Functions():
                name = idc.get_func_name(addr)
                if "printf" in name and "v" not in name and idc.get_segm_name(addr) in (".text", ".plt", ".idata"):
                    xrefs = idautils.CodeRefsTo(addr, False)
                    for xref in xrefs:
                        vul = self.check_fmt_function(name, xref)
                        if vul:
                            found.append(vul)
            if found:
                print("[!] Done! %d possible vulnerabilities found." % len(found))
                ch = VulnChoose("Vulnerability", found, None, False)
                ch.Show()
            else:
                print("[-] No format string vulnerabilities found.")
        elif self.action == ACTION_COPYNAME:
            copy_highlight_name()
        elif self.action == ACTION_PASTENAME:
            paste_highlight_name()
        else:
            return 0

        return 1