Exemple #1
0
def main():
    idaapi.auto_wait()
    base = idaapi.get_imagebase()
    tif = idaapi.tinfo_t()

    f = open(os.environ.get("DESTPATH", "functype_"), 'w')

    for ea in Segments():
        # only code segment
        if idaapi.segtype(ea) != idaapi.SEG_CODE:
            continue

        for fva in Functions(get_segm_start(ea), get_segm_end(ea)):
            func_name = get_func_name(fva)
            has_type = idaapi.get_tinfo(tif, fva) or idaapi.guess_tinfo(
                tif, fva)

            if not has_type:
                continue

            info = serialize(tif)
            if info is None:
                continue

            print(
                hex(fva - base)[:-1], "|", func_name, "|", tif, "|",
                len(info['args']))
            f.write("0x%x|%s|%s\n" % (fva - base, func_name, json.dumps(info)))

    f.close()
    idaapi.qexit(0)
Exemple #2
0
def cleanStart(analyzer, scs, undef=False):
    """Clean the selected code segments, and re-analyzer them using the gathered metadata until now.

    Args:
        analyzer (instance): analyzer instance to be used
        scs (list): list of (sark) code segments to work on
        undef (bool, optional): True iff should undefine the code segments (False by default)
    """
    for sc in scs:
        if undef:
            analyzer.logger.info("Undefining code segment: 0x%x - 0x%x",
                                 sc.start_ea, sc.end_ea)
            sark.data.undefine(sc.start_ea, sc.end_ea)
            if analyzer.switch_identifier.hasSwithTables(sc):
                analyzer.logger.info(
                    "Marking all known switch tables in the segment")
                analyzer.switch_identifier.markSwitchTables(sc)
            else:
                analyzer.logger.debug("No known switch tables in the segment")
    if analyzer.fptr_identifier.hasKnownFptrs():
        analyzer.logger.info("Marking all known fptr functions")
        analyzer.fptr_identifier.makePointedFunctions()
    else:
        analyzer.logger.debug("No known fptr functions")
    for sc in scs:
        analyzer.logger.info("Re-Analyzing code segment: 0x%x - 0x%x",
                             sc.start_ea, sc.end_ea)
        idc.plan_and_wait(sc.start_ea, sc.end_ea)
        idaapi.auto_wait()
Exemple #3
0
    def check_address(address):
        # Checks if given address contains virtual table. Returns True if more than 2 function pointers found
        # Also if table's addresses point to code in executable section, than tries to make functions at that addresses
        if helper.is_code_ea(address):
            return False

        if not idaapi.get_name(address):
            return False

        functions_count = 0
        while True:
            func_address = helper.get_ptr(address)
            # print "[INFO] Address 0x{0:08X}".format(func_address)
            if helper.is_code_ea(func_address) or helper.is_imported_ea(
                    func_address):
                functions_count += 1
                address += const.EA_SIZE
            else:
                segment = idaapi.getseg(func_address)
                if segment and segment.perm & idaapi.SEGPERM_EXEC:
                    idc.del_items(func_address, 1, idaapi.DELIT_SIMPLE)
                    if idc.add_func(func_address):
                        functions_count += 1
                        address += const.EA_SIZE
                        continue
                break
            idaapi.auto_wait()
        return functions_count
Exemple #4
0
def make_head(ea):
  flags = idc.get_full_flags(ea)
  if not idc.is_head(flags):
    # idc.SetFlags(ea, flags | idc.FF_DATA)
    idc.create_data(ea, idc.FF_BYTE, 1, idc.BADADDR)
    idaapi.auto_wait()
    return is_head(ea)
  return True
Exemple #5
0
def make_head(ea):
    flags = idc.get_full_flags(ea)
    if not idc.is_head(flags):
        # idc.SetFlags(ea, flags | idc.FF_DATA)
        idc.create_data(ea, idc.FF_BYTE, 1, idc.BADADDR)
        idaapi.auto_wait()
        return is_head(ea)
    return True
Exemple #6
0
def load_file(f, neflags, format):
    
    print('# PS3 Syscon Loader')
    
    # PS3 Syscon Processor and Library
    processor('arm', 'gnulnx_arm')
    
    print('# Creating ROM Segment...')
    address = 0x0
    end = address + f.size()
    
    f.file2base(address, address, end, FILEREG_PATCHABLE)
    idaapi.add_segm(0x0, address, end, 'ROM', 'CODE', 0x0)
    
    # Processor Specific Segment Details
    idc.set_segm_addressing(address, 0x1)
    idc.set_segm_alignment(address, saAbs)
    idc.set_segm_combination(address, scPriv)
    idc.set_segm_attr(address, SEGATTR_PERM, SEGPERM_MAXVAL)
    idc.set_default_sreg_value(address, 'T', 0x0)
    idc.set_default_sreg_value(address, 'DS', 0x1)
    
    print('# Waiting for the AutoAnalyzer to Complete...')
    idaapi.auto_wait()
    
    # Create some missing functions...
    while address < end:
        address = idaapi.find_binary(address, end, '?? B5', 0x10, SEARCH_DOWN)
        
        idaapi.create_insn(address)
        
        # Pablo escobar
        if idc.print_insn_mnem(address + 2) in ['LDR', 'MOVS', 'SUB']:
            idc.add_func(address)
        else:
            idaapi.do_unknown(address)
        
        address += 4
    
    print('# Done!')
    return 1

