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)
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()
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
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
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
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)
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
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
def wait(cls): '''Wait until IDA's autoanalysis queues are empty.''' return idaapi.autoWait() if idaapi.__version__ < 7.0 else idaapi.auto_wait()
def PLUGIN_ENTRY(): """ IDAPython plugin wrapper """ idaapi.auto_wait() return SkelenoxPlugin()
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)
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
"..." 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
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
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()