def write_segment(va_start, va_end, segm_name, data): ida_segment.add_segm(0, va_start, va_end, segm_name, None, 0xe) va = va_start for b in data: ida_bytes.patch_byte(va, ord(b)) va += 1 print("wrote 0x%x bytes to 0x%x [%s]" % (len(data), va_start, segm_name))
def create_rom_segment(): success = add_segm(0, ROM_START_ADDRESS, ROM_START_ADDRESS + ROM_SIZE, "ROM", "CODE") == 1 msg("creating ROM segment..%s" % ("ok!\n" if success else "failure!\n")) if (not success): return set_segm_addressing(getseg(ROM_START_ADDRESS), 0)
def create_ram_segment(): success = add_segm(0, RAM_START_ADDRESS, RAM_START_ADDRESS + RAM_SIZE, "RAM", None) == 1 msg("creating RAM segment..%s" % ("ok!\n" if success else "failure!\n")) if (not success): return set_segm_addressing(getseg(RAM_START_ADDRESS), 0)
def create_exprom_segment(): success = add_segm(0, EXPROM_START_ADDRESS, EXPROM_START_ADDRESS + EXPROM_SIZE, "EXP_ROM", None) == 1 msg("creating EXP_ROM segment..%s" % ("ok!\n" if success else "failure!\n")) if (not success): return set_segm_addressing(getseg(EXPROM_START_ADDRESS), 0)
def load_trainer(li): if (not INES_MASK_SRAM(hdr.rom_control_byte_0)): success = add_segm(0, TRAINER_START_ADDRESS, TRAINER_START_ADDRESS + TRAINER_SIZE, "TRAINER", "CODE") == 1 msg("creating TRAINER segment..%s", "ok!\n" if success else "failure!\n") set_segm_addressing(getseg(TRAINER_START_ADDRESS), 0) li.file2base(INES_HDR_SIZE, TRAINER_START_ADDRESS, TRAINER_START_ADDRESS + TRAINER_SIZE, FILEREG_PATCHABLE)
def add_segment(ea, size, seg_class, debug=False): # align page size ea = ea & 0xFFFFF000 end_ea = ea + size is_changed = False if ea == 0: return False while ea < end_ea: cur_seg = ida_segment.getseg(ea) next_seg = ida_segment.get_next_seg(ea) if debug: print("=" * 30) if cur_seg: print("cur_seg: %x - %x" % (cur_seg.start_ea, cur_seg.end_ea)) if next_seg: print("next_seg: %x - %x" % (next_seg.start_ea, next_seg.end_ea)) print("new_seg: %x - %x" % (ea, end_ea)) # if there is no segment, so create new segment if not cur_seg: if not next_seg: ida_segment.add_segm(0, ea, end_ea, "", seg_class) is_changed = True break # if next_seg exists if end_ea <= next_seg.start_ea: ida_segment.add_segm(0, ea, end_ea, "", seg_class) is_changed = True break # end_ea > next_seg.start_ea, need to create more segments ida_segment.add_segm(0, ea, next_seg.start_ea, "", seg_class) # if segment already exists, we extend current segment else: if end_ea <= cur_seg.end_ea: break if not next_seg: ida_segment.set_segm_end(ea, end_ea, 0) ida_segment.set_segm_class(cur_seg, seg_class) is_changed = True break # if next_seg exists if end_ea <= next_seg.start_ea: ida_segment.set_segm_end(ea, end_ea, 0) ida_segment.set_segm_class(cur_seg, seg_class) is_changed = True break # end_ea > next_seg.start_ea, need to create more segments if cur_seg.end_ea < next_seg.start_ea: ida_segment.set_segm_end(ea, next_seg.start_ea, 0) ida_segment.set_segm_class(cur_seg, seg_class) is_changed = True ea = next_seg.start_ea return is_changed
def load_file(f: ida_idaapi.loader_input_t, neflags: Any, format: Any) -> int: """ load the given file into the current IDA Pro database. Args: f (file): the file-like object to load. neflags (Any): unused format (Any): unused Returns: int: 1 on success, 0 on failure """ # compute file size, then read the entire contents f.seek(0x0, os.SEEK_END) flen = f.tell() f.seek(0x0) buf = f.read(flen) # mark the proc type, so IDA can invoke the correct disassembler/processor. # this must match `processor.wasm_processor_t.psnames` ida_idp.set_processor_type('wasm', ida_idp.SETPROC_LOADER_NON_FATAL) f.seek(0x0) # load the entire file directly at address zero. f.file2base(0, 0, len(buf), True) p = 0 sections = wasm.decode_module(buf) for i, section in enumerate(sections): if i == 0: sname = 'header' else: if section.data.id == wasm.wasmtypes.SEC_UNK: if section.data.name: sname = section.data.name.tobytes().decode('utf-8') else: sname = '' else: sname = idawasm.const.WASM_SECTION_NAMES.get( section.data.id, 'unknown') if sname != 'header' and section.data.id in ( wasm.wasmtypes.SEC_CODE, wasm.wasmtypes.SEC_GLOBAL): stype = 'CODE' else: stype = 'DATA' # add IDA segment with type, name, size as appropriate slen = sum(section.data.get_decoder_meta()['lengths'].values()) ida_segment.add_segm(0, p, p + slen, sname, stype) if sname != 'header': loader = SECTION_LOADERS.get(section.data.id) if loader is not None: loader(section, p) load_section(section, p) p += slen # magic ida_bytes.create_data(0x0, ida_bytes.FF_DWORD, 4, ida_idaapi.BADADDR) ida_name.set_name(0x0, 'WASM_MAGIC', ida_name.SN_CHECK) # version ida_bytes.create_data(0x4, ida_bytes.FF_DWORD, 4, ida_idaapi.BADADDR) ida_name.set_name(0x4, 'WASM_VERSION', ida_name.SN_CHECK) return 1
def load_file(li, neflags, format): li.seek(0) text_offset = [] text_addr = [] text_size = [] data_offset = [] data_addr = [] data_size = [] print('Reading offsets...') for x in range(0, 7): text_offset.append(read_int(li)) print(hex(text_offset[x])) for x in range(0, 11): data_offset.append(read_int(li)) print(hex(data_offset[x])) print('Reading addresses...') for x in range(0, 7): text_addr.append(read_int(li)) for x in range(0, 11): data_addr.append(read_int(li)) print('Reading sizes...') for x in range(0, 7): text_size.append(read_int(li)) for x in range(0, 11): data_size.append(read_int(li)) print('Reading bss info...') bss_addr = read_int(li) bss_size = read_int(li) print('Reading entry point...') entry_point = read_int(li) print('Setting processor type...') idaapi.set_processor_type('ppc', SETPROC_LOADER) print('Adding text segments...') for x in range(0, 7): if text_size[x] == 0: continue end_addr = text_addr[x] + text_size[x] ida_segment.add_segm(0, text_addr[x], end_addr, 'Text' + str(x), 'CODE') li.file2base(text_offset[x], text_addr[x], end_addr, 1) print('Adding data segments...') for x in range(0, 11): if data_size[x] == 0: continue end_addr = data_addr[x] + data_size[x] ida_segment.add_segm(0, data_addr[x], end_addr, 'Data' + str(x), 'DATA') li.file2base(data_offset[x], data_addr[x], end_addr, 1) print('Adding bss segment...') if bss_size != 0: ida_segment.add_segm(0, bss_addr, bss_addr + bss_size, 'bss', 'BSS') ida_entry.add_entry(entry_point, entry_point, 'entry', 1) return 1
def load_file(f, neflags, format): f.seek(0) ida_idp.set_processor_type("metapc", ida_idp.SETPROC_LOADER) MGROUPStart = 0 magic = f.read(2) if magic == MZ_HEADER_MAGIC: f.seek(0x22) MGROUPStart = DW(f) * 16 f.seek(MGROUPStart) magic = f.read(2) headerSize = DW(f) segmentDataAlignment = DW(f) nextExeOff = DD(f) SegDataOff = DD(f) f.file2base(MGROUPStart, 0, SegDataOff, True) ida_segment.add_segm(0, 0, 0x50, "HEADER", "MODULE") f.seek(MGROUPStart + 2) headerSize = rnDW(f, "headerSize", MGROUPStart) segmentDataAlignment = rnDW(f, "segmentDataAlignment", MGROUPStart) nextExeOff = rnDD(f, "nextExeOff", MGROUPStart) SegDataOff = rnDD(f, "SegDataOff", MGROUPStart) ResDataOff = rnDD(f, "ResDataOff", MGROUPStart) flags = rnDW(f, "flags", MGROUPStart) version = rnDB(f, "version", MGROUPStart) revision = rnDB(f, "revision", MGROUPStart) AutoDataSegNo = rnDW(f, "AutoDataSegNo", MGROUPStart) HeapSize = rnDW(f, "HeapSize", MGROUPStart) StackSize = rnDW(f, "StackSize", MGROUPStart) StartProc = rnDD(f, "StartProc", MGROUPStart) LoadProc = rnDD(f, "LoadProc", MGROUPStart) FreeProc = rnDD(f, "FreeProc", MGROUPStart) nSegments = rnDW(f, "nSegments", MGROUPStart) pSegTable = rnDW(f, "pSegTable", MGROUPStart) cbResTab = rnDW(f, "cbResTab", MGROUPStart) pResTab = rnDW(f, "pResTab", MGROUPStart) cbEntTab = rnDW(f, "cbEntTab", MGROUPStart) pEntTab = rnDW(f, "pEntTab", MGROUPStart) cbNamTab = rnDW(f, "cbNamTab", MGROUPStart) pNamTab = rnDW(f, "pNamTab", MGROUPStart) cbStrTab = rnDW(f, "cbStrTab", MGROUPStart) pStrTab = rnDW(f, "pStrTab", MGROUPStart) cbNRNamTab = rnDW(f, "cbNRNamTab", MGROUPStart) pNRNamTab = rnDW(f, "pNRNamTab", MGROUPStart) ida_segment.add_segm(0, pSegTable, pSegTable + (nSegments * SEG_STRUCT_SIZE), "SEGTABLE", "MODULE") ida_segment.add_segm(0, pResTab, pResTab + cbResTab, "RESOURCES", "MODULE") ida_segment.add_segm(0, pEntTab, pEntTab + cbEntTab, "ENTTABLE", "MODULE") ida_segment.add_segm(0, pNamTab, pNamTab + cbNamTab, "ENTNAME", "MODULE") ida_segment.add_segm(0, pStrTab, pStrTab + cbStrTab, "IMPORTS", "MODULE") ida_segment.add_segm(0, pNRNamTab, pNRNamTab + cbNRNamTab, "NRENTNAME", "MODULE") #parse segtable segentsid = defSEGENT() base = SegDataOff // 16 importCount = 0 for i in range(nSegments): segEntStart = pSegTable + i * SEG_STRUCT_SIZE ida_bytes.create_struct(segEntStart, SEG_STRUCT_SIZE, segentsid) segStart = ida_bytes.get_word(segEntStart + 2) segLen = ida_bytes.get_word(segEntStart + 4) segImports = ida_bytes.get_word(segEntStart + 6) importCount += segImports f.file2base(MGROUPStart + SegDataOff + segStart * 16, SegDataOff + segStart * 16, SegDataOff + (segStart + segLen) * 16, True) segBase = (base + segStart) * 16 #segmentDef = ida_segment.segment_t() #segmentDef.start_ea = segBase #segmentDef.end_ea = (base+segStart+segLen)*16 #ida_segment.set_selector() print(base + segStart) ida_segment.add_segm(base + segStart, segBase, (base + segStart + segLen) * 16, "", "", 0) sel = ida_segment.find_selector(base + segStart) seg = ida_segment.getseg(segBase) ida_segment.set_segm_addressing(seg, 0) segtable[i] = seg segimportstable[i] = segImports if i + 1 == AutoDataSegNo: ida_segment.set_segm_name(seg, "DATA", 0) ida_segment.set_segm_class(seg, "DATA", 0) dataSel = sel else: ida_segment.set_segm_name(seg, "TEXT", 0) ida_segment.set_segm_class(seg, "CODE", 0) if AutoDataSegNo == 0: dataSel = sel ida_segregs.set_default_dataseg(dataSel) #parse enttable pENT = pEntTab currord = 1 while pENT < pEntTab + cbEntTab: bundleCount = ida_bytes.get_byte(pENT) bundleFlags = ida_bytes.get_byte(pENT + 1) if bundleCount == 0 and bundleFlags == 0: break pENT += 2 for i in range(bundleCount): if bundleFlags == 0xFF: ordFlags = ida_bytes.get_byte(pENT) if ordFlags & 0x80: toexport.append(currord) segNo = ida_bytes.get_byte(pENT + 3) segOff = ida_bytes.get_word(pENT + 4) enttable[currord] = (segtable[segNo - 1].start_ea // 16, segOff) pENT += 6 else: ordFlags = ida_bytes.get_byte(pENT) if ordFlags & 0x80: toexport.append(currord) segOff = ida_bytes.get_word(pENT + 1) enttable[currord] = (segtable[bundleFlags - 1].start_ea // 16, segOff) pENT += 3 currord += 1 modulename = readPASSTR(pNamTab) make_entry(StartProc, modulename + "_start") make_entry(LoadProc, modulename + "_load") make_entry(FreeProc, modulename + "_free") #export named ordinals namedordtable = loadExportsF(f) for i in toexport: if i in namedordtable: name = namedordtable[i] else: name = "Ordinal" + str(i) (base, off) = enttable[i] addr = base * 16 + off ida_entry.add_entry(i, addr, name, 1) #process imports ida_segment.add_segm(0xF000, 0xF0000, 0xF0000 + importCount * 2, "IMPORTS", "XTRN", 0) import_ea = 0xF0000 for seg in segtable: segend = segtable[seg].end_ea f.seek(MGROUPStart + segend) for i in range(segimportstable[seg]): count = DB(f) mode = DB(f) relocStart = DW(f) module = DW(f) proc = DW(f) if (module == 0xFFFF): (base, off) = enttable[proc] else: modulestr = readPASSTR(pStrTab + module) if (proc & 0x8000) != 0: # read by ord ordinal = proc & 0x7FFF procname = modulestr + "_Ordinal" + str(ordinal) if not modulestr in importedmodules: if os.path.isfile(modulestr + ".EXE"): importedmodules[modulestr] = loadExports( modulestr + ".EXE") else: filename = ida_kernwin.ask_file( 0, modulestr + ".EXE", "Select file to name exports") if filename is not None and os.path.isfile( filename): importedmodules[modulestr] = loadExports( filename) else: importedmodules[modulestr] = None if modulestr in importedmodules and ( importedmodules[modulestr] is not None ) and ordinal in importedmodules[modulestr]: procname = importedmodules[modulestr][ordinal] else: procname = readPASSTR(pStrTab + proc) ida_bytes.create_data(import_ea, ida_bytes.FF_WORD, 2, ida_idaapi.BADADDR) ida_name.force_name(import_ea, procname) ida_bytes.set_cmt(import_ea, "Imported from " + modulestr, 1) base = 0xF000 off = import_ea - 0xF0000 import_ea += 2 for xx in range(count): next = ida_bytes.get_word(segtable[seg].start_ea + relocStart) if mode == 0x20: ida_bytes.put_word(segtable[seg].start_ea + relocStart + 2, base) ida_bytes.put_word(segtable[seg].start_ea + relocStart, off) elif mode == 0x10: ida_bytes.put_word(segtable[seg].start_ea + relocStart, off) elif mode == 0x0: ida_bytes.put_word(segtable[seg].start_ea + relocStart, base) relocStart = next #print "import %d: seg %d mode %s count %d relocStart %s module %s proc %s" % (i, seg, hex(mode), count, hex(relocStart), modulestr, hex(proc)) return 1
def create_ioreg_segment(): success = add_segm(0, IOREGS_START_ADDRESS, IOREGS_START_ADDRESS + IOREGS_SIZE, "IO_REGS", None) == 1 msg("creating IO_REGS segment..%s" % ("ok!\n" if success else "failure!\n")) if (not success): return set_segm_addressing(getseg(IOREGS_START_ADDRESS), 0) define_item(PPU_CR_1_ADDRESS, PPU_CR_1_SIZE, PPU_CR_1_SHORT_DESCRIPTION, PPU_CR_1_COMMENT) define_item(PPU_CR_2_ADDRESS, PPU_CR_2_SIZE, PPU_CR_2_SHORT_DESCRIPTION, PPU_CR_2_COMMENT) define_item(PPU_SR_ADDRESS, PPU_SR_SIZE, PPU_SR_SHORT_DESCRIPTION, PPU_SR_COMMENT) define_item(SPR_RAM_AR_ADDRESS, SPR_RAM_AR_SIZE, SPR_RAM_AR_SHORT_DESCRIPTION, SPR_RAM_AR_COMMENT) define_item(SPR_RAM_IOR_ADDRESS, SPR_RAM_IOR_SIZE, SPR_RAM_IOR_SHORT_DESCRIPTION, SPR_RAM_IOR_COMMENT) define_item(VRAM_AR_1_ADDRESS, VRAM_AR_1_SIZE, VRAM_AR_1_SHORT_DESCRIPTION, VRAM_AR_1_COMMENT) define_item(VRAM_AR_2_ADDRESS, VRAM_AR_2_SIZE, VRAM_AR_2_SHORT_DESCRIPTION, VRAM_AR_2_COMMENT) define_item(VRAM_IOR_ADDRESS, VRAM_IOR_SIZE, VRAM_IOR_SHORT_DESCRIPTION, VRAM_IOR_COMMENT) define_item(PAPU_PULSE_1_CR_ADDRESS, PAPU_PULSE_1_CR_SIZE, PAPU_PULSE_1_CR_SHORT_DESCRIPTION, PAPU_PULSE_1_CR_COMMENT) define_item(PAPU_PULSE_1_RCR_ADDRESS, PAPU_PULSE_1_RCR_SIZE, PAPU_PULSE_1_RCR_SHORT_DESCRIPTION, PAPU_PULSE_1_RCR_COMMENT) define_item(PAPU_PULSE_1_FTR_ADDRESS, PAPU_PULSE_1_FTR_SIZE, PAPU_PULSE_1_FTR_SHORT_DESCRIPTION, PAPU_PULSE_1_FTR_COMMENT) define_item(PAPU_PULSE_1_CTR_ADDRESS, PAPU_PULSE_1_CTR_SIZE, PAPU_PULSE_1_CTR_SHORT_DESCRIPTION, PAPU_PULSE_1_CTR_COMMENT) define_item(PAPU_PULSE_2_CR_ADDRESS, PAPU_PULSE_2_CR_SIZE, PAPU_PULSE_2_CR_SHORT_DESCRIPTION, PAPU_PULSE_2_CR_COMMENT) define_item(PAPU_PULSE_2_RCR_ADDRESS, PAPU_PULSE_2_RCR_SIZE, PAPU_PULSE_2_RCR_SHORT_DESCRIPTION, PAPU_PULSE_2_RCR_COMMENT) define_item(PAPU_PULSE_2_FTR_ADDRESS, PAPU_PULSE_2_FTR_SIZE, PAPU_PULSE_2_FTR_SHORT_DESCRIPTION, PAPU_PULSE_2_FTR_COMMENT) define_item(PAPU_PULSE_2_CTR_ADDRESS, PAPU_PULSE_2_CTR_SIZE, PAPU_PULSE_2_CTR_SHORT_DESCRIPTION, PAPU_PULSE_2_CTR_COMMENT) define_item(PAPU_TRIANGLE_CR_1_ADDRESS, PAPU_TRIANGLE_CR_1_SIZE, PAPU_TRIANGLE_CR_1_SHORT_DESCRIPTION, PAPU_TRIANGLE_CR_1_COMMENT) define_item(PAPU_TRIANGLE_CR_2_ADDRESS, PAPU_TRIANGLE_CR_2_SIZE, PAPU_TRIANGLE_CR_2_SHORT_DESCRIPTION, PAPU_TRIANGLE_CR_2_COMMENT) define_item(PAPU_TRIANGLE_FR_1_ADDRESS, PAPU_TRIANGLE_FR_1_SIZE, PAPU_TRIANGLE_FR_1_SHORT_DESCRIPTION, PAPU_TRIANGLE_FR_1_COMMENT) define_item(PAPU_TRIANGLE_FR_2_ADDRESS, PAPU_TRIANGLE_FR_2_SIZE, PAPU_TRIANGLE_FR_2_SHORT_DESCRIPTION, PAPU_TRIANGLE_FR_2_COMMENT) define_item(PAPU_NOISE_CR_1_ADDRESS, PAPU_NOISE_CR_1_SIZE, PAPU_NOISE_CR_1_SHORT_DESCRIPTION, PAPU_NOISE_CR_1_COMMENT) define_item(PAPU_NOISE_CR_2_ADDRESS, PAPU_NOISE_CR_2_SIZE, PAPU_NOISE_CR_2_SHORT_DESCRIPTION, PAPU_NOISE_CR_2_COMMENT) define_item(PAPU_NOISE_FR_1_ADDRESS, PAPU_NOISE_FR_1_SIZE, PAPU_NOISE_FR_1_SHORT_DESCRIPTION, PAPU_NOISE_FR_1_COMMENT) define_item(PAPU_NOISE_FR_2_ADDRESS, PAPU_NOISE_FR_2_SIZE, PAPU_NOISE_FR_2_SHORT_DESCRIPTION, PAPU_NOISE_FR_2_COMMENT) define_item(PAPU_DM_CR_ADDRESS, PAPU_DM_CR_SIZE, PAPU_DM_CR_SHORT_DESCRIPTION, PAPU_DM_CR_COMMENT) define_item(PAPU_DM_DAR_ADDRESS, PAPU_DM_DAR_SIZE, PAPU_DM_DAR_SHORT_DESCRIPTION, PAPU_DM_DAR_COMMENT) define_item(PAPU_DM_AR_ADDRESS, PAPU_DM_AR_SIZE, PAPU_DM_AR_SHORT_DESCRIPTION, PAPU_DM_AR_COMMENT) define_item(PAPU_DM_DLR_ADDRESS, PAPU_DM_DLR_SIZE, PAPU_DM_DLR_SHORT_DESCRIPTION, PAPU_DM_DLR_COMMENT) define_item(PAPU_SV_CSR_ADDRESS, PAPU_SV_CSR_SIZE, PAPU_SV_CSR_SHORT_DESCRIPTION, PAPU_SV_CSR_COMMENT) define_item(SPRITE_DMAR_ADDRESS, SPRITE_DMAR_SIZE, SPRITE_DMAR_SHORT_DESCRIPTION, SPRITE_DMAR_COMMENT) define_item(JOYPAD_1_ADDRESS, JOYPAD_1_SIZE, JOYPAD_1_SHORT_DESCRIPTION, JOYPAD_1_COMMENT) define_item(JOYPAD_2_ADDRESS, JOYPAD_2_SIZE, JOYPAD_2_SHORT_DESCRIPTION, JOYPAD_2_COMMENT)