Пример #1
0
def apply_cfg(reload=False, filters={}):
    """loads abyss configuration."""

    cfg_file = get_cfg_filename()
    kw.msg("%s: %sloading %s...\n" %
           (PLUGIN_NAME, "re" if reload else "", cfg_file))
    if not os.path.isfile(cfg_file):
        kw.msg("%s: default configuration (%s) does not exist!\n" %
               (PLUGIN_NAME, cfg_file))
        kw.msg("Creating default configuration\n")
        try:
            with open(cfg_file, "w") as f:
                f.write("[init]\n")
                for name, mod in filters.items():
                    f.write("%s=False\n" % name)
        except:
            kw.msg("failed!\n")
            return False
        return apply_cfg(reload=True)

    config = configparser.RawConfigParser()
    config.readfp(open(cfg_file))

    # read all sections
    for section in config.sections():
        if section == "init":
            for name, value in config.items(section):
                try:
                    filters[name].set_activated(
                        config[section].getboolean(name))
                    #print("%s -> %s" % (name, value))
                except:
                    pass
    kw.msg("done!\n")
    return True
Пример #2
0
def create_ram_segment():
    success = add_segm(0, RAM_START_ADDRESS, RAM_START_ADDRESS + RAM_SIZE,
                       "RAM", None) == 1
    msg("creating RAM segment..%s" % ("ok!\n" if success else "failure!\n"))
    if (not success):
        return
    set_segm_addressing(getseg(RAM_START_ADDRESS), 0)
Пример #3
0
def create_rom_segment():
    success = add_segm(0, ROM_START_ADDRESS, ROM_START_ADDRESS + ROM_SIZE,
                       "ROM", "CODE") == 1
    msg("creating ROM segment..%s" % ("ok!\n" if success else "failure!\n"))
    if (not success):
        return
    set_segm_addressing(getseg(ROM_START_ADDRESS), 0)
Пример #4
0
def install_plugin():
    """Installs script to IDA userdir as a plugin."""
    if is_plugin():
        kw.msg("Command not available. Plugin already installed.\n")
        return False

    src = SELF
    if is_installed():
        btnid = kw.ask_yn(
            kw.ASKBTN_NO,
            "File exists:\n\n%s\n\nReplace?" % get_target_filename())
        if btnid is not kw.ASKBTN_YES:
            return False
    dst = get_target_filename()
    usrdir = os.path.dirname(dst)
    kw.msg("Copying script from \"%s\" to \"%s\" ..." % (src, usrdir))
    if not os.path.exists(usrdir):
        try:
            os.path.makedirs(usrdir)
        except OSError as e:
            if e.errno != errno.EEXIST:
                kw.msg("failed (mkdir)!\n")
                return False
    try:
        shutil.copy(src, dst)
    except:
        kw.msg("failed (copy)!\n")
        return False
    kw.msg(("done\n"
            "Plugin installed - please restart this IDA instance now.\n"))
    return True
Пример #5
0
def detect_arch():
    #heuristically determine what architecture we're on
    #only x86-64 and arm64 are supported
    is_le = False
    bits = 0
    info = get_inf_structure()
    arch = ARCH_UNKNOWN
    if info.is_64bit():
        bits = 64
    elif info.is_32bit():
        bits = 32
    else:
        bits = 16

    if not info.is_be():
        is_le = True

    procname = info.procName
    if bits == 64 and is_le:
        if procname == "ARM":
            msg("Detected architecture: arm64\n")
            arch = ARCH_ARM64
        elif procname == "metapc":
            msg("Detected architecture: x86_64\n")
            arch = ARCH_X86_64

    return arch
