//------------------------------------------------------------------------ static void describe_all(DatabaseHdrType &h) { create_filename_cmt(); add_pgm_cmt("Version : %04X",h.version); add_pgm_cmt("DatabaseType: %4.4s",(char*)&h.type); add_pgm_cmt("\n appl \"%s\", '%4.4s'", h.name, (char*)&h.id); }
//----------------------------------------------------------------------------- // write comments. static void mas_write_comments(void) { create_filename_cmt(); char entry_point_str[20]; if (entry_point == -1) qstrncpy(entry_point_str, "NOT DETECTED", sizeof(entry_point_str)); else qsnprintf(entry_point_str, sizeof entry_point_str, "0x%X", entry_point); // write name of the creator program add_pgm_cmt("Creator program : %s", creator); // write address of the entry point add_pgm_cmt("Entry point : %s", entry_point_str); }
//---------------------------------------------------------------------- // // loads the whole file into IDA // this is a wrapper function, which: // // - checks the header for validity and fixes broken headers // - creates all necessary segments // - saves the whole file to blobs // - loads prg pages/banks // - adds informational descriptions to the database // static void load_ines_file( linput_t *li ) { // go to file offset 0 - just to be sure qlseek(li, 0, SEEK_SET); // read the whole header if( qlread(li, &hdr, sizeof(ines_hdr)) != sizeof(ines_hdr) ) vloader_failure("File read error!",0); // check if header is corrupt // show a warning msg, but load the rom nonetheless if( is_corrupt_ines_hdr() ) { //warning("The iNES header seems to be corrupt.\nLoader might give inaccurate results!"); int code = askyn_c(1, "The iNES header seems to be corrupt.\n" "The NES loader could produce wrong results!\n" "Do you want to internally fix the header ?\n\n" "(this will not affect the input file)"); if( code == 1 ) fix_ines_hdr(); } // create NES segments create_segments( li ); // save NES file to blobs save_image_as_blobs( li ); // load relevant ROM banks into database load_rom_banks( li ); // make vectors public add_entry_points( li ); // fill inf structure set_ida_export_data(); // add information about the ROM image describe_rom_image(); // let IDA add some information about the loaded file create_filename_cmt(); }
//-------------------------------------------------------------------------- void load_file(linput_t *li, ushort /*neflag*/, const char * /*fileformatname*/) { header h; qlseek(li, 0); lread(li, &h, sizeof(h)); h.swap(); if ( ph.id != PLFM_HPPA ) set_processor_type("hppa", SETPROC_ALL|SETPROC_FATAL); inf.baseaddr = 0; load_aux_headers(li, h.aux_header_location, h.aux_header_size); load_spaces(li, h, h.space_location, h.space_total); load_subspaces(li, h, h.subspace_location, h.subspace_total); load_symbols(li, h, h.symbol_location, h.symbol_total); load_dl_header(li); create_filename_cmt(); ulong dp = h.presumed_dp; if ( dp == 0 ) { // 23 61 28 00 ldil ...., %dp // 37 7B 01 60 ldo 0xB0(%dp), %dp if ( ua_ana0(inf.startIP) && cmd.Op1.type == o_imm && cmd.Op2.type == o_reg ) { ulong v = cmd.Op1.value; if ( ua_ana0(cmd.ea+4) && cmd.Op1.type == o_displ ) dp = v + cmd.Op1.addr; } } if ( dp != 0 ) { netnode n; n.create("$ got"); n.altset(0, dp+1); } add_til("hpux"); }
/* * this is where we finally load the file and create segments and other processing */ void idaapi load_file(linput_t *li, ushort neflags, const char *fileformatname) { /* reset file position to 0 - accept_file changed it? */ qlseek(li, 0); /* add header structures */ add_types(); create_filename_cmt(); /* process header and create its own segment */ EFI_IMAGE_TE_HEADER teHeader = {0}; if (qlread(li, &teHeader, sizeof(EFI_IMAGE_TE_HEADER)) != sizeof(EFI_IMAGE_TE_HEADER)) { warning("Failed to read TE header\n"); return; } /* read the data to the database */ /* header starts at 0 */ ea_t delta = teHeader.StrippedSize - sizeof(EFI_IMAGE_TE_HEADER); ea_t header_start = teHeader.ImageBase - delta; /* header total size is the TE header plus all sections that follow */ ea_t header_end = teHeader.ImageBase - delta + sizeof(EFI_IMAGE_TE_HEADER) + teHeader.NumberOfSections * sizeof(EFI_IMAGE_SECTION_HEADER); #if 1 msg("Header start: 0x%llx\n", header_start); msg("Header end: 0x%llx\n", header_end); msg("Delta: 0x%llx\n", delta); #endif file2base(li, 0, header_start, header_end, 1); /* create the HEADER segment */ add_segm(0, header_start, header_end, "HEADER", "DATA"); /* set header structures */ doStruct(teHeader.ImageBase - delta, sizeof(EFI_IMAGE_TE_HEADER), efi_image_te_header_struct); for (uint8_t i = 0; i < teHeader.NumberOfSections; i++) { doStruct(teHeader.ImageBase - delta + sizeof(EFI_IMAGE_TE_HEADER) + i * sizeof(EFI_IMAGE_SECTION_HEADER), sizeof(EFI_IMAGE_SECTION_HEADER), efi_image_section_header_struct); } int headerPosition = sizeof(EFI_IMAGE_TE_HEADER); /* read sections */ for (uint8_t i = 0; i < teHeader.NumberOfSections; i++) { qlseek(li, headerPosition); EFI_IMAGE_SECTION_HEADER sectionHeader = {0}; qlread(li, §ionHeader, sizeof(EFI_IMAGE_SECTION_HEADER)); msg("Section name: %s\n", sectionHeader.Name); /* ok */ uint32_t position = sectionHeader.PointerToRawData - delta; msg("Position %x\n", position); qlseek(li, position); ea_t section_start = sectionHeader.VirtualAddress + teHeader.ImageBase - delta; ea_t section_end = 0; if (sectionHeader.Misc.VirtualSize > sectionHeader.SizeOfRawData) { section_end = sectionHeader.VirtualAddress + teHeader.ImageBase - delta + sectionHeader.Misc.VirtualSize; } else { section_end = sectionHeader.VirtualAddress + teHeader.ImageBase - delta + sectionHeader.SizeOfRawData; } msg("Section start: 0x%llx\n", section_start); msg("Section end: 0x%llx\n", section_end); file2base(li, position, section_start, section_end, 1); int bitness = -1; switch (teHeader.Machine) { case IMAGE_FILE_MACHINE_I386: bitness = 1; break; case IMAGE_FILE_MACHINE_X64: bitness = 2; break; default: bitness = 0; } const char *classType; if (qstrcmp((const char*)sectionHeader.Name, ".text") == 0) { classType = "CODE"; } else { classType = "DATA"; } add_segm(0, section_start, section_end, (const char*)sectionHeader.Name, classType); set_segm_addressing(get_segm_by_name((const char *)sectionHeader.Name), bitness); /* try to find the GUIDs in data section */ if (qstrcmp((const char *)sectionHeader.Name, ".data") == 0) { find_guids(section_start, section_end); } /* advance to next section */ headerPosition += sizeof(EFI_IMAGE_SECTION_HEADER); } /* configure the entrypoint address */ add_entry(teHeader.AddressOfEntryPoint + teHeader.ImageBase - delta, teHeader.AddressOfEntryPoint + teHeader.ImageBase - delta, "_start", 1); /* all done */ }
//-------------------------------------------------------------------------- void idaapi load_file(linput_t *li, ushort _neflag, const char * /*fileformatname*/) { char line[MAXSTR]; char *words[MAXSTR]; neflag = _neflag; iscode = (neflag & NEF_CODE) != 0; sel = BADSEL; sea = BADADDR; ea_t ea = 0; ea_t top= 0; bool use32 = false; bool octpref = false; bool octnum = false; size_t fill = 0; // Since we made all the checks in accept_file, // here we don't repeat them ssize_t p0len = -1; // length of the first word's hex part char w0sep[10]; // separator after the first word w0sep[0] = '\0'; int nontrivial_line_count = 0; while ( qlgets(line, sizeof(line), li) ) { strrpl(line, '-', ' '); if ( line[0] == ';' || line[0] == '#' ) continue; int n = make_words(line, words, qnumber(words)); if ( n == 0 ) continue; nontrivial_line_count++; ssize_t bi; // od -x format may contain '*' lines which mean repetition if ( strcmp(words[0], "*") == 0 && n == 1 ) { fill = size_t(top - ea); octpref = true; // od -x have octal prefixes continue; } // the first word must be a number (more than one digit) char *ptr = words[0]; uint32 w0 = octpref ? oct(ptr) : hex(ptr); p0len = ptr - words[0]; // take the separator from the first line if ( nontrivial_line_count == 1 ) qstrncpy(w0sep, ptr, sizeof(w0sep)); // process '*' and fill the gap if ( fill > 0 ) { while ( top < w0 ) { ea = top; top = ea + fill; copy(ea, top); } } int idx = 0; if ( w0sep[0] != '\0' || p0len >= 4 ) { if ( nontrivial_line_count > 1 && !octpref && top != w0 ) { // strange, the sequence is not contiguous // check if the prefixes are octal (od -x) ptr = words[0]; if ( oct(ptr) == top ) { octpref = true; ptr = words[0]; w0 = oct(ptr); } } ea = w0; idx = 1; } else { ea = top; } for ( bi=0; idx < n; idx++ ) //lint !e443 { ptr = words[idx]; if ( nontrivial_line_count == 1 && !octnum && strlen(ptr) == 6 ) { oct(ptr); if ( ptr-words[idx] == 6 ) octnum = true; ptr = words[idx]; // msg("ptr=%s octnum=%d\n", ptr, octnum); } uint32 b = octnum ? oct(ptr) : hex(ptr); ssize_t nc = ptr - words[idx]; if ( nc < 2 ) { // we tolerate one-letter separators between numbers if ( words[idx][1] == '\0' && strchr("\xA6|-:", words[idx][0]) != NULL ) continue; break; } nc /= octnum ? 3 : 2; // number of bytes *(uint32 *)&bytes[bi] = b; bi += nc; } top = ea + bi; copy(ea, top); } if ( eea >= 0x10000 || p0len > 4 ) use32 = true; if ( neflag & NEF_SEGS ) { if ( use32 ) { set_segm_addressing(getseg(sea), 1); if ( ph.id == PLFM_386 ) inf.lflags |= LFLG_PC_FLAT; } set_default_dataseg(sel); } if ( (neflag & NEF_RELOAD) == 0 ) create_filename_cmt(); }
//-------------------------------------------------------------------------- void idaapi load_file(linput_t *li, ushort neflag, const char * /*fileformatname*/) { char line[BUFFSIZE], bigaddr = 0; ea_t addr, startEA = toEA(inf.baseaddr, 0), endEA = 0, seg_start = 0; char rstart = (inf.filetype == f_SREC) ? 'S' : ((inf.filetype == f_HEX) ? ':' : ';'); register char *p; memset(&lc, 0, sizeof(local_data)); inf.startIP = BADADDR; // f_SREC without start record bool iscode = (neflag & NEF_CODE) != 0; int nb = iscode ? ph.cnbits : ph.dnbits; // number of bits in a byte int bs = (nb + 7) / 8; // number of bytes sel_t sel = setup_selector(startEA >> 4); bool segment_created = false; bool cvt_to_bytes = false; if ( ph.id == PLFM_PIC ) { // pic12xx and pic16xx use 12-bit and 14-bit words in program memory // pic18xx uses 16-bit opcodes but byte addressing if ( strncmp(inf.procName, "PIC18", 5) != 0 ) { static const char form[] = // "PIC HEX file addressing mode\n" // "\n" "There are two flavors of HEX files for PIC: with word addressing\n" "and with byte addressing. It is not possible to recognize the\n" "flavor automatically. Please specify what addressing mode should\n" "be used to load the input file. If you don't know, try both and\n" "choose the one which produces the more meaningful result\n"; int code = askbuttons_c("~B~yte addressing", "~W~ord addressing", "~C~ancel", 1, form); switch ( code ) { case 1: break; case 0: cvt_to_bytes = true; break; default: loader_failure(NULL); } } } ea_t subs_addr = 0; for(lc.ln = 1; qlgets(p = line, BUFFSIZE, li); lc.ln++) { while ( *p == ' ' ) ++p; if ( *p == '\n' || *p == '\r' ) continue; if ( *p++ != rstart) errfmt( ); int sz = 2; int mode = (inf.filetype == f_SREC) ? (uchar)*p++ : 0x100; lc.ptr = p; hexdata(0); if ( mode == 0x100 ) { if ( !lc.len ) break; lc.len += 2; if ( inf.filetype == f_HEX ) ++lc.len; } else { switch ( mode ) { default: errfmt(); case '0': case '5': continue; case '3': case '7': ++sz; case '2': case '8': ++sz; case '1': case '9': if ( mode > '3' ) mode = 0; --lc.len; break; } } addr = hexdata(sz) / bs; if ( !mode ) { inf.startIP = addr; continue; } if ( inf.filetype == f_HEX ) { int type = hexdata(1); // record type switch ( type ) { case 0xFF: // mitsubishi hex format case 4: // Extended linear address record subs_addr = hexdata(2) << 16; break; case 2: // Extended segment address record subs_addr = hexdata(2) << 4; break; } if ( type != 0 ) { if ( type == 1 ) break; // end of file record continue; // not a data record } } addr += subs_addr / bs; if ( lc.len ) { ea_t top = addr + lc.len / bs; p = line; while ( lc.len ) { *p++ = (uchar)hexdata(1); if ( cvt_to_bytes ) // pic *p++ = '\0'; } if ( top >= 0x10000l ) bigaddr = 1; addr += startEA; showAddr(addr); if ( (top += startEA) > endEA || !segment_created ) { endEA = top; if ( neflag & NEF_SEGS ) { if ( !segment_created ) { if ( !add_segm(sel, addr, endEA, NULL, iscode ? CLASS_CODE : CLASS_DATA)) loader_failure(NULL ); segment_created = true; seg_start = addr; } else set_segm_end(get_first_seg()->startEA, endEA, SEGMOD_KILL); } } if ( seg_start > addr ) { set_segm_start(get_first_seg()->startEA, addr, SEGMOD_KILL); seg_start = addr; } mem2base(line, addr, top, -1); } { ushort chi; // checksum ++lc.len; switch ( inf.filetype ) { case f_SREC: chi = (uchar)(~lc.sum); chi ^= (uchar)hexdata(1); break; case f_HEX: hexdata(1); chi = (uchar)lc.sum; break; default: //MEX ++lc.len; chi = lc.sum; chi -= (ushort)hexdata(2); break; } if ( chi ) { static char first = 0; if ( !first ) { ++first; warning("Bad hex input file checksum, line %u. Ignore?", lc.ln); } } } } if ( (neflag & NEF_SEGS) != 0 ) { if ( bigaddr ) { set_segm_addressing(get_first_seg(), 1); if ( ph.id == PLFM_386 ) inf.lflags |= LFLG_PC_FLAT; } set_default_dataseg(sel); inf.start_cs = sel; } else { enable_flags(startEA, endEA, STT_CUR); } inf.af &= ~AF_FINAL; // behave as a binary file create_filename_cmt(); }
//-------------------------------------------------------------------------- // // load file into the database. // void idaapi load_file(linput_t *li, ushort /*neflag*/, const char * /*fileformatname*/) { // int i; aif_header_t hd; if ( ph.id != PLFM_ARM ) set_processor_type("arm", SETPROC_ALL|SETPROC_FATAL); lread(li,&hd,sizeof(hd)); mf = uchar(match_zero_code(hd) - 1); if ( (hd.address_mode & 0xFF) != 32 ) { if ( (hd.address_mode & 0xFF) != 0 ) loader_failure("26-bit modules are not supported"); msg("Old AIF format file..."); } if ( hd.decompress_code != NOP ) loader_failure("Compressed modules are not supported"); if ( hd.self_reloc_code != NOP ) loader_failure("Self-relocating modules are not supported"); inf.baseaddr = 0; int isexec = is_bl(hd.entry_point); uint32 offset = sizeof(aif_header_t); uint32 start = hd.image_base; if ( isexec ) { start += sizeof(aif_header_t); hd.readonly_size -= sizeof(aif_header_t); } uint32 end = start + hd.readonly_size; file2base(li, offset, start, end, FILEREG_PATCHABLE); offset += hd.readonly_size; create_section(1, start, end, NAME_CODE, CLASS_CODE); if ( hd.readwrite_size != 0 ) { start = (hd.address_mode & AIF_SEP_DATA) ? hd.data_base : end; end = start + hd.readwrite_size; file2base(li, offset, start, end, FILEREG_PATCHABLE); offset += hd.readwrite_size; create_section(2, start, end, NAME_DATA, CLASS_DATA); } if ( hd.zero_init_size != 0 ) { start = end; end = start + hd.zero_init_size; create_section(3, start, end, NAME_BSS, CLASS_BSS); } create_filename_cmt(); if ( isexec ) hd.entry_point = hd.image_base + offsetof(aif_header_t,entry_point) + ((hd.entry_point & ~BLMASK) << 2) + 8; inf.start_cs = 1; inf.startIP = hd.entry_point; inf.beginEA = hd.entry_point; if ( hd.debug_size != 0 ) { msg("Debugging information is present (%u bytes at file offset 0x%X)...\n", hd.debug_size, offset); uchar *di = qalloc_array<uchar>(size_t(hd.debug_size)); if ( di == NULL ) nomem("AIF debugging info"); qlseek(li,offset); lread(li, di, size_t(hd.debug_size)); uchar *ptr = di; uchar *end = di + size_t(hd.debug_size); section_t *sect = NULL; while ( ptr < end ) { size_t len = process_item(ptr, end-ptr, sect); if ( len == 0 ) { warning("Corrupted debug info."); break; } ptr += len; } qfree(di); } }