# PROGRAM END
Exemple #7
0
    def set_function(address: int, name: str, is_func: bool, is_entry: bool) -> None:
        ida_auto.auto_make_code(address)

        if is_func:
            ida_auto.auto_make_proc(address)
            idaapi.set_name(address, name, idaapi.SN_NOCHECK | idaapi.SN_NOWARN)

        idaapi.auto_wait()

        if is_func:
            fn = idaapi.get_func(address)

            if fn:
                fn.flags |= idaapi.FUNC_LIB

        if is_entry:
            ida_entry.add_entry(address, address, name, True)

        if is_func and SigApplier.has_non_default_name(address, None):
            return

        idaapi.set_name(address, name, idaapi.SN_NOCHECK | idaapi.SN_NOWARN | idaapi.SN_LOCAL)
Exemple #8
0
def try_mark_as_code(ea):
    if is_code(ea) and not is_code_by_flags(ea):
        idc.MakeCode(ea)
        idaapi.auto_wait()
        return True
    return False
Exemple #9
0
def load_file(f, neflags, format):

    print('# PS4 Module Loader')
    ps = Binary(f)

    # PS4 Processor, Compiler, Library
    bitness = ps.procomp('metapc', CM_N64 | CM_M_NN | CM_CC_FASTCALL,
                         'gnulnx_x64')

    # Load Aerolib...
    nids = load_nids(idc.idadir() + '/loaders/aerolib.csv')

    # Segment Loading...
    for segm in ps.E_SEGMENTS:

        # Process Loadable Segments...
        if segm.name() in [
                'CODE', 'DATA', 'SCE_RELRO', 'DYNAMIC', 'GNU_EH_FRAME',
                'SCE_DYNLIBDATA'
        ]:

            address = segm.MEM_ADDR if segm.name() not in [
                'DYNAMIC', 'SCE_DYNLIBDATA'
            ] else segm.OFFSET + 0x1000000
            size = segm.MEM_SIZE if segm.name() not in [
                'DYNAMIC', 'SCE_DYNLIBDATA'
            ] else segm.FILE_SIZE

            print('# Processing %s Segment...' % segm.name())
            f.file2base(segm.OFFSET, address, address + segm.FILE_SIZE,
                        FILEREG_PATCHABLE)

            if segm.name() not in ['DYNAMIC', 'GNU_EH_FRAME']:

                idaapi.add_segm(0, address, address + size, segm.name(),
                                segm.type(), ADDSEG_NOTRUNC | ADDSEG_FILLGAP)

                # Processor Specific Segment Details
                idc.set_segm_addressing(address, bitness)
                idc.set_segm_alignment(address, segm.alignment())
                idc.set_segm_attr(address, SEGATTR_PERM, segm.flags())

            # Process Dynamic Segment....
            elif segm.name() == 'DYNAMIC':

                stubs = {}
                modules = {}
                libraries = {}
                f.seek(segm.OFFSET)

                offset = segm.OFFSET
                dynamic = address
                dynamicsize = size

                for entry in xrange(size / 0x10):
                    idc.set_cmt(address + (entry * 0x10),
                                Dynamic(f).process(stubs, modules, libraries),
                                False)
            '''
            # Process Exception Handling Segment...
            elif segm.name() == 'GNU_EH_FRAME':
                
                # Exception Handling Frame Header Structure
                members = [('version', 'Version', 0x1),
                           ('eh_frame_ptr_enc', 'Encoding of Exception Handling Frame Pointer', 0x1),
                           ('fde_count_enc', 'Encoding of Frame Description Entry Count', 0x1),
                           ('table_enc', 'Encoding of Table Entries', 0x1)]
                struct = segm.struct('EHFrame', members)
                
                idaapi.create_struct(address, 0x4, struct)
                
                # Exception Handling Structure
                members = [('exception', 'value', 0x8)]
                struct = segm.struct('Exception', members)
                
                for entry in xrange(size / 0x8):
                    idaapi.create_struct(address + (entry * 0x8), 0x8, struct)
            '''

        # Process SCE 'Special' Shared Object Segment...
        if segm.name() == 'SCE_DYNLIBDATA':

            # SCE Fingerprint
            idc.make_array(address, 0x14)
            idc.set_name(address, 'SCE_FINGERPRINT',
                         SN_NOCHECK | SN_NOWARN | SN_FORCE)
            idc.set_cmt(
                address, ' '.join(
                    x.encode('hex')
                    for x in idc.get_bytes(address, 0x14)).upper(), False)

            # Dynamic Symbol Table
            try:
                # --------------------------------------------------------------------------------------------------------
                # Dynamic Symbol Entry Structure
                members = [('name', 'Name (String Index)', 0x4),
                           ('info', 'Info (Binding : Type)', 0x1),
                           ('other', 'Other', 0x1),
                           ('shtndx', 'Section Index', 0x2),
                           ('value', 'Value', 0x8), ('size', 'Size', 0x8)]
                struct = segm.struct('Symbol', members)

                # Dynamic Symbol Table
                location = address + Dynamic.SYMTAB
                f.seek(segm.OFFSET + Dynamic.SYMTAB)
                symbols = {}

                for entry in xrange(Dynamic.SYMTABSZ / 0x18):
                    idaapi.create_struct(location + (entry * 0x18), 0x18,
                                         struct)
                    idc.set_cmt(location + (entry * 0x18),
                                Symbol(f).process(symbols), False)

            except:
                pass

            # Dynamic String Table
            try:
                # --------------------------------------------------------------------------------------------------------
                # Dynamic String Table
                location = address + Dynamic.STRTAB
                f.seek(segm.OFFSET + Dynamic.STRTAB)

                # Stubs
                for key in stubs:
                    idc.create_strlit(location + key, BADADDR)
                    stubs[key] = idc.get_strlit_contents(
                        location + key, BADADDR)
                    idc.set_cmt(location + key, 'Stub', False)

                #print('Stubs: %s' % stubs)

                # Modules
                for key in modules:
                    idc.create_strlit(location + key, BADADDR)
                    modules[key] = idc.get_strlit_contents(
                        location + key, BADADDR)
                    idc.set_cmt(location + key, 'Module', False)

                #print('Modules: %s' % modules)

                # Libraries and LIDs
                lids = {}
                for key, value in libraries.iteritems():
                    idc.create_strlit(location + key, BADADDR)
                    lids[value] = idc.get_strlit_contents(
                        location + key, BADADDR)
                    libraries[key] = idc.get_strlit_contents(
                        location + key, BADADDR)
                    idc.set_cmt(location + key, 'Library', False)

                #print('LIDs: %s' % lids)

                # Symbols
                for key in symbols:
                    idc.create_strlit(location + key, BADADDR)
                    symbols[key] = idc.get_strlit_contents(
                        location + key, BADADDR)
                    idc.set_cmt(location + key, 'Symbol', False)

                #print('Symbols: %s' % symbols)

            except:
                pass

            # Resolve Export Symbols
            try:
                symbols = sorted(symbols.iteritems())
                location = address + Dynamic.SYMTAB + 0x30
                f.seek(segm.OFFSET + Dynamic.SYMTAB + 0x30)

                for entry in xrange((Dynamic.SYMTABSZ - 0x30) / 0x18):
                    Symbol(f).resolve(location + (entry * 0x18), nids,
                                      symbols[entry][1])

            except:
                pass

            # Jump Table
            try:
                # --------------------------------------------------------------------------------------------------------
                # Jump Entry Structure
                members = [('offset', 'Offset (String Index)', 0x8),
                           ('info', 'Info (Symbol Index : Relocation Code)',
                            0x8), ('addend', 'AddEnd', 0x8)]
                struct = segm.struct('Jump', members)

                # PS4 Base64 Alphabet
                base64 = list(
                    'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-'
                )
                alphabet = {
                    character: index
                    for index, character in enumerate(base64)
                }
                #print('Base64 Table: %s' % alphabet)

                # Jump Table
                location = address + Dynamic.JMPTAB
                f.seek(segm.OFFSET + Dynamic.JMPTAB)

                for entry in xrange(Dynamic.JMPTABSZ / 0x18):
                    idaapi.create_struct(location + (entry * 0x18), 0x18,
                                         struct)
                    idc.set_cmt(
                        location + (entry * 0x18),
                        Relocation(f).resolve(alphabet, nids, symbols, lids),
                        False)

            except:
                pass

            # Relocation Table
            try:
                # --------------------------------------------------------------------------------------------------------
                # Relocation Entry Structure (with specific addends)
                members = [('offset', 'Offset (String Index)', 0x8),
                           ('info', 'Info (Symbol Index : Relocation Code)',
                            0x8), ('addend', 'AddEnd', 0x8)]
                struct = segm.struct('Relocation', members)

                # Relocation Table (with specific addends)
                location = address + Dynamic.RELATAB
                f.seek(segm.OFFSET + Dynamic.RELATAB)

                for entry in xrange(Dynamic.RELATABSZ / 0x18):
                    idaapi.create_struct(location + (entry * 0x18), 0x18,
                                         struct)
                    idc.set_cmt(location + (entry * 0x18),
                                Relocation(f).process(nids, symbols), False)

            except:
                pass

            # Hash Table
            try:
                # --------------------------------------------------------------------------------------------------------
                # Hash Entry Structure
                members = [('bucket', 'Bucket', 0x2), ('chain', 'Chain', 0x2),
                           ('buckets', 'Buckets', 0x2),
                           ('chains', 'Chains', 0x2)]
                struct = segm.struct('Hash', members)

                # Hash Table
                location = address + Dynamic.HASHTAB
                f.seek(segm.OFFSET + Dynamic.HASHTAB)

                for entry in xrange(Dynamic.HASHTABSZ / 0x8):
                    idaapi.create_struct(location + (entry * 0x8), 0x8, struct)

            except:
                pass

            # Dynamic Tag Table
            try:
                # --------------------------------------------------------------------------------------------------------
                # Dynamic Tag Entry Structure
                members = [('tag', 'Tag', 0x8), ('value', 'Value', 0x8)]
                struct = segm.struct('Tag', members)

                f.seek(offset)

                for entry in xrange(dynamicsize / 0x10):
                    idaapi.create_struct(dynamic + (entry * 0x10), 0x10,
                                         struct)
                    idc.set_cmt(
                        dynamic + (entry * 0x10),
                        Dynamic(f).comment(address, stubs, modules, libraries),
                        False)

            except:
                pass

    # Start Function
    idc.add_entry(ps.E_START_ADDR, ps.E_START_ADDR, 'start', True)

    print('# Waiting for the AutoAnalyzer to Complete...')
    idaapi.auto_wait()

    # Set No Return for __stack_chk_fail...
    try:
        function = idc.get_name_ea_simple('__stack_chk_fail')
        function = idaapi.get_func(function)
        function.flags |= FUNC_NORET
        idaapi.update_func(function)

    except:
        pass

    # Missed Function Creation...
    try:
        code = idaapi.get_segm_by_name('CODE')

        address = code.start_ea
        end = code.end_ea

        # Final Pass
        print('# Performing Final Pass...')
        while address < end:
            address = idaapi.find_not_func(address, SEARCH_DOWN)

            if idaapi.is_unknown(idaapi.get_flags(address)):
                idaapi.create_insn(address)
            else:
                idc.add_func(address)

            address += 4

    except:
        pass

    print('# Done!')
    return 1