Пример #6
0
 def on_mb_click(self, event, addr, size, mouse_offs):
     button = event.button()
     if button == Qt.MiddleButton:
         mouse = addr + mouse_offs
         c = get_byte(mouse)
         head, name, size = self._get_item_info(mouse)
         funcname = self._get_func_name(mouse)
         self.ann = [(mouse, qRgb(c, 0xFF,
                                  self.hl_color), "Address: %X" % (mouse),
                      qRgb(c, 0xFF, self.hl_color)),
                     (None, None, "  Item: %s" % (name),
                      qRgb(c, 0xFF, self.hl_color)),
                     (None, None, "  Head: %X" % (head),
                      qRgb(c, 0xFF, self.hl_color)),
                     (None, None, "  Size: %d" % (size),
                      qRgb(c, 0xFF, self.hl_color))]
         if funcname:
             self.ann.append((None, None, "  Function: %s" % (funcname),
                              qRgb(c, 0xFF, self.hl_color)))
         self.last_sel = (head, size)
     elif button == Qt.MiddleButton:
         pass
     elif button == Qt.RightButton:
         self.switch ^= 1
         msg('Highlighting %s\n' % self.mode[self.switch])
Пример #7
0
    def init(self):
        self.xray_hooks = None
        if not is_compatible():
            kw.msg("%s: decompiler not available, skipping." % PLUGIN_NAME)
            return ida_idaapi.PLUGIN_SKIP

        load_cfg()

        kw.register_action(
            kw.action_desc_t(
                XRAY_LOADCFG_ACTION_ID,
                "%s: reload config" % PLUGIN_NAME,
                loadcfg_action_handler_t(),
                "Ctrl-R"))

        kw.register_action(
            kw.action_desc_t(
                XRAY_FILTER_ACTION_ID,
                "%s: toggle" % PLUGIN_NAME,
                xray_action_handler_t(),
                "F3"))

        kw.register_action(
            kw.action_desc_t(
                XRAY_QUERY_ACTION_ID,
                "%s: search" % PLUGIN_NAME,
                regexfilter_action_handler_t(),
                "Ctrl-F"))

        self.xray_hooks = xray_hooks_t()
        self.xray_hooks.hook()
        return ida_idaapi.PLUGIN_KEEP
Пример #8
0
    def __init__(self, objc_class_va, segment_map, arch=ARCH_X86_64):
        """Create a new ObjcClass instance
                
        Arguments:
            objc_class_va {number} -- Virtual address of the Objective-C class to parse
            segment_map {dictionary} -- A dictionary mapping segment names to a start/end virtual address tuple
        
        Keyword Arguments:
            arch {number} -- CPU architecture. Either ARCH_X86_64 or ARM64 (default: {ARCH_X86_64})
        """
        self.arch = arch
        self.segment_map = segment_map
        class_ro_va = get_qword(objc_class_va + self.OBJC2_CLASS_RO_OFFSET)
        self.name_pointer = get_qword(class_ro_va +
                                      self.OBJC2_CLASS_RO_NAME_OFFSET)
        self.method_list = []
        if class_ro_va == BADADDR or class_ro_va == 0:
            self.class_ro_va = None
            return
        self.class_ro_va = class_ro_va

        class_methods_va = get_qword(class_ro_va +
                                     self.OBJC2_CLASS_RO_BASE_METHODS_OFFSET)

        if class_methods_va == BADADDR or class_methods_va == 0:
            self.class_methods_va = None
            return
        self.class_methods_va = class_methods_va
        msg("Class found at virtual address: 0x%x\n" % objc_class_va)
        msg("Class name: %s\n" % get_strlit_contents(self.name_pointer))
        #Parse the method_list_t struct and build a list of methods
        self.method_list = ObjcMethodList(class_methods_va,
                                          segment_map,
                                          arch=arch)
 def run(self, arg=0):
     #we need the calls again if we wanna load it via File/Plugins/editor
     ida_kernwin.msg(
         "StyleSheet Paster Loaded to menu \n use Alt+P hot key to quick load "
     )
     hackish = MyEditorHandlerPaste(
     )  #must be the same as line (53) change also hackish =  must be unique also line (100)
     hackish.activate(self)  #hackish must the same as line hackish = (99)
Пример #10
0
    def OnViewKeydown(self, key, state):
        c = chr(key & 0xFF)

        if c == 'C':
            self.center_node = not self.center_node
            ida_kernwin.msg("%s: centering graph %sabled\n" %
                            (PLUGIN_NAME, "en" if self.center_node else "dis"))
        return True
