Beispiel #1
0
//-----------------------------------------------------------------------
static void show_extdefs(linput_t *li, uint32 offset, uint32 length)
{
  if ( offset == 0 || length == 0 ) return;
  qlseek(li, offset);

  inf.specsegs = 1;
  int segsize = 4 * h.num_externals;
  sel_t sel = h.num_segs+1;
  set_selector(sel, 0);
  xea = freechunk(inf.maxEA, segsize, -15);
  add_segm(sel, xea, xea+segsize, "XTRN", "XTRN");
  set_segm_addressing(getseg(xea), true);

  int n = 0;
  for ( int i=0; i < length; n++ )
  {
    extdef p;
    const int size = offsetof(extdef, allocate_len);
    lread(li, &p, size);
    p.allocate_len.len_4 = 0;
    if ( p.allocate )
    {
      ask_for_feedback("extdef.allocate\n");
      lread(li, &p.allocate_len.len_4, sizeof(p.allocate_len.len_4));
    }
    int nlen = read_pstring(li, p.sym_name, sizeof(p.sym_name));
    i += size + 1 + nlen;

    ea_t a = xea + 4*n;
    set_name(a, p.sym_name);
    if ( p.allocate )
      put_long(a, p.allocate_len.len_4);
  }
}
Beispiel #2
0
void create_load_seg(linput_t *li, ea_t start, ea_t end, int type, const char *name)
{
	add_segm(0, start, end, name, "");
	switch (type)
	{
	   case 1:
			for (ea_t i = 0; i < end-start; i+=4)
			{
				uint32 data;
				qlread(li, &data, 4);
				put_long(start+i, data);
			}
			break;
	   case 2: // Word Swap
			for (ea_t i = 0; i < end-start; i+=4)
			{
				uint16 data, data2;
				qlread(li, &data, 2);
				qlread(li, &data2, 2);
				put_long(start+i, (data << 16) | data2);
			}
			break;
		case 3: // Reverse order
			for (ea_t i = 0; i < end-start; i+=4)
			{
				uint32 data;
				qlread(li, &data, 4);
				data = swap32(data);
				put_long(end-i-1, data);
			}
			break;
		default: break;
	}
}
Beispiel #3
0
//--------------------------------------------------------------------------
static void load_subspaces(linput_t *li, header &h, long fpos, int n)
{
  if ( !n ) return;
  char buf[MAXSTR];
  for ( int i=0; i < n; i++ )
  {
    subspace_dictionary_record sr;
    qlseek(li, fpos + i*sizeof(sr));
    lread(li, &sr, sizeof(sr));
    sr.swap();

    if ( !sr.is_loadable() || !sr.subspace_length ) continue;
    if ( sr.fixup_request_quantity ) complain_fixup();
    ea_t start = sr.subspace_start;
    ea_t end = start + sr.initialization_length;
    file2base(li, sr.file_loc_init_value, start, end, FILEREG_PATCHABLE);
    end = start + sr.subspace_length;
    char *name = get_space_name(li, h, sr.name.n_strx, buf, sizeof(buf));
    set_selector(i, 0);
    const char *sclass = strstr(name, "CODE") ? CLASS_CODE : CLASS_DATA;
    add_segm(i, start, end, name, sclass);

    if ( i == first_text_subspace_idx )
      first_text_subspace_fpos = sr.file_loc_init_value;
//    sr.alignment,
  }
}
Beispiel #4
0
//-----------------------------------------------------------------------
static void show_segdefs(linput_t *li, uint32 offset, uint32 length)
{
  if ( offset == 0 || length == 0 ) return;
  qlseek(li, offset);
  int n = 0;
  for ( int i=0; i < length; )
  {
    segdef s;
    const int size = offsetof(segdef, combine_name);
    lread(li, &s, size);
    int nlen = read_pstring(li, s.combine_name, sizeof(s.combine_name));
    i += size + 1 + nlen;
    n++;

    const char *sname = s.combine_name;
    const char *sclas = sname;
    if ( strnicmp(sname, "CODE", 4) == 0 ) sclas = "CODE";
    if ( strnicmp(sname, "DATA", 4) == 0 ) sclas = "DATA";
    if ( strnicmp(sname, "CONST", 5) == 0 ) sclas = "CONST";
    if ( stricmp(sname, "STACK") == 0 ) sclas = "STACK";
    if ( strchr(sname, ':') != NULL ) continue;

    int segsize = s.slimit + 1;
    if ( strcmp(sname, "DATA") == 0 ) dsel = n;
    set_selector(n, 0);
    ea_t ea = freechunk(inf.maxEA, segsize, -(1<<s.align));
    add_segm(n, ea, ea+segsize, sname, sclas);
    set_segm_addressing(getseg(ea), true);
    if ( strcmp(sclas, "STACK") == 0 )
      doByte(ea, segsize);
  }
}
Beispiel #5
0
//----------------------------------------------------------------------
//
//      creates an SRAM segment, if available on cartridge
//
static void create_sram_segment( void )
{
    bool success = add_segm( 0, SRAM_START_ADDRESS, SRAM_START_ADDRESS + SRAM_SIZE, "SRAM", NULL ) == 1;
    msg("creating SRAM segment..%s", success ? "ok!\n" : "failure!\n");
    if(!success)
        return;
    set_segm_addressing( getseg( SRAM_START_ADDRESS ), 0 );
}
Beispiel #6
0
//----------------------------------------------------------------------
//
//      creates an EXPANSION ROM segment, I don't know when it is used
//
static void create_exprom_segment( void )
{
    bool success = add_segm( 0, EXPROM_START_ADDRESS, EXPROM_START_ADDRESS + EXPROM_SIZE, "EXP_ROM", NULL ) == 1;
    msg("creating EXP_ROM segment..%s", success ? "ok!\n" : "failure!\n");
    if(!success)
        return;
    set_segm_addressing( getseg( EXPROM_START_ADDRESS ), 0 );
}
Beispiel #7
0
//----------------------------------------------------------------------
//
//      creates a ROM segment where all the code is being loaded to
//
static void create_rom_segment( void )
{
    bool success = add_segm( 0, ROM_START_ADDRESS, ROM_START_ADDRESS + ROM_SIZE, "ROM", CLASS_CODE ) == 1;
    msg("creating ROM segment..%s", success ? "ok!\n" : "failure!\n");
    if(!success)
        return;
    set_segm_addressing( getseg( ROM_START_ADDRESS ), 0 );
}
Beispiel #8
0
//--------------------------------------------------------------------------
// Create a section.
static void create_section(ushort sel, ea_t startEA, ea_t endEA,
                                   const char *name, const char *classname)
{
  set_selector(sel, 0);
  if( !add_segm(sel, startEA, endEA, name, classname) )
    loader_failure();
  segment_t *s = getseg(startEA);
  set_arm_segm_flags(startEA, 2 << 10); // alignment
  s->update();
}
Beispiel #9
0
//----------------------------------------------------------------------
//
//      loads a 512 byte trainer (located at file offset INES_HDR_SIZE)
//      to TRAINER_START_ADDRESS
//
static void load_trainer( linput_t *li )
{
    if( !INES_MASK_SRAM( hdr.rom_control_byte_0 ) )
    {
        bool success = add_segm( 0, TRAINER_START_ADDRESS, TRAINER_START_ADDRESS + TRAINER_SIZE, "TRAINER", CLASS_CODE ) == 1;
        msg("creating TRAINER segment..%s", success ? "ok!\n" : "failure!\n");
        set_segm_addressing( getseg( TRAINER_START_ADDRESS ), 0 );
    }
    file2base(li, INES_HDR_SIZE, TRAINER_START_ADDRESS, TRAINER_START_ADDRESS + TRAINER_SIZE, FILEREG_PATCHABLE);
}
Beispiel #10
0
//----------------------------------------------------------------------
//
//      creates a RAM segment
//
static void create_ram_segment( void )
{
    bool success = add_segm( 0, RAM_START_ADDRESS, RAM_START_ADDRESS + RAM_SIZE, "RAM", NULL ) == 1;
    msg("creating RAM segment..%s", success ? "ok!\n" : "failure!\n");
    if(!success)
        return;
    set_segm_addressing( getseg( RAM_START_ADDRESS ), 0 );
    
    // how do I properly initialize a segment ?
    //for( unsigned int ea = SRAM_START_ADDRESS; ea<= SRAM_START_ADDRESS + SRAM_SIZE; ea++ )
    //    put_byte( ea, 0 );
}
Beispiel #11
0
//----------------------------------------------------------------------
//
//      creates an I/O registers segment and names all io registers
//
static void create_ioreg_segment( void )
{
    bool success = add_segm( 0, IOREGS_START_ADDRESS, IOREGS_START_ADDRESS + IOREGS_SIZE, "IO_REGS", NULL ) == 1;
    msg("creating IO_REGS segment..%s", success ? "ok!\n" : "failure!\n");
    if(!success)
        return;
    set_segm_addressing( getseg( IOREGS_START_ADDRESS ), 0 );

    define_item( PPU_CR_1_ADDRESS, PPU_CR_1_SIZE, PPU_CR_1_SHORT_DESCRIPTION, PPU_CR_1_COMMENT );
    define_item( PPU_CR_2_ADDRESS, PPU_CR_2_SIZE, PPU_CR_2_SHORT_DESCRIPTION, PPU_CR_2_COMMENT );
    define_item( PPU_SR_ADDRESS, PPU_SR_SIZE, PPU_SR_SHORT_DESCRIPTION, PPU_SR_COMMENT );

    define_item( SPR_RAM_AR_ADDRESS, SPR_RAM_AR_SIZE, SPR_RAM_AR_SHORT_DESCRIPTION, SPR_RAM_AR_COMMENT );
    define_item( SPR_RAM_IOR_ADDRESS, SPR_RAM_IOR_SIZE, SPR_RAM_IOR_SHORT_DESCRIPTION, SPR_RAM_IOR_COMMENT );

    define_item( VRAM_AR_1_ADDRESS, VRAM_AR_1_SIZE, VRAM_AR_1_SHORT_DESCRIPTION, VRAM_AR_1_COMMENT );
    define_item( VRAM_AR_2_ADDRESS, VRAM_AR_2_SIZE, VRAM_AR_2_SHORT_DESCRIPTION, VRAM_AR_2_COMMENT );
    define_item( VRAM_IOR_ADDRESS, VRAM_IOR_SIZE, VRAM_IOR_SHORT_DESCRIPTION, VRAM_IOR_COMMENT );

    define_item( PAPU_PULSE_1_CR_ADDRESS, PAPU_PULSE_1_CR_SIZE, PAPU_PULSE_1_CR_SHORT_DESCRIPTION, PAPU_PULSE_1_CR_COMMENT );
    define_item( PAPU_PULSE_1_RCR_ADDRESS, PAPU_PULSE_1_RCR_SIZE, PAPU_PULSE_1_RCR_SHORT_DESCRIPTION, PAPU_PULSE_1_RCR_COMMENT );
    define_item( PAPU_PULSE_1_FTR_ADDRESS, PAPU_PULSE_1_FTR_SIZE, PAPU_PULSE_1_FTR_SHORT_DESCRIPTION, PAPU_PULSE_1_FTR_COMMENT );
    define_item( PAPU_PULSE_1_CTR_ADDRESS, PAPU_PULSE_1_CTR_SIZE, PAPU_PULSE_1_CTR_SHORT_DESCRIPTION, PAPU_PULSE_1_CTR_COMMENT );

    define_item( PAPU_PULSE_2_CR_ADDRESS, PAPU_PULSE_2_CR_SIZE, PAPU_PULSE_2_CR_SHORT_DESCRIPTION, PAPU_PULSE_2_CR_COMMENT );
    define_item( PAPU_PULSE_2_RCR_ADDRESS, PAPU_PULSE_2_RCR_SIZE, PAPU_PULSE_2_RCR_SHORT_DESCRIPTION, PAPU_PULSE_2_RCR_COMMENT );
    define_item( PAPU_PULSE_2_FTR_ADDRESS, PAPU_PULSE_2_FTR_SIZE, PAPU_PULSE_2_FTR_SHORT_DESCRIPTION, PAPU_PULSE_2_FTR_COMMENT );
    define_item( PAPU_PULSE_2_CTR_ADDRESS, PAPU_PULSE_2_CTR_SIZE, PAPU_PULSE_2_CTR_SHORT_DESCRIPTION, PAPU_PULSE_2_CTR_COMMENT );

    define_item( PAPU_TRIANGLE_CR_1_ADDRESS, PAPU_TRIANGLE_CR_1_SIZE, PAPU_TRIANGLE_CR_1_SHORT_DESCRIPTION, PAPU_TRIANGLE_CR_1_COMMENT );
    define_item( PAPU_TRIANGLE_CR_2_ADDRESS, PAPU_TRIANGLE_CR_2_SIZE, PAPU_TRIANGLE_CR_2_SHORT_DESCRIPTION, PAPU_TRIANGLE_CR_2_COMMENT );
    define_item( PAPU_TRIANGLE_FR_1_ADDRESS, PAPU_TRIANGLE_FR_1_SIZE, PAPU_TRIANGLE_FR_1_SHORT_DESCRIPTION, PAPU_TRIANGLE_FR_1_COMMENT );
    define_item( PAPU_TRIANGLE_FR_2_ADDRESS, PAPU_TRIANGLE_FR_2_SIZE, PAPU_TRIANGLE_FR_2_SHORT_DESCRIPTION, PAPU_TRIANGLE_FR_2_COMMENT );
    
    define_item( PAPU_NOISE_CR_1_ADDRESS, PAPU_NOISE_CR_1_SIZE, PAPU_NOISE_CR_1_SHORT_DESCRIPTION, PAPU_NOISE_CR_1_COMMENT );
    define_item( PAPU_NOISE_CR_2_ADDRESS, PAPU_NOISE_CR_2_SIZE, PAPU_NOISE_CR_2_SHORT_DESCRIPTION, PAPU_NOISE_CR_2_COMMENT );
    define_item( PAPU_NOISE_FR_1_ADDRESS, PAPU_NOISE_FR_1_SIZE, PAPU_NOISE_FR_1_SHORT_DESCRIPTION, PAPU_NOISE_FR_1_COMMENT );
    define_item( PAPU_NOISE_FR_2_ADDRESS, PAPU_NOISE_FR_2_SIZE, PAPU_NOISE_FR_2_SHORT_DESCRIPTION, PAPU_NOISE_FR_2_COMMENT );

    
    define_item( PAPU_DM_CR_ADDRESS, PAPU_DM_CR_SIZE, PAPU_DM_CR_SHORT_DESCRIPTION, PAPU_DM_CR_COMMENT );
    define_item( PAPU_DM_DAR_ADDRESS, PAPU_DM_DAR_SIZE, PAPU_DM_DAR_SHORT_DESCRIPTION, PAPU_DM_DAR_COMMENT );
    define_item( PAPU_DM_AR_ADDRESS, PAPU_DM_AR_SIZE, PAPU_DM_AR_SHORT_DESCRIPTION, PAPU_DM_AR_COMMENT );
    define_item( PAPU_DM_DLR_ADDRESS, PAPU_DM_DLR_SIZE, PAPU_DM_DLR_SHORT_DESCRIPTION, PAPU_DM_DLR_COMMENT );

    define_item( PAPU_SV_CSR_ADDRESS, PAPU_SV_CSR_SIZE, PAPU_SV_CSR_SHORT_DESCRIPTION, PAPU_SV_CSR_COMMENT );    
    
    define_item( SPRITE_DMAR_ADDRESS, SPRITE_DMAR_SIZE, SPRITE_DMAR_SHORT_DESCRIPTION, SPRITE_DMAR_COMMENT );

    define_item( JOYPAD_1_ADDRESS, JOYPAD_1_SIZE, JOYPAD_1_SHORT_DESCRIPTION, JOYPAD_1_COMMENT );
    define_item( JOYPAD_2_ADDRESS, JOYPAD_2_SIZE, JOYPAD_2_SHORT_DESCRIPTION, JOYPAD_2_COMMENT );
}
Beispiel #12
0
//----------------------------------------------------------------------
static void process_loader(char *ptr, pef_section_t *sec, int nsec) {
  int i;
  pef_loader_t &pl = *(pef_loader_t *)ptr;
  pef_library_t *pil = (pef_library_t *)(&pl + 1);
  swap_pef_loader(pl);
  uint32 *impsym = (uint32 *)(pil + pl.importLibraryCount);
  pef_reloc_header_t *prh =
                (pef_reloc_header_t *)(impsym + pl.totalImportedSymbolCount);
  uint16 *relptr = (uint16 *)(ptr + pl.relocInstrOffset);
  uint32 *hash = (uint32 *)(ptr + pl.exportHashOffset);
  uint32 hashsize = (1 << pl.exportHashTablePower);
  uint32 *keytable = hash + hashsize;
  pef_export_t *pe = (pef_export_t *)(keytable + pl.exportedSymbolCount);
#if !__MF__
  for ( i=0; i < pl.importLibraryCount; i++ )
    swap_pef_library(pil[i]);
  for ( i=0; i < pl.relocSectionCount; i++ )
    swap_pef_reloc_header(prh[i]);
  for ( i=0; i < pl.exportedSymbolCount; i++ )
    swap_pef_export(pe[i]);
#endif
  char *stable = ptr + pl.loaderStringsOffset;

  if ( pl.totalImportedSymbolCount != 0 ) {
    uint32 size = pl.totalImportedSymbolCount*4;
    ea_t undef = freechunk(inf.maxEA, size, -0xF);
    ea_t end = undef + size;
    set_selector(nsec+1, 0);
    if(!add_segm(nsec+1, undef, end, "IMPORT", "XTRN")) loader_failure();

    for ( i=0; i < pl.importLibraryCount; i++ ) {
      ea_t ea = undef + 4*pil[i].firstImportedSymbol;
      add_long_cmt(ea, 1, "Imports from library %s", stable+pil[i].nameOffset);
      if ( pil[i].options & PEF_LIB_WEAK )
        add_long_cmt(ea, 1, "Library is weak");
    }

    inf.specsegs = 1;
    for ( i=0; i < pl.totalImportedSymbolCount; i++ ) {
      uint32 sym = mflong(impsym[i]);
      uchar sclass = uchar(sym >> 24);
      ea_t ea = undef+4*i;
      set_name(ea, get_impsym_name(stable,impsym,i));
      if ( (sclass & kPEFWeak) != 0 ) make_name_weak(ea);
      doDwrd(ea,4);
      put_long(ea, 0);
      impsym[i] = (uint32)ea;
    }
  }
Beispiel #13
0
void ScuLoadState (linput_t *li, ea_t *pc, int size)
{
	scuregs_struct Scu;
	scudspregs_struct ScuDsp;

	qlread(li, (void *)&Scu, sizeof(Scu));
	qlread(li, (void *)&ScuDsp, sizeof(ScuDsp));

	if (pc)
	{
		*pc = ScuDsp.PC;
		ea_t start=0, end=0x100;
		add_segm(0, start, end, "RAM", "");
		for (ea_t i = 0; i < end-start; i++)
			put_long(start+i, ScuDsp.ProgramRam[i]);
	}
}
Beispiel #14
0
//------------------------------------------------------------------
static const char *idaapi parse_area_line(const char *line, char *buf, size_t bufsize)
{
  char word[MAXSTR];
  char aclass[MAXSTR];
  ea_t ea1, ea2;
  if ( sscanf(line, "area %s %s %" FMT_EA "i:%" FMT_EA "i", aclass, word, &ea1, &ea2) == 4 )
  {
    int ram = 0;
    int rom = 0;
    int eprom = 0;
    int eeprom = 0;
    static const char format[] = "RAM=%d ROM=%d EPROM=%d " CUSTOM1 "=%d";
    sscanf(buf, format, &ram, &rom, &eprom, &eeprom);
    int size = ea2 - ea1;
         if ( stristr(word, "RAM")    != NULL ) ram    += size;
    else if ( stristr(word, CUSTOM1)  != NULL ) eeprom += size;
    else if ( stristr(word, "EPROM")  != NULL ) eprom  += size;
    else if ( stristr(word, "ROM")    != NULL ) rom    += size;
    if ( ram || rom || eeprom || eeprom )
      qsnprintf(buf, bufsize, format, ram, rom, eprom, eeprom);
    else
      buf[0] = '\0';
    if ( (respect_info & IORESP_AREA) != 0 && get_segm_qty() != 0 )
    {
#ifdef I8051
      if ( ( stristr(word, "FSR") != NULL ) ||( stristr(word, "RAM") != NULL ))
      {
        AdditionalSegment( ea2-ea1, ea1, word );
      }
      else
#endif
      {
        sel_t sel = allocate_selector(0);
        add_segm(sel, ea1, ea2, word, aclass);
      }
      if ( ea2-ea1 > 0xFFFF )
        set_segm_addressing(getseg(ea1), true);
    }
    return NULL;
  }
  return "syntax error";
}
Beispiel #15
0
//----------------------------------------------------------------------------
static bool map_psram(linput_t *li, uint32 psram_start_in_file)
{
  bool succeeded = false;

  segment_t s;
  s.startEA = 0x00000;
  s.endEA   = 0x10000;
  s.sel     = allocate_selector(s.startEA >> 4);

  if ( !file2base(li, psram_start_in_file, s.startEA, s.endEA, FILEREG_PATCHABLE) )
    loader_failure("Failed mapping 0x%x -> [0x%a, 0x%a)\n", psram_start_in_file, s.startEA, s.endEA);

  succeeded = add_segm(s.sel, s.startEA, s.endEA, "RAM", NULL);
  if ( succeeded )
    succeeded = true;
  else
    loader_failure("Failed adding RAM segment\n");

  return succeeded;
}
Beispiel #16
0
static void copy(ea_t &ea, ea_t &top)
{
  if ( sea == BADADDR )
  {
    if ( neflag & NEF_SEGS )
    {
      const char *sname = iscode ? "CODE" : "DATA";
      sel = setup_selector(0);
      add_segm(sel, ea, top, sname, sname);
    }
    sea = ea;
    eea = top;
  }
  else
  {
    if ( eea < top )
    {
      eea = top;
      set_segm_end(sea, eea, SEGMOD_KILL);
    }
  }
  mem2base(bytes, ea, top, -1);
}
Beispiel #17
0
/*
 * 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, &sectionHeader, 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 */
}
Beispiel #18
0
//--------------------------------------------------------------------------
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();
}
Beispiel #19
0
//-----------------------------------------------------------------------------
// process a file record according to its "record_type".
// return true if there is no more records to process.
static bool process_record(linput_t *li, const uchar record_type, bool load) {
    bool finished = false;

    switch (record_type) {

        // A record with a header byte of $81 is a record that may contain code or
        // data from arbitrary segments.
        //
        // header      : 1 byte
        // segment     : 1 byte
        // gran        : 1 byte
        // start_addr  : 4 bytes (entry point)
        // length      : 2 bytes
        // data        : length bytes
        case 0x81:
            {
                mas_header_t header;
                memset(&header, 0, sizeof header);

                // read the header
                if (qlread(li, &header, sizeof header) != sizeof header)
                    mas_error("unable to read header (%d bytes)", sizeof header);

                // granularities that differ from 1 are rare and mostly appear
                // in DSP CPU's that are not designed for byte processing.
                if (header.gran != 1)
                    mas_error("unsupported granularity (%d)", header.gran);

                // set processor
                if (!mas_set_cpu(header.header))
                    mas_error("processor type '0x%X' is currently unsupported",
                        header.header);
                if (!load) // we have the processor, nothing else to do
                {
                  finished = true;
                  break;
                }

                // get segment name
                const char *segname = mas_get_segname(header.segment);
                if (segname == NULL)
                    mas_error("invalid segment '0x%X'", header.segment);

#if defined(DEBUG)
                msg("MAS: ready to read %d bytes (0x%X -> 0x%X)\n",
                    header.length, header.start_addr, header.start_addr + header.length);
#endif

                // send code in the database
                file2base(li, qltell(li), header.start_addr,
                    header.start_addr + header.length,
                    FILEREG_PATCHABLE);

                // set selector
                sel_t selector = allocate_selector(0);

                // create segment
                add_segm(selector, header.start_addr, header.start_addr + header.length,
                           segname, segname);
            }
            break;

        // The last record in a file bears the Header $00 and has only a string as
        // data field. This string does not have an explicit length specification;
        // its end is equal to the file's end.
        //
        // The string contains only the name of the program that created the file
        // and has no further meaning.
        //
        // creator     : x bytes
        case 0x00:
            {
                ulong length = qlsize(li) - qltell(li);
#if defined(DEBUG)
                msg("MAS: creator length : %ld bytes\n", length);
#endif
                if (length >= sizeof creator)
                    mas_error("creator length is too large (%ld >= %ld",
                        length, sizeof creator);
                int tmp;
                if ((tmp = qlread(li, creator, length)) != length)
                    mas_error("unable to read creator string (i read %d)", tmp);
                creator[tmp] = '\0';
            }
            finished = true;
            break;

        // entry_point : 4 bytes
        case 0x80:
            {
                if (qlread(li, &entry_point, 4) != 4)
                    mas_error("unable to read entry_point");
                if (load)
                {
#if defined(DEBUG)
                  msg("MAS: detected entry point : 0x%X\n", entry_point);
#endif
                  inf.startIP = entry_point;      // entry point
                  segment_t *s = getseg(entry_point);
                  inf.start_cs = s ? s->sel : 0;  // selector of code
                }
            }
            break;

        default:
            // start_addr  : 4 bytes
            // length      : 2 bytes
            // data        : length bytes
            if (record_type >= 0x01 && record_type <= 0x7F) {
                struct header {
                    int start_addr;
                    short length;
                } header;

                memset(&header, 0, sizeof header);

                // read the header
                if (qlread(li, &header, sizeof header) != sizeof header)
                    mas_error("unable to read header (%d bytes)", sizeof header);

                if (load)
                {
                  // send code in the database
                  file2base(li, qltell(li), header.start_addr,
                      header.start_addr + header.length,
                      FILEREG_PATCHABLE);

#if defined(DEBUG)
                  msg("MAS: i've read %d DATA bytes (0x%X -> 0x%X)\n",
                      header.length, header.start_addr, header.start_addr + header.length);
#endif

                  // set selector
                  sel_t selector = allocate_selector(0);

                  // create data segment
                  add_segm(selector, header.start_addr, header.start_addr + header.length,
                           "DATA", "DATA");
                }
                else
                  qlseek(li, qltell(li)+header.length);
            }
            else
                mas_error("invalid record type '0x%X'\n", record_type);
    }

    return finished;
}