Ejemplo n.º 1
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.set_inf_attr(idc.INFFL_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()
Ejemplo n.º 2
0
 def load(infos):
     idc.set_inf_attr(idc.INF_COMPILER, 6)
     for info in infos:
         type = info.get('type', None)
         ida_name.set_name(info['start'], info['name'])
         if type:
             idc.SetType(info['start'], type)
Ejemplo n.º 3
0
def load_file(li, neflags, format):
    # pydevd_pycharm.settrace('localhost', port=1234, stdoutToServer=True, stderrToServer=True)

    fname = idaapi.get_input_file_path()
    psx = PsxExe(os.path.basename(fname), ONLY_FIRST, MIN_ENTROPY)
    psx.parse(li, True)

    idaapi.set_processor_type('mipsl', ida_idp.SETPROC_LOADER)

    idaapi.cvar.inf.af = \
        idaapi.AF_CODE | idaapi.AF_JUMPTBL | idaapi.AF_USED | idaapi.AF_UNK | idaapi.AF_PROC | idaapi.AF_STKARG | \
        idaapi.AF_REGARG | idaapi.AF_TRACE | idaapi.AF_VERSP | idaapi.AF_ANORET | idaapi.AF_MEMFUNC | \
        idaapi.AF_TRFUNC | idaapi.AF_FIXUP | idaapi.AF_JFUNC | idaapi.AF_IMMOFF | idaapi.AF_STRLIT | \
        idaapi.AF_MARKCODE | idaapi.AF_LVAR | idaapi.AF_PROCPTR | idaapi.AF_FLIRT

    psx.create_segments(li)

    im = idaapi.compiler_info_t()
    idaapi.inf_get_cc(im)
    im.id = idaapi.COMP_GNU
    im.cm = idaapi.CM_N32_F48 | idaapi.CM_M_NN | idaapi.CM_CC_CDECL
    im.defalign = 4
    im.size_i = 4
    im.size_b = 1
    im.size_e = 4
    im.size_s = 2
    im.size_l = 4
    im.size_ll = 8
    im.size_ldbl = 8
    idaapi.inf_set_cc(im)
    # Replace predefined macros and included directories by id
    # from IDA.CFG (see 'CC_PARMS' in Built-in C parser parameters)
    idaapi.set_c_macros(ida_idp.cfg_get_cc_predefined_macros(im.id))
    idaapi.set_c_header_path(ida_idp.cfg_get_cc_header_path(im.id))
    # Resetting new settings :)
    idc.set_inf_attr(idc.INF_COMPILER, im.id)

    idc.process_config_line("MIPS_DEFAULT_ABI=o32")

    detect = DetectPsyQ(psx.get_exe_name(), ONLY_FIRST, MIN_ENTROPY)
    version = detect.get_psyq_version(psx.rom_addr,
                                      psx.rom_addr + psx.rom_size)

    if len(version) > 0:
        psx.apply_psyq_signatures_by_version(version)

    idaapi.add_entry(psx.init_pc, psx.init_pc, 'start', 1)

    PsxExe.apply_til(version)

    psx.update_gp()

    return 1
Ejemplo n.º 4
0
    def pre_hook(self):
        self.unhook()
        hooks.idb.unhook()

        idc.set_inf_attr(idc.INFFL_AUTO, True)
        idc.Wait()
        idaapi.request_refresh(idaapi.IWID_STRUCTS | idaapi.IWID_ENUMS
                               | idaapi.IWID_XREFS)
        idc.set_inf_attr(idc.INFFL_AUTO, False)
        idaapi.request_refresh(idaapi.IWID_STRUCTS | idaapi.IWID_ENUMS
                               | idaapi.IWID_XREFS)

        self.hook()
        hooks.idb.hook()
Ejemplo n.º 5
0
    def update(self):
        memory_exporter = ya.MakeModel()

        modified_files = self.repo_manager.update_cache()
        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)

        idc.set_inf_attr(idc.INFFL_AUTO, True)
        idc.Wait()
        idc.set_inf_attr(idc.INFFL_AUTO, False)
        idc.Refresh()
        logger.debug("hook")
        self.ida_hooks.hook()
Ejemplo n.º 6
0
def processor(processor):

    # Processor
    idc.set_processor_type(processor, SETPROC_LOADER)

    # Assembler
    idc.set_target_assembler(0x0)

    # Compiler
    idc.set_inf_attr(INF_COMPILER, COMP_GNU)

    # Loader Flags
    idc.set_inf_attr(INF_LFLAGS, LFLG_PC_FLAT | LFLG_COMPRESS)

    # Assume GCC3 names
    idc.set_inf_attr(INF_DEMNAMES, DEMNAM_GCC3)

    # Analysis Flags
    idc.set_inf_attr(INF_AF, 0xBFFFBFFF)
