示例#1
0
    def pre_hook(self):
        self.unhook()
        hooks.idb.unhook()

        idc.SetCharPrm(idc.INF_AUTO, True)
        idc.Wait()
        idaapi.request_refresh(idaapi.IWID_STRUCTS | idaapi.IWID_ENUMS | idaapi.IWID_XREFS)
        idc.SetCharPrm(idc.INF_AUTO, False)
        idaapi.request_refresh(idaapi.IWID_STRUCTS | idaapi.IWID_ENUMS | idaapi.IWID_XREFS)

        self.hook()
        hooks.idb.hook()
示例#2
0
    def start(self):
        logger.info("YaCo.start()")
        self.YaCoUI.hook()

        try:
            self.ida_hooks.unhook()
            self.initial_load()
            idc.Wait()
            self.ida_hooks.hook()
        except:
            traceback.print_exc()
            self.YaCoUI.unhook()
            self.ida_hooks.unhook()
            logger.error('Error during load cache, YaCo is disabled !')

        idc.SetCharPrm(idc.INF_AUTO, False)

        for menu_item in self.yaco_menus:
            name = menu_item[0]
            text = menu_item[1]
            callback = menu_item[2]
            shortcut = menu_item[3]
            handler = YaCoHandler(self, callback)
            action = idaapi.action_desc_t(name, text, handler, shortcut, "")
            idaapi.register_action(action)
            idaapi.attach_action_to_menu("Edit/YaTools/", name,
                                         idaapi.SETMENU_APP)

        if PROFILE_YACO_LOADING:
            self.pr.disable()
            f = open("yaco-loading.profile", 'w')
            ps = pstats.Stats(self.pr, stream=f).sort_stats('time')
            ps.print_stats()
            f.close()
示例#3
0
    def update(self):
        # pydevd.settrace()
        logger.debug("Yaco.update()")
        (modified_object_ids_str, deleted_object_ids_str, modified_files,
         _deleted_files) = self.repo_manager.update_cache()
        modified_object_ids = []
        deleted_object_ids = []
        for obj_id in modified_object_ids_str:
            modified_object_ids.append(ya.YaToolObjectId_From_String(obj_id))

        for obj_id in deleted_object_ids_str:
            deleted_object_ids.append(ya.YaToolObjectId_From_String(obj_id))

        logger.debug("delete objects")
        # fixme do something

        logger.debug("invalidate objects")
        # fixme do something

        logger.debug("loading XML")
        logger.debug("modified files : %r", modified_files)

        memory_exporter = ya.MakeModel()

        logger.debug("exporting XML to memory")
        ya.MakeXmlFilesDatabaseModel(modified_files).accept(
            memory_exporter.visitor)

        logger.debug("unhook")
        self.ida_hooks.unhook()

        logger.debug("export mem->ida")
        ya.export_to_ida(memory_exporter.model, self.hash_provider,
                         ya.UseFrames)

        idc.SetCharPrm(idc.INF_AUTO, True)
        idc.Wait()
        idc.SetCharPrm(idc.INF_AUTO, False)
        idc.Refresh()
        logger.debug("hook")
        self.ida_hooks.hook()
