def go(self): idaapi.set_processor_type("arm", idc.SETPROC_ALL | idc.SETPROC_FATAL) inf = idaapi.get_inf_structure() inf.af &= ~idc.AF_MARKCODE # this is so that IDA does not find functions inside .data segments inf.af2 &= ~idc.AF2_FTAIL # don't create function tails inf.af2 |= idc.AF2_PURDAT # control flow to data segment is ignored print "0) Loading NIDs" self.load_nids() print "1) Mapping kernel VA" self.dump_first_level() print "2) Finding module table using heuristic" self.find_module_ptr() print "3) Creating segments" self.process_chunks() print "4) Resolving imports/exports" self.resolve_impexp() print "5) Waiting for IDA to analyze the program, this will take a while..." idc.Wait() print "6) Analyzing system instructions" from highlight_arm_system_insn import run_script run_script() print "7) Adding MOVT/MOVW pair xrefs" add_xrefs()
def load_file(li, neflags, format): idaapi.set_processor_type("n2t-hack", idaapi.SETPROC_ALL|idaapi.SETPROC_FATAL) li.seek(0) hack_data = li.read(li.size()) hack_instructions = [int(instruction, 2) for instruction in hack_data.splitlines()] hack_instructions_bin = ''.join(struct.pack("!H", instruction) for instruction in hack_instructions) print "Found %d hack instructions" % len(hack_instructions) seg = idaapi.segment_t() seg.startEA= 0 seg.endEA = len(hack_instructions) seg.align = idaapi.saAbs seg.comb = idaapi.scPriv seg.bitness = 0 # 16-bit idaapi.add_segm_ex(seg, "Hack-ROM", "CODE", idaapi.ADDSEG_OR_DIE) # This method seems to change in next versions. #idaapi.mem2base(hack_instructions_bin, 0, -1) idaapi.mem2base(hack_instructions_bin, 0) return 1
def accept_file(li, n): """ Check if the file is of supported format @param li: a file-like object which can be used to access the input data @param n : format number. The function will be called with incrementing number until it returns zero @return: 0 - no more supported formats string "name" - format name to display in the chooser dialog dictionary { 'format': "name", 'options': integer } options: should be 1, possibly ORed with ACCEPT_FIRST (0x8000) to indicate preferred format """ # we support only one format per file if n > 0: return 0 li.seek(0) magic = li.read(2) if struct.unpack('>h',magic)[0] in magics: idaapi.set_processor_type("A29K", SETPROC_ALL) return { 'format': fmt_a29k_coff_big, 'options': 1 } if struct.unpack('<h',magic)[0] in magics: idaapi.set_processor_type("A29K", SETPROC_ALL) return { 'format': fmt_a29k_coff_little, 'options': 1 } # unrecognized format return 0
def load_file(f, neflags, fmt): idaapi.set_processor_type("mipsl", SETPROC_ALL | SETPROC_FATAL) f.seek(0) rh = ReesesHdr() # BOGUS because ida gives you a "file like" object... f.readinto(rh) stsz = sizeof(rh) fbytes = f.read(stsz) fit = min(len(fbytes), stsz) memmove(addressof(rh), fbytes, fit) print "reeses hdr done" # get sections f.seek(rh.sec1hdr_off) for i in range(0, rh.nsec1): curseg = SecHdr1() # SUPER BOGUS f.readinto(curseg) stsz = sizeof(curseg) fbytes = f.read(stsz) fit = min(len(fbytes), stsz) memmove(addressof(curseg), fbytes, fit) if curseg.cls == 1: print "reeses: add segment 0x%08x, length=%d" % (curseg.addr, curseg.length) f.file2base(curseg.offset, curseg.addr, curseg.addr + curseg.length, 1) idaapi.add_segm(0, curseg.addr, curseg.addr + curseg.length, "seg%d" % i, "CODE") print "reeses: seg %d done" % i print "reeses load_file done" #print "entry pt is 0x%08x" % rh.entry return 1
def load_file(li, neflags, format): # Select the PC processor module idaapi.set_processor_type("BPF", SETPROC_ALL|SETPROC_FATAL) buf = read_whole_file(li, 8) if not buf: return 0 start = 0x0 seg = idaapi.segment_t() size = len(buf) end = start + size # Create the segment seg.startEA = start seg.endEA = end seg.bitness = 1 # 32-bit idaapi.add_segm_ex(seg, "bpf_c", "CODE", 0) # Copy the bytes idaapi.mem2base(buf, start, end) # add entry point idaapi.add_entry(start, start, "start", 1) # add comment to beginning of disassembly idaapi.describe(start, True, "BPF bytecode disassembly") # Mark for analysis AutoMark(start, AU_CODE) setup_enums() return 1
def accept_file(li, n): """ Check if the file is of supported format @param li: a file-like object which can be used to access the input data @param n : format number. The function will be called with incrementing number until it returns zero @return: 0 - no more supported formats string "name" - format name to display in the chooser dialog dictionary { 'format': "name", 'options': integer } options: should be 1, possibly ORed with ACCEPT_FIRST (0x8000) to indicate preferred format """ # check the MAGIC li.seek(0) if n > 0: return 0 if dwordAt(li, 4) == MAGIC_NUM: # accept the file idaapi.set_processor_type("arm:ARMv7-A&R", SETPROC_ALL | SETPROC_FATAL) idc.ChangeConfig('ARM_DEFAULT_ARCHITECTURE = metaarm') return SBL1 if dwordAt(li, 4) == HDR_FLASH_VER: # accept the file idaapi.set_processor_type("arm:ARMv7-A&R", SETPROC_ALL | SETPROC_FATAL) idc.ChangeConfig('ARM_DEFAULT_ARCHITECTURE = metaarm') return MBN
def accept_file(li, n): """ Check if the file is of supported format @param li: a file-like object which can be used to access the input data @param n : format number. The function will be called with incrementing number until it returns zero @return: 0 - no more supported formats string "name" - format name to display in the chooser dialog dictionary { 'format': "name", 'options': integer } options: should be 1, possibly ORed with ACCEPT_FIRST (0x8000) to indicate preferred format """ # check the MAGIC li.seek(0) if n > 0: return 0 if dwordAt(li, 4) == MAGIC_NUM: # accept the file idaapi.set_processor_type("arm:ARMv7-A&R", SETPROC_ALL|SETPROC_FATAL) idc.ChangeConfig('ARM_DEFAULT_ARCHITECTURE = metaarm') return SBL1 if dwordAt(li, 4) == HDR_FLASH_VER: # accept the file idaapi.set_processor_type("arm:ARMv7-A&R", SETPROC_ALL|SETPROC_FATAL) idc.ChangeConfig('ARM_DEFAULT_ARCHITECTURE = metaarm') return MBN
def accept_file(li, n): """ Check if the file is of supported format @param li: a file-like object which can be used to access the input data @param n : format number. The function will be called with incrementing number until it returns zero @return: 0 - no more supported formats string "name" - format name to display in the chooser dialog dictionary { 'format': "name", 'options': integer } options: should be 1, possibly ORed with ACCEPT_FIRST (0x8000) to indicate preferred format """ # we support only one format per file if n > 0: return 0 while True: s = gets(li) if s == None: break s = s.strip() if len(s) == 0 or s.startswith("#") or s.startswith(".*: ") or s.startswith(" "): continue if s.startswith("Disassembly of "): idaapi.set_processor_type("arm", SETPROC_ALL|SETPROC_FATAL) return FormatName else: break # unrecognized format return 0
def load_file(li, neflags, format): if format != "NeoGeo 68k loader": return 0 idaapi.set_processor_type("68000", SETPROC_ALL | SETPROC_FATAL) idaapi.add_segm(0, 0x000000, 0x0FFFFF, "ROM", "CODE") idaapi.add_segm(0, 0x100000, 0x10F2FF, "WRAM", "DATA") idaapi.add_segm(0, 0x10F300, 0x10FFFF, "BIOSRAM", "DATA") idaapi.add_segm(0, 0x200000, 0x2FFFFF, "PORT", "DATA") idaapi.add_segm(0, 0x300000, 0x3FFFFF, "IO", "DATA") idaapi.add_segm(0, 0x400000, 0x401FFF, "PALETTES", "DATA") idaapi.add_segm(0, 0x800000, 0xBFFFFF, "MEMCARD", "DATA") idaapi.add_segm(0, 0xC00000, 0xC1FFFF, "SYSROM", "DATA") idaapi.add_segm(0, 0xD00000, 0xD0FFFF, "BRAM", "DATA") li.seek(0, 2) size = li.tell() li.seek(0) file_data = li.read(size) idaapi.mem2base(file_data, 0, 0x100000) name_long(0x000000, "InitSP") name_long(0x000004, "InitPC") idaapi.do_unknown(0x3C0000, 1) idaapi.doByte(0x3C0000, 1) idaapi.set_name(0x3C0000, "REG_VRAMADDR") #idaapi.set_cmt(0x3C0000, "Pouet.", 1) return 1
def load_file(li, neflags, format): cpu_set = False sz = li.seek(0, 2) li.seek(0) f = li.read(sz) offset = 0 fpt = MeFptTable(f, offset) manifs = [] for p in fpt.parts: if p.ptype() == PT_CODE: poff = offset + p.Offset manif = get_struct(f, poff, MeManifestHeader) manif.parse_mods(f, poff) if not cpu_set: cpuname = manif.cpu if cpuname == "ARCompact": cpuname = "arcmpct" elif cpuname == "SPARC": cpuname = "sparcb" idaapi.set_processor_type(cpuname, idaapi.SETPROC_ALL|idaapi.SETPROC_FATAL) cpu_set = True for idx, mod in enumerate(manif.modules): data, ext = manif._get_mod_data(f, poff+offset, idx) if ext == "huff": data = "" load_mod(mod, data) SetShortPrm(INF_AF2, GetShortPrm(INF_AF2) & ~(AF2_FTAIL|AF2_ANORET)) return 1
def accept_file(li, n): """ Check if the file is of supported format @param li: a file-like object which can be used to access the input data @param n : format number. The function will be called with incrementing number until it returns zero @return: 0 - no more supported formats string "name" - format name to display in the chooser dialog dictionary { 'format': "name", 'options': integer } options: should be 1, possibly ORed with ACCEPT_FIRST (0x8000) to indicate preferred format """ # we support only one format per file if n > 0: return 0 while True: s = gets(li) if s == None: break s = s.strip() if len(s) == 0 or s.startswith("#") or s.startswith(".*: ") or s.startswith(" "): continue if s.startswith("Disassembly of "): idaapi.set_processor_type("arm", SETPROC_ALL|SETPROC_FATAL) return FormatName else: break # unrecognized format return 0
def load_file(li, neflags, format): """ Load the file into database @param li: a file-like object which can be used to access the input data @param neflags: options selected by the user, see loader.hpp @return: 0-failure, 1-ok """ if format == RomFormatName: jump = dwordAt(li, 0) if jump & 0xFF000000 == 0xEA000000: # looks like an ARM branch? idaapi.set_processor_type("arm", SETPROC_ALL | SETPROC_FATAL) li.seek(0, idaapi.SEEK_END) size = li.tell() #next dword after signature is a pointer to ROMHDR romhdr = dwordAt(li, ROM_SIGNATURE_OFFSET + 4) # let's try to find such imagebase that potential ROMHDR's "physfirst" value matches it imgbase = (romhdr - size) & ~0xfff bases = [] maxbase = 0 while imgbase < romhdr + 8: physfirst = dwordAt(li, romhdr - imgbase + 8) if physfirst == imgbase: bases.append(imgbase) imgbase += 0x1000 if len(bases) == 1: start = bases[0] elif len(bases) > 1: print "Warning: several potential imagebases detemined: " + ", ".join( "%08X" % i for i in bases) start = bases[-1] else: Warning("Unable to determine load image base.") start = 0x80000000 print "Using imagebase %08X" % start physlast = dwordAt(li, romhdr - start + 12) if physlast <= start: Warning("Internal error") return 0 size = physlast - start AddSeg(start, start + size, 0, 1, idaapi.saRelPara, idaapi.scPub) # copy bytes to the database li.seek(0) li.file2base(0, start, start + size, 0) idaapi.add_entry(start, start, "start", 1) print "Load OK" return 1 Warning("Unknown format name: '%s'" % format) return 0
def load_file_sbl(li, neflags, format): # set the processor type and enable 'metaarm' so ida disassembles all instructions idaapi.set_processor_type("arm:ARMv7-A&R", idaapi.SETPROC_ALL | idaapi.SETPROC_FATAL) idc.ChangeConfig('ARM_DEFAULT_ARCHITECTURE = metaarm') # rewind the input file and read its contents li.seek(0) init_val = li.read(li.size()) # Load the file data (sans header) into IDA rom = SblImage(init_val) AddSeg(rom.header.image_dest_ptr, rom.header.image_dest_ptr + rom.header.image_size, 0, 1, idaapi.saRelPara, idaapi.scPub) SetSegmentType(rom.header.image_dest_ptr, idaapi.SEG_CODE) RenameSeg(rom.header.image_dest_ptr, "CODE") # li.file2base(file_offset, seg1, seg1 + code_seg_size, 0) # Load the file data (sans header) into IDA li.file2base(80, rom.header.image_dest_ptr, rom.header.image_dest_ptr + rom.header.code_size, 0) # Define the .text .data and .bss segments #AddSegEx(0, rom.header.image_dest_ptr, rom.header.image_dest_ptr + rom.header.code_size, s, ".code", "CODE", ADDSEG_OR_DIE) # AddSegment(0, data_start, data_end, ".data", "DATA") # AddSegment(0, data_end, bss_end, ".bss", "BSS") image_base = rom.header.image_dest_ptr entry = rom.header.image_src #if DEBUG: # print "Created File Segments: " # print "\t.text 0x%.8X - 0x%.8X" % (entry, data_start) # print "\t.data 0x%.8X - 0x%.8X" % (data_start, data_end) # print "\t.bss 0x%.8X - 0x%.8X" % (data_end, bss_end) # mark the entry point as being the first byte of the loaded image idaapi.add_entry(rom.header.image_dest_ptr, rom.header.image_dest_ptr, "HEADER", 1) AddIdbComment(image_base, 'Codeword: ', rom.header.codeword) AddIdbComment(image_base, 'Magic No.: ', rom.header.magic) AddIdbComment(image_base, 'Source Location: ', rom.header.image_src) AddIdbComment(image_base, 'Destination Address: ', rom.header.image_dest_ptr) AddIdbComment(image_base, 'Image Size: ', rom.header.image_size) AddIdbComment(image_base, 'Code Size: ', rom.header.code_size) AddIdbComment(image_base, 'Signature Ptr: ', rom.header.sig_ptr) AddIdbComment(image_base, 'Signature Size: ', rom.header.sig_size) AddIdbComment(image_base, 'Cert Chain Ptr: ', rom.header.cert_chain_ptr) AddIdbComment(image_base, 'Cert Chain Size: ', rom.header.cert_chain_size) AddIdbComment(image_base, 'OEM Cert Sel: ', rom.header.oem_root_cert_sel) AddIdbComment(image_base, 'OEM Cert Num: ', rom.header.oem_num_root_certs) 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 == RomFormatName: jump = dwordAt(li, 0) if jump & 0xFF000000 == 0xEA000000: # looks like an ARM branch? idaapi.set_processor_type("arm", SETPROC_ALL|SETPROC_FATAL) li.seek(0, idaapi.SEEK_END) size = li.tell() #next dword after signature is a pointer to ROMHDR romhdr = dwordAt(li, ROM_SIGNATURE_OFFSET + 4) # let's try to find such imagebase that potential ROMHDR's "physfirst" value matches it imgbase = (romhdr-size) & ~0xfff bases = [] maxbase = 0 while imgbase < romhdr+8: physfirst = dwordAt(li, romhdr - imgbase + 8) if physfirst == imgbase: bases.append(imgbase) imgbase += 0x1000 if len(bases) == 1: start = bases[0] elif len(bases) > 1: print "Warning: several potential imagebases detemined: " + ", ".join("%08X"%i for i in bases) start = bases[-1] else: Warning("Unable to determine load image base.") start = 0x80000000 print "Using imagebase %08X" % start physlast = dwordAt(li, romhdr - start + 12) if physlast <= start: Warning("Internal error") return 0 size = physlast - start AddSeg(start, start+size, 0, 1, idaapi.saRelPara, idaapi.scPub) # copy bytes to the database li.seek(0) li.file2base(0, start, start+size, 0) idaapi.add_entry(start, start, "start", 1) print "Load OK" return 1 Warning("Unknown format name: '%s'" % format) return 0
def set_processor_type(type): if type == ProcessorType.ARM32: idaapi.set_processor_type('ARM:ARMv7-A', idaapi.SETPROC_LOADER_NON_FATAL) idaapi.get_inf_structure().lflags |= idaapi.LFLG_PC_FLAT elif type == ProcessorType.ARM64: idaapi.set_processor_type("arm", idaapi.SETPROC_LOADER_NON_FATAL) idaapi.get_inf_structure().lflags |= idaapi.LFLG_64BIT
def load_file(li, neflags, format): # set the processor type and enable 'metaarm' so ida disassembles all instructions idaapi.set_processor_type('arm', idaapi.SETPROC_ALL | idaapi.SETPROC_FATAL) idc.ChangeConfig('ARM_DEFAULT_ARCHITECTURE = metaarm') # rewind the input file and read its contents li.seek(0) rom_data = li.read(li.size()) # for some reason this doesnt work, so we end up with this #rom_name = li.filename().split('.')[0] rom_name = '' while rom_name == '': rom_name = AskStr('', "Enter the input file's basename:") if rom_name is None: rom_name = 'rom' while True: rom_name = os.path.basename(rom_name).split('.')[0] # read the rom, letting exceptions fall through to ida's exception handler rom = MbnRom(rom_data) # for convenience image_base = rom.header.image_virtual_address # create the segments AddSegment('%s_code' % rom_name, rom.code_base, rom.code_data) if rom.sig_data is not None: AddSegment('%s_sig' % rom_name, rom.sig_base, rom.sig_data) if rom.cert_data is not None: AddSegment('%s_cert' % rom_name, rom.cert_base, rom.cert_data) if rom.tail_data is not None: AddSegment('%s_tail' % rom_name, rom.tail_base, rom.tail_data) if rom.overlay_data is not None: AddSegment('%s_overlay' % rom_name, rom.overlay_base, rom.overlay_data) # mark the entry point as being the first byte of the loaded image idaapi.add_entry(rom.code_base, rom.code_base, '%s_start' % rom_name, 1) # make some comments for usability AddIdbComment(image_base, 'ROM: %s' % rom_name) AddIdbComment(image_base, '') AddIdbComment(image_base, 'Load Index', rom.header.load_index) AddIdbComment(image_base, 'Flash Partition Version', rom.header.flash_partition_version) AddIdbComment(image_base, 'Image File Offset', rom.header.image_offset + MbnHeader.SBL_HEADER_SIZE) AddIdbComment(image_base, 'Image VA', rom.header.image_virtual_address) AddIdbComment(image_base, 'Image Size', rom.header.image_size) AddIdbComment(image_base, 'Code VA', rom.header.code_size) AddIdbComment(image_base, 'Signature VA', rom.header.signature_virtual_address) AddIdbComment(image_base, 'Signature Size', rom.header.signature_size) AddIdbComment(image_base, 'Cert Chain VA', rom.header.cert_chain_virtual_address) AddIdbComment(image_base, 'Cert Chain Size', rom.header.cert_chain_size) # give the opportunity to keep loading mbn files into the address space rom_name = AskFile(0, '*.mbn', 'Choose the next ROM filename to load, or click Cancel to continue') if rom_name is None: break else: rom_data = open(rom_name, 'rb').read() return 1
def load_file(li, neflags, format): # Select the PC processor module idaapi.set_processor_type("EVM", SETPROC_ALL | SETPROC_FATAL) # TODO: detect and emulate contract creation code li.seek(0) buf = li.read(li.size()) if not buf: return 0 if buf[0:2] == '0x': print "Detected hex" new_buf = buf[2:].strip().rstrip() buf_set = set() for c in new_buf: buf_set.update(c) hex_set = set(list('0123456789abcdef')) if buf_set <= hex_set: # subset print "Replacing original buffer with hex decoded version" buf = new_buf.decode('hex') # Load all shellcode into different segments start = 0x0 seg = idaapi.segment_t() size = len(buf) end = start + size # Create the segment seg.startEA = start seg.endEA = end seg.bitness = 1 # 32-bit idaapi.add_segm_ex(seg, "evm", "CODE", 0) # TODO: make segments for stack, memory, storage # Copy the bytes idaapi.mem2base(buf, start, end) # check for swarm hash and make it data instead of code swarm_hash_address = buf.find('ebzzr0') if swarm_hash_address != -1: print "Swarm hash detected, making it data" for i in range(swarm_hash_address - 1, swarm_hash_address + 42): MakeByte(i) ida_bytes.set_cmt(swarm_hash_address - 1, "swarm hash", True) # add entry point idaapi.add_entry(start, start, "start", 1) # add comment to beginning of disassembly idaapi.describe(start, True, "EVM bytecode disassembly") # Mark for analysis AutoMark(start, AU_CODE) #setup_enums() return 1
def load_file(f, neflags, format): idaapi.set_processor_type("arm:armv8", idaapi.SETPROC_LOADER) f.seek(-0x20, os.SEEK_END) nseg, = struct.unpack("<12xI16x", f.read(0x20)) print(f"Number of segments: {nseg}") for sno in range(nseg): f.seek(-0x20-0x20*(nseg-sno), os.SEEK_END) mem_addr, file_addr, size, name = struct.unpack("<QII8x8s", f.read(0x20)) name, _, _ = name.partition(b'\0') name = name.decode() print(f"Segment {sno}: {name} at mem={hex(mem_addr)} file={hex(file_addr)} size={hex(size)}") ida_seg_type = None if name == "__TEXT": ida_seg_type = "CODE" if name == "__DATA": ida_seg_type = "DATA" idaapi.add_segm(0, mem_addr, mem_addr + size, name, ida_seg_type) f.file2base(file_addr, mem_addr, mem_addr + size, True) f.seek(-0x20-0x20*nseg, os.SEEK_END) footer_start = f.tell() footer_end = footer_start + 0x20 + 0x20 * nseg idaapi.add_segm(0, footer_start, footer_end, "__FOOTER", "DATA") f.file2base(footer_start, footer_start, footer_end, True) header_start = footer_start + 0x20 * nseg idaapi.add_extra_line(header_start, True, "") idaapi.add_extra_cmt(header_start, True, f"File Header") idaapi.create_strlit(header_start, 4, 0) idaapi.set_cmt(header_start, "Magic", False) idaapi.create_dword(header_start + 4, 4) idaapi.set_cmt(header_start + 4, "Version?", False) idaapi.create_dword(header_start + 8, 4) idaapi.set_cmt(header_start + 8, "File length minus headers", False) idaapi.create_dword(header_start + 12, 4) idaapi.set_cmt(header_start + 12, "Section count", False) for sno in range(nseg): header_start = footer_start + 0x20 * sno idaapi.add_extra_line(header_start, True, "") idaapi.add_extra_cmt(header_start, True, f"Segment {sno + 1}") idaapi.create_qword(header_start, 8) idaapi.set_cmt(header_start, "Memory Address", False) idaapi.create_dword(header_start + 8, 4) idaapi.set_cmt(header_start + 8, "File Offset", False) idaapi.create_dword(header_start + 12, 4) idaapi.create_qword(header_start + 16, 8) idaapi.set_cmt(header_start + 12, "Segment Length", False) idaapi.create_strlit(header_start + 24, 8, 0) idaapi.set_cmt(header_start + 24, "Segment Name", False) idaapi.add_entry(0, 0, "start", 1) return 1
def load_file(li, neflags, fmt): idaapi.set_processor_type('rl78', idaapi.SETPROC_ALL | idaapi.SETPROC_FATAL) f = FupdFile(li) if f.magic != MAGIC_PATCH: make_seg(0xf0000, 0x10000) for desc, block in f.iter_blocks(): make_seg(desc.flash_addr, desc.size) idaapi.put_many_bytes(desc.flash_addr, block) return 1
def go(self): print "0) Building NID cache..." self.load_nids() # Vita is ARM idaapi.set_processor_type("arm", idaapi.SETPROC_ALL | idaapi.SETPROC_FATAL) print "1) Loading ELF segments" self.fin.seek(0) header = ELFHeader(self.fin.read(0x34)) self.fin.seek(header.e_phoff) phdrs = [ ELFphdr(self.fin.read(header.e_phentsize)) for _ in xrange(header.e_phnum) ] for phdr in phdrs: if phdr.p_type == p_type.PT_LOAD: idaapi.add_segm(0, phdr.p_vaddr, phdr.p_vaddr + phdr.p_memsz, ".text" if phdr.x else ".data", "CODE" if phdr.x else "DATA") self.fin.file2base(phdr.p_offset, phdr.p_vaddr, phdr.p_vaddr + phdr.p_filesz, 1) self.seg0_off = phdrs[0].p_offset self.seg0_va = phdrs[0].p_vaddr self.fin.seek(self.seg0_off + header.e_entry) modinfo = Modinfo(self.fin.read(0x34)) print "2) Doing noreturn functions first" self.parse_impexp(modinfo.export_top, modinfo.export_end, Modexport, self.cb_noret) self.parse_impexp(modinfo.import_top, modinfo.import_end, Modimport, self.cb_noret) print "3) Parsing export tables" self.parse_impexp(modinfo.export_top, modinfo.export_end, Modexport, self.cb_exp) print "4) Parsing import tables" self.parse_impexp(modinfo.import_top, modinfo.import_end, Modimport, self.cb_imp) print "5) Waiting for IDA to analyze the program" idc.Wait() print "6) Analyzing system instructions" from highlight_arm_system_insn import run_script run_script() print "6) Adding MOVT/MOVW pair xrefs" add_xrefs()
def load_file(li, neflags, format): if format == CRO_FORMAT_NAME: idaapi.set_processor_type("arm", SETPROC_ALL | SETPROC_FATAL) load_cro(li, False) print "Load OK" return 1 return 0
def load_file(li, neflags, format): if format == CRO_FORMAT_NAME: idaapi.set_processor_type("arm", SETPROC_ALL|SETPROC_FATAL) load_cro(li, False) print "Load OK" return 1 return 0
def load_file(li, neflags, format): # pydevd_pycharm.settrace('localhost', port=1234, stdoutToServer=True, stderrToServer=True) fname = idaapi.get_input_file_path() psx = PsxExe(os.path.basename(fname), ONLY_FIRST, MIN_ENTROPY) psx.parse(li, True) idaapi.set_processor_type('mipsl', ida_idp.SETPROC_LOADER) idaapi.cvar.inf.af = \ idaapi.AF_CODE | idaapi.AF_JUMPTBL | idaapi.AF_USED | idaapi.AF_UNK | idaapi.AF_PROC | idaapi.AF_STKARG | \ idaapi.AF_REGARG | idaapi.AF_TRACE | idaapi.AF_VERSP | idaapi.AF_ANORET | idaapi.AF_MEMFUNC | \ idaapi.AF_TRFUNC | idaapi.AF_FIXUP | idaapi.AF_JFUNC | idaapi.AF_IMMOFF | idaapi.AF_STRLIT | \ idaapi.AF_MARKCODE | idaapi.AF_LVAR | idaapi.AF_PROCPTR | idaapi.AF_FLIRT psx.create_segments(li) im = idaapi.compiler_info_t() idaapi.inf_get_cc(im) im.id = idaapi.COMP_GNU im.cm = idaapi.CM_N32_F48 | idaapi.CM_M_NN | idaapi.CM_CC_CDECL im.defalign = 4 im.size_i = 4 im.size_b = 1 im.size_e = 4 im.size_s = 2 im.size_l = 4 im.size_ll = 8 im.size_ldbl = 8 idaapi.inf_set_cc(im) # Replace predefined macros and included directories by id # from IDA.CFG (see 'CC_PARMS' in Built-in C parser parameters) idaapi.set_c_macros(ida_idp.cfg_get_cc_predefined_macros(im.id)) idaapi.set_c_header_path(ida_idp.cfg_get_cc_header_path(im.id)) # Resetting new settings :) idc.set_inf_attr(idc.INF_COMPILER, im.id) idc.process_config_line("MIPS_DEFAULT_ABI=o32") detect = DetectPsyQ(psx.get_exe_name(), ONLY_FIRST, MIN_ENTROPY) version = detect.get_psyq_version(psx.rom_addr, psx.rom_addr + psx.rom_size) if len(version) > 0: psx.apply_psyq_signatures_by_version(version) idaapi.add_entry(psx.init_pc, psx.init_pc, 'start', 1) PsxExe.apply_til(version) psx.update_gp() return 1
def load_file(li, neflags, format): if format != ROM_FORMAT_NAME: Warning("Unknown format name: '%s'" % format) return 0 jump = dwordAt(li, 0) idaapi.set_processor_type("gb", SETPROC_ALL|SETPROC_FATAL) li.seek(0, idaapi.SEEK_END) size = li.tell() # ROM0 idc.AddSeg(ROM0_START, ROM0_START + ROM0_SIZE, 0, 0, idaapi.saRelPara, idaapi.scPub) idc.RenameSeg(ROM0_START, "ROM0") idc.SetSegmentType(ROM0_START, idc.SEG_CODE) li.seek(0) li.file2base(0, ROM0_START, ROM0_START + ROM0_SIZE, 0) # ROM1 idc.AddSeg(ROM1_START, ROM1_START + ROM1_SIZE, 0, 0, idaapi.saRelPara, idaapi.scPub) idc.RenameSeg(ROM1_START, "ROM1") idc.SetSegmentType(ROM1_START, idc.SEG_CODE) # VRAM idc.AddSeg(VRAM_START, VRAM_START + VRAM_SIZE, 0, 0, idaapi.saRelPara, idaapi.scPub) idc.RenameSeg(VRAM_START, "VRAM") # RAM1 idc.AddSeg(RAM1_START, RAM1_START + RAM1_SIZE, 0, 0, idaapi.saRelPara, idaapi.scPub) idc.RenameSeg(RAM1_START, "RAM1") # RAM0 idc.AddSeg(RAM0_START, RAM0_START + RAM0_SIZE, 0, 0, idaapi.saRelPara, idaapi.scPub) idc.RenameSeg(RAM0_START, "RAM0") # ECHO idc.AddSeg(ECHO_START, ECHO_START + ECHO_SIZE, 0, 0, idaapi.saRelPara, idaapi.scPub) idc.RenameSeg(ECHO_START, "ECHO") # OAM idc.AddSeg(OAM_START, OAM_START + OAM_SIZE, 0, 0, idaapi.saRelPara, idaapi.scPub) idc.RenameSeg(OAM_START, "OAM") # IO idc.AddSeg(IO_START, IO_START + IO_SIZE, 0, 0, idaapi.saRelPara, idaapi.scPub) idc.RenameSeg(IO_START, "IO") # HRAM idc.AddSeg(HRAM_START, HRAM_START + HRAM_SIZE, 0, 0, idaapi.saRelPara, idaapi.scPub) idc.RenameSeg(HRAM_START, "HRAM") header_info(li) naming() print("[+] Load OK") return 1
def load_file(li, neflags, format): chunksize = 0x10000 base = 0xF000 start = base << 4 size = li.size() if (size & 0xFFF) != 0: size &= ~0xFFFF offs = size - chunksize idaapi.set_processor_type("metapc", idaapi.SETPROC_ALL | idaapi.SETPROC_FATAL) if size < chunksize: offs = 0 start += (chunksize - size) chunksize = size # make E and F segments for real-mode part myAddSeg(start, start + chunksize, base, 0, "BIOS_F", "CODE") li.file2base(offs, start, start + chunksize, 1) if offs > 0 and base > 0xE000: base -= 0x1000 start -= chunksize offs -= chunksize myAddSeg(start, start + chunksize, base, 0, "BIOS_%X" % (base >> 12), "CODE") li.file2base(offs, start, start + chunksize, 1) # set default ds to point to the current segment SetSegDefReg(start, "ds", base) if offs > 0: # file is bigger than 128KB # make a flat 32-bit segment for the flash alias area start = (-size) & 0xFFFFFFFF # place it so that it ends at 4GB chunksize = size if not __EA64__: chunksize -= 2 # truncate last two bytes to avoid address space overlap # map the whole file offs = 0 base = 0 myAddSeg(start, start + chunksize, base, 1, "BIOS_FLASH", "CODE") li.file2base(offs, start, start + chunksize, 1) # set the entry registers to F000:FFF0 SetLongPrm(INF_START_IP, 0xFFF0) SetLongPrm(INF_START_CS, 0xF000) # turn off "Convert 32bit instruction operand to offset", too many false positives in high areas SetShortPrm(INF_START_AF, GetShortPrm(INF_START_AF) & ~AF_IMMOFF) # turn off "Create function tails" SetShortPrm(INF_AF2, GetShortPrm(INF_AF2) & ~AF2_FTAIL) return 1
def load_file(li, neflags, fmt): # Assume BCM20734 == cortex-m3 idaapi.set_processor_type('arm:armv7-m', idaapi.SETPROC_ALL | idaapi.SETPROC_FATAL) parser = FwParser(li) fw_index = parser.active_fw if len(parser.fw) > 1: msg = ['SPI dump has more than one PatchRAM image.\n\nEnter the index of the one to load:'] for i in range(len(parser.fw)): if parser.fw_present(i): msg.append('%i @ 0x%08x %s' % (i, parser.fw_offsets[i], '[active]' if i == parser.active_fw else '')) fw_index = ida_kernwin.asklong(parser.active_fw, '\n'.join(msg)) # Create known memory regions make_seg([0x0, 0xC8000], 1) make_seg([0x260000, 0x26C000], 1) make_seg([0xD0000, 0xE0000]) make_seg([0x200000, 0x248000]) load_bin_file(0x0, "Choose ROM 1 (@0x000000)") load_bin_file(0x260000, "Choose ROM 2 (@0x260000)") load_bin_file(0xD0000, "Choose RAM_LO (@0x0D0000)") load_bin_file(0x200000, "Choose RAM_HI (@0x200000)") # The PatchRAM changes will show up as patched bytes load_rampatch = 0 if ram_loaded == 0: load_rampatch = ida_kernwin.askbuttons_c('Yes', 'No', 'Not sure', 1,'Do you want to patch ROM 1 and RAM regions with the provided PatchRAM?\n\n') if load_rampatch == 1: print('Patching ROM1, RAM_LO and RAM_HI:') parser.process({0x08 : lambda r: idaapi.patch_many_bytes(r.addr, r.data), 0x0a : lambda r: idaapi.patch_many_bytes(r.addr, r.data)}, fw_index) print('ROM 1, RAM_LO and RAM_HI regions were patched.') elif ram_loaded == 1: print('Patching ROM1:') parser.process({0x08 : lambda r: idaapi.patch_many_bytes(r.addr, r.data)}, fw_index) print('Only one RAM region loaded. ROM 1 was patched.') elif ram_loaded == 2: load_rampatch = ida_kernwin.askbuttons_c('Yes', 'No', 'Not sure', 0,'RAM_LO and RAM_HI were loaded.\n\nDo you want to patch them with the provided PatchRAM?\n\n') if load_rampatch == -1 or load_rampatch == 0: print('Patching ROM1:') parser.process({0x08 : lambda r: idaapi.patch_many_bytes(r.addr, r.data)}, fw_index) print('RAM_LO and RAM_HI loaded. ROM 1 was patched.') elif load_rampatch == 1: print('Patching ROM1, RAM_LO and RAM_HI:') parser.process({0x08 : lambda r: idaapi.patch_many_bytes(r.addr, r.data), 0x0a : lambda r: idaapi.patch_many_bytes(r.addr, r.data)}, fw_index) print('RAM_LO and RAM_HI loaded. ROM 1 and both RAM regions were patched.') # Code is THUMB only idc.SetReg(0x0, 't', 1) return 1
def load_file(li, neflags, format): if format != MBNImageFormatName and format != SBLImageFormatName: Warning("Unknown format name: '%s'" % format) return 0 idaapi.set_processor_type("arm:ARMv7-A&R", SETPROC_ALL | SETPROC_FATAL) if format == SBLImageFormatName: return load_file_sbl(li) elif format == MBNImageFormatName: return load_file_mbn(li) return 0
def load_file_sbl(li, neflags, format): # set the processor type and enable 'metaarm' so ida disassembles all instructions idaapi.set_processor_type("arm:ARMv7-A&R", idaapi.SETPROC_ALL | idaapi.SETPROC_FATAL) idc.ChangeConfig('ARM_DEFAULT_ARCHITECTURE = metaarm') # rewind the input file and read its contents li.seek(0) init_val = li.read(li.size()) # Load the file data (sans header) into IDA rom = SblImage(init_val) AddSeg(rom.header.image_dest_ptr, rom.header.image_dest_ptr + rom.header.image_size, 0, 1, idaapi.saRelPara, idaapi.scPub) SetSegmentType(rom.header.image_dest_ptr, idaapi.SEG_CODE) RenameSeg(rom.header.image_dest_ptr, "CODE") # li.file2base(file_offset, seg1, seg1 + code_seg_size, 0) # Load the file data (sans header) into IDA li.file2base(80, rom.header.image_dest_ptr, rom.header.image_dest_ptr + rom.header.code_size, 0) # Define the .text .data and .bss segments #AddSegEx(0, rom.header.image_dest_ptr, rom.header.image_dest_ptr + rom.header.code_size, s, ".code", "CODE", ADDSEG_OR_DIE) # AddSegment(0, data_start, data_end, ".data", "DATA") # AddSegment(0, data_end, bss_end, ".bss", "BSS") image_base = rom.header.image_dest_ptr entry = rom.header.image_src #if DEBUG: # print "Created File Segments: " # print "\t.text 0x%.8X - 0x%.8X" % (entry, data_start) # print "\t.data 0x%.8X - 0x%.8X" % (data_start, data_end) # print "\t.bss 0x%.8X - 0x%.8X" % (data_end, bss_end) # mark the entry point as being the first byte of the loaded image idaapi.add_entry(rom.header.image_dest_ptr, rom.header.image_dest_ptr, "HEADER", 1) AddIdbComment(image_base, 'Codeword: ', rom.header.codeword) AddIdbComment(image_base, 'Magic No.: ', rom.header.magic) AddIdbComment(image_base, 'Source Location: ', rom.header.image_src) AddIdbComment(image_base, 'Destination Address: ', rom.header.image_dest_ptr) AddIdbComment(image_base, 'Image Size: ', rom.header.image_size) AddIdbComment(image_base, 'Code Size: ', rom.header.code_size) AddIdbComment(image_base, 'Signature Ptr: ', rom.header.sig_ptr) AddIdbComment(image_base, 'Signature Size: ', rom.header.sig_size) AddIdbComment(image_base, 'Cert Chain Ptr: ', rom.header.cert_chain_ptr) AddIdbComment(image_base, 'Cert Chain Size: ', rom.header.cert_chain_size) AddIdbComment(image_base, 'OEM Cert Sel: ', rom.header.oem_root_cert_sel) AddIdbComment(image_base, 'OEM Cert Num: ', rom.header.oem_num_root_certs) return 1
def load_file(li, neflags, format): chunksize = 0x10000 base = 0xF000 start = base << 4 size = li.size() if (size & 0xFFF) != 0: size &= ~0xFFFF offs = size - chunksize idaapi.set_processor_type("metapc", idaapi.SETPROC_ALL | idaapi.SETPROC_FATAL) if size < chunksize: offs = 0 start += chunksize - size chunksize = size # make E and F segments for real-mode part myAddSeg(start, start + chunksize, base, 0, "BIOS_F", "CODE") li.file2base(offs, start, start + chunksize, 1) if offs > 0 and base > 0xE000: base -= 0x1000 start -= chunksize offs -= chunksize myAddSeg(start, start + chunksize, base, 0, "BIOS_%X" % (base >> 12), "CODE") li.file2base(offs, start, start + chunksize, 1) # set default ds to point to the current segment SetSegDefReg(start, "ds", base) if offs > 0: # file is bigger than 128KB # make a flat 32-bit segment for the flash alias area start = (-size) & 0xFFFFFFFF # place it so that it ends at 4GB chunksize = size if not __EA64__: chunksize -= 2 # truncate last two bytes to avoid address space overlap # map the whole file offs = 0 base = 0 myAddSeg(start, start + chunksize, base, 1, "BIOS_FLASH", "CODE") li.file2base(offs, start, start + chunksize, 1) # set the entry registers to F000:FFF0 SetLongPrm(INF_START_IP, 0xFFF0) SetLongPrm(INF_START_CS, 0xF000) # turn off "Convert 32bit instruction operand to offset", too many false positives in high areas SetShortPrm(INF_START_AF, GetShortPrm(INF_START_AF) & ~AF_IMMOFF) # turn off "Create function tails" SetShortPrm(INF_AF2, GetShortPrm(INF_AF2) & ~AF2_FTAIL) return 1
def load_file(li, neflags, format): if format != MBNImageFormatName and format != SBLImageFormatName: Warning("Unknown format name: '%s'" % format) return 0 idaapi.set_processor_type("arm:ARMv7-A&R", SETPROC_ALL|SETPROC_FATAL) if format == SBLImageFormatName: return load_file_sbl(li) elif format == MBNImageFormatName: return load_file_mbn(li) return 0
def load_file(li, neflags, format): """ Load the file into database @param li: a file-like object which can be used to access the input data @param neflags: options selected by the user, see loader.hpp @return: 0-failure, 1-ok """ if format.startswith(RomFormatName): li.seek(0) header = read_struct(li, image_header) c = header.ih_arch cname = IDACPUNames[c] if cname == "": warning("Unsupported CPU") return if not header.ih_comp in (IH_COMP_NONE, IH_COMP_GZIP): warning("Can only handle uncompressed or gzip-compressed images") return idaapi.set_processor_type(cname, SETPROC_LOADER) AddSeg(header.ih_load, header.ih_load + header.ih_size, 0, 1, idaapi.saRelPara, idaapi.scPub) # copy bytes to the database if header.ih_comp == IH_COMP_NONE: li.file2base(ctypes.sizeof(header), header.ih_load, header.ih_load + header.ih_size, 0) else: cdata = li.read(header.ih_size) d = zlib.decompressobj(zlib.MAX_WBITS | 32) udata = d.decompress(cdata) udata += d.flush() # expand segment to fit uncompressed data set_segment_bounds(header.ih_load, header.ih_load, header.ih_load + len(udata), SEGMOD_KEEP) idaapi.put_bytes(header.ih_load, udata) if cname == "ARM" and (header.ih_ep & 1) != 0: # Thumb entry point header.ih_ep -= 1 split_sreg_range(header.ih_ep, "T", 1) idaapi.add_entry(header.ih_ep, header.ih_ep, "start", 1) print "Load OK" return 1
def load_file(li, neflags, format): """ Load the SEGA Master System ROM :param li: Loader input :param neflags: :param format: :return: 1 on success, otherwise 0 """ idaapi.set_processor_type('z80', idaapi.SETPROC_LOADER) is_reload = (neflags & idaapi.NEF_RELOAD) != 0 if is_reload: return 1 # Create ROM segment rom_seg = idaapi.segment_t() rom_seg.start_ea = 0x0000 rom_seg.end_ea = 0xbfff rom_seg.bitness = 0 idaapi.add_segm_ex(rom_seg, 'ROM', 'CODE', idaapi.ADDSEG_OR_DIE) # Read file into ROM segment li.seek(0) li.file2base(0, 0, li.size(), False) # Create RAM Segment ram_seg = idaapi.segment_t() ram_seg.start_ea = 0xc000 ram_seg.end_ea = 0xdfff ram_seg.bitness = 0 idaapi.add_segm_ex(ram_seg, 'RAM', 'DATA', idaapi.ADDSEG_OR_DIE) # Create RAM mirror segment ram_mirror_seg = idaapi.segment_t() ram_mirror_seg.start_ea = 0xe000 ram_mirror_seg.end_ea = 0xffff ram_mirror_seg.bitness = 0 idaapi.add_segm_ex(ram_mirror_seg, 'RAM_MIRROR', 'DATA', idaapi.ADDSEG_OR_DIE) # Define the I/O ports create_io_ports() # Disassemble reset vectors create_reset_vectors() # Specify entry idaapi.add_entry(0x0000, 0x0000, 'RST0', 1) 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 """ # Select the PC processor module idaapi.set_processor_type("metapc", ida_idp.SETPROC_LOADER) # read MBR into buffer li.seek(0, os.SEEK_SET) buf = li.read(li.size()) seg = idaapi.segment_t() start = 0x7C00 size = len(buf) end = start + size # Create the segment seg.start_ea = start seg.end_ea = end seg.bitness = 0 # 16-bit idaapi.add_segm_ex(seg, "seg0", "CODE", 0) # Copy the bytes idaapi.mem2base(buf, start, end) # add entry point idaapi.add_entry(start, start, "start", 1) strid = add_struct_def() idaapi.set_name(start + 0x1BE, "MBR_PARTITION_TABLE", idaapi.SN_CHECK) str_size = idaapi.get_struc_size(strid) idaapi.create_struct(start + 0x1BE, str_size, strid) idaapi.set_name(510, "MBR_SIGN", idaapi.SN_CHECK) # Mark for analysis AutoMark(start, AU_CODE) load_debugger("bochs", 0) return 1
def load_file(f, neflags, format): idaapi.set_processor_type('yara', idaapi.SETPROC_ALL) f.seek(0x0, os.SEEK_END) flen = f.tell() f.seek(0) hdr = parse_hdr(f) file_hdr = parse_file_hdr(f) # mark the proc type, so IDA can invoke the correct disassembler/processor. mapsize = hdr.size # map 0..mapsize from file at offset 0xc into idb (without relocation data) # this makes all pointers relative offsets to this mapping's start f.file2base(0xc, 0, flen - 0x0c, True) # true makes it patchable f.seek(hdr.size + 0x0c) code_end = find_code_end(file_hdr) or hdr.size # list head shoule come right after (except some CC paddings. weirdly t4.yara compiles some extra garbage between the code and rules_list_head) # note specifying CODE since it will force decoding of data that's in the section for padding idaapi.add_segm(0, file_hdr.code_start, code_end, ".text", "") # this will allow string references to work later idaapi.add_segm(0, 0, file_hdr.code_start, ".data", "DATA") idaapi.add_segm(0, code_end, mapsize, ".data", "DATA") idaapi.add_segm(0, mapsize, flen - 0x0c, ".reloc", "RELOC") parse_data_seg(hdr, file_hdr, f) define_consts() # set up entry point idaapi.add_entry(file_hdr.code_start, file_hdr.code_start, "start", 1) # 1 means make code # some comments idaapi.describe(file_hdr.code_start, True, "Compiled YARA rule disassembly") yaraver = '(yara {})'.format(YARA_ARENA_TO_VERSION[ hdr.arena_ver]) if hdr.arena_ver in YARA_ARENA_TO_VERSION else '' idaapi.describe(file_hdr.code_start, True, "Arena version {} {}".format( hdr.arena_ver, yaraver)) # T TODO: check changes between arena versions idaapi.describe(file_hdr.code_start, True, "max_threads: {}".format(hdr.max_threads)) return 1
def load_file(li, neflags, fmt): idaapi.set_processor_type('arm', SETPROC_ALL|SETPROC_FATAL) options = FORMAT_OPTIONS[fmt] if OPT_EXEFS_LOAD in options: ret = load_as_exefs(li, options) else: ret = load_one_file(li, options, 0) eh_parse = idaapi.find_plugin('eh_parse', True) if eh_parse: print 'eh_parse ->', idaapi.run_plugin(eh_parse, 0) else: print 'warning: eh_parse missing' return ret
def load_file(f, neflags, format): f.seek(0) magic = f.read(4) version = struct.unpack("<I", f.read(4))[0] flags = struct.unpack("<I", f.read(4))[0] memType = struct.unpack("<I", f.read(4))[0] serviceType = struct.unpack("<I", f.read(4))[0] numInstances = struct.unpack("<I", f.read(4))[0] uuid = struct.unpack("<IIII", f.read(16)) driverId = struct.unpack("<I", f.read(4))[0] numThreads = struct.unpack("<I", f.read(4))[0] textVA = struct.unpack("<I", f.read(4))[0] textLen = struct.unpack("<I", f.read(4))[0] dataVA = struct.unpack("<I", f.read(4))[0] dataLen = struct.unpack("<I", f.read(4))[0] bssLen = struct.unpack("<I", f.read(4))[0] entry = struct.unpack("<I", f.read(4))[0] f.seek(MCLF_TEXT_INFO_OFFSET) idaapi.set_processor_type("arm", ida_idp.SETPROC_LOADER_NON_FATAL) # Set VA for .text and add the segment f.file2base(0, textVA, textVA + textLen, True) idaapi.add_segm(0, textVA, textVA + textLen, ".text", "CODE") # Set VA for .data and add the segment f.file2base(textLen, dataVA, dataVA + dataLen, True) idaapi.add_segm(0, dataVA, dataVA + dataLen, ".data", "DATA") # Add BSS segment after .text and .data idaapi.add_segm(0, dataVA + dataLen, dataVA + dataLen + bssLen, ".bss", "BSS") if entry % 4 == 1: #Thumb address is always +1 to set the T bit idaapi.add_entry(entry - 1, entry - 1, "_entry", 1) idc.split_sreg_range(entry - 1, "T", 0x1, ida_segregs.SR_user) else: idaapi.add_entry(entry, entry, "_entry", 1) idc.split_sreg_range(entry, "T", 0x0, ida_segregs.SR_user) ida_bytes.create_data(tlApiLibEntry, idaapi.FF_DWORD, 4, idaapi.BADADDR) idc.set_name(tlApiLibEntry, "tlApiLibEntry", ida_name.SN_CHECK) return 1
def load_file(f, neflags, format): f.seek(0) magic = f.read(4) version = struct.unpack("<I", f.read(4))[0] flags = struct.unpack("<I", f.read(4))[0] memType = struct.unpack("<I", f.read(4))[0] serviceType = struct.unpack("<I", f.read(4))[0] numInstances = struct.unpack("<I", f.read(4))[0] uuid = struct.unpack("<IIII", f.read(16)) driverId = struct.unpack("<I", f.read(4))[0] numThreads = struct.unpack("<I", f.read(4))[0] textVA = struct.unpack("<I", f.read(4))[0] textLen = struct.unpack("<I", f.read(4))[0] dataVA = struct.unpack("<I", f.read(4))[0] dataLen = struct.unpack("<I", f.read(4))[0] bssLen = struct.unpack("<I", f.read(4))[0] entry = struct.unpack("<I", f.read(4))[0] f.seek(MCLF_TEXT_INFO_OFFSET) idaapi.set_processor_type("arm", SETPROC_ALL) # Set VA for .text and add the segment f.file2base(0, textVA, textVA + textLen, True) idaapi.add_segm(0, textVA, textVA + textLen, ".text", "CODE") # Set VA for .data and add the segment f.file2base(MCLF_HEADER_SIZE_V23 + textLen, dataVA, dataVA + dataLen, True) idaapi.add_segm(0, dataVA, dataVA + dataLen, ".data", "DATA") # Add BSS segment after .text and .data idaapi.add_segm(0, dataVA + dataLen, dataVA + dataLen + bssLen, ".bss", "BSS") if entry % 4 == 1: #Thumb address is always +1 to set the T bit idaapi.add_entry(entry - 1, entry - 1, "_entry", 1) SetRegEx(entry - 1, "T", 0x1, SR_user) else: idaapi.add_entry(entry, entry, "_entry", 1) SetRegEx(entry, "T", 0x0, SR_user) MakeDword(tlApiLibEntry) MakeName(tlApiLibEntry, "tlApiLibEntry") 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 not format == FILE_FORMAT_NAME: warning("Unknown format name: '%s'" % format) return 0 idaapi.set_processor_type("sh3b", ida_idp.SETPROC_LOADER) load_sh2_data(li) print("Load OK") 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 """ # Select the PC processor module idaapi.set_processor_type("metapc", SETPROC_ALL|SETPROC_FATAL) buf = read_whole_file(li) r = extract_pdf_shellcode(buf) if not r: return 0 # Load all shellcode into different segments start = 0x10000 seg = idaapi.segment_t() for id, ver, n, sc in r: size = len(sc) end = start + size # Create the segment seg.startEA = start seg.endEA = end seg.bitness = 1 # 32-bit idaapi.add_segm_ex(seg, "obj_%d_%d_%d" % (id, ver, n), "CODE", 0) # Copy the bytes idaapi.mem2base(sc, start, end) # Mark for analysis AutoMark(start, AU_CODE) # Compute next loading address start = ((end / 0x1000) + 1) * 0x1000 # Select the bochs debugger LoadDebugger("bochs", 0) return 1
def load_file(li, neflags, format): """Load the file into database Args: li: a file-like object which can be used to access the input data neflags: options selected by the user, see loader.hpp Returns: 0-failure 1-ok """ idaapi.set_processor_type("sh4", SETPROC_ALL | SETPROC_FATAL) li.seek(0, idaapi.SEEK_END) size = li.tell() li.seek(0) rom_data = li.read(size) s = idaapi.segment_t() s.startEA = 0 s.endEA = size s.bitness = 1 # 32-bit s.align = idaapi.saRelByte s.comb = idaapi.scPub s.sel = idaapi.setup_selector(0) idaapi.add_segm_ex(s, "ROM", "DATA", idaapi.ADDSEG_NOSREG | idaapi.ADDSEG_OR_DIE) idaapi.mem2base(rom_data, 0) headr = JasperThe2kCat() headr.AnotateHeader(binary_file=li) headr.MakeStrings(binary_file=li) gentries = gameEntries() gentries.readGameLoops(binary_file=li) gentries.CreateSegments(binary_file=li) gentries.makeDWordTables() gentries.makeDWordTables(start_address=0x2a0, end_address=0x1000) gentries.addIDA_entry() print("load ok") 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 """ # Select the PC processor module idaapi.set_processor_type("metapc", SETPROC_LOADER) buf = read_whole_file(li) r = extract_pdf_shellcode(buf) if not r: return 0 # Load all shellcode into different segments start = 0x10000 seg = idaapi.segment_t() for id, ver, n, sc in r: size = len(sc) end = start + size # Create the segment seg.start_ea = start seg.end_ea = end seg.bitness = 1 # 32-bit idaapi.add_segm_ex(seg, "obj_%d_%d_%d" % (id, ver, n), "CODE", 0) # Copy the bytes idaapi.mem2base(sc, start, end) # Mark for analysis AutoMark(start, AU_CODE) # Compute next loading address start = ((end / 0x1000) + 1) * 0x1000 # Select the bochs debugger load_debugger("bochs", 0) 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 """ li.seek(0) vmlinux = li.read(li.size()) do_get_arch(kallsyms, vmlinux) do_kallsyms(kallsyms, vmlinux) # print_kallsyms(kallsyms, vmlinux) if kallsyms['numsyms'] == 0: print '[!]get kallsyms error...' return 0 idaapi.set_processor_type("arm", idaapi.SETPROC_ALL | idaapi.SETPROC_FATAL) if kallsyms['arch'] == 64: idaapi.get_inf_structure().lflags |= idaapi.LFLG_64BIT li.file2base(0, kallsyms['_start'], kallsyms['_start'] + li.size(), True) s = idaapi.segment_t() s.bitness = kallsyms['arch'] / 32 s.startEA = kallsyms['_start'] s.endEA = kallsyms['_start'] + li.size() idaapi.add_segm_ex(s, ".text", "CODE", idaapi.ADDSEG_OR_DIE) for i in xrange(kallsyms['numsyms']): if kallsyms['type'][i] in ['t', 'T']: idaapi.add_entry(kallsyms['address'][i], kallsyms['address'][i], kallsyms['name'][i], 1) else: idaapi.add_entry(kallsyms['address'][i], kallsyms['address'][i], kallsyms['name'][i], 0) print "Android/Linux vmlinux loaded..." 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 """ li.seek(0) vmlinux = li.read(li.size()) do_get_arch(kallsyms, vmlinux) do_kallsyms(kallsyms, vmlinux) # print_kallsyms(kallsyms, vmlinux) if kallsyms['numsyms'] == 0: print '[!]get kallsyms error...' return 0 idaapi.set_processor_type("arm", SETPROC_ALL|SETPROC_FATAL) if kallsyms['arch'] == 64: idaapi.get_inf_structure().lflags |= idaapi.LFLG_64BIT li.file2base(0, kallsyms['_start'], kallsyms['_start']+li.size(), True) s = idaapi.segment_t() s.bitness = kallsyms['arch'] / 32 s.startEA = kallsyms['_start'] s.endEA = kallsyms['_start']+li.size() idaapi.add_segm_ex(s,".text","CODE",ADDSEG_OR_DIE) for i in xrange(kallsyms['numsyms']): if kallsyms['type'][i] in ['t','T']: idaapi.add_entry(kallsyms['address'][i], kallsyms['address'][i], kallsyms['name'][i], 1) else: idaapi.add_entry(kallsyms['address'][i], kallsyms['address'][i], kallsyms['name'][i], 0) print "Android vmlinux loaded..." return 1
def load_file(li, neflags, format): idaapi.set_processor_type("arm", SETPROC_ALL|SETPROC_FATAL) offs = 0 for s in segments: start = s["start"] length = s["len"] name = s["name"] seg_type = s["type"] li.file2base(offs, start, start+length, True) idaapi.add_segm(0, start, start+length, name, seg_type) offs += length create_modem_hdr_struct() add_modem_hdr_struct(8*4 + segments[0]["start"]) #this might fail unless we carve out a DATA segment from the CODE segment for it. print "Samsung Shannon image loaded." 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 == FormatName: idaapi.set_processor_type("arm", SETPROC_ALL|SETPROC_FATAL) chunk = "" while True: s = gets(li) if s == None: break # warning(s) if s.startswith("#") or s.startswith(" ") or s.startswith(".*: "): continue words = s.split() if len(words) > 2 and words[1].startswith('<') and words[1].endswith('>'): hex = words[2].decode('hex') chunk += hex[::-1] if ishex(words[3]) and len(words[3]) == len(words[2]): hex = words[3].decode('hex') chunk += hex[::-1] if len(chunk) == 0: return 0 size = len(chunk) AddSeg(0, size, 0, 1, idaapi.saRelByte, idaapi.scPub) idaapi.put_many_bytes(0, chunk) print "Load OK" return 1 Warning("Unknown format name: '%s'" % format) return 0
def load_file(li, neflags, format): """ Load the file into database @param li: a file-like object which can be used to access the input data @param neflags: options selected by the user, see loader.hpp @return: 0-failure, 1-ok """ if format.startswith(RomFormatName): li.seek(0) header = read_struct(li, image_header) c = header.ih_arch cname = IDACPUNames[c] if cname == "": Warning("Unsupported CPU") return if header.ih_comp != IH_COMP_NONE: Warning("Cannot load compressed images") return idaapi.set_processor_type(cname, SETPROC_ALL|SETPROC_FATAL) AddSeg(header.ih_load, header.ih_load + header.ih_size, 0, 1, idaapi.saRelPara, idaapi.scPub) # copy bytes to the database li.file2base(ctypes.sizeof(header), header.ih_load, header.ih_load + header.ih_size, 0) if cname == "ARM" and (header.ih_ep & 1) != 0: # Thumb entry point header.ih_ep -= 1 SetReg(header.ih_ep, "T", 1) idaapi.add_entry(header.ih_ep, header.ih_ep, "start", 1) print "Load OK" return 1
def load_file(li, neflags, format): idaapi.set_processor_type("arm:ARMv7-A&R", SETPROC_ALL|SETPROC_FATAL) idc.ChangeConfig('ARM_DEFAULT_ARCHITECTURE = metaarm') if format == SBL1: init_val = li.read(li.size()) rom = SblImage(init_val) image_base = rom.header.image_dest_ptr entry = image_base return load_file_sbl(li, neflags, format) elif format == MBN: init_val = li.read(li.size()) rom = MbnImage(init_val) image_base = rom.header.image_dest_ptr entry = image_base - rom.header.image_src return load_file_mbn(li, neflags, format) # rewind the input file and read its contents li.seek(0) (image_id, header_flash_ver, image_src, image_dest_ptr, image_size, code_size, signature_ptr, signature_size, cert_chain_ptr, cert_chain_size) = struct.unpack(">IIIIIIIIII", li.read(4*10)) # Load the file data (sans header) into IDA li.file2base(entry, entry, data_end, True) # Define the .text .data and .bss segments add_segm(0, entry, data_end, ".text", "CODE") add_segm(0, data_start, data_end, ".data", "DATA") add_segm(0, data_end, bss_end, ".bss", "BSS") if DEBUG: print "Created File Segments: " print "\t.text 0x%.8X - 0x%.8X" % (entry, data_start) print "\t.data 0x%.8X - 0x%.8X" % (data_start, data_end) print "\t.bss 0x%.8X - 0x%.8X" % (data_end, bss_end)
def load_file(li, neflags, format): idaapi.set_processor_type('xap2csr', idaapi.SETPROC_ALL | idaapi.SETPROC_FATAL) li.seek(0) lines = li.read(li.size()).split('\n') segs = {} for seg in ('code', 'data'): segs[seg] = {'chunks': [], 'syms': []} def handle_line(line): raise ValueError('got non-commented line before title: %r' % (line,)) for line in lines: #print repr(line) line = line.strip() if not line: continue if not line.startswith('// '): line = re.sub('\s*//.*', '', line) handle_line(line) continue m = re.match('^// Title +: "(Code|Constant|Symbol) Table"', line) if not m: continue kind = m.group(1) if kind in ('Code', 'Constant'): chunks = segs['code' if kind == 'Code' else 'data']['chunks'] if chunks != []: raise ValueError('more than one %s table in file' % (kind,)) cur_addr_box = [None] cur_chunk_box = [None] def handle_line(line): m = re.match('^@([0-9A-Fa-f]+)\s+([0-9A-Fa-f]{4})$', line) if not m: raise ValueError('unrecognized seg line: %r' % (line,)) addr, word = [int(x, 16) for x in m.groups()] cur_addr, cur_chunk = cur_addr_box[0], cur_chunk_box[0] if cur_addr is None or addr > cur_addr: cur_chunk = cur_chunk_box[0] = [] chunks.append((addr, cur_chunk)) elif addr < cur_addr: raise ValueError('going backwards with addresses (cur_addr=0x%x): %r' % (cur_addr, line,)) cur_chunk.append(word) cur_addr_box[0] = addr + 1 else: assert kind == 'Symbol' cur_syms_box = [None] def handle_line(line): if line in ('.CODE', '.DATA'): cur_syms_box[0] = segs[line[1:].lower()]['syms'] else: m = re.match('^([^,]+), ([0-9a-fA-F]+)*$', line) if not m: raise ValueError('unknown symbol line: %r' % (line,)) cur_syms = cur_syms_box[0] if cur_syms is None: raise ValueError('symbols without a segment: %r' % (line,)) cur_syms.append((int(m.group(2), 16), m.group(1))) # (addr, name) for (segname, info) in segs.iteritems(): kind = {'code': 0, 'data': 1}[segname] base_addr = (0, 0x1000000)[kind] if segname == 'code' and info['chunks'] == [] and info['syms'] == []: continue if not idaapi.set_selector(kind + 1, base_addr >> 4): raise Exception("couldn't set selector for segment %s" % (name,)) for addr, chunk in info['chunks']: seg = idaapi.segment_t() seg.startEA = base_addr + addr seg.endEA = base_addr + addr + len(chunk) seg.bitness = 1 # 32-bit (we can have more than 16 bits of code, so just use for both) seg.sel = kind + 1 name = '%s_%x' % (segname, addr) klass = segname.upper() #print '%s from %x to %x' % (name, seg.startEA, seg.endEA) if not idaapi.add_segm_ex(seg, name, klass, ADDSEG_NOSREG): raise Exception("couldn't add segment %s" % (name,)) ea = seg.startEA for word in chunk: idaapi.put_byte(ea, word) ea += 1 if segname == 'code': idaapi.autoMark(seg.startEA, AU_CODE) if segname == 'data': # fill in the remaining area with BSS spaces = zip([0] + [addr+len(chunk) for (addr, chunk) in info['chunks']], [addr for (addr, chunk) in info['chunks']] + [0x10000]) for start, end in spaces: if end - start < 0x10: continue assert end > start seg = idaapi.segment_t() seg.startEA = base_addr + start seg.endEA = base_addr + end seg.bitness = 1 seg.sel = kind + 1 name = 'bss_%x' % (start,) #print '%s from %x to %x' % (name, seg.startEA, seg.endEA) if not idaapi.add_segm_ex(seg, name, 'BSS', idaapi.ADDSEG_SPARSE | ADDSEG_NOSREG): raise Exception("couldn't add segment %s" % (name,)) 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 """ li.seek(0) vmlinux = li.read(li.size()) do_get_arch(kallsyms, vmlinux) do_kallsyms(kallsyms, vmlinux) if kallsyms['numsyms'] == 0: print_log('[!]get kallsyms error...') return 0 idaapi.set_processor_type("arm", idaapi.SETPROC_ALL|idaapi.SETPROC_FATAL) if kallsyms['arch'] == 64: idaapi.get_inf_structure().lflags |= idaapi.LFLG_64BIT li.file2base(0, kallsyms['_start'], kallsyms['_start']+li.size(), True) sinittext_addr = 0 max_sym_addr = 0 for i in range(kallsyms['numsyms']): if kallsyms['arch'] == 32: if kallsyms['address'][i] > 0xd0000000: continue if kallsyms['name'][i] == '_sinittext': sinittext_addr = kallsyms['address'][i] if kallsyms['address'][i] > max_sym_addr: max_sym_addr = kallsyms['address'][i] max_sym_addr = max_sym_addr + 1024 print_log("max_sym_addr = ", hex(max_sym_addr)) if (kallsyms['_start']+li.size()) > max_sym_addr: max_sym_addr = kallsyms['_start']+li.size() s = idaapi.segment_t() s.bitness = kallsyms['arch'] // 32 s.startEA = kallsyms['_start'] if sinittext_addr == 0: s.endEA = max_sym_addr else: s.endEA = sinittext_addr s.perm = 5 idaapi.add_segm_ex(s,".text","CODE",idaapi.ADDSEG_OR_DIE) if sinittext_addr > 0: s = idaapi.segment_t() s.bitness = kallsyms['arch'] // 32 s.startEA = sinittext_addr s.endEA = max_sym_addr s.perm = 7 idaapi.add_segm_ex(s,".data","DATA",idaapi.ADDSEG_OR_DIE) for i in range(kallsyms['numsyms']): if kallsyms['type'][i] in ['t','T']: idaapi.add_entry(kallsyms['address'][i], kallsyms['address'][i], kallsyms['name'][i], 1) else: idaapi.add_entry(kallsyms['address'][i], kallsyms['address'][i], kallsyms['name'][i], 0) print_log("Android/Linux vmlinux loaded...") return 1
def load_file_mbn(li, neflags, format): # set the processor type and enable 'metaarm' so ida disassembles all instructions idaapi.set_processor_type("arm:ARMv7-A&R", idaapi.SETPROC_ALL | idaapi.SETPROC_FATAL) idc.ChangeConfig('ARM_DEFAULT_ARCHITECTURE = metaarm') # rewind the input file and read its contents li.seek(0) init_val = li.read(li.size()) # Load the file data (sans header) into IDA rom = MbnImage(init_val) #CODE SEGMENT #seg1_size = (rom.header.image_dest_ptr + 0xFFF) &(~0xFFF) #file_offset = header_size + reloc_header_size*3 AddSeg(rom.header.image_dest_ptr, rom.header.image_dest_ptr + rom.header.image_size, 0, 1, idaapi.saRelPara, idaapi.scPub) SetSegmentType(rom.header.image_dest_ptr, idaapi.SEG_CODE) RenameSeg(rom.header.image_dest_ptr, "CODE") # li.file2base(file_offset, seg1, seg1 + code_seg_size, 0) # Load the file data (sans header) into IDA li.file2base(40, rom.header.image_dest_ptr, rom.header.image_dest_ptr + rom.header.code_size, 0) #AddSegment('%s_code' % rom, rom.code_base, rom.code_data) #if rom.sig_data is not None: AddSegment('%s_sig' % rom, rom.sig_base, rom.sig_data) RenameSeg(rom.header.image_dest_ptr, "CODE") #if rom.cert_data is not None: AddSegment('%s_cert' % rom, rom.cert_base, rom.cert_data) #if rom.tail_data is not None: AddSegment('%s_tail' % rom, rom.tail_base, rom.tail_data) #dataseg = rom.header.image_dest_ptr #dataseg_size = init_val #filofs = rom.header.code_size #AddSeg(dataseg, rom.header.image_dest_ptr + rom.header.image_size, 0, 1, idaapi.saRelPara, idaapi.scPub) #SetSegmentType(dataseg, idaapi.SEG_DATA) #RenameSeg(dataseg, "DATA") #li.file2base(rom.header.image_dest_ptr, dataseg, dataseg + rom.header.image_dest_ptr + rom.header.image_size, 0) # Define the .text .data and .bss segments #AddSegEx(rom.header.image_dest_ptr, rom.header.image_dest_ptr + rom.header.code_size, 0, 1, ".code", "CODE", ADDSEG_OR_DIE) #AddSegment(0, data_start, data_end, ".data", "DATA") #AddSegment(0, data_end, bss_end, ".bss", "BSS") image_base = rom.header.image_dest_ptr entry = image_base - rom.header.image_src #if DEBUG: # print "Created File Segments: " # print "\t.text 0x%.8X - 0x%.8X" % (entry, data_start) # print "\t.data 0x%.8X - 0x%.8X" % (data_start, data_end) # print "\t.bss 0x%.8X - 0x%.8X" % (data_end, bss_end) # mark the entry point as being the first byte of the loaded image idaapi.add_entry(rom.header.image_dest_ptr, rom.header.image_dest_ptr, "HEADER", 1) AddIdbComment(image_base, 'Flash Part Version: ', rom.header.flash_parti_ver) AddIdbComment(image_base, 'Source Location: ', rom.header.image_src) AddIdbComment(image_base, 'Destination Address: ', rom.header.image_dest_ptr) AddIdbComment(image_base, 'Image Size: ', rom.header.image_size) AddIdbComment(image_base, 'Code Size: ', rom.header.code_size) AddIdbComment(image_base, 'Signature Ptr: ', rom.header.sig_ptr) AddIdbComment(image_base, 'Signature Size: ', rom.header.sig_size) AddIdbComment(image_base, 'Cert Chain Ptr: ', rom.header.cert_chain_ptr) AddIdbComment(image_base, 'Cert Chain Size: ', rom.header.cert_chain_size) 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 == _3DSX_FORMAT_NAME: idaapi.set_processor_type("arm", SETPROC_ALL|SETPROC_FATAL) li.seek(0) (magic, header_size, reloc_header_size, format_ver, flags, code_seg_size, rodata_seg_size, data_seg_size, bss_seg_size) = struct.unpack("<IHHIIIIII", li.read(4*8)) #print(hex(header_size)) #print(hex(reloc_header_size)) #print(hex(code_seg_size)) #print(hex(rodata_seg_size)) #print(hex(data_seg_size)) #print(hex(bss_seg_size)) #CODE SEGMENT seg1 = CN_3DSX_LOADADR seg1_size = (code_seg_size + 0xFFF) &(~0xFFF) file_offset = header_size + reloc_header_size*3 AddSeg(seg1, seg1 + seg1_size, 0, 1, idaapi.saRelPara, idaapi.scPub) SetSegmentType(seg1, idaapi.SEG_CODE) RenameSeg(seg1, "CODE") li.file2base(file_offset, seg1, seg1 + code_seg_size, 0) #RO_DATA SEGMENT seg2 = seg1 + seg1_size seg2_size = (rodata_seg_size + 0xFFF) &(~0xFFF) file_offset += code_seg_size AddSeg(seg2, seg2 + seg2_size, 0, 1, idaapi.saRelPara, idaapi.scPub) SetSegmentType(seg2, idaapi.SEG_DATA) RenameSeg(seg2, "RODATA") li.file2base(file_offset, seg2, seg2 + rodata_seg_size, 0) #DATA SEGMENT seg3 = seg2 + seg2_size seg3_size = (data_seg_size + 0xFFF) &(~0xFFF) file_offset += rodata_seg_size AddSeg(seg3, seg3 + seg3_size, 0, 1, idaapi.saRelPara, idaapi.scPub) SetSegmentType(seg3, idaapi.SEG_DATA) RenameSeg(seg3, "DATA") li.file2base(file_offset, seg3, seg3 + (data_seg_size - bss_seg_size), 0) #relocations relocs_ptr = file_offset + (data_seg_size - bss_seg_size) segments = [seg1, seg2, seg3] for rel_table in range(3): li.seek(header_size + rel_table * 8) (abs_count, rel_count) = struct.unpack("<II", li.read(4*2)) li.seek(relocs_ptr) relocs_ptr = relocs_ptr + (abs_count * 4 + rel_count * 4) pos = segments[rel_table] #absolute relocations for i in range(abs_count): (skip, patches) = struct.unpack("<HH", li.read(2*2)) pos += skip * 4 for x in range(patches): addr = Dword(pos) if addr < seg1_size: addr = seg1 + addr elif addr < (seg1_size + seg2_size): addr = seg2 + addr - seg1_size else: addr = seg3 + addr - (seg1_size + seg2_size) PatchDword(pos, addr) SetFixup(pos, idaapi.FIXUP_OFF32 or idaapi.FIXUP_CREATED, 0, addr, 0) pos += 4 # cross-segment relative relocations for i in range(rel_count): (skip, patches) = struct.unpack("<HH", li.read(2*2)) pos += skip * 4 for x in range(patches): addr = Dword(pos) if addr < seg1_size: addr = seg1 + addr elif addr < (seg1_size + seg2_size): addr = seg2 + addr - seg1_size else: addr = seg3 + addr - (seg1_size + seg2_size) PatchDword(pos, addr - pos) SetFixup(pos, idaapi.FIXUP_OFF32 or idaapi.FIXUP_CREATED, 0, addr - pos, 0) pos += 4 idaapi.add_entry(CN_3DSX_LOADADR, CN_3DSX_LOADADR, "start", 1) idaapi.analyze_area(seg1, seg1 + seg1_size) print "Load OK" return 1 return 0
def load_file(li, neflags, format): if format != ROM_FORMAT_NAME: Warning("Unknown format name: '%s'" % format) return 0 idaapi.set_processor_type("M6502", SETPROC_ALL | SETPROC_FATAL) li.seek(0, idaapi.SEEK_END) size = li.tell() # RAM idc.AddSeg(RAM_START, RAM_START + RAM_SIZE, 0, 0, idaapi.saRelPara, idaapi.scPub) idc.RenameSeg(RAM_START, "RAM") li.seek(0x6) CartTypeLSB = struct.unpack("<B", li.read(1))[0] # SRAM if (((CartTypeLSB & 0x2) >> 1) == 1): idc.AddSeg(SRAM_START, SRAM_START + SRAM_SIZE, 0, 0, idaapi.saRelPara, idaapi.scPub) idc.RenameSeg(SRAM_START, "SRAM") # EXPROM idc.AddSeg(EXPROM_START, EXPROM_START + EXPROM_SIZE, 0, 0, idaapi.saRelPara, idaapi.scPub) idc.RenameSeg(EXPROM_START, "EXPROM") # TRAINER if (((CartTypeLSB & 0x4) >> 2) == 1): idc.AddSeg(TRAINER_START, TRAINER_START + TRAINER_SIZE, 0, 0, idaapi.saRelPara, idaapi.scPub) idc.RenameSeg(TRAINER_START, "TRAINER") # ROM idc.AddSeg(ROM_START, ROM_START + ROM_SIZE, 0, 0, idaapi.saRelPara, idaapi.scPub) idc.RenameSeg(ROM_START, "ROM") idc.SetSegmentType(ROM_START, idc.SEG_CODE) CartTypeMSB = struct.unpack("<B", li.read(1))[0] mapper_version = (((CartTypeLSB & 0xF0) >> 4) | (CartTypeMSB & 0xF0)) if (mapper_version == MAPPER_NONE or mapper_version == MAPPER_MMC1 or mapper_version == MAPPER_UxROM or mapper_version == MAPPER_CNROM or mapper_version == MAPPER_MMC3 or mapper_version == MAPPER_MMC5 or mapper_version == MAPPER_CAMERIC or mapper_version == MAPPER_GNROM): li.seek(0x4) prg_rom_size = struct.unpack("<B", li.read(1))[0] if (prg_rom_size != 0): offset = HEADER_SIZE if (((CartTypeLSB & 0x4) >> 2) == 1): offset += TRAINER_SIZE li.seek(offset) li.file2base(0, ROM_START, ROM_START + PRG_PAGE_SIZE, 0) offset = HEADER_SIZE + (prg_rom_size - 1) * PRG_PAGE_SIZE if (((CartTypeLSB & 0x4) >> 2) == 1): offset += TRAINER_SIZE li.seek(offset) li.file2base(0, ROM_START + PRG_PAGE_SIZE, ROM_START + PRG_PAGE_SIZE + PRG_PAGE_SIZE, 0) elif (mapper_version == MAPPER_MMC2): print("Second case mapper") elif (mapper_version == MAPPER_AxROM or mapper_version == MAPPER_COLOR_DREAMS or mapper_version == MAPPER_BxROM): print("Third case mapper") else: print("Mapper %d is not supported" % mapper_version) naming() idaapi.add_entry(Word(0xFFFC), Word(0xFFFC), "start", 1) idaapi.cvar.inf.startIP = Word(0xFFFC) idaapi.cvar.inf.beginEA = Word(0xFFFC) header_info(li, 0xFFEF) print("[+] Load OK") return 1
def load_file(li, neflags, format): if format != ROM_FORMAT_NAME: Warning("Unknown format name: '%s'" % format) return 0 jump = dwordAt(li, 0) # Test ARM branch if jump & 0xFF000000 != 0xEA000000: Warning("Unknown format name: '%s'" % format) return 0 idaapi.set_processor_type("arm", SETPROC_ALL | SETPROC_FATAL) li.seek(0, idaapi.SEEK_END) size = li.tell() # Adding Header Section idc.AddSeg(ROM_START, ROM_START + SIZE_HEADER, 0, 1, idaapi.saRelPara, idaapi.scPub) idc.RenameSeg(ROM_START, "HEADER") idc.SetSegmentType(ROM_START, idc.SEG_CODE) li.seek(0) li.file2base(0, ROM_START, ROM_START + SIZE_HEADER, 0) # Adding OEP idaapi.add_entry(ROM_START, ROM_START, "start", 1) idaapi.cvar.inf.startIP = ROM_START idaapi.cvar.inf.beginEA = ROM_START # Adding ROM Section idc.AddSeg(ROM_START + SIZE_HEADER, ROM_START + (ROM_SIZE - SIZE_HEADER), 0, 1, idaapi.saRelPara, idaapi.scPub) idc.RenameSeg(ROM_START + SIZE_HEADER, "ROM") idc.SetSegmentType(ROM_START + SIZE_HEADER, idc.SEG_CODE) li.seek(SIZE_HEADER) li.file2base(0, ROM_START + SIZE_HEADER, ROM_START + size, 0) # Adding EWRAM idc.AddSeg(0x02000000, 0x02040000, 0, 1, idaapi.saRelPara, idaapi.scPub) idc.RenameSeg(0x02000000, "EWRAM") memset_seg(0x02000000, 0x40000) # Adding IWRAM idc.AddSeg(0x03000000, 0x03008000, 0, 1, idaapi.saRelPara, idaapi.scPub) idc.RenameSeg(0x03000000, "IWRAM") memset_seg(0x03000000, 0x8000) # Adding IO / Registers idc.AddSeg(0x04000000, 0x04000400, 0, 1, idaapi.saRelPara, idaapi.scPub) idc.RenameSeg(0x04000000, "IOregisters") memset_seg(0x04000000, 0x400) # Adding BIOS System ROM idc.AddSeg(0x00000000, 0x00004000, 0, 1, idaapi.saRelPara, idaapi.scPub) idc.RenameSeg(0x00000000, "BIOS") memset_seg(0x00000000, 0x4000) idc.SetSegmentType(0x0000000, idc.SEG_CODE) idaapi.add_long_cmt(ROM_START, True, "ROM HEADER") li.seek(0xA0) idc.ExtLinA(ROM_START, 1, "; Game Title : %s" % li.read(12)) idc.ExtLinA(ROM_START, 2, "; Game Code : %s" % li.read(4)) idc.ExtLinA(ROM_START, 3, "; Marker Code : %s" % li.read(2)) idc.ExtLinA(ROM_START, 4, "; Fixed value : %02X" % struct.unpack("<B", li.read(1))[0]) idc.ExtLinA(ROM_START, 5, "; Main unit code : %02X" % struct.unpack("<B", li.read(1))[0]) idc.ExtLinA(ROM_START, 6, "; Device type : %02X" % struct.unpack("<B", li.read(1))[0]) idc.ExtLinA(ROM_START, 7, "; Reserved Area : db 7 dup(0)") li.read(7) idc.ExtLinA(ROM_START, 8, "; Software version %02X" % struct.unpack("<B", li.read(1))[0]) idc.ExtLinA(ROM_START, 9, "; Complement Check %02X" % struct.unpack("<B", li.read(1))[0]) idc.ExtLinA(ROM_START, 10, "; Reserved Area : db 2 dup(0)") io_naming() print("[+] Load OK") return 1
def load_file(li, neflags, format): if format != ROM_FORMAT_NAME: Warning("Unknown format name: '%s'" % format) return 0 idaapi.set_processor_type("M6502", SETPROC_ALL | SETPROC_FATAL) li.seek(0, idaapi.SEEK_END) size = li.tell() li.seek(0, idaapi.SEEK_SET) nheader = NES_HEADER.from_buffer_copy(li.read(LEN_NES_HEADER)) # RAM SEGMENT idc.AddSeg(RAM_START, RAM_START + RAM_SIZE, 0, 0, idaapi.saRelPara, idaapi.scPub) idc.RenameSeg(RAM_START, "RAM") zeromemory(RAM_START, RAM_SIZE) # IOREG SEGMENT idc.AddSeg(IOREG_START, IOREG_START + IOREG_SIZE, 0, 0, idaapi.saRelPara, idaapi.scPub) idc.RenameSeg(IOREG_START, "IOREG") zeromemory(IOREG_START, IOREG_SIZE) # SRAM SEGMENT # bit 1 : Cartridge contains battery-backed PRG RAM ($6000-7FFF) or other persistent memory if (nheader.rom_control_byte_0 & 0x02) != 0x00: idc.AddSeg(SRAM_START, SRAM_START + SRAM_SIZE, 0, 0, idaapi.saRelPara, idaapi.scPub) idc.RenameSeg(SRAM_START, "SRAM") zeromemory(SRAM_START, SRAM_SIZE) # EXPROM SEGMENT idc.AddSeg(EXPROM_START, EXPROM_START + EXPROM_SIZE, 0, 0, idaapi.saRelPara, idaapi.scPub) idc.RenameSeg(EXPROM_START, "EXPROM") zeromemory(EXPROM_START, EXPROM_SIZE) # TRAINER SEGMENT # bit 2 : 512-byte trainer at $7000-$71FF (stored before PRG data) if (nheader.rom_control_byte_0 & 0x04) != 0x00: idc.AddSeg(TRAINER_START, TRAINER_START + TRAINER_SIZE, 0, 0, idaapi.saRelPara, idaapi.scPub) idc.RenameSeg(TRAINER_START, "TRAINER") zeromemory(TRAINER_START, TRAINER_SIZE) # ROM SEGMENT idc.AddSeg(ROM_START, ROM_START + ROM_SIZE, 0, 0, idaapi.saRelPara, idaapi.scPub) idc.RenameSeg(ROM_START, "ROM") idc.SetSegmentType(ROM_START, idc.SEG_CODE | idc.SEG_DATA) zeromemory(ROM_START, ROM_SIZE) describe_header_info(li) mapper_version = (((nheader.rom_control_byte_0 & 0xF0) >> 4) | (nheader.rom_control_byte_1 & 0xF0)) if (mapper_version == MAPPER_NONE or mapper_version == MAPPER_MMC1 or mapper_version == MAPPER_UxROM or mapper_version == MAPPER_CNROM or mapper_version == MAPPER_MMC3 or mapper_version == MAPPER_MMC5 or mapper_version == MAPPER_CAMERIC or mapper_version == MAPPER_GNROM): offset = LEN_NES_HEADER if (nheader.rom_control_byte_0 & 0x04) != 0x00: offset = offset + TRAINER_SIZE offset = offset li.file2base(offset, ROM_START, ROM_START + PRG_PAGE_SIZE, 0) offset = LEN_NES_HEADER if (nheader.rom_control_byte_0 & 0x04) != 0x00: offset = offset + TRAINER_SIZE offset = offset + (nheader.nb_prg_page_16k - 1) * PRG_PAGE_SIZE li.file2base(offset, ROM_START + PRG_PAGE_SIZE, ROM_START + PRG_PAGE_SIZE + PRG_PAGE_SIZE, 0) offset = LEN_NES_HEADER if (nheader.rom_control_byte_0 & 0x04) != 0x00: offset = offset + TRAINER_SIZE offset = offset + PRG_PAGE_SIZE * nheader.nb_prg_page_16k li.file2base(offset, RAM_START, RAM_START + CHR_PAGE_SIZE, 0) elif (mapper_version == MAPPER_MMC2): Warning("Second case mapper") elif (mapper_version == MAPPER_AxROM or mapper_version == MAPPER_COLOR_DREAMS or mapper_version == MAPPER_BxROM): Warning("Third case mapper") else: Warning("Mapper %d is not supported" % mapper_version) naming() idaapi.add_entry(Word(0xFFFC), Word(0xFFFC), "start", 1) idaapi.cvar.inf.startIP = Word(0xFFFC) idaapi.cvar.inf.beginEA = Word(0xFFFC) 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 == FormatName: idaapi.set_processor_type("dsp56k", SETPROC_ALL | SETPROC_FATAL) li.seek(0) s = gets(li) minprog = BADADDR maxprog = 0 start_addr = 0 chunk = "" clist = ChunkList() while True: if s == None: break s = s.strip() if len(s) == 0 or s.startswith(" "): s = gets(li) continue words = s.split() if s.startswith("_START "): # skip s = gets(li) continue elif s.startswith("_DATA"): # _DATA <Memory space> <Address> <Code/data> ... if len(words) < 3: idaapi.error("Bad _DATA record: %s" % s) # we handle only P (program) memory if not words[1] in ("P", "X", "Y"): idaapi.error("Unhandled _DATA memory space: %s" % words[1]) if not ishex(words[2]): idaapi.error("Bad _DATA starting address: %s" % words[2]) if len(chunk): # append current chunk to the list clist.add_chunk(start_addr, chunk, cur_mem) # start a new chunk cur_mem = words[1] start_addr = int(words[2], 16) chunk = make_chunk(words[3:], cur_mem) s = gets(li) continue elif s.startswith("_END"): if len(words) < 2 or not ishex(words[1]): idaapi.error("Bad _END record: %s" % s) # append current chunk to the list clist.add_chunk(start_addr, chunk, cur_mem) # load all clist.load_to_idb() # add the entrypoint entry_ea = int(words[1], 16) idaapi.add_entry(entry_ea, entry_ea, "start", 1) break elif s.startswith("_"): idaapi.error("Unhandled record type: %s" % words[0]) # we're inside a _DATA record chunk += make_chunk(words, cur_mem) s = gets(li) print "Load OK" return 1 Warning("Unknown format name: '%s'" % format) return 0