Пример #11
0
def FindInstructions(instr, asm_where=None):
    """
    Finds instructions/opcodes
    @return: Returns a tuple(True, [ ea, ... ]) or a tuple(False, "error message")
    """
    if not asm_where:
        # get first segment
        seg = ida_segment.get_first_seg()
        asm_where = seg.start_ea if seg else ida_idaapi.BADADDR
        if asm_where == ida_idaapi.BADADDR:
            return (False, "No segments defined")

    # regular expression to distinguish between opcodes and instructions
    re_opcode = re.compile('^[0-9a-f]{2} *', re.I)

    # split lines
    lines = instr.split(";")

    # all the assembled buffers (for each instruction)
    bufs = []
    for line in lines:
        if re_opcode.match(line):
            # convert from hex string to a character list then join the list to form one string
            buf = bytes(bytearray([int(x, 16) for x in line.split()]))
        else:
            # assemble the instruction
            ret, buf = idautils.Assemble(asm_where, line)
            if not ret:
                return (False, "Failed to assemble:" + line)
        # add the assembled buffer
        bufs.append(buf)

    # join the buffer into one string
    buf = b''.join(bufs)

    # take total assembled instructions length
    tlen = len(buf)

    # convert from binary string to space separated hex string
    bin_str = ' '.join(
        ["%02X" % (ord(x) if sys.version_info.major < 3 else x) for x in buf])

    # find all binary strings
    print("Searching for: [%s]" % bin_str)
    ea = ida_ida.cvar.inf.min_ea
    ret = []
    while True:
        ea = ida_search.find_binary(ea, ida_idaapi.BADADDR, bin_str, 16,
                                    ida_search.SEARCH_DOWN)
        if ea == ida_idaapi.BADADDR:
            break
        ret.append(ea)
        ida_kernwin.msg(".")
        ea += tlen
    if not ret:
        return (False, "Could not match [%s]" % bin_str)
    ida_kernwin.msg("\n")
    return (True, ret)
Пример #12
0
 def walk_classes(self, segment_map):
     msg("Walking classes\n")
     classes = []
     objc_data_start, objc_data_end = segment_map["__objc_data"]
     for va in range(objc_data_start, objc_data_end, self.objc2ClassSize):
         objc_class = ObjcClass(va, segment_map, arch=self.arch)
         classes.append(objc_class)
         self.extend(objc_class.patched_xrefs())
     self.classes = classes
Пример #13
0
 def init(self):
     global banner
     self.forms = []
     self.options = (PluginForm.WOPN_MENU | PluginForm.WOPN_ONTOP
                     | PluginForm.WOPN_RESTORE | PluginForm.FORM_SAVE
                     | PluginForm.WOPN_PERSIST
                     | PluginForm.WCLS_CLOSE_LATER)
     msg('%s' % banner)
     return PLUGIN_KEEP
Пример #14
0
 def activate(self, ctx):
     global IS_ACTIVATED
     IS_ACTIVATED = not IS_ACTIVATED
     vu = ida_hexrays.get_widget_vdui(ctx.widget)
     if vu:
         vu.refresh_ctext()
     kw.msg("[%s] %sactivated.\n" %
            (PLUGIN_NAME, "" if IS_ACTIVATED else "de"))
     return 1
Пример #15
0
def create_exprom_segment():
    success = add_segm(0, EXPROM_START_ADDRESS,
                       EXPROM_START_ADDRESS + EXPROM_SIZE, "EXP_ROM",
                       None) == 1
    msg("creating EXP_ROM segment..%s" %
        ("ok!\n" if success else "failure!\n"))
    if (not success):
        return
    set_segm_addressing(getseg(EXPROM_START_ADDRESS), 0)
Пример #16
0
    def init(self):
        self.gamma_hooks = None
        if not is_compatible():
            kw.msg("%s: decompiler not available, skipping." % PLUGIN_NAME)
            return ida_idaapi.PLUGIN_SKIP

        self.gamma_hooks = gamma_hooks_t()
        self.gamma_hooks.hook()
        return ida_idaapi.PLUGIN_KEEP