示例#4
0
文件: nxo64.py 项目: tiliarou/loaders
    def load_file(li, neflags, format):
        idaapi.set_processor_type("arm", SETPROC_ALL|SETPROC_FATAL)
        f = load_nxo(li)
        if f.armv7:
            idc.SetShortPrm(idc.INF_LFLAGS, idc.GetShortPrm(idc.INF_LFLAGS) | idc.LFLG_PC_FLAT)
        else:
            idc.SetShortPrm(idc.INF_LFLAGS, idc.GetShortPrm(idc.INF_LFLAGS) | idc.LFLG_64BIT)

        idc.SetCharPrm(idc.INF_DEMNAMES, idaapi.DEMNAM_GCC3)
        idaapi.set_compiler_id(idaapi.COMP_GNU)
        idaapi.add_til2('gnulnx_arm' if f.armv7 else 'gnulnx_arm64', 1)

        loadbase = 0x60000000 if f.armv7 else 0x7100000000

        f.binfile.seek(0)
        as_string = f.binfile.read(f.bssoff)
        idaapi.mem2base(as_string, loadbase)

        for start, end, name, kind in f.sections:
            if name.startswith('.got'):
                kind = 'CONST'
            idaapi.add_segm(0, loadbase+start, loadbase+end, name, kind)
            segm = idaapi.get_segm_by_name(name)
            if kind == 'CONST':
                segm.perm = idaapi.SEGPERM_READ
            elif kind == 'CODE':
                segm.perm = idaapi.SEGPERM_READ | idaapi.SEGPERM_EXEC
            elif kind == 'DATA':
                segm.perm = idaapi.SEGPERM_READ | idaapi.SEGPERM_WRITE
            elif kind == 'BSS':
                segm.perm = idaapi.SEGPERM_READ | idaapi.SEGPERM_WRITE
            idaapi.update_segm(segm)
            idaapi.set_segm_addressing(segm, 1 if f.armv7 else 2)

        # do imports
        # TODO: can we make imports show up in "Imports" window?
        undef_count = 0
        for s in f.symbols:
            if not s.shndx and s.name:
                undef_count += 1
        last_ea = max(loadbase + end for start, end, name, kind in f.sections)
        undef_entry_size = 8
        undef_ea = ((last_ea + 0xFFF) & ~0xFFF) + undef_entry_size # plus 8 so we don't end up on the "end" symbol
        idaapi.add_segm(0, undef_ea, undef_ea+undef_count*undef_entry_size, "UNDEF", "XTRN")
        segm = idaapi.get_segm_by_name("UNDEF")
        segm.type = idaapi.SEG_XTRN
        idaapi.update_segm(segm)
        for i,s in enumerate(f.symbols):
            if not s.shndx and s.name:
                idc.MakeQword(undef_ea)
                idaapi.do_name_anyway(undef_ea, s.name)
                s.resolved = undef_ea
                undef_ea += undef_entry_size
            elif i != 0:
                assert s.shndx
                s.resolved = loadbase + s.value
                if s.name:
                    if s.type == STT_FUNC:
                        print hex(s.resolved), s.name
                        idaapi.add_entry(s.resolved, s.resolved, s.name, 0)
                    else:
                        idaapi.do_name_anyway(s.resolved, s.name)

            else:
                # NULL symbol
                s.resolved = 0

        funcs = set()
        for s in f.symbols:
            if s.name and s.shndx and s.value:
                if s.type == STT_FUNC:
                    funcs.add(loadbase+s.value)

        got_name_lookup = {}
        for offset, r_type, sym, addend in f.relocations:
            target = offset + loadbase
            if r_type in (R_ARM_GLOB_DAT, R_ARM_JUMP_SLOT, R_ARM_ABS32):
                if not sym:
                    print 'error: relocation at %X failed' % target
                else:
                    idaapi.put_long(target, sym.resolved)
            elif r_type == R_ARM_RELATIVE:
                idaapi.put_long(target, idaapi.get_long(target) + loadbase)
            elif r_type in (R_AARCH64_GLOB_DAT, R_AARCH64_JUMP_SLOT, R_AARCH64_ABS64):
                idaapi.put_qword(target, sym.resolved + addend)
                if addend == 0:
                    got_name_lookup[offset] = sym.name
            elif r_type == R_AARCH64_RELATIVE:
                idaapi.put_qword(target, loadbase + addend)
                if addend < f.textsize:
                    funcs.add(loadbase + addend)
            else:
                print 'TODO r_type %d' % (r_type,)
            ida_make_offset(f, target)

        for func, target in f.plt_entries:
            if target in got_name_lookup:
                addr = loadbase + func
                funcs.add(addr)
                idaapi.do_name_anyway(addr, got_name_lookup[target])

        funcs |= find_bl_targets(loadbase, loadbase+f.textsize)

        for addr in sorted(funcs, reverse=True):
            idc.AutoMark(addr, AU_CODE)
            idc.AutoMark(addr, AU_PROC)

        return 1
