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 make_xref(from_ea, to_ea, data_type, xref_size): """Force the data at `from_ea` to reference the data at `to_ea`.""" if not idc.get_full_flags(to_ea) or is_invalid_ea(to_ea): DEBUG(" Not making reference (A) from {:x} to {:x}".format( from_ea, to_ea)) return False make_head(from_ea) if is_code(from_ea): _CREFS_FROM[from_ea].add(to_ea) _CREFS_TO[to_ea].add(from_ea) else: _DREFS_FROM[from_ea].add(to_ea) _DREFS_TO[to_ea].add(from_ea) # If we can't make a head, then it probably means that we're at the # end of the binary, e.g. the last thing in the `.extern` segment. # or in the middle of structure. Return False in such case # # NOTE(artem): Commenting out since this breaks recovery of C++ applications # with IDA7. The failure occurs when processign references in .init_array # when the below code is enabled, those references are not treated as # references because make_head fails. # #if not make_head(from_ea + xref_size): # return False ida_bytes.del_items(from_ea, idc.DELIT_EXPAND, xref_size) if data_type == idc.FF_QWORD: data_size = 8 elif data_type == idc.FF_DWORD: data_size = 4 else: raise ValueError("Invalid data type") idc.create_data(from_ea, data_type, data_size, idaapi.BADADDR) if not is_code_by_flags(from_ea): idc.add_dref(from_ea, to_ea, idc.XREF_USER | idc.dr_O) else: DEBUG(" Not making reference (B) from {:x} to {:x}".format( from_ea, to_ea)) return True
def znullptr(address, end, search, struct): magic = idaapi.find_binary(address, end, search, 0x10, idc.SEARCH_DOWN) pattern = '%02X %02X %02X %02X FF FF FF FF' % (magic & 0xFF, ((magic >> 0x8) & 0xFF), ((magic >> 0x10) & 0xFF), ((magic >> 0x18) & 0xFF)) sysvec = idaapi.find_binary(address, cvar.inf.maxEA, pattern, 0x10, idc.SEARCH_UP) - 0x60 idaapi.set_name(sysvec, 'sysentvec', SN_NOCHECK | SN_NOWARN | SN_FORCE) sysent = idaapi.get_qword(sysvec + 0x8) idaapi.set_name(sysent, 'sv_table', SN_NOCHECK | SN_NOWARN | SN_FORCE) sysnames = idaapi.get_qword(sysvec + 0xD0) idaapi.set_name(sysnames, 'sv_syscallnames', SN_NOCHECK | SN_NOWARN | SN_FORCE) # Get the list of syscalls offset = idaapi.find_binary(address, cvar.inf.maxEA, '73 79 73 63 61 6C 6C 00 65 78 69 74 00', 0x10, SEARCH_DOWN) numsyscalls = idaapi.get_qword(sysvec) for entry in xrange(numsyscalls): initial = sysnames + (entry * 0x8) idc.create_data(initial, FF_QWORD, 0x8, BADNODE) offset = idaapi.get_qword(initial) length = idaapi.get_max_strlit_length(offset, STRTYPE_C) name = idaapi.get_strlit_contents(offset, length, STRTYPE_C) sysentoffset = sysent + 0x8 + (entry * 0x30) idaapi.do_unknown_range(sysentoffset - 0x8, 0x30, 0) idaapi.create_struct(sysentoffset - 0x8, 0x30, struct) idc.set_cmt(sysentoffset - 0x8, '#%i' % entry, False) if '{' in name: continue # Rename the functions function = idaapi.get_qword(sysentoffset) idaapi.set_name(function, name.replace('#', 'sys_'), SN_NOCHECK | SN_NOWARN | SN_FORCE)
def make_xref(from_ea, to_ea, data_type, xref_size): """Force the data at `from_ea` to reference the data at `to_ea`.""" if not idc.get_full_flags(to_ea) or is_invalid_ea(to_ea): DEBUG(" Not making reference (A) from {:x} to {:x}".format(from_ea, to_ea)) return False make_head(from_ea) if is_code(from_ea): _CREFS_FROM[from_ea].add(to_ea) _CREFS_TO[to_ea].add(from_ea) else: _DREFS_FROM[from_ea].add(to_ea) _DREFS_TO[to_ea].add(from_ea) # If we can't make a head, then it probably means that we're at the # end of the binary, e.g. the last thing in the `.extern` segment. # or in the middle of structure. Return False in such case # # NOTE(artem): Commenting out since this breaks recovery of C++ applications # with IDA7. The failure occurs when processign references in .init_array # when the below code is enabled, those references are not treated as # references because make_head fails. # #if not make_head(from_ea + xref_size): # return False ida_bytes.del_items(from_ea, idc.DELIT_EXPAND, xref_size) if data_type == idc.FF_QWORD: data_size = 8 elif data_type == idc.FF_DWORD: data_size = 4 else: raise ValueError("Invalid data type") idc.create_data(from_ea, data_type, data_size, idaapi.BADADDR) if not is_code_by_flags(from_ea): idc.add_dref(from_ea, to_ea, idc.XREF_USER|idc.dr_O) else: DEBUG(" Not making reference (B) from {:x} to {:x}".format(from_ea, to_ea)) return True
def make_xref(from_ea, to_ea, data_type, xref_size): """Force the data at `from_ea` to reference the data at `to_ea`.""" if not idc.get_full_flags(to_ea) or is_invalid_ea(to_ea): DEBUG(" Not making reference (A) from {:x} to {:x}".format( from_ea, to_ea)) return False make_head(from_ea) if is_code(from_ea): _CREFS_FROM[from_ea].add(to_ea) _CREFS_TO[to_ea].add(from_ea) else: _DREFS_FROM[from_ea].add(to_ea) _DREFS_TO[to_ea].add(from_ea) # If we can't make a head, then it probably means that we're at the # end of the binary, e.g. the last thing in the `.extern` segment. # or in the middle of structure. Return False in such case if not make_head(from_ea + xref_size): return False ida_bytes.del_items(from_ea, idc.DELIT_EXPAND, xref_size) if data_type == idc.FF_QWORD: data_size = 8 elif data_type == idc.FF_DWORD: data_size = 4 else: raise ValueError("Invalid data type") idc.create_data(from_ea, data_type, data_size, idaapi.BADADDR) if not is_code_by_flags(from_ea): idc.add_dref(from_ea, to_ea, idc.XREF_USER | idc.dr_O) else: DEBUG(" Not making reference (B) from {:x} to {:x}".format( from_ea, to_ea)) return True
def xex_load_imports(li): global directory_entry_headers li.seek(directory_entry_headers[XEX_HEADER_IMPORTS]) import_desc = read_struct(li, XEXImportDescriptor) # seperate the library names in the name table import_libnames = [] cur_lib = "" for i in range(0, import_desc.NameTableSize): name_char = li.read(1) if name_char == '\0' or name_char == '\xCD': if cur_lib != "": import_libnames.append(cur_lib) cur_lib = "" else: cur_lib += name_char # read each import library table for i in range(0, import_desc.ModuleCount): table_addr = li.tell() table_header = read_struct(li, XEXImportTable) libname = import_libnames[table_header.ModuleIndex] variables = {} for i in range(0, table_header.ImportCount): record_addr = read_dwordBE(li) record_value = ida_bytes.get_dword(record_addr) record_type = (record_value & 0xFF000000) >> 24 ordinal = record_value & 0xFFFF import_name = x360_imports.DoNameGen(libname, 0, ordinal) if record_type == 0: # variable idc.create_data(record_addr, idc.FF_WORD, 2, idc.BADADDR) idc.create_data(record_addr + 2, idc.FF_WORD, 2, idc.BADADDR) idc.make_array(record_addr, 2) idc.set_name(record_addr, "__imp__" + import_name) variables[ordinal] = record_addr elif record_type == 1: # thunk # have to rewrite code to set r3 & r4 like xorlosers loader does # r3 = module index afaik # r4 = ordinal # important to note that basefiles extracted via xextool have this rewrite done already, but raw basefile from XEX doesn't! # todo: find out how to add to imports window like xorloser loader... ida_bytes.put_dword(record_addr + 0, 0x38600000 | table_header.ModuleIndex) ida_bytes.put_dword(record_addr + 4, 0x38800000 | ordinal) idc.add_func(record_addr, record_addr + 0x10) idc.set_name(record_addr, import_name) # add comment to thunk like xorloser's loader idc.set_cmt( record_addr + 4, "%s :: %s" % (libname.rsplit('.', 1)[0], import_name), 1) # this should mark the func as a library function, but it doesn't do anything for some reason # tried a bunch of things like idaapi.autoWait() before running it, just crashes IDA with internal errors... idc.set_func_flags( record_addr, idc.get_func_flags(record_addr) | idc.FUNC_LIB) # thunk means it's not a variable, so remove from variables dict if ordinal in variables: variables.pop(ordinal) else: print( "[+] %s import %d (%s) (@ 0x%X) unknown type %d!" % (libname, ordinal, import_name, record_addr, record_type)) # remove "__imp__" part from variable import names for ordinal in variables: import_name = x360_imports.DoNameGen(libname, 0, ordinal) idc.set_name(variables[ordinal], import_name) # Seek to end of this import table li.seek(table_addr + table_header.TableSize) return
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 __call__(self): idc.create_data(self.ea, self.flags, self.size, self.tid)
def cmd_make_qword(self, a): return str( idc.create_data(int(a, 0), idc.FF_QWORD, 8, ida_idaapi.BADADDR))
def cmd_make_byte(self, a): return str( idc.create_data(int(a, 0), idc.FF_BYTE, 1, ida_idaapi.BADADDR))
def io_naming(): idc.set_name(0x04000000, "LCDControl", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000000, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000002, "Undocumented-GreenSwap", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000002, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000004, "GeneralLCDStatus(STAT,LYC)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000004, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000006, "VerticalCounter(LY)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000006, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000008, "BG0Control", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000008, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x0400000A, "BG1Control", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x0400000A, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x0400000C, "BG2Control", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x0400000C, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x0400000E, "BG3Control", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x0400000E, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000010, "BG0X-Offset", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000010, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000012, "BG0Y-Offset", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000012, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000014, "BG1X-Offset", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000014, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000016, "BG1Y-Offset", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000016, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000018, "BG2X-Offset", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000018, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x0400001A, "BG2Y-Offset", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x0400001A, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x0400001C, "BG3X-Offset", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x0400001C, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x0400001E, "BG3Y-Offset", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x0400001E, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000020, "BG2Rotation/ScalingParameterA(dx)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000020, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000022, "BG2Rotation/ScalingParameterB(dmx)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000022, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000024, "BG2Rotation/ScalingParameterC(dy)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000024, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000026, "BG2Rotation/ScalingParameterD(dmy)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000026, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000028, "BG2ReferencePointX-Coordinate", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000028, idc.FF_DWORD, 4, idaapi.BADADDR) idc.set_name(0x0400002C, "BG2ReferencePointY-Coordinate", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x0400002C, idc.FF_DWORD, 4, idaapi.BADADDR) idc.set_name(0x04000030, "BG3Rotation/ScalingParameterA(dx)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000030, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000032, "BG3Rotation/ScalingParameterB(dmx)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000032, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000034, "BG3Rotation/ScalingParameterC(dy)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000034, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000036, "BG3Rotation/ScalingParameterD(dmy)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000036, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000038, "BG3ReferencePointX-Coordinate", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000038, idc.FF_DWORD, 4, idaapi.BADADDR) idc.set_name(0x0400003C, "BG3ReferencePointY-Coordinate", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x0400003C, idc.FF_DWORD, 4, idaapi.BADADDR) idc.set_name(0x04000040, "Window0HorizontalDimensions", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000040, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000042, "Window1HorizontalDimensions", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000042, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000044, "Window0VerticalDimensions", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000044, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000046, "Window1VerticalDimensions", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000046, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000048, "InsideofWindow0and1", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000048, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x0400004A, "InsideofOBJWindow&OutsideofWindows", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x0400004A, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x0400004C, "MosaicSize", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x0400004C, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x0400004E, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN) idc.set_name(0x04000050, "ColorSpecialEffectsSelection", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000050, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000052, "AlphaBlendingCoefficients", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000052, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000054, "Brightness(Fade-In/Out)Coefficient", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000054, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000056, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN) idc.set_name(0x04000060, "Channel1Sweepregister(NR10)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000060, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000062, "Channel1Duty/Length/Envelope(NR11,NR12)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000062, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000064, "Channel1Frequency/Control(NR13,NR14)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000064, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000066, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN) idc.set_name(0x04000068, "Channel2Duty/Length/Envelope(NR21,NR22)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000068, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x0400006A, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN) idc.set_name(0x0400006C, "Channel2Frequency/Control(NR23,NR24)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x0400006C, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x0400006E, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN) idc.set_name(0x04000070, "Channel3Stop/WaveRAMselect(NR30)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000070, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000072, "Channel3Length/Volume(NR31,NR32)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000072, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000074, "Channel3Frequency/Control(NR33,NR34)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000074, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000076, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN) idc.set_name(0x04000078, "Channel4Length/Envelope(NR41,NR42)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000078, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x0400007A, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN) idc.set_name(0x0400007C, "Channel4Frequency/Control(NR43,NR44)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x0400007C, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x0400007E, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN) idc.set_name(0x04000080, "ControlStereo/Volume/Enable(NR50,NR51)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000080, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000082, "ControlMixing/DMAControl", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000082, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000084, "ControlSoundon/off(NR52)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000084, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000086, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN) idc.set_name(0x04000088, "SoundPWMControl", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000088, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x0400008A, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN) idc.set_name(0x04000090, "Channel3WavePatternRAM(2banks!!)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.set_name(0x040000A0, "ChannelAFIFO,Data0-3", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x040000A0, idc.FF_DWORD, 4, idaapi.BADADDR) idc.set_name(0x040000A4, "ChannelBFIFO,Data0-3", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x040000A4, idc.FF_DWORD, 4, idaapi.BADADDR) idc.set_name(0x040000A8, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN) idc.set_name(0x040000B0, "DMA0SourceAddress", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x040000B0, idc.FF_DWORD, 4, idaapi.BADADDR) idc.set_name(0x040000B4, "DMA0DestinationAddress", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x040000B4, idc.FF_DWORD, 4, idaapi.BADADDR) idc.set_name(0x040000B8, "DMA0WordCount", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x040000B8, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x040000BA, "DMA0Control", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x040000BA, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x040000BC, "DMA1SourceAddress", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x040000BC, idc.FF_DWORD, 4, idaapi.BADADDR) idc.set_name(0x040000C0, "DMA1DestinationAddress", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x040000C0, idc.FF_DWORD, 4, idaapi.BADADDR) idc.set_name(0x040000C4, "DMA1WordCount", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x040000C4, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x040000C6, "DMA1Control", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x040000C6, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x040000C8, "DMA2SourceAddress", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x040000C8, idc.FF_DWORD, 4, idaapi.BADADDR) idc.set_name(0x040000CC, "DMA2DestinationAddress", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x040000CC, idc.FF_DWORD, 4, idaapi.BADADDR) idc.set_name(0x040000D0, "DMA2WordCount", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x040000D0, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x040000D2, "DMA2Control", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x040000D2, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x040000D4, "DMA3SourceAddress", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x040000D4, idc.FF_DWORD, 4, idaapi.BADADDR) idc.set_name(0x040000D8, "DMA3DestinationAddress", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x040000D8, idc.FF_DWORD, 4, idaapi.BADADDR) idc.set_name(0x040000DC, "DMA3WordCount", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x040000DC, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x040000DE, "DMA3Control", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x040000DE, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x040000E0, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN) idc.set_name(0x04000100, "Timer0Counter/Reload", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000100, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000102, "Timer0Control", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000102, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000104, "Timer1Counter/Reload", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000104, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000106, "Timer1Control", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000106, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000108, "Timer2Counter/Reload", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000108, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x0400010A, "Timer2Control", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x0400010A, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x0400010C, "Timer3Counter/Reload", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x0400010C, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x0400010E, "Timer3Control", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x0400010E, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000110, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN) idc.set_name(0x04000120, "SIOData(Normal-32bitMode)(sharedwithbelow!)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000120, idc.FF_DWORD, 4, idaapi.BADADDR) idc.set_name(0x04000120, "SIOData0(Parent)(Multi-PlayerMode)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000120, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000122, "SIOData1(1stChild)(Multi-PlayerMode)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000122, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000124, "SIOData2(2ndChild)(Multi-PlayerMode)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000124, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000126, "SIOData3(3rdChild)(Multi-PlayerMode)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000126, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000128, "SIOControlRegister", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000128, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x0400012A, "SIOData(LocalofMulti-Player)(sharedbelow)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x0400012A, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x0400012A, "SIOData(Normal-8bitandUARTMode)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x0400012A, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x0400012C, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN) idc.set_name(0x04000130, "KeyStatus", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000130, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000132, "KeyInterruptControl", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000132, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000134, "SIOModeSelect/GeneralPurposeData", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000134, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000136, "IRAncient-InfraredRegister(Prototypesonly)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.set_name(0x04000138, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN) idc.set_name(0x04000140, "SIOJOYBusControl", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000140, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000142, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN) idc.set_name(0x04000150, "SIOJOYBusReceiveData", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000150, idc.FF_DWORD, 4, idaapi.BADADDR) idc.set_name(0x04000154, "SIOJOYBusTransmitData", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000154, idc.FF_DWORD, 4, idaapi.BADADDR) idc.set_name(0x04000158, "SIOJOYBusReceiveStatus", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000158, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x0400015A, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN) idc.set_name(0x04000200, "InterruptEnableRegister", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000200, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000202, "InterruptRequestFlags/IRQAcknowledge", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000202, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000204, "GamePakWaitstateControl", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000204, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x04000206, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN) idc.set_name(0x04000208, "InterruptMasterEnableRegister", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000208, idc.FF_WORD, 2, idaapi.BADADDR) idc.set_name(0x0400020A, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN) idc.set_name(0x04000300, "Undocumented-PostBootFlag", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000300, idc.FF_BYTE, 1, idaapi.BADADDR) idc.set_name(0x04000301, "Undocumented-PowerDownControl", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000301, idc.FF_BYTE, 1, idaapi.BADADDR) idc.set_name(0x04000302, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN) idc.set_name(0x04000411, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN) idc.set_name(0x04000800, "Undocumented-InternalMemoryControl(R/W)", idc.SN_NOCHECK | idc.SN_NOWARN) idc.create_data(0x04000800, idc.FF_DWORD, 4, idaapi.BADADDR) idc.set_name(0x04000804, "Notused", idc.SN_NOCHECK | idc.SN_NOWARN)
def load_file(f, neflags, format): print('# PS4 Kernel Loader') ps4 = Binary(f) # PS4 Processor, Compiler, Library bitness = ps4.procomp('metapc', CM_N64 | CM_M_NN | CM_CC_FASTCALL, 'gnulnx_x64') # Segment Loading... for segm in ps4.E_SEGMENTS: # 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: 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) # -------------------------------------------------------------------------------------------------------- # 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) 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(ps4.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 # Start Function idc.add_entry(ps4.E_START_ADDR, ps4.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 | SN_FORCE) # -------------------------------------------------------------------------------------------------------- # 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 Structures...') # 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... # Default patterns set pablo(0, code.start_ea, 0x10, '55 48 89') pablo(2, code.start_ea, code.end_ea, '90 90 55 48 ??') pablo(2, code.start_ea, code.end_ea, 'C3 90 55 48 ??') pablo(2, code.start_ea, code.end_ea, '66 90 55 48 ??') pablo(2, code.start_ea, code.end_ea, 'C9 C3 55 48 ??') pablo(2, code.start_ea, code.end_ea, '0F 0B 55 48 ??') pablo(2, code.start_ea, code.end_ea, 'EB ?? 55 48 ??') pablo(2, code.start_ea, code.end_ea, '5D C3 55 48 ??') pablo(2, code.start_ea, code.end_ea, '5B C3 55 48 ??') pablo(2, code.start_ea, code.end_ea, '90 90 55 41 ?? 41 ??') pablo(2, code.start_ea, code.end_ea, '66 90 48 81 EC ?? 00 00 00') pablo(2, code.start_ea, code.end_ea, '0F 0B 48 89 9D ?? ?? FF FF 49 89') pablo(2, code.start_ea, code.end_ea, '90 90 53 4C 8B 54 24 20') pablo(2, code.start_ea, code.end_ea, '90 90 55 41 56 53') pablo(2, code.start_ea, code.end_ea, '90 90 53 48 89') pablo(2, code.start_ea, code.end_ea, '90 90 41 ?? 41 ??') pablo(3, code.start_ea, code.end_ea, '0F 0B 90 55 48 ??') pablo(3, code.start_ea, code.end_ea, 'EB ?? 90 55 48 ??') pablo(3, code.start_ea, code.end_ea, '41 5F C3 55 48 ??') pablo(3, code.start_ea, code.end_ea, '41 5C C3 55 48 ??') pablo(3, code.start_ea, code.end_ea, '31 C0 C3 55 48 ??') pablo(3, code.start_ea, code.end_ea, '41 5D C3 55 48 ??') pablo(3, code.start_ea, code.end_ea, '41 5E C3 55 48 ??') pablo(3, code.start_ea, code.end_ea, '66 66 90 55 48 ??') pablo(3, code.start_ea, code.end_ea, '0F 1F 00 55 48 ??') pablo(3, code.start_ea, code.end_ea, '41 ?? C3 53 48') pablo(3, code.start_ea, code.end_ea, '0F 1F 00 48 81 EC ?? 00 00 00') pablo(4, code.start_ea, code.end_ea, '0F 1F 40 00 55 48 ??') pablo(4, code.start_ea, code.end_ea, '0F 1F 40 00 48 81 EC ?? 00 00 00') pablo(5, code.start_ea, code.end_ea, 'E9 ?? ?? ?? ?? 55 48 ??') pablo(5, code.start_ea, code.end_ea, 'E8 ?? ?? ?? ?? 55 48 ??') pablo(5, code.start_ea, code.end_ea, '48 83 C4 ?? C3 55 48 ??') pablo(5, code.start_ea, code.end_ea, '0F 1F 44 00 00 55 48 ??') pablo(5, code.start_ea, code.end_ea, '0F 1F 44 00 00 48 81 EC ?? 00 00 00') pablo(6, code.start_ea, code.end_ea, 'E9 ?? ?? ?? ?? 90 55 48 ??') pablo(6, code.start_ea, code.end_ea, 'E8 ?? ?? ?? ?? 90 55 48 ??') pablo(6, code.start_ea, code.end_ea, '66 0F 1F 44 00 00 55 48 ??') pablo(7, code.start_ea, code.end_ea, '0F 1F 80 00 00 00 00 55 48 ??') pablo(8, code.start_ea, code.end_ea, '0F 1F 84 00 00 00 00 00 55 48 ??') pablo(8, code.start_ea, code.end_ea, 'C3 0F 1F 80 00 00 00 00 48') pablo(8, code.start_ea, code.end_ea, '0F 1F 84 00 00 00 00 00 53 48 83 EC') # Special cases patterns set pablo(13, code.start_ea, code.end_ea, 'C3 90 90 90 90 90 90 90 90 90 90 90 90 48') pablo(13, code.start_ea, code.end_ea, 'C3 90 90 90 90 90 90 90 90 90 90 90 90 55') pablo(17, code.start_ea, code.end_ea, 'E9 ?? ?? ?? ?? 90 90 90 90 90 90 90 90 90 90 90 90 48') pablo(19, code.start_ea, code.end_ea, 'E9 ?? ?? ?? ?? 90 90 90 90 90 90 90 90 90 90 90 90 90 90 48') pablo(19, code.start_ea, code.end_ea, 'E8 ?? ?? ?? ?? 90 90 90 90 90 90 90 90 90 90 90 90 90 90 48') pablo( 20, code.start_ea, code.end_ea, 'E9 ?? ?? ?? ?? 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 48') pablo( 20, code.start_ea, code.end_ea, 'E9 ?? ?? ?? ?? 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 48') # Script 2) Fix-up Dumped Data Pointers... if dumped: print('# Processing Pablo\'s Dumped Data Pointers IDC...') pablo(0, data.start_ea, data.end_ea, '?? FF FF FF FF') except: pass # -------------------------------------------------------------------------------------------------------- # Kiwidog's __stack_chk_fail 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' ) print('# Done!') return 1