Пример #17
0
def coffee_main():
    global coffee

    if coffee and not coffee.is_dead():
        coffee.die()
        coffee = None
        return
    coffee = painter_t()
    ida_kernwin.msg("Caffeinated\n")
Пример #18
0
def FindInstructions(instr, asm_where=None):
    """
    Finds instructions/opcodes
    @return: Returns a tuple(True, [ ea, ... ]) or a tuple(False, "error message")
    """
    if not asm_where:
        # get first segment
        seg = ida_segment.get_first_seg()
        asm_where = seg.start_ea if seg else ida_idaapi.BADADDR
        if asm_where == ida_idaapi.BADADDR:
            return (False, "No segments defined")

    # regular expression to distinguish between opcodes and instructions
    re_opcode = re.compile('^[0-9a-f]{2} *', re.I)

    # split lines
    lines = instr.split(";")

    # all the assembled buffers (for each instruction)
    bufs = []
    for line in lines:
        if re_opcode.match(line):
            # convert from hex string to a character list then join the list to form one string
            buf = ''.join([chr(int(x, 16)) for x in line.split()])
        else:
            # assemble the instruction
            ret, buf = idautils.Assemble(asm_where, line)
            if not ret:
                return (False, "Failed to assemble:"+line)
        # add the assembled buffer
        bufs.append(buf)

    # join the buffer into one string
    buf = ''.join(bufs)

    # take total assembled instructions length
    tlen = len(buf)

    # convert from binary string to space separated hex string
    bin_str = ' '.join(["%02X" % ord(x) for x in buf])

    # find all binary strings
    print("Searching for: [%s]" % bin_str)
    ea = ida_ida.cvar.inf.min_ea
    ret = []
    while True:
        ea = ida_search.find_binary(ea, ida_idaapi.BADADDR, bin_str, 16, ida_search.SEARCH_DOWN)
        if ea == ida_idaapi.BADADDR:
            break
        ret.append(ea)
        ida_kernwin.msg(".")
        ea += tlen
    if not ret:
        return (False, "Could not match [%s]" % bin_str)
    ida_kernwin.msg("\n")
    return (True, ret)
Пример #19
0
def load_trainer(li):
    if (not INES_MASK_SRAM(hdr.rom_control_byte_0)):
        success = add_segm(0, TRAINER_START_ADDRESS,
                           TRAINER_START_ADDRESS + TRAINER_SIZE, "TRAINER",
                           "CODE") == 1
        msg("creating TRAINER segment..%s",
            "ok!\n" if success else "failure!\n")
        set_segm_addressing(getseg(TRAINER_START_ADDRESS), 0)
    li.file2base(INES_HDR_SIZE, TRAINER_START_ADDRESS,
                 TRAINER_START_ADDRESS + TRAINER_SIZE, FILEREG_PATCHABLE)
Пример #20
0
def SCRIPT_ENTRY():
    """Entry point of this code if launched as a script."""
    if not is_plugin():
        if not is_installed():
            kw.msg(("%s: Available commands:\n"
                "[+] \"install_plugin()\" - install script to ida_userdir/plugins\n") % (
                PLUGIN_NAME))
        create_mc_widget()
        return True
    return False
Пример #21
0
 def apply(self, opnum, path, top_tif, spath):
     typename = ida_typeinf.print_tinfo('', 0, 0,
                                        ida_typeinf.PRTYPE_1LINE,
                                        top_tif, '', '')
     ida_kernwin.msg("User selected %s of type %s\n" %
                     (spath, typename))
     if path.empty():
         return False
     vu.cfunc.set_user_union_selection(self.ea, path)
     vu.cfunc.save_user_unions()
     return True