示例#5
0
    def make_stackframe(self, object_version, address):
        object_id = object_version.get_id()
        parent_object_id = object_version.get_parent_object_id()
        # associate stack frame id to function id
        self.stackframes_functions[object_id] = parent_object_id

        # association stackframe id to internal struc id
        eaFunc = object_version.get_object_address()
        logger.debug("stackframe[%s] : address of function is 0x%08X" %
                     (self.hash_provider.hash_to_string(object_id), eaFunc))

        attributes = object_version.get_attributes()
        stack_lvars = None
        stack_regvars = None
        stack_args = None
        try:
            stack_lvars = self.yatools.hex_string_to_address(
                attributes["stack_lvars"])
            stack_regvars = self.yatools.hex_string_to_address(
                attributes["stack_regvars"])
            stack_args = self.yatools.hex_string_to_address(
                attributes["stack_args"])
        except KeyError:
            logger.warning("Stackframe at %s has missing attribute" %
                           self.yatools.address_to_hex_string(eaFunc))

        stack_frame = idaapi.get_frame(eaFunc)
        if stack_frame is None:
            logger.error(
                "No function found for stackframe[%s] at 0x%08X" %
                (self.hash_provider.hash_to_string(object_id), eaFunc))
            self.analyze_function(eaFunc)
            stack_frame = idaapi.get_frame(eaFunc)

        if stack_frame is None:
            logger.error(
                "No function found for stackframe[%s] at 0x%08X after reanalysis"
                % (self.hash_provider.hash_to_string(object_id), eaFunc))
            idc.SetCharPrm(idc.INF_AUTO, 1)
            idc.Wait()
            idc.SetCharPrm(idc.INF_AUTO, 0)
            stack_frame = idaapi.get_frame(eaFunc)

        if stack_frame is None:
            logger.error(
                "No function found for stackframe[%s] at 0x%08X after full reanalysis"
                % (self.hash_provider.hash_to_string(object_id), eaFunc))
            idc.MakeFrame(eaFunc, stack_lvars, stack_regvars, stack_args)
            stack_frame = idaapi.get_frame(eaFunc)

        if stack_frame is None:
            logger.error(
                "No function found for stackframe[%s] at 0x%08X after idc.MakeFrame"
                % (self.hash_provider.hash_to_string(object_id), eaFunc))
        else:
            self.struc_ids[object_id] = stack_frame.id
            _yatools_ida_exporter.set_struct_id(object_id, stack_frame.id)
            stack_lvars = None
            try:
                stack_lvars = self.yatools.hex_string_to_address(
                    object_version.get_attributes()["stack_lvars"])
            except KeyError:
                logger.warning(
                    "Stackframe at %s has no stack_lvars attribute" %
                    self.yatools.address_to_hex_string(eaFunc))

            if stack_lvars is not None:
                logger.debug(
                    "Clearing everything for stackframe at 0x%08X, with stack_lvars=0x%04X",
                    eaFunc, stack_lvars)
                self.clear_struc_fields(
                    stack_frame.id,
                    object_version.get_size(),
                    object_version.get_xrefed_id_map().iterkeys(),
                    member_type=ya.OBJECT_TYPE_STACKFRAME_MEMBER,
                    name_offset=stack_lvars)
示例#6
0
    def make_data(self, object_version, address):
        size = 0
        try:
            size = object_version.get_size()
        except KeyError:
            pass
        flags = None
        try:
            flags = object_version.get_object_flags()
        except KeyError:
            pass

        if size == 0:
            idc.MakeUnkn(address, idc.DOUNK_EXPAND)
        else:
            if flags is not None:
                if idc.isASCII(flags):
                    try:
                        str_type = object_version.get_string_type()
                        YaToolIDATools.check_and_set_str_type(str_type)
                    except KeyError:
                        pass
                    idc.MakeStr(address, address + size)
                    idc.SetFlags(address, flags)

                if idc.isStruct(flags):
                    found = False
                    for xref_offset_operand, xref_id_attr in object_version.get_xrefed_id_map(
                    ).iteritems():
                        (xref_offset, xref_operand) = xref_offset_operand
                        for xref_hash, xref_attrs in xref_id_attr:

                            if xref_hash in self.struc_ids:
                                struc_id = self.struc_ids[xref_hash]
                                if DEBUG_EXPORTER:
                                    logger.debug(
                                        "making unknown from 0x%08X to 0x%08X"
                                        % (address, address + size))
                                idaapi.do_unknown_range(
                                    address, size, idc.DOUNK_DELNAMES)

                                #   idc.MakeUnkn(address, DOUNK_SIMPLE | idc.DOUNK_DELNAMES)
                                #   for i in xrange(1, size):
                                #       MakeName(address + i, "")
                                #       idc.MakeUnkn(address + i, DOUNK_SIMPLE | idc.DOUNK_DELNAMES)
                                # idc.MakeStructEx uses idaapi.doStruct (but asks for name while
                                # we already have the struc id)
                                if DEBUG_EXPORTER:
                                    logger.debug(
                                        "Making struc at %s : %s (sizeof(%s)=0x%08X, size=0x%08X, flags=0x%08X"
                                        % (self.yatools.address_to_hex_string(
                                            address),
                                           self.yatools.address_to_hex_string(
                                               struc_id),
                                           idaapi.get_struc_name(struc_id),
                                           idc.GetStrucSize(struc_id), size,
                                           flags))
                                idc.SetCharPrm(idc.INF_AUTO, True)
                                idc.Wait()
                                if idaapi.doStruct(address, size,
                                                   struc_id) == 0:
                                    if DEBUG_EXPORTER:
                                        logger.warning("Making struc failed")
                                idc.SetCharPrm(idc.INF_AUTO, False)
                                #                                     idc.SetFlags(address, flags)
                                found = True
                    else:
                        logger.error(
                            "bad struc flags : idc.isStruct is true but no xref available for object %s"
                            % self.hash_provider.hash_to_string(
                                object_version.get_id()))
                    if not found:
                        logger.error(
                            "bad struc flags : idc.isStruct is true "
                            "but no struc available for object %s (%s)" %
                            (self.hash_provider.hash_to_string(
                                object_version.get_id()),
                             object_version.get_name()))
                else:
                    idc.MakeData(address, flags & (idc.DT_TYPE | idc.MS_0TYPE),
                                 size, 0)

            else:
                idc.MakeData(address, idc.FF_BYTE, size, 0)

        self.make_name(object_version, address, False)

        self.set_type(object_version, address)
