//---------------------------------------------------------------------- // // check input file format. if recognized, then return 1 // and fill 'fileformatname'. // otherwise return 0 // int accept_file(linput_t *li, char fileformatname[MAX_FILE_FORMAT_NAME], int n) { if( n!= 0 ) return 0; // quit if file is smaller than size of iNes header if (qlsize(li) < sizeof(ines_hdr)) return 0; // set filepos to offset 0 qlseek(li, 0, SEEK_SET); // read NES header if(qlread(li, &hdr, INES_HDR_SIZE) != INES_HDR_SIZE) return 0; // is it a valid ROM image in iNes format? if( memcmp("NES", &hdr.id, sizeof(hdr.id)) != 0 || hdr.term != 0x1A ) return 0; // this is the name of the file format which will be // displayed in IDA's dialog qstrncpy(fileformatname, "Nintendo Entertainment System ROM", MAX_FILE_FORMAT_NAME); // set processor to 6502 if ( ph.id != PLFM_6502 ) { msg("Nintendo Entertainment System ROM detected: setting processor type to M6502.\n"); set_processor_type("M6502", SETPROC_ALL|SETPROC_FATAL); } return (1 | ACCEPT_FIRST); }
//----------------------------------------------------------------------------- // set the current processor type according to "cpu_type". static bool mas_set_cpu(uchar cpu_type) { for (int i = 0; i < qnumber(families); i++) { if (families[i].code != cpu_type) continue; set_processor_type(families[i].processor, SETPROC_ALL|SETPROC_FATAL); #if defined(DEBUG) msg("MAS: detected processor %s\n", families[i].processor); #endif return true; } return false; }
static void idaapi load_yss_file(linput_t *li, ushort neflags, const char * /*fileformatname*/) { switch (ph.id) { case PLFM_68K: set_processor_type("68000", SETPROC_ALL|SETPROC_FATAL); load_68k_data(li); break; case PLFM_SCUDSP: set_processor_type("scudsp", SETPROC_ALL|SETPROC_FATAL); load_scudsp_data(li); break; case PLFM_SCSPDSP: set_processor_type("scspdsp", SETPROC_ALL|SETPROC_FATAL); load_scspdsp_data(li); break; case PLFM_SH: default: set_processor_type("sh3b", SETPROC_ALL|SETPROC_FATAL); load_sh2_data(li); break; } }
//---------------------------------------------------------------------------- void idaapi load_file(linput_t *li, ushort /*neflags*/, const char * /*ffn*/) { // One should always set the processor type // as early as possible: IDA will draw some // informations from it; e.g., the size of segments. set_processor_type("spc700", SETPROC_ALL|SETPROC_FATAL); // Store information for the cpu module netnode node; node.create("$ spc700"); node.hashset("device", "spc700"); // PSRAM inf.start_cs = map_psram(li, 0x100); info("You have just loaded a SNES SPC-700 sound file.\n\n" "Please move to what you think is an entry point and press 'C' to start the auto analysis."); }
//-------------------------------------------------------------------------- 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"); }
void idaapi load_file(linput_t *fp, ushort neflag, const char * /*fileformatname*/) { // Hello here I am msg("---------------------------------------\n"); msg("Nintendo REL Loader Plugin 0.1\n"); msg("---------------------------------------\n"); // we need PowerPC support to do anything with rels if (ph.id != PLFM_PPC) set_processor_type("PPC", SETPROC_ALL | SETPROC_FATAL); set_compiler_id(COMP_GNU); rel_track track(fp); inf.beginEA = START; // map selector 1 to 0 set_selector(1, 0); track.apply_patches(); }
//-------------------------------------------------------------------------- bool idaapi init_loader_options(linput_t*) { set_processor_type("hppa", SETPROC_ALL|SETPROC_FATAL); return true; }
//-------------------------------------------------------------------------- // // 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); } }
static int notify(processor_t::idp_notify msgid, ...) { static int first_time = 1; va_list va; va_start(va, msgid); // A well behaving processor module should call invoke_callbacks() // in his notify() function. If this function returns 0, then // the processor module should process the notification itself // Otherwise the code should be returned to the caller: int code = invoke_callbacks(HT_IDP, msgid, va); if ( code ) return code; switch ( msgid ) { case processor_t::init: helper.create("$ intel 8051"); inf.mf = 1; // Set a big endian mode of the IDA kernel default: break; case processor_t::term: free_ioports(ports, numports); break; case processor_t::newfile: { segment_t *sptr = get_first_seg(); if ( sptr != NULL ) { if ( sptr->startEA-get_segm_base(sptr) == 0 ) { inf.beginEA = sptr->startEA; inf.startIP = 0; for ( int i=0; i < qnumber(entries); i++ ) { if ( entries[i].proc > ptype ) continue; ea_t ea = inf.beginEA+entries[i].off; if ( isEnabled(ea) && get_byte(ea) != 0xFF ) { add_entry(ea, ea, entries[i].name, 1); set_cmt(ea, entries[i].cmt, 1); } } } } segment_t *scode = get_first_seg(); set_segm_class(scode, "CODE"); if ( ptype > prc_51 ) { AdditionalSegment(0x10000-256-128, 256+128, "RAM"); if ( scode != NULL ) { ea_t align = (scode->endEA + 0xFFF) & ~0xFFF; if ( getseg(align-7) == scode ) // the code segment size is { // multiple of 4K or near it uchar b0 = get_byte(align-8); // 251: // 0 : 1-source, 0-binary mode // 6,7: must be 1s // 82930: // 0 : 1-source, 0-binary mode // 7 : must be 1s // uchar b1 = get_byte(align-7); // 251 // 0: eprommap 0 - FE2000..FE4000 is mapped into 00E000..100000 // 1 - .............. is not mapped ............... // 1: must be 1 // 3: // 2: must be 1 // 4: intr 1 - upon interrupt PC,PSW are pushed into stack // 0 - upon interrupt only PC is pushed into stack // 5: must be 1 // 6: must be 1 // 7: must be 1 // 82930: // 3: must be 1 // 5: must be 1 // 6: must be 1 // 7: must be 1 // msg("b0=%x b1=%x\n", b0, b1); // if ( (b0 & 0x80) == 0x80 && (b1 & 0xEA) == 0xEA ) { // the init bits are correct char pname[sizeof(inf.procName)+1]; inf.get_proc_name(pname); char ntype = (b0 & 1) ? 's' : 'b'; char *ptr = tail(pname)-1; if ( ntype != *ptr && askyn_c(1, "HIDECANCEL\n" "The input file seems to be for the %s mode of the processor. " "Do you want to change the current processor type?", ntype == 's' ? "source" : "binary") > 0 ) { *ptr = ntype; first_time = 1; set_processor_type(pname, SETPROC_COMPAT); } } } } } // the default data segment will be INTMEM { segment_t *s = getseg(intmem); if ( s != NULL ) set_default_dataseg(s->sel); } if ( choose_ioport_device(cfgname, device, sizeof(device), parse_area_line0) ) set_device_name(device, IORESP_ALL); if ( get_segm_by_name("RAM") == NULL ) AdditionalSegment(256, 0, "RAM"); if ( get_segm_by_name("FSR") == NULL ) AdditionalSegment(128, 128, "FSR"); setup_data_segment_pointers(); } break; case processor_t::oldfile: setup_data_segment_pointers(); break; case processor_t::newseg: // make the default DS point to INTMEM // (8051 specific issue) { segment_t *newseg = va_arg(va, segment_t *); segment_t *intseg = getseg(intmem); if ( intseg != NULL ) newseg->defsr[rVds-ph.regFirstSreg] = intseg->sel; } break; case processor_t::newprc: { processor_subtype_t prcnum = processor_subtype_t(va_arg(va, int)); if ( !first_time && prcnum != ptype ) { warning("Sorry, it is not possible to change" // (this is 8051 specific) " the processor mode on the fly." " Please reload the input file" " if you want to change the processor."); return 0; } first_time = 0; ptype = prcnum; } break; case processor_t::newasm: // new assembler type { char buf[MAXSTR]; if ( helper.supval(-1, buf, sizeof(buf)) > 0 ) set_device_name(buf, IORESP_NONE); } break; case processor_t::move_segm:// A segment is moved // Fix processor dependent address sensitive information // args: ea_t from - old segment address // segment_t - moved segment { // ea_t from = va_arg(va, ea_t); // segment_t *s = va_arg(va, segment_t *); // Add commands to adjust your internal variables here // Most of the time this callback will be empty // // If you keep information in a netnode's altval array, you can use // node.altshift(from, s->startEA, s->endEA - s->startEA); // // If you have a variables pointing to somewhere in the disassembled program memory, // you can adjust it like this: // // asize_t size = s->endEA - s->startEA; // if ( var >= from && var < from+size ) // var += s->startEA - from; } break; case processor_t::is_sane_insn: // is the instruction sane for the current file type? // arg: int no_crefs // 1: the instruction has no code refs to it. // ida just tries to convert unexplored bytes // to an instruction (but there is no other // reason to convert them into an instruction) // 0: the instruction is created because // of some coderef, user request or another // weighty reason. // The instruction is in 'cmd' // returns: 1-ok, <=0-no, the instruction isn't // likely to appear in the program { int no_crefs = va_arg(va, int); return is_sane_insn(no_crefs); } } va_end(va); return(1); }
//---------------------------------------------------------------------- // initialize user configurable options based on the input file. static bool idaapi init_loader_options(linput_t*) { set_processor_type("java", SETPROC_ALL|SETPROC_FATAL); return(true); }