Пример #22
0
 def OnSelectLine(self, n):
     module, symbol, docstring = self.items[n]
     postfix = " (%s)" % module if len(module) else ""
     if not len(docstring):
         ida_kernwin.msg("No documentation available for \"%s\"\n" % symbol)
     else:
         f = DocstringViewer("%s%s" % (symbol, postfix), docstring)
         f.modal = False
         f.openform_flags = ida_kernwin.PluginForm.FORM_TAB
         f, args = f.Compile()
         f.Open()
     return (ida_kernwin.Choose.NOTHING_CHANGED, )
Пример #23
0
 def OnSelectLine(self, n):
     data = self.items[n]
     postfix = " (%s)" % data.mod_name if len(data.mod_name) else ""
     if not data.doc_str:
         ida_kernwin.msg("No documentation available for \"%s\"\n" % data.sym_name)
     else:
         f = DocstringViewer("%s%s" % (data.sym_name, postfix), data.doc_str)
         f.modal = False
         f.openform_flags = ida_kernwin.PluginForm.WOPN_TAB
         f, args = f.Compile()
         f.Open()
     return (ida_kernwin.Choose.NOTHING_CHANGED, )
Пример #24
0
def create_mc_widget():
    """Checks minimum requirements for the script/plugin to be able to run.
    Displays microcode or in case of failure, displays error message.
    This function acts as the main entry point that is invoked if the
    code is run as a script or as a plugin."""
    if not is_compatible():
        kw.msg("%s: Unsupported IDA / Hex-rays version\n" % (PLUGIN_NAME))
        return False
    success, message = show_microcode()
    output = kw.msg if success else kw.warning
    output("%s: %s\n" % (PLUGIN_NAME, message))
    return success
Пример #25
0
def load_file(li, _a, _b):
    # set processor to 6502
    if (ph.id != PLFM_6502):
        msg("Nintendo Entertainment System ROM detected: setting processor type to M6502.\n"
            )
        set_processor_type("M6502", SETPROC_LOADER_NON_FATAL)

    try:
        return load_ines_file(li)
    except:
        import traceback
        traceback.print_exc()
        return 0
Пример #26
0
    def OnViewKeydown(self, key, state):
        c = chr(key & 0xFF)

        if c == 'C':
            self.center_node = not self.center_node
            ida_kernwin.msg("%s: centering %sabled\n" %
                            (PLUGIN_NAME, "en" if self.center_node else "dis"))
        elif c == 'D':
            self.debug = (self.debug + 1) % 3
            ida_kernwin.msg("%s: debug %d\n" % (PLUGIN_NAME, self.debug))
            self.redraw = True
            self.Refresh()
        return True
Пример #27
0
    def __init__(self, method_va, segment_map):
        """Do not instantiate directly
        
        Arguments:
            method_va
            segment_map
        """
        msg("Found method at virtual address: 0x%x\n" % method_va)

        self.method_va = method_va
        self.segment_map = segment_map

        self.name_pointer = get_qword(method_va)
        self.method_type = get_qword(method_va + self.OBJC_METHOD_TYPE_OFFSET)
        self.method_pointer_va = method_va + self.OBJC_METHOD_IMP_OFFSET
        self.method_pointer = get_qword(self.method_pointer_va)
        self.patched_xrefs = []
        objc_selrefs = segment_map["__objc_selrefs"]
        objc_msgrefs = segment_map["__objc_msgrefs"]
        objc_const = segment_map["__objc_const"]
        msg("Method name: %s\n" % get_func_name(self.method_pointer))
        is_msg_ref, selector_ref, const_ref_count = self.get_xref(
            objc_selrefs, objc_msgrefs, objc_const)
        self.is_msg_ref = is_msg_ref
        self.const_ref_count = const_ref_count
        if not selector_ref:
            msg("No selref found.\n")
            self.selector_ref = None
            return
        if const_ref_count == 1:
            #We can only work with unambiguous situations where there is exactly one const reference
            #to the selector.
            self.selector_ref = selector_ref
        else:
            msg("Selector ref count not exactly 1. Potentially ambiguous: %d" %
                const_ref_count)
            # Otherwise this same selector is used by more than one class. (Or none at all)
            self.selector_ref = None
            return

        self.sel_ref_va = self.selector_ref.frm
        if is_msg_ref:
            # adjust pointer to beginning of message ref struct to get xrefs
            self.sel_ref_va -= POINTER_SIZE

        msg("selref VA: 0x%X - function VA: 0x%X\n" %
            (self.sel_ref_va, self.method_pointer))
        #Find all the references to this *selref* (note: not the string itself but the selref)
        #These should precede calls to the method
        #Patch the references to the selref with a reference to the method implementation
        self.walk_selector_refs()