Ejemplo n.º 7
0
def processor(processor, til):
    
    # Processor
    idc.set_processor_type(processor, SETPROC_LOADER)
    
    # Assembler
    idc.set_target_assembler(0x0)
    
    # Type Library
    idc.add_default_til(til)
    
    # Compiler
    idc.set_inf_attr(INF_COMPILER, COMP_GNU)
    
    # Loader Flags
    idc.set_inf_attr(INF_LFLAGS, LFLG_PC_FLAT)
    
    # Assume GCC3 names
    idc.set_inf_attr(INF_DEMNAMES, DEMNAM_GCC3)
    
    # Analysis Flags
    idc.set_inf_attr(INF_AF, 0xC7FFFFD7)
Ejemplo n.º 8
0
    def load_file(li, neflags, format):
        idaapi.set_processor_type(
            "arm", idaapi.SETPROC_LOADER_NON_FATAL | idaapi.SETPROC_LOADER)
        f = load_nxo(li)
        if f.armv7:
            idc.set_inf_attr(
                idc.INF_LFLAGS,
                idc.get_inf_attr(idc.INF_LFLAGS) | idc.LFLG_PC_FLAT)
        else:
            idc.set_inf_attr(idc.INF_LFLAGS,
                             idc.get_inf_attr(idc.INF_LFLAGS) | idc.LFLG_64BIT)

        idc.set_inf_attr(idc.INF_DEMNAMES, idaapi.DEMNAM_GCC3)
        idaapi.set_compiler_id(idaapi.COMP_GNU)
        idaapi.add_til('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)
        if f.text[1] != None:
            li.file2base(f.text[1], loadbase + f.text[2],
                         loadbase + f.text[2] + f.text[3], True)
        if f.ro[1] != None:
            li.file2base(f.ro[1], loadbase + f.ro[2],
                         loadbase + f.ro[2] + f.ro[3], True)
        if f.data[1] != None:
            li.file2base(f.data[1], loadbase + f.data[2],
                         loadbase + f.data[2] + f.data[3], True)

        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:
                idaapi.create_data(undef_ea, idc.FF_QWORD, 8, idaapi.BADADDR)
                idaapi.force_name(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.force_name(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_dword(target, sym.resolved)
            elif r_type == R_ARM_RELATIVE:
                idaapi.put_dword(target, idaapi.get_dword(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.force_name(addr, got_name_lookup[target])

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

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

        return 1
Ejemplo n.º 9
0
def set_start_cs(x):
    return idc.set_inf_attr(INF_START_CS, x)
Ejemplo n.º 10
0
    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
Ejemplo n.º 11
0
    def procomp(self, processor, pointer, til):

        # Set Processor...
        idc.set_processor_type(processor, SETPROC_LOADER)

        # Set Compiler...
        idc.set_inf_attr(INF_COMPILER, COMP_GNU)
        idc.set_inf_attr(INF_MODEL, pointer)
        idc.set_inf_attr(INF_SIZEOF_BOOL, 0x1)
        idc.set_inf_attr(INF_SIZEOF_LONG, 0x8)
        idc.set_inf_attr(INF_SIZEOF_LDBL, 0x10)

        # Type Library
        idc.add_default_til(til)

        # Loader Flags
        idc.set_inf_attr(INF_LFLAGS, LFLG_64BIT)

        # Assume GCC3 names
        idc.set_inf_attr(INF_DEMNAMES, DEMNAM_GCC3)

        # File Type
        idc.set_inf_attr(INF_FILETYPE, FT_ELF)

        # Analysis Flags
        idc.set_inf_attr(INF_AF, 0xC7FFFFD7)

        # Return Bitsize
        return self.EI_CLASS
Ejemplo n.º 12
0
import idc
import idaapi
import binascii

idc.set_inf_attr(INF_AF, idc.get_inf_attr(INF_AF) | AF_DODATA)

print("Waiting for the end of the auto analysis...")
idc.auto_wait()
print("Autoanalysis done!")

dumped_netnode_value = 'ca75b28848ea06bcae409699fa2510a03bbaf43bd167eecb17d52918187133a793ebf8d3270230c7164d7a79b53c2c3edd611ede975690784cf2c254abe8b587140d19a3f46b2be109bde1da1b7ed4d7c9f7b58135f2c296db4e86ad29b6f0b999b5599d40c3bae8b29d2cc06ecef63cba0e1b9a9505c1efe9019a7020127e100000000000000000000000000000000000000000000000000000000000000000'
idaapi.netnode('$ user1', 0,
               False).kill()  # deleting netnode with plain text info
idaapi.netnode('$ original user', 0,
               False).supset(0, binascii.unhexlify(dumped_netnode_value))

idc.qexit(0)
Ejemplo n.º 13
0
def SetAppcallOptions(x):
    return idc.set_inf_attr(INF_APPCALL_OPTIONS, x)
Ejemplo n.º 14
0
import idc

currentEA = ''
currentMnem = ''
prevMnem = ''
nextMnem = ''
currentOp = ''

print("Running IDA setup script")
print("Setting startup options")

# set demangled names options to show names
idc.set_inf_attr(INF_DEMNAMES, DEMNAM_NAME)
# show the address next to each command
idc.set_inf_attr(INF_OUTFLAGS, OFLG_SHOW_PREF)
idc.set_inf_attr(INF_PREFFLAG, 0)
print("Finished setting options")

currentEA = idc.get_first_seg()
currentEA = idc.next_head(currentEA, 0xFFFFFFFFFFFFFFFF)

while (currentEA != BADADDR):
    currentMnem = idc.print_insn_mnem(currentEA)

    #Highlight call functions
    if (currentMnem == "call"):
        #check to see if it's a call pop
        nextMnem = idc.print_insn_mnem(idc.get_operand_value(currentEA, 0))
        if nextMnem == "pop":
            idc.set_color(currentEA, CIC_ITEM, 0xff1d4a)
            idc.set_color(idc.get_operand_value(currentEA, 0), CIC_ITEM,
Ejemplo n.º 15
0
def Indent(x):
    return idc.set_inf_attr(INF_INDENT, x)
Ejemplo n.º 16
0
    def procomp(self, processor, pointer, til):

        # Processor Type
        idc.set_processor_type(processor, SETPROC_LOADER)

        # Compiler Attributes
        idc.set_inf_attr(INF_COMPILER, COMP_GNU)
        idc.set_inf_attr(INF_MODEL, pointer)
        idc.set_inf_attr(INF_SIZEOF_BOOL, 0x1)
        idc.set_inf_attr(INF_SIZEOF_LONG, 0x8)
        idc.set_inf_attr(INF_SIZEOF_LDBL, 0x10)

        # Type Library
        idc.add_default_til(til)

        # Loader Flags
        idc.set_inf_attr(INF_LFLAGS, LFLG_64BIT)

        # Assume GCC3 Names
        idc.set_inf_attr(INF_DEMNAMES, DEMNAM_GCC3 | DEMNAM_NAME)

        # File Type
        idc.set_inf_attr(INF_FILETYPE, FT_ELF)

        # Analysis Flags
        # (unchecked) Delete instructions with no xrefs
        # (unchecked) Coagulate data segments in the final pass
        idc.set_inf_attr(INF_AF, 0xDFFFFFDF)

        # Return Bitsize
        return self.EI_CLASS
Ejemplo n.º 17
0
def StringStp(x):
    return idc.set_inf_attr(INF_STRLIT_BREAK, x)
Ejemplo n.º 18
0
def XrefShow(x):
    return idc.set_inf_attr(INF_XREFNUM, x)
Ejemplo n.º 19
0
def TailDepth(x):
    return idc.set_inf_attr(INF_MAXREF, x)
Ejemplo n.º 20
0
def HighVoids(x):
    return idc.set_inf_attr(INF_HIGH_OFF, x)
Ejemplo n.º 21
0
def CmtIndent(x):
    return idc.set_inf_attr(INF_COMMENT, x)
Ejemplo n.º 22
0
 def load(infos):
     idc.set_inf_attr(idc.INF_COMPILER, 6)
     for info in infos:
         ida_name.set_name(info['start'], info['name'])
         if info['type']:
             idc.SetType(info['start'], info['type'])
Ejemplo n.º 23
0
 def load(info):
     idc.set_inf_attr(idc.INF_COMPILER, info['compiler'])
Ejemplo n.º 24
0
def set_start_ip(x):
    return idc.set_inf_attr(INF_START_IP, x)
Ejemplo n.º 25
0
import idautils
import os
import argparse


def parse_command():
	parser = argparse.ArgumentParser(description='Process some integers.')
	parser.add_argument("--path", type=str, help="The directory where to store the generated .ida file")
	args = parser.parse_args()
	return args

if __name__ == '__main__':
	idaapi.autoWait()
	#args = parse_command()
	#path = args.path

	print "open a new binary"
	path = "D:\\Code\\python\\binary_search\\Genius\\Gencoding-master\\raw-feature-extractor\\extracted-acfg"
	
	analysis_flags = get_inf_attr(idc.INF_AF) # 得到analysis_flags  INF_AF
	analysis_flags &= ~AF_IMMOFF  # AF_IMMOFF :将32位的指令操作转换为偏移量
	# turn off "automatically make offset" heuristic
	idc.set_inf_attr(INF_AF, analysis_flags) #设置analysis_flags
	cfgs = get_func_cfgs_c(FirstSeg())
	binary_name = GetInputFile() + '.cfg'
	fullpath = os.path.join(path, binary_name)
	pickle.dump(cfgs, open(fullpath,'w'))
	print binary_name

	idc.Exit(0)
Ejemplo n.º 26
0
def load_file(li, neflags, format):
    # Set flags
    idaapi.set_processor_type(
        "arm", idaapi.SETPROC_LOADER_NON_FATAL | idaapi.SETPROC_LOADER)
    idc.set_inf_attr(idc.INF_LFLAGS,
                     idc.get_inf_attr(idc.INF_LFLAGS) | idc.LFLG_64BIT)
    idc.set_inf_attr(idc.INF_DEMNAMES, idaapi.DEMNAM_GCC3)
    idaapi.set_compiler_id(idaapi.COMP_GNU)
    idaapi.add_til('gnulnx_arm64', 1)

    # Load IRAM memory
    li.seek(0)
    pk11 = li.read(PK1L_SIZE)
    idaapi.mem2base(pk11, PK1L_ADDRESS)

    # Add identity mappings
    add_segment(PK1L_ADDRESS, PK1L_SIZE, '.pk1_identity', 'RWX')
    add_segment(TZRAM_BASE, TZRAM_SIZE, '.tz_identity', 'RWX')

    # Emulate package1 to determine interesting extents
    emu = Emulator()
    emu.run_emulator(pk11)

    # Refresh IRAM contents to reflect any decompression that may have occurred.
    idaapi.mem2base(emu.read_mem(PK1L_ADDRESS, PK1L_SIZE), PK1L_ADDRESS)

    if not emu.found_smc_evp:
        # Set coldboot crt0
        idc.create_insn(emu.entrypoint)
        idc.set_name(emu.entrypoint, 'coldboot_crt0')
        return 1

    iram_mappings = []
    dram_mappings = []
    tzram_mappings = []
    mmio_mappings = []

    for m in emu.mappings:
        if is_tzram(m):
            tzram_mappings.append(m)
        elif is_dram(m):
            dram_mappings.append(m)
        elif is_iram(m):
            iram_mappings.append(m)
        else:
            assert is_mmio(m)
            mmio_mappings.append(m)

    for m in mmio_mappings:
        add_mmio_mapping(m)

    # Process IRAM mappings
    if len(iram_mappings) == 3:
        sorted_irams = sorted(iram_mappings, key=lambda m: m[2])
        if [m[2] for m in sorted_irams] == [0x1000, 0x1000, 0x10000]:
            assert len(set([m[3] for m in sorted_irams])) == 2
            if sorted_irams[1][3] == sorted_irams[2][3]:
                add_segment(sorted_irams[0][0], sorted_irams[0][2], '.bl_sync',
                            'IO')
                add_segment(sorted_irams[1][0], sorted_irams[1][2], '.sc7_fw',
                            'DATA')
                add_segment(sorted_irams[2][0], sorted_irams[2][2],
                            '.sc7_tmp_save', 'DATA')
            else:
                assert sorted_irams[0][3] == sorted_irams[2][3]
                add_segment(sorted_irams[1][0], sorted_irams[1][2], '.bl_sync',
                            'IO')
                add_segment(sorted_irams[0][0], sorted_irams[0][2], '.sc7_fw',
                            'DATA')
                add_segment(sorted_irams[2][0], sorted_irams[2][2],
                            '.sc7_tmp_save', 'DATA')
        else:
            print iram_mappings
            raise ValueError('Unknown IRAM mapping set')
    elif len(iram_mappings) == 2:
        sorted_irams = sorted(iram_mappings, key=lambda m: m[2])
        if [m[2] for m in sorted_irams] == [0x1000, 0x10000]:
            assert len(set([m[3] for m in sorted_irams])) == 2
            add_segment(sorted_irams[0][0], sorted_irams[0][2], '.bl_sync',
                        'IO')
            add_segment(sorted_irams[1][0], sorted_irams[1][2],
                        '.sc7_tmp_save', 'DATA')
        else:
            print iram_mappings
            raise ValueError('Unknown IRAM mapping set')
    else:
        print iram_mappings
        raise ValueError('Unknown IRAM mapping set')

    # Process DRAM mappings
    if len(dram_mappings) == 2:
        sorted_drams = sorted(dram_mappings, key=lambda m: m[2])
        if [m[2] for m in sorted_drams] == [0x1000, 0x10000]:
            add_segment(sorted_drams[0][0], sorted_drams[0][2], '.sc7_se_ctx',
                        'DATA')
            add_segment(sorted_drams[1][0], sorted_drams[1][2], '.sc7_sm_ctz',
                        'DATA')
        else:
            print dram_mappings
            raise ValueError('Unknown DRAM mapping set')
    else:
        print dram_mappings
        raise ValueError('Unknown DRAM mapping set')

    # Process TZRAM segments
    tzram_groups = []
    for (vaddr, paddr, size, attr) in sorted(tzram_mappings,
                                             key=lambda m: m[0]):
        inserted = False
        for i in xrange(len(tzram_groups)):
            if vaddr == tzram_groups[i][-1][0] + tzram_groups[i][-1][
                    2] and tzram_groups[i][-1][2] != 0x40000:
                tzram_groups[i].append((vaddr, paddr, size, attr))
                inserted = True
                break
        if not inserted:
            tzram_groups.append([(vaddr, paddr, size, attr)])

    for group in tzram_groups:
        print 'Group'
        for m in group:
            print '    %x %x %x %x' % m

    # Process groups
    for group in tzram_groups:
        if len(group) > 1:
            if is_executable(group[0]):
                # .text/.rodata/.rwdata :)
                if len(group) == 2:
                    add_segment(group[0][0], group[0][2], '.text_rodata',
                                'CODE')
                    add_segment(group[1][0], group[1][2], '.rwdata', 'DATA')
                    load_mapping(emu, group[0])
                    load_mapping(emu, group[1])
                else:
                    assert len(group) == 3
                    add_segment(group[0][0], group[0][2], '.text', 'CODE')
                    add_segment(group[1][0], group[1][2], '.rodata', 'CONST')
                    add_segment(group[2][0], group[2][2], '.rwdata', 'DATA')
                    load_mapping(emu, group[0])
                    load_mapping(emu, group[1])
                    load_mapping(emu, group[2])
        elif is_executable(group[0]):
            assert len(group) == 1
            vaddr, paddr, size, attr = group[0]
            if size > 0x8000:
                assert len(
                    filter(lambda g: is_executable(g[0]) and g[0][2] > 0x8000,
                           tzram_groups)) == 1
                assert is_writable(group[0])
                add_segment(vaddr, size, '.code', 'RWX')
                load_mapping(emu, group[0])
            elif size == 0x2000:
                assert len(
                    filter(lambda g: is_executable(g[0]) and g[0][2] == 0x2000,
                           tzram_groups)) == 1
                add_segment(vaddr, size, '.pk2ldr', 'RWX')
                load_mapping(emu, group[0])
            else:
                assert size == 0x1000
                assert len(
                    filter(lambda g: is_executable(g[0]) and g[0][2] == 0x1000,
                           tzram_groups)) == 1
                add_segment(vaddr, size, '.vectors', 'CODE')
                load_mapping(emu, group[0])
        elif len(group) == 1 and (group[0][2] == 0x10000
                                  or group[0][2] == 0x40000):
            assert len(
                filter(
                    lambda g: len(g) == 1 and not is_executable(g[0]) and
                    (g[0][2] == 0x10000 or g[0][2] == 0x40000),
                    tzram_groups)) == 1
            assert not is_writable(group[0])
            vaddr, paddr, size, attr = group[0]
            add_segment(vaddr, size, '.tzram_ro_view', 'CONST')
        elif len(group) == 1 and group[0][2] == 0x1000:
            vaddr, paddr, size, attr = group[0]
            pk2ldr_group = filter(
                lambda g: is_executable(g[0]) and g[0][2] == 0x2000,
                tzram_groups)
            assert len(pk2ldr_group) == 1
            pk2ldr_group = pk2ldr_group[0][0]
            if paddr == emu.l3_table:
                add_segment(vaddr, size, '.l3_table', 'DATA')
            elif paddr == (emu.l3_table - 0x1000):
                add_segment(vaddr, size, '.l2_table', 'DATA')
            elif paddr == pk2ldr_group[1]:
                add_segment(vaddr, size, '.reused_stack0', 'DATA')
            elif paddr == (pk2ldr_group[1] + 0x1000):
                add_segment(vaddr, size, '.reused_stack1', 'DATA')
            elif vaddr == emu.phys_to_virt[
                    emu.ttbr & ~0xFFF][0] or vaddr == emu.core0_stack_page:
                add_segment(vaddr, size, '.shared_data', 'DATA')
            else:
                print 'Unknown Group'
                for m in group:
                    print '    %x %x %x %x' % m
                assert False
        else:
            print 'Unknown Group'
            for m in group:
                print '    %x %x %x %x' % m
            assert False

    # Set vector types as code.
    for i, ctx in enumerate(['sp0', 'spx', 'a64', 'a32']):
        for j, kind in enumerate(['synch', 'irq', 'fiq', 'serror']):
            addr = emu.vbar + 0x200 * i + 0x80 * j
            name = '%s_%s_exception' % (ctx, kind)
            idc.create_insn(addr)
            idc.set_name(addr, name)

    # Set coldboot crt0
    idc.create_insn(emu.entrypoint)
    idc.set_name(emu.entrypoint, 'coldboot_crt0')

    # Add SMC list entries
    assert len(emu.smc_lists) == 2
    idc.set_name(emu.smc_lists_addr, 'g_smc_lists')
    for i, name in enumerate(['user', 'priv']):
        addr, num_entries, pad = emu.smc_lists[i]
        idc.set_name(addr, 'g_smc_list_%s' % name)
        for n in xrange(num_entries):
            id, access, func = up('<IIQ', emu.read_mem(addr + 0x10 * n, 0x10))
            if func == 0:
                continue
            smc_name = get_smc_name(name == 'user', id)
            process_smc(func, smc_name)

    # We're done
    return 1
Ejemplo n.º 27
0
    def load_file(li, neflags, fmt):
        idaapi.set_processor_type(
            "arm", idaapi.SETPROC_LOADER_NON_FATAL | idaapi.SETPROC_LOADER)
        idc.set_inf_attr(idc.INF_LFLAGS,
                         idc.get_inf_attr(idc.INF_LFLAGS) | idc.LFLG_64BIT)
        idc.set_inf_attr(idc.INF_DEMNAMES, idaapi.DEMNAM_GCC3)
        idaapi.set_compiler_id(idaapi.COMP_GNU)
        idaapi.add_til('gnulnx_arm64', 1)

        # Get the meta offset
        meta_ofs = find_kernel_meta(li)
        assert meta_ofs != -1

        # Read important offsets.
        li.seek(meta_ofs + 0x40)
        text_base, init_base, init_base2, kernel_end = struct.unpack(
            '<QQQQ', li.read(0x20))

        # Load the init segment.
        li.seek(0)
        init_data = li.read(KERNEL_INIT_SIZE)

        idaapi.mem2base(init_data, init_base)

        # Emulate the kernel init segment to determine interesting extents
        emu = Emulator()
        emu.run_emulator(init_base, init_data)

        builder = SegmentBuilder()
        builder.add_segment(init_base, KERNEL_INIT_SIZE, '.init', 'RWX')
        text_phys = 0
        text_size = 0
        ro_size = 0
        rw_size = 0
        core_dram_mappings = []
        for (virt_addr, size, phys_addr, attr) in emu.mappings:
            print('%x, %x, %x, %x' % (virt_addr, size, phys_addr, attr))
            assert attr in [
                0x4000000000078B, 0x78B, 0x6000000000078B, 0x6000000000070B,
                0x60000000000607, 0x60000000000709
            ]
            if attr == 0x78B or attr == 0x4000000000078B:
                # .text
                assert virt_addr == text_base
                builder.add_segment(virt_addr, size, '.text', 'CODE')
                li.seek(phys_addr - init_base)
                idaapi.mem2base(li.read(size), virt_addr)
                text_phys = phys_addr
                text_size = size
            elif attr == 0x6000000000078B:
                # .rodata
                assert text_size != 0
                assert virt_addr == text_base + text_size
                builder.add_segment(virt_addr, size, '.rodata', 'CONST')
                li.seek(phys_addr - init_base)
                idaapi.mem2base(li.read(size), virt_addr)
                ro_size = size
            elif attr == 0x6000000000070B and virt_addr == text_base + text_size + ro_size:
                assert text_size != 0
                assert ro_size != 0
                # .rwdata
                builder.add_segment(virt_addr, size, '.rwdata', 'DATA')
                li.seek(phys_addr - init_base)
                idaapi.mem2base(li.read(size), virt_addr)
                rw_size = size
            elif attr == 0x60000000000607:
                # IO
                DEVICES = {
                    (0x40000000, 0x40000): '.iram',
                    (0x50041000, 0x01000): '.gicd',
                    (0x50042000, 0x01000): '.gicc',
                    (0x60001000, 0x01000): '.semaphore',
                    (0x60004000, 0x01000): '.primary_ictlr',
                    (0x60006000, 0x01000): '.clkrst',
                    (0x60007000, 0x01000): '.flow_ctlr',
                    (0x6000F000, 0x01000): '.evp',
                    (0x70006000, 0x01000): '.uart',
                    (0x7000E000, 0x01000): '.rtc_pmc',
                    (0x70016000, 0x02000): '.atomics',
                    (0x70019000, 0x01000): '.mc',
                    (0x7001C000, 0x01000): '.mc0',
                    (0x7001D000, 0x01000): '.mc1',
                }
                assert (phys_addr, size) in DEVICES.keys()
                name = DEVICES[(phys_addr, size)]
                builder.add_segment(virt_addr, size, name, 'IO')
            elif attr == 0x6000000000070B:
                # Kernel DRAM
                if phys_addr == (emu.ttbr & ~0xFFF) and size == 0x1000:
                    builder.add_segment(virt_addr, size, '.ttbr1', 'DATA')
                else:
                    core_dram_mappings.append(
                        (virt_addr, size, phys_addr, attr))
            else:
                # Linear DRAM
                assert attr == 0x60000000000709
                idaapi.add_segm(0, virt_addr, virt_addr + size, '.linear_dram',
                                'DATA', idaapi.ADDSEG_SPARSE)
                segm = idaapi.get_segm_by_name('.linear_dram')
                segm.perm = idaapi.SEGPERM_READ | idaapi.SEGPERM_WRITE
                idaapi.update_segm(segm)
                idaapi.set_segm_addressing(segm, 2)

        assert len(core_dram_mappings) % 5 == 0
        if len(core_dram_mappings) // 5 == 3:
            # 1.0.0-style core local mappings
            assert core_dram_mappings[
                0 + 0][2] == core_dram_mappings[0 + 3][2] - 0x2000
            assert core_dram_mappings[
                0 + 3][2] == core_dram_mappings[0 + 6][2] - 0x2000
            assert core_dram_mappings[
                0 + 6][2] == core_dram_mappings[0 + 9][2] - 0x2000
            assert core_dram_mappings[0 + 0][2] == core_dram_mappings[0 +
                                                                      12][2]

            assert core_dram_mappings[
                1 + 0][2] == core_dram_mappings[1 + 3][2] - 0x2000
            assert core_dram_mappings[
                1 + 3][2] == core_dram_mappings[1 + 6][2] - 0x2000
            assert core_dram_mappings[
                1 + 6][2] == core_dram_mappings[1 + 9][2] - 0x2000
            assert core_dram_mappings[1 + 0][2] == core_dram_mappings[1 +
                                                                      12][2]

            assert core_dram_mappings[
                2 + 0][2] == core_dram_mappings[2 + 3][2] - 0x1000
            assert core_dram_mappings[
                2 + 3][2] == core_dram_mappings[2 + 6][2] - 0x1000
            assert core_dram_mappings[
                2 + 6][2] == core_dram_mappings[2 + 9][2] - 0x1000
            assert core_dram_mappings[2 + 0][2] == core_dram_mappings[2 +
                                                                      12][2]

            builder.add_segment(core_dram_mappings[0][0], 0xA000 * 4,
                                '.core_local_regions', 'DATA')
            builder.add_segment(core_dram_mappings[3 * 4 + 0][0],
                                core_dram_mappings[3 * 4 + 0][1],
                                '.current_common_stack', 'DATA')
            builder.add_segment(core_dram_mappings[3 * 4 + 1][0],
                                core_dram_mappings[3 * 4 + 1][1],
                                '.current_main_stack', 'DATA')
            builder.add_segment(core_dram_mappings[3 * 4 + 2][0],
                                core_dram_mappings[3 * 4 + 2][1],
                                '.current_context', 'DATA')
        elif len(core_dram_mappings) // 5 == 4:
            # 3.0.0-style core local mappings
            assert core_dram_mappings[
                0 + 0][2] == core_dram_mappings[0 + 4][2] - 0x2000
            assert core_dram_mappings[
                0 + 4][2] == core_dram_mappings[0 + 8][2] - 0x2000
            assert core_dram_mappings[
                0 + 8][2] == core_dram_mappings[0 + 12][2] - 0x2000
            assert core_dram_mappings[0 + 0][2] == core_dram_mappings[0 +
                                                                      16][2]

            assert core_dram_mappings[
                1 + 0][2] == core_dram_mappings[1 + 4][2] - 0x2000
            assert core_dram_mappings[
                1 + 4][2] == core_dram_mappings[1 + 8][2] - 0x2000
            assert core_dram_mappings[
                1 + 8][2] == core_dram_mappings[1 + 12][2] - 0x2000
            assert core_dram_mappings[1 + 0][2] == core_dram_mappings[1 +
                                                                      16][2]

            assert core_dram_mappings[
                2 + 0][2] == core_dram_mappings[2 + 4][2] - 0x2000
            assert core_dram_mappings[
                2 + 4][2] == core_dram_mappings[2 + 8][2] - 0x2000
            assert core_dram_mappings[
                2 + 8][2] == core_dram_mappings[2 + 12][2] - 0x2000
            assert core_dram_mappings[2 + 0][2] == core_dram_mappings[2 +
                                                                      16][2]

            assert core_dram_mappings[
                3 + 0][2] == core_dram_mappings[3 + 4][2] - 0x1000
            assert core_dram_mappings[
                3 + 4][2] == core_dram_mappings[3 + 8][2] - 0x1000
            assert core_dram_mappings[
                3 + 8][2] == core_dram_mappings[3 + 12][2] - 0x1000
            assert core_dram_mappings[3 + 0][2] == core_dram_mappings[3 +
                                                                      16][2]

            builder.add_segment(core_dram_mappings[0][0], 0xE000 * 4,
                                '.core_local_regions', 'DATA')
            builder.add_segment(core_dram_mappings[4 * 4 + 0][0],
                                core_dram_mappings[4 * 4 + 0][1],
                                '.current_common_stack', 'DATA')
            builder.add_segment(core_dram_mappings[4 * 4 + 1][0],
                                core_dram_mappings[4 * 4 + 1][1],
                                '.current_main_stack', 'DATA')
            builder.add_segment(core_dram_mappings[4 * 4 + 2][0],
                                core_dram_mappings[4 * 4 + 2][1],
                                '.current_idle_stack', 'DATA')
            builder.add_segment(core_dram_mappings[4 * 4 + 3][0],
                                core_dram_mappings[4 * 4 + 3][1],
                                '.current_context', 'DATA')

        seg_prefix = ''
        for start, end, name, kind in builder.flatten():
            idaapi.add_segm(0, start, 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
            elif kind == 'RWX':
                segm.perm = idaapi.SEGPERM_READ | idaapi.SEGPERM_WRITE | idaapi.SEGPERM_EXEC
            elif kind == 'IO':
                segm.perm = idaapi.SEGPERM_READ | idaapi.SEGPERM_WRITE
            idaapi.update_segm(segm)
            idaapi.set_segm_addressing(segm, 2)

        # Set vector types as code.
        for i, ctx in enumerate(['sp0', 'spx', 'a64', 'a32']):
            for j, kind in enumerate(['synch', 'irq', 'fiq', 'serror']):
                addr = emu.vbar + 0x200 * i + 0x80 * j
                name = '%s_%s_exception' % (kind, ctx)
                idc.create_insn(addr)
                idc.set_name(addr, name)

        # Set .init as code.
        idc.create_insn(init_base)
        idc.set_name(init_base, 'crt0')

        # Set text start as code.
        idc.create_insn(text_base)
        idc.set_name(text_base, 'HorizonKernelMain')

        # Patch movk instructions to be better understandable by ida.
        li.seek(text_phys - init_base)
        text = li.read(text_size)
        ro_rw = li.read(ro_size + rw_size)
        patch_movk_to_adrp(text_base, text, ro_rw, emu.mappings)

        return 1
Ejemplo n.º 28
0
def LowVoids(x):
    return idc.set_inf_attr(INF_LOW_OFF, x)