Exemple #10
0
def try_mark_as_code(ea):
  if is_code(ea) and not is_code_by_flags(ea):
    idc.MakeCode(ea)
    idaapi.auto_wait()
    return True
  return False
Exemple #11
0
 def wait(cls):
     '''Wait until IDA's autoanalysis queues are empty.'''
     return idaapi.autoWait() if idaapi.__version__ < 7.0 else idaapi.auto_wait()
Exemple #12
0
def PLUGIN_ENTRY():
    """
        IDAPython plugin wrapper
    """
    idaapi.auto_wait()
    return SkelenoxPlugin()
Exemple #13
0
                name=name,
                return_type=return_type,
                arguments=arguments,
                local_vars=local_vars,
                raw_code=raw_code,
            )
            self.functions.append(
                CollectedFunction(
                    ea=ea,
                    debug=self.debug_functions[ea],
                    decompiler=decompiler,
                ))
        self.write_info()
        return 1


ida.auto_wait()
if not ida.init_hexrays_plugin():
    ida.load_plugin("hexrays")
    ida.load_plugin("hexx64")
    if not ida.init_hexrays_plugin():
        print("Unable to load Hex-rays")
        ida.qexit(1)
    else:
        print(f"Hex-rays version {ida.get_hexrays_version()}")

decompiler = CollectDecompiler()
decompiler.activate(None)
print("Done with activate")
ida.qexit(0)
Exemple #14
0
def PLUGIN_ENTRY():
    """
        IDAPython plugin wrapper
    """
    idaapi.auto_wait()
    return SkelenoxPlugin()