示例#7
0
文件: nxo64.py 项目: Thog/swipc-gen
    def load_one_file(li, options, idx, basename=None):
        bypass_plt = OPT_BYPASS_PLT in options

        f = load_nxo(li)

        if idx == 0:
            if f.armv7:
                idc.SetShortPrm(idc.INF_LFLAGS, idc.GetShortPrm(idc.INF_LFLAGS) | idc.LFLG_PC_FLAT)
            else:
                idc.SetShortPrm(idc.INF_LFLAGS, idc.GetShortPrm(idc.INF_LFLAGS) | idc.LFLG_64BIT)

            idc.SetCharPrm(idc.INF_DEMNAMES, idaapi.DEMNAM_GCC3)
            idaapi.set_compiler_id(idaapi.COMP_GNU)
            idaapi.add_til2('gnulnx_arm' if f.armv7 else 'gnulnx_arm64', 1)
            # don't create tails
            idc.set_inf_attr(idc.INF_AF, idc.get_inf_attr(idc.INF_AF) & ~idc.AF_FTAIL)

        if OPT_LOAD_31_BIT in options:
            loadbase = 0x8000000
            step = 0x1000000
        elif f.armv7:
            loadbase = 0x60000000
            step = 0x10000000
        else:
            loadbase = 0x7100000000
            step = 0x100000000
        loadbase += idx * step

        f.binfile.seek(0)
        as_string = f.binfile.read(f.bssoff)
        idaapi.mem2base(as_string, loadbase)

        seg_prefix = basename if basename is not None else ''
        for start, end, name, kind in f.sections:
            if name.startswith('.got'):
                kind = 'CONST'
            idaapi.add_segm(0, loadbase+start, loadbase+end, seg_prefix+name, kind)
            segm = idaapi.get_segm_by_name(seg_prefix+name)
            if kind == 'CONST':
                segm.perm = idaapi.SEGPERM_READ
            elif kind == 'CODE':
                segm.perm = idaapi.SEGPERM_READ | idaapi.SEGPERM_EXEC
            elif kind == 'DATA':
                segm.perm = idaapi.SEGPERM_READ | idaapi.SEGPERM_WRITE
            elif kind == 'BSS':
                segm.perm = idaapi.SEGPERM_READ | idaapi.SEGPERM_WRITE
            idaapi.update_segm(segm)
            idaapi.set_segm_addressing(segm, 1 if f.armv7 else 2)

        # do imports
        # TODO: can we make imports show up in "Imports" window?
        undef_count = 0
        for s in f.symbols:
            if not s.shndx and s.name:
                undef_count += 1
        last_ea = max(loadbase + end for start, end, name, kind in f.sections)
        undef_entry_size = 8
        undef_ea = ((last_ea + 0xFFF) & ~0xFFF) + undef_entry_size # plus 8 so we don't end up on the "end" symbol

        undef_seg = basename + '.UNDEF' if basename is not None else 'UNDEF'
        idaapi.add_segm(0, undef_ea, undef_ea+undef_count*undef_entry_size, undef_seg, 'XTRN')
        segm = idaapi.get_segm_by_name(undef_seg)
        segm.type = idaapi.SEG_XTRN
        idaapi.update_segm(segm)
        for i,s in enumerate(f.symbols):
            if not s.shndx and s.name:
                idc.MakeQword(undef_ea)
                idaapi.do_name_anyway(undef_ea, s.name)
                s.resolved = undef_ea
                undef_ea += undef_entry_size
            elif i != 0:
                assert s.shndx
                s.resolved = loadbase + s.value
                if s.name:
                    if s.type == STT_FUNC:
                        idaapi.add_entry(s.resolved, s.resolved, s.name, 0)
                    else:
                        idaapi.do_name_anyway(s.resolved, s.name)

            else:
                # NULL symbol
                s.resolved = 0

        funcs = set()
        for s in f.symbols:
            if s.name and s.shndx and s.value:
                if s.type == STT_FUNC:
                    funcs.add(loadbase+s.value)
                    symend = loadbase+s.value+s.size
                    if Dword(symend) != 0:
                        funcs.add(symend)

        got_name_lookup = {}
        for offset, r_type, sym, addend in f.relocations:
            target = offset + loadbase
            if r_type in (R_ARM_GLOB_DAT, R_ARM_JUMP_SLOT, R_ARM_ABS32):
                if not sym:
                    print 'error: relocation at %X failed' % target
                else:
                    idaapi.put_long(target, sym.resolved)
            elif r_type == R_ARM_RELATIVE:
                idaapi.put_long(target, idaapi.get_long(target) + loadbase)
            elif r_type in (R_AARCH64_GLOB_DAT, R_AARCH64_JUMP_SLOT, R_AARCH64_ABS64):
                idaapi.put_qword(target, sym.resolved + addend)
                if addend == 0:
                    got_name_lookup[offset] = sym.name
            elif r_type == R_AARCH64_RELATIVE:
                idaapi.put_qword(target, loadbase + addend)
                if addend < f.textsize:
                    funcs.add(loadbase + addend)
            else:
                print 'TODO r_type %d' % (r_type,)
            ida_make_offset(f, target)

        for func, target in f.plt_entries:
            if target in got_name_lookup:
                addr = loadbase + func
                funcs.add(addr)
                idaapi.do_name_anyway(addr, got_name_lookup[target])

        if not f.armv7:
            funcs |= find_bl_targets(loadbase, loadbase+f.textsize)

            if bypass_plt:
                plt_lookup = f.plt_lookup
                for pco in xrange(0, f.textsize, 4):
                    pc = loadbase + pco
                    d = Dword(pc)
                    if (d & 0x7c000000) == (0x94000000 & 0x7c000000):
                        imm = d & 0x3ffffff
                        if imm & 0x2000000:
                            imm |= ~0x1ffffff
                        if 0 <= imm <= 2:
                            continue
                        target = (pc + imm * 4) - loadbase
                        if target in plt_lookup:
                            new_target = plt_lookup[target] + loadbase
                            new_instr = (d & ~0x3ffffff) | (((new_target - pc) / 4) & 0x3ffffff)
                            idaapi.put_long(pc, new_instr)

            for pco in xrange(0, f.textsize, 4):
                pc = loadbase + pco
                d = Dword(pc)
                if d == 0x14000001:
                    funcs.add(pc + 4)

        for pc, _ in f.eh_table:
            funcs.add(loadbase + pc)

        for addr in sorted(funcs, reverse=True):
            idaapi.auto_make_proc(addr)

        return 1
示例#8
0
def check_and_set_str_type(new_type):
    global latest_str_type
    if latest_str_type != new_type:
        latest_str_type = new_type
        if idc.GetCharPrm(idc.INF_STRTYPE) != new_type:
            idc.SetCharPrm(idc.INF_STRTYPE, new_type)
示例#9
0
def EnableAutoAnalysis():
    global do_wait
    idc.SetCharPrm(idc.INF_AUTO, True)
    do_wait = True
    idc.Wait()
示例#10
0
def DisableAutoAnalysis():
    global do_wait
    idc.SetCharPrm(idc.INF_AUTO, False)
    do_wait = False