Пример #28
0
def load_chr_rom_bank(li, banknr, address):
    # todo: add support for PPU
    # this function currently is disabled, since no
    # segment for the PPU is created
    msg("The loader was trying to load a CHR bank but the PPU is not supported yet.\n"
        )
    return

    if ((banknr == 0) or (hdr.chr_page_count_8k == 0)):
        return

    # this is the file offset to begin reading pages from
    offset = INES_HDR_SIZE + \
        (TRAINER_SIZE if INES_MASK_TRAINER(hdr.rom_control_byte_0) else 0) + \
        PRG_PAGE_SIZE * hdr.prg_page_count_16k + \
        (banknr - 1) * CHR_ROM_BANK_SIZE

    # load page from ROM file into segment
    msg("mapping CHR-ROM page %02d to %08x-%08x (file offset %08x) ..", banknr,
        address, address + CHR_PAGE_SIZE, offset)
    if (file2base(li, offset, address, address + CHR_ROM_BANK_SIZE,
                  FILEREG_PATCHABLE) == 1):
        msg("ok\n")
    else:
        msg("failure (corrupt ROM image?)\n")
Пример #29
0
def install_plugin():
    """Installs script to IDA userdir as a plugin."""
    dst = get_dest_filename()
    src = SELF
    if is_installed():
        btnid = kw.ask_yn(kw.ASKBTN_NO,
            "File exists:\n\n%s\n\nReplace?" % dst)
        if btnid is not kw.ASKBTN_YES:
            return False
    else:
        btnid = kw.ask_yn(kw.ASKBTN_NO,
            "This plugin is about to be installed to:\n\n%s\n\nInstall now?" % dst)
        if btnid is not kw.ASKBTN_YES:
            return False

    usrdir = os.path.dirname(dst)
    kw.msg("%s: copying script from \"%s\" to \"%s\" ..." % (PLUGIN_NAME, src, usrdir))
    if not os.path.exists(usrdir):
        try:
            os.path.makedirs(usrdir)
        except OSError as e:
            if e.errno != errno.EEXIST:
                kw.msg("failed (mkdir)!\n")
                return False
    try:
        shutil.copy(src, dst)
    except:
        kw.msg("failed (copy)!\n")
        return False
    kw.msg(("done\n"
        "Plugin installed - please restart this instance of IDA.\n"))
    return True
Пример #30
0
 def _update_key(self, buffers):
     if buffers:
         tmp = ''
         for mapped, buf in buffers:
             tmp += buf if mapped else ''
         self.size = len(tmp)            
         c = Counter(tmp.replace("\x00",""))
         mc = c.most_common(1)
         if len(mc):
             cur, self.occurence = mc[0]
             cur = ord(cur)
             if cur != self.key:
                 msg('Key %02Xh - %d/%d (%.2f%%)\n' % (cur, self.occurence, self.size, float(self.occurence)/float(self.size)*100.0))
                 self.key = cur
Пример #31
0
def save_trainer_as_blob(li):
    node = ida_netnode.netnode()

    if (not INES_MASK_TRAINER(hdr.rom_control_byte_0)):
        return False

    li.seek(INES_HDR_SIZE)
    buffer = li.read(TRAINER_SIZE)
    if (not node.create("$ Trainer")):
        return False
    if (not node.setblob(buffer, TRAINER_SIZE, 0, 'I')):
        msg("Could not store trainer to netnode!\n")

    return True
Пример #32
0
 def write(self, text):
     # NB: in case 'text' is Unicode, msg() will decode it
     # and call msg() to print it
     ida_kernwin.msg(text)