Exemple #15
0
 def wait(cls):
     '''Wait until IDA's autoanalysis queues are empty.'''
     return idaapi.autoWait() if idaapi.__version__ < 7.0 else idaapi.auto_wait()
    def lvar_type_changed(self, vu, v, tif):
        if (vu.cfunc):
            func_tif = ida_typeinf.tinfo_t()
            vu.cfunc.get_func_type(func_tif)

            funcdata = idaapi.func_type_data_t()
            got_data = func_tif.get_func_details(funcdata)

            if (not got_data):
                # self._log("Didnt get the data")
                pass

            lvars = vu.cfunc.get_lvars()
            for j in range(len(vu.cfunc.argidx)):
                # for i in vu.cfunc.argidx:
                i = vu.cfunc.argidx[j]
                if (lvars[i].name == v.name):
                    #self._log("lvar_type_changed: function argument changed = %s, index = %s, atype = %s" % (lvars[i].name, i, funcdata[j].argloc.atype()))
                    if (funcdata[i].argloc.atype() == 3):
                        #    self._log("lvar_type_changed: reg is : %s" %(funcdata[i].argloc.reg1()))
                        pass

                    if (funcdata[i].argloc.atype() != 3
                            or funcdata[i].argloc.reg1() != RCX_REG):
                        break

                    #self._log("applyName = %s" % (applyName))

                    firstPtrRemove = ida_typeinf.remove_pointer(tif)
                    #self._log("type name = %s" % (firstPtrRemove._print()))
                    #self._log("remove_pointer.is_ptr = %s" % (firstPtrRemove.is_ptr()))
                    #self._log("remove_pointer.is_struct = %s" % (firstPtrRemove.is_struct()))
                    if (firstPtrRemove.is_struct()
                            and not firstPtrRemove.is_ptr()):
                        currentFuncName = ida_name.get_ea_name(
                            vu.cfunc.entry_ea)
                        # self._log("before demangle current func name = %s" % (currentFuncName))
                        demangled = idc.demangle_name(
                            currentFuncName,
                            idc.get_inf_attr(idc.INF_SHORT_DN))
                        if (demangled != None):
                            self._log("Overriding mangled name = %s" %
                                      (currentFuncName))
                            currentFuncName = demangled
                        # self._log("after demangle current func name = %s" % (currentFuncName))
                        tokens = currentFuncName.split("::")
                        if len(tokens) > 1:
                            currentFuncName = tokens[1]
                        currentFuncName = currentFuncName.split("(")[0]
                        # self._log("current func name = %s" % (currentFuncName))
                        idc.set_name(
                            vu.cfunc.entry_ea,
                            firstPtrRemove._print() + "::" + currentFuncName,
                            idc.SN_NOWARN)
                        idaapi.auto_wait()
                        # self._log("Decomp Res : %s" % idaapi.decompile(vu.cfunc.entry_ea))
                        idaapi.refresh_idaview_anyway()
                        vu.refresh_ctext()
                        idaapi.refresh_idaview_anyway()
                        vu.refresh_ctext()
                        vu.refresh_view(True)

                        current_widget = idaapi.get_current_widget()
                        vu1 = idaapi.get_widget_vdui(current_widget)
                        if vu1:
                            vu1.refresh_ctext()
                    break

        #self._log("lvar_type_changed: vu=%s, v=%s, tinfo=%s" % (vu, self._format_lvar(v), tif._print()))
        return 1
Exemple #17
0
                        "..." not in s  # (...) is used in error msgs
                    ):
                    docstr_needed[entry] = s
                    break  # out of docstr iteration

    # update any results
    for called_in, lua_list in result.iteritems():
        for obj in lua_list:
            obj.docstr = docstr_needed[obj.name]

    # remove the defaultness to allow ez serialization
    return dict(result)


LOG.info("Noita IDAPython init")
idaapi.auto_wait()
LOG.info("analysis finished")
idb_path = idautils.GetIdbDir() + "noita_auto.idb"
LOG.info("saving IDB to {}".format(idb_path))
#idaapi.save_database(idb_path)

all_strings = idautils.Strings()

# do something useful?
lua_natives = get_all_registered_lua_natives()

# person who started IDA defined where the log file is, so they can parse this out of it.
# import ast; natives_fromlogs = ast.literal_eval(x.split("|lol|")[1])
# ...py3, need to re.sub(r"(\d+)L,", "\\1,", x)
natives_fordisk = []
for caller, natives in lua_natives.iteritems():
def load_file(f, neflags, format):
    
    print('# PS4 Kernel Loader')
    ps = Binary(f)
    
    # PS4 Processor, Compiler, Library
    bitness = ps.procomp('metapc', CM_N64 | CM_M_NN | CM_CC_FASTCALL, 'gnulnx_x64')
    
    # Segment Loading...
    for segm in ps.E_SEGMENTS:
        if segm.name() == 'PHDR':
            kASLR = False if segm.FILE_SIZE == 0x118 else True
        
        # Process Loadable Segments...
        if segm.name() in ['CODE', 'DATA', 'SCE_RELRO']:
            address = segm.MEM_ADDR
            size = segm.MEM_SIZE
            
            # Dumped Kernel Fix-ups
            if segm.name() in ['DATA', 'SCE_RELRO'] and (idaapi.get_segm_by_name('CODE').start_ea != 0xFFFFFFFF82200000 or not kASLR):
                offset = address - idaapi.get_segm_by_name('CODE').start_ea
                dumped = segm.MEM_SIZE
            else:
                offset = segm.OFFSET
                dumped = segm.FILE_SIZE
            
            print('# Creating %s Segment...' % segm.name())
            f.file2base(offset, address, address + dumped, FILEREG_PATCHABLE)
            
            idaapi.add_segm(0, address, address + size, segm.name(), segm.type(), ADDSEG_NOTRUNC | ADDSEG_FILLGAP)
            
            # Processor Specific Segment Details
            idc.set_segm_addressing(address, bitness)
            idc.set_segm_alignment(address, segm.alignment())
            idc.set_segm_attr(address, SEGATTR_PERM, segm.flags())
        
        # Process Dynamic Segment...
        elif segm.name() == 'DYNAMIC':
            code = idaapi.get_segm_by_name('CODE')
            data = idaapi.get_segm_by_name('DATA')
            relro = idaapi.get_segm_by_name('SCE_RELRO')
            
            # ------------------------------------------------------------------------------------------------------------
            # Dynamic Tag Entry Structure
            members = [('tag', 'Tag', 0x8),
                       ('value', 'Value', 0x8)]
            struct = segm.struct('Tag', members)
            
            # Dynamic Tag Table
            stubs = {}
            modules = {}
            location = segm.MEM_ADDR
            
            # Dumps are offset by a small amount
            if code.start_ea != 0xFFFFFFFF82200000:
                dumped = code.start_ea - 0xFFFFFFFF82200000
            else:
                dumped = 0
            
            f.seek(location - code.start_ea)
            for entry in xrange(segm.MEM_SIZE / 0x10):
                idaapi.create_struct(location + (entry * 0x10), 0x10, struct)
                idc.set_cmt(location + (entry * 0x10), Dynamic(f).process(dumped, stubs, modules), False)
            
            # ------------------------------------------------------------------------------------------------------------
            # Hash Entry Structure
            members = [('bucket', 'Bucket', 0x2),
                       ('chain', 'Chain', 0x2),
                       ('buckets', 'Buckets', 0x2),
                       ('chains', 'Chains', 0x2)]
            struct = segm.struct('Hash', members)
            
            # Hash Table
            try:
                location = Dynamic.HASHTAB
                size = Dynamic.HASHTABSZ
            
            except:
                location = Dynamic.HASH
                size = Dynamic.SYMTAB - location
            
            f.seek(location - code.start_ea)
            for entry in xrange(size / 0x8):
                idaapi.create_struct(location + (entry * 0x8), 0x8, struct)
            
            if kASLR:
                # --------------------------------------------------------------------------------------------------------
                # Relocation Entry Structure (with specific addends)
                members = [('offset', 'Offset (String Index)', 0x8),
                           ('info', 'Info (Symbol Index : Relocation Code)', 0x8),
                           ('addend', 'AddEnd', 0x8)]
                struct = segm.struct('Relocation', members)
                
                # Relocation Table (with specific addends)
                location = Dynamic.RELATAB
                
                f.seek(location - code.start_ea)
                for entry in xrange(Dynamic.RELATABSZ / 0x18):
                    idaapi.create_struct(location + (entry * 0x18), 0x18, struct)
                    idc.set_cmt(location + (entry * 0x18), Relocation(f).process(dumped, code.end_ea), False)
                
                # Initialization Function
                idc.add_entry(Dynamic.INIT, Dynamic.INIT, '.init', True)
            
            else:
                # --------------------------------------------------------------------------------------------------------
                # Symbol Entry Structure
                members = [('name', 'Name (String Index)', 0x4),
                           ('info', 'Info (Binding : Type)', 0x1),
                           ('other', 'Other', 0x1),
                           ('shtndx', 'Section Index', 0x2),
                           ('offset', 'Value', 0x8),
                           ('size', 'Size', 0x8)]
                struct = segm.struct('Symbol', members)
                
                # Symbol Table
                location = Dynamic.SYMTAB
                f.seek(location - code.start_ea)
                functions = {}
                
                # .symtab
                idc.add_entry(location, location, '.symtab', False)
                
                for entry in xrange((Dynamic.STRTAB - location) / 0x18):
                    idaapi.create_struct(location + (entry * 0x18), 0x18, struct)
                    idc.set_cmt(location + (entry * 0x18), Symbol(f).process(functions), False)
                
                # --------------------------------------------------------------------------------------------------------
                # Dynamic String Table
                location = Dynamic.STRTAB
                
                # .strtab
                idc.add_entry(location, location, '.strtab', False)
                
                # Functions
                for key in functions:
                    idc.create_strlit(location + key, BADADDR)
                    functions[key] = idc.get_strlit_contents(location + key, BADADDR)
                    idc.set_cmt(location + key, 'Function', False)
                
                functions = sorted(functions.iteritems(), key = operator.itemgetter(0))
                #print('Functions: %s' % functions)
                
                # Resolve Functions
                location = Dynamic.SYMTAB
                f.seek(location - code.start_ea + 0x18)
                
                for entry in xrange((Dynamic.STRTAB - location - 0x18) / 0x18):
                    Symbol(f).resolve(functions[entry][1])
    
    # Fix-up
    if kASLR:
        address = relro.start_ea
        del_items(address, DELIT_SIMPLE, relro.end_ea - address)
        
        while address < relro.end_ea:
            create_data(address, FF_QWORD, 0x8, BADNODE)
            address += 0x8
    
    address = code.start_ea
    
    # ELF Header Structure
    members = [('File format', 0x4),
               ('File class', 0x1),
               ('Data encoding', 0x1),
               ('File version', 0x1),
               ('OS/ABI', 0x1),
               ('ABI version', 0x1),
               ('Padding', 0x7),
               ('File type', 0x2),
               ('Machine', 0x2),
               ('File version', 0x4),
               ('Entry point', 0x8),
               ('PHT file offset', 0x8),
               ('SHT file offset', 0x8),
               ('Processor-specific flags', 0x4),
               ('ELF header size', 0x2),
               ('PHT entry size', 0x2),
               ('Number of entries in PHT', 0x2),
               ('SHT entry size', 0x2),
               ('Number of entries in SHT', 0x2),
               ('SHT entry index for string table\n', 0x2)]
    
    for (comment, size) in members:
        flags = idaapi.get_flags_by_size(size)
        idc.create_data(address, flags if flags != 0 else FF_STRLIT, size, BADNODE)
        idc.set_cmt(address, comment, False)
        address += size
    
    for index, entry in enumerate(ps.E_SEGMENTS):
        # ELF Program Header Structure
        members = [('Type: %s' % entry.name(), 0x4),
                   ('Flags', 0x4),
                   ('File offset', 0x8),
                   ('Virtual address', 0x8),
                   ('Physical address', 0x8),
                   ('Size in file image', 0x8),
                   ('Size in memory image', 0x8),
                   ('Alignment\n', 0x8)]
        
        for (comment, size) in members:
            flags = idaapi.get_flags_by_size(size)
            
            idc.create_data(address, flags if flags != 0 else FF_STRLIT, size, BADNODE)
            idc.set_cmt(address, comment, False)
            address += size
    
    # Wait for the AutoAnalyzer to Complete...
    print('# Waiting for the AutoAnalyzer to Complete...')
    idaapi.auto_wait()
    
    if kASLR:
        # Start Function
        idc.add_entry(ps.E_START_ADDR, ps.E_START_ADDR, 'start', True)
        
        # Xfast_syscall
        address = idaapi.find_binary(code.start_ea, code.end_ea, '0F 01 F8 65 48 89 24 25 A8 02 00 00 65 48 8B 24', 0x10, SEARCH_DOWN)
        idaapi.do_unknown(address, 0)
        idaapi.create_insn(address)
        idaapi.add_func(address, BADADDR)
        idaapi.set_name(address, 'Xfast_syscall', SN_NOCHECK | SN_NOWARN)
        
        # --------------------------------------------------------------------------------------------------------
        # Znullptr's syscalls
        print('# Processing Znullptr\'s Syscalls...')
        
        # Syscall Entry Structure
        members = [('narg', 'Number of Arguments', 0x4),
                   ('_pad', 'Padding', 0x4),
                   ('function', 'Function', 0x8),
                   ('auevent', 'Augmented Event?', 0x2),
                   ('_pad1', 'Padding', 0x2),
                   ('_pad2', 'Padding', 0x4),
                   ('trace_args_func', 'Trace Arguments Function', 0x8),
                   ('entry', 'Entry', 0x4),
                   ('return', 'Return', 0x4),
                   ('flags', 'Flags', 0x4),
                   ('thrcnt', 'Thread Count?', 0x4)]
        struct = segm.struct('Syscall', members)
        
        znullptr(code.start_ea, code.end_ea, '4F 52 42 49 53 20 6B 65 72 6E 65 6C 20 53 45 4C 46', struct)
        
        # --------------------------------------------------------------------------------------------------------
        # Chendo's cdevsw con-struct-or
        print('# Processing Chendo\'s cdevsw structs...')
        
        # cdevsw Entry Structure
        members = [('d_version', 'Version', 0x4),
                   ('d_flags', 'Flags', 0x4),
                   ('d_name', 'Name', 0x8),
                   ('d_open', 'Open', 0x8),
                   ('d_fdopen', 'File Descriptor Open', 0x8),
                   ('d_close', 'Close', 0x8),
                   ('d_read', 'Read', 0x8),
                   ('d_write', 'Write', 0x8),
                   ('d_ioctl', 'Input/Ouput Control', 0x8),
                   ('d_poll', 'Poll', 0x8),
                   ('d_mmap', 'Memory Mapping', 0x8),
                   ('d_strategy', 'Strategy', 0x8),
                   ('d_dump', 'Dump', 0x8),
                   ('d_kqfilter', 'KQFilter', 0x8),
                   ('d_purge', 'Purge', 0x8),
                   ('d_mmap_single', 'Single Memory Mapping', 0x8),
                   ('d_spare0', 'Spare0', 0x8),
                   ('d_spare1', 'Spare1', 0x8),
                   ('d_spare2', 'Spare2', 0x8),
                   ('d_spare3', 'Spare3', 0x8),
                   ('d_spare4', 'Spare4', 0x8),
                   ('d_spare5', 'Spare5', 0x8),
                   ('d_spare6', 'Spare6', 0x4),
                   ('d_spare7', 'Spare7', 0x4)]
        struct = segm.struct('cdevsw', members)
        
        chendo(data.start_ea, data.end_ea, '09 20 12 17', struct)
    
    # --------------------------------------------------------------------------------------------------------
    # Pablo's IDC
    try:
        print('# Processing Pablo\'s Push IDC...')
        
        # Script 1) Push it real good...
        pablo(code.start_ea, code.end_ea, 'C5 FA 5A C0 C5 F2 5A C9 C5 EA 5A D2 C5 FB 59 C1')
        pablo(code.start_ea, code.end_ea, 'C5 F9 7E C0 31 C9')
        pablo(code.start_ea, code.end_ea, '48 89 E0 55 53')
        pablo(code.start_ea, code.end_ea, 'B8 2D 00 00 00 C3')
        pablo(code.start_ea, code.end_ea, '31 C0 C3')
        pablo(code.start_ea, code.end_ea, '55 48 89')
        pablo(code.start_ea, code.end_ea, '48 81 EC A0 00 00 00 C7')
        pablo(code.start_ea, code.end_ea, '48 81 EC A8 00 00 00')
        
        # Script 2) Fix-up Dumped Data Pointers...
        if dumped or not kASLR:
            print('# Processing Pablo\'s Dumped Data Pointers IDC...')
            pablo(data.start_ea, data.end_ea, '?? FF FF FF FF')
    
    except:
        pass
    
    # --------------------------------------------------------------------------------------------------------
    # Kiwidog's __stack_chk_fail
    if kASLR:
        print('# Processing Kiwidog\'s Stack Functions...')
        
        kiwidog(code.start_ea, code.end_ea, '73 74 61 63 6B 20 6F 76 65 72 66 6C 6F 77 20 64 65 74 65 63 74 65 64 3B')
    
    # --------------------------------------------------------------------------------------------------------
    # Final Pass
    print('# Performing Final Pass...')
    address = code.start_ea
    while address < code.end_ea:
        address = idaapi.find_not_func(address, SEARCH_DOWN)
        
        if idaapi.isUnknown(idaapi.getFlags(address)):
            idaapi.create_insn(address)
        else:
            idc.add_func(address)
        
        address += 4
    
    print('# Done!')
    return 1
Exemple #19
0
def load_file(li, neflags, format):
    """
    Load the file into database

    @param li: a file-like object which can be used to access the input data
    @param neflags: options selected by the user, see loader.hpp
    @return: 0-failure, 1-ok
    """
    if format == AtariSTTOSImageName:
        idaapi.set_processor_type('68K', ida_idp.SETPROC_LOADER)

        li.seek(0)
        header = read_struct(li, tos_image_header)

        li.seek(0, idaapi.SEEK_END)
        filesize = li.tell()

        idc.add_segm_ex(header.os_beg, header.os_beg + filesize, 0, 1,
                        idaapi.saRelPara, idaapi.scPub, idc.ADDSEG_NOSREG)
        idc.set_segm_name(header.os_beg, 'TOS')

        li.seek(0)
        li.file2base(0, header.os_beg, header.os_beg + filesize, 0)

        idaapi.add_entry(header.os_beg, header.os_beg, "ostext", 1)
        idc.set_cmt(header.os_beg, 'branch to reset handler', 0)
        idc.set_name(header.os_beg + 2, 'os_version')
        idc.create_word(header.os_beg + 2)
        idc.set_cmt(header.os_beg + 2, 'OS version number', 0)
        idc.set_cmt(header.os_beg + 4, '-> system reset handler', 0)
        reseth = ida_bytes.get_dword(header.os_beg + 4)
        idc.set_name(reseth, 'reseth')
        idc.set_name(header.os_beg + 8, 'os_beg')
        idc.set_cmt(header.os_beg + 8, '-> base of OS', 0)
        idc.set_name(header.os_beg + 12, 'os_end')
        idc.set_cmt(header.os_beg + 12, '-> end of OS memory usage', 0)
        os_end = ida_bytes.get_dword(header.os_beg + 12)
        idc.add_segm_ex(0x0, os_end, 0, 1, idaapi.saRelPara, idaapi.scPub,
                        idc.ADDSEG_NOSREG)
        idc.set_segm_name(0x0, 'DOSRAM')
        idc.set_name(os_end, 'endos')
        idc.set_name(header.os_beg + 16, 'os_exec')
        idc.set_cmt(header.os_beg + 16, '-> default shell', 0)
        idc.set_name(header.os_beg + 20, 'os_magic')
        idc.set_cmt(header.os_beg + 20, '-> GEM magic (or NULL)', 0)
        idc.set_name(header.os_beg + 24, 'os_date')
        idc.create_dword(header.os_beg + 24)
        idc.set_cmt(header.os_beg + 24, 'date the system was built', 0)
        idc.set_name(header.os_beg + 28, 'os_conf')
        idc.create_word(header.os_beg + 28)
        idc.set_cmt(header.os_beg + 28, 'configuration bits', 0)
        idc.set_name(header.os_beg + 30, 'os_dosdate')
        idc.create_word(header.os_beg + 30)
        idc.set_cmt(header.os_beg + 30, 'DOS-format date the system was built',
                    0)
        addr = header.os_beg + 32
        while addr < reseth:
            if addr == header.os_beg + 0x20:
                idc.set_cmt(addr, 'base of GEMDOS pool', 0)
                idc.set_name(ida_bytes.get_dword(addr), '_root')
            elif addr == header.os_beg + 0x24:
                idc.set_cmt(addr, '-> keyboard shift-state byte', 0)
                idc.set_name(ida_bytes.get_dword(addr), 'kbshift')
            elif addr == header.os_beg + 0x28:
                idc.set_cmt(addr, '-> current process', 0)
                idc.set_name(ida_bytes.get_dword(addr), '_run')
            elif addr == header.os_beg + 0x2c:
                idc.set_cmt(addr, 'reserved for future use', 0)
            idc.create_dword(addr)
            addr += 4

        the_magic = ida_bytes.get_dword(header.os_beg + 20)
        gem_end = ida_bytes.get_dword(the_magic + 4)
        aes_init = ida_bytes.get_dword(the_magic + 8)
        idc.add_segm_ex(os_end, gem_end + 1, 0, 1, idaapi.saRelPara,
                        idaapi.scPub, idc.ADDSEG_NOSREG)
        idc.set_segm_name(os_end, 'GEMRAM')

        idc.set_name(the_magic, 'the_magic')
        idc.create_dword(the_magic)
        idc.set_cmt(the_magic, '$87654321 if GEM present', 0)
        idc.create_dword(the_magic + 4)
        idc.set_cmt(the_magic + 4, 'End address of OS RAM usage', 0)
        idc.create_dword(the_magic + 8)
        idc.set_cmt(the_magic + 8, 'Execution address of GEM', 0)
        idaapi.add_entry(aes_init, aes_init, "gem_entry", 1)
        idc.set_name(gem_end, 'gem_end')

        idaapi.auto_wait()
        return 1

    elif format == AtariSTProgramName:
        idaapi.set_processor_type('68K', ida_idp.SETPROC_LOADER)

        li.seek(0)
        header = read_struct(li, gemdos_executable_header)

        base_addr = AtariSTBaseAddress

        text_addr = base_addr
        data_addr = text_addr + header.PRG_tsize
        bss_addr = data_addr + header.PRG_dsize
        idc.add_segm_ex(text_addr, text_addr + header.PRG_tsize, 0, 1,
                        idaapi.saRelPara, idaapi.scPub, idc.ADDSEG_NOSREG)
        idc.set_segm_name(text_addr, 'tseg')
        idc.add_segm_ex(data_addr, data_addr + header.PRG_dsize, 0, 1,
                        idaapi.saRelPara, idaapi.scPub, idc.ADDSEG_NOSREG)
        idc.set_segm_name(data_addr, 'dseg')
        idc.add_segm_ex(bss_addr, bss_addr + header.PRG_bsize, 0, 1,
                        idaapi.saRelPara, idaapi.scPub, idc.ADDSEG_SPARSE)
        idc.set_segm_name(bss_addr, 'bseg')
        li.file2base(ctypes.sizeof(gemdos_executable_header), text_addr,
                     text_addr + header.PRG_tsize + header.PRG_dsize, 0)

        # relocate the application
        li.seek(0, idaapi.SEEK_END)
        filesize = li.tell()
        li.seek(0, idaapi.SEEK_SET)
        relocDataOffset = ctypes.sizeof(
            gemdos_executable_header
        ) + header.PRG_tsize + header.PRG_dsize + header.PRG_ssize
        li.seek(relocDataOffset)
        relocData = li.read(filesize - relocDataOffset)
        roffset = 4
        rea = struct.unpack('>I', relocData[:roffset])[0]
        if rea != 0:
            rea = rea + base_addr
            idc.patch_dword(rea, ida_bytes.get_dword(rea) + base_addr)
            if rea >= data_addr:  # in the DATA segment, make sure it is an actual pointer
                idc.create_dword(rea)
            while True:
                offset = ord(relocData[roffset])
                roffset += 1
                if offset == 0:  # end of the relocation table
                    break
                if offset == 1:  # odd numbers are not valid, 1 is a special case to skip 254 bytes without relocating
                    rea += 254
                    continue
                rea += offset
                idc.patch_dword(rea, ida_bytes.get_dword(rea) + base_addr)
                if rea >= data_addr:  # in the DATA segment, make sure it is an actual pointer
                    idc.create_dword(rea)

        # apply a symbol table, if part of the file
        if header.PRG_ssize:
            symboltableDataOffset = ctypes.sizeof(
                gemdos_executable_header) + header.PRG_tsize + header.PRG_dsize
            li.seek(symboltableDataOffset)
            symboltableData = li.read(header.PRG_ssize)
            soffset = 0
            while soffset < header.PRG_ssize:
                entry = symboltableData[soffset:soffset + 14]
                soffset += 14
                name = entry[:8]
                flags, value = struct.unpack('>HL', entry[8:])
                if (
                        flags & 0x0048
                ) and soffset + 14 < header.PRG_ssize:  # GST extended DRI symbol format?
                    entry = symboltableData[soffset:soffset + 14]
                    soffset += 14
                    name += entry[:8]
                if (
                        flags & 0xf000
                ) == 0xa000:  # global defined symbol? (registers, etc are not supported)
                    value += text_addr  # relocate the value
                    if (flags & 0xf00) == 0x0100:  # BSS
                        idc.set_name(value, name)
                    elif (flags & 0xf00) == 0x0200:  # TEXT
                        idaapi.add_entry(value, value, name, 1)
                    elif (flags & 0xf00) == 0x0400:  # DATA
                        idc.set_name(value, name)

        idaapi.add_entry(text_addr, text_addr, "start", 1)
        idaapi.plan_and_wait(text_addr, text_addr + header.PRG_tsize)
        idaapi.auto_wait()
        return 1

    return 0
Exemple #20
0
    help = "Polichombr collaboration agent"
    wanted_name = "Skelenox"
    wanted_hotkey = "Ctrl-F4"
    skel_object = None

    def init(self):
        """
        IDA plugin init
        """
        self.icon_id = 0
        self.skel_object = None

        return idaapi.PLUGIN_OK

    def run(self, arg=0):
        self.skel_object = launch_skelenox()
        return

    def term(self):
        if self.skel_object is not None:
            self.skel_object.end_skelenox()


if __name__ == '__main__':
    # run as a script
    idaapi.auto_wait()
    if "skel" in globals() and skel is not None:
        g_logger.info("Previous instance found, killing it")
        skel.end_skelenox()
    skel = launch_skelenox()