Esempio n. 1
0
//-----------------------------------------------------------------------------
// output an error and exit loader.
static void mas_error(const char *format, ...) {
    char b[MAXSTR];
    va_list va;

    va_start(va, format);
    qvsnprintf(b, sizeof b, format, va);
    va_end(va);
    loader_failure("mas loader critical error : %s", b);
}
Esempio n. 2
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();
}
Esempio n. 3
0
//--------------------------------------------------------------------------
static void _errstruct(int line)
{
  static bool asked = false;
  if ( !asked )
  {
    if ( askyn_c(1, "HIDECANCEL\n"
                    "Bad file structure or read error (line %d). Continue?", line)
                <= 0 ) loader_failure();
    asked = true;
  }
}
Esempio n. 4
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;
}
Esempio n. 5
0
inline void pe_failure(const char *format, ...)
{
    va_list va;
    va_start(va, format);
    qstring question("AUTOHIDE REGISTRY\n");
    question.cat_vsprnt(format, va);
    question.append("\nDo you wish to continue?");
    if ( askyn_c(1, question.c_str()) != 1 )
    {
        loader_failure(NULL);
    }
    va_end(va);
}
Esempio n. 6
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;
    }
  }
Esempio n. 7
0
//--------------------------------------------------------------------------
// read 64 or 32 bit number depending on the ELF type
static bool read_uword(uint64 *p, bool sign=false)
{
  if ( elf64 )
  {
#if defined(__EA64__) || !defined(BUILD_LOADER)
    return lread8bytes(li, p, mf) == 0;
#else
    loader_failure("Please use IDA Pro 64-bit to load 64-bit files");
#ifdef __BORLANDC__
    return false;
#endif
#endif
  }
  else
  {
    uint32 x;
    if ( lread4bytes(li, &x, mf) != 0 )
      return false;
    *p = sign ? int32(x) : x;
    return true;
  }
}
Esempio n. 8
0
//--------------------------------------------------------------------------
static void load_aux_headers(linput_t *li, long fpos, size_t size)
{
  if ( !size ) return;
  qlseek(li, fpos);
  while ( size > 0 )
  {
    char buf[4096];
    aux_id aih;
    lread(li, &aih, sizeof(aih));
    aih.swap();
    size_t total = sizeof(aih) + aih.length;
    if ( total >= sizeof(buf) )
      loader_failure("Too big aux_header size %u", total);
    if ( total > size )
      return; // loader_failure("Illegal aux header size %u, rest %u", total, size);
    size -= total;
    qlseek(li, -sizeof(aih), SEEK_CUR);
    lread(li, buf, total);
    switch ( aih.type )
    {
      case HPUX_AUX_ID:
        {
          som_exec_auxhdr *p = (som_exec_auxhdr*)buf;
          p->swap();
          inf.start_cs = 0;
          inf.startIP  = p->exec_entry;
          data_start   = p->exec_dmem;
        }
        break;
      case VERSION_AUX_ID:
      case COPYRIGHT_AUX_ID:
      case SHLIB_VERSION_AUX_ID:
      default:
        break;
    }
  }
}
Esempio n. 9
0
//--------------------------------------------------------------------------
static void errfmt(void)
{
  loader_failure("Bad hex input file format, line %u", lc.ln);
}
Esempio n. 10
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();
}
Esempio n. 11
0
//--------------------------------------------------------------------------
static void ask_for_exit(const char *str)
{
  if ( askyn_c(1, "HIDECANCEL\n%s. Continue?", str) <= 0 )
    loader_failure();
}
Esempio n. 12
0
SuperFamicomCartridge::SuperFamicomCartridge(linput_t *li) {
  int32 size = qlsize(li);
  if(size < 0) {
    loader_failure("Failed retrieving rom size.\n");
    return;
  }

  firmware_appended = false;

  //skip copier header
  if((size & 0x7fff) == 512) size -= 512;

  if(size < 0x8000) return;

  read_header(li);

  if(type == TypeGameBoy) return;
  if(type == TypeBsx) return;
  if(type == TypeSufamiTurbo) return;

  if(type == TypeSuperGameBoy1Bios || type == TypeSuperGameBoy2Bios) {
    if((rom_size & 0x7fff) == 0x100) {
      firmware_appended = true;
      rom_size -= 0x100;
    }
  }

  else if(has_cx4) {
    if((rom_size & 0x7fff) == 0xc00) {
      firmware_appended = true;
      rom_size -= 0xc00;
    }
  }

  if(has_dsp1) {
    if((size & 0x7fff) == 0x2000) {
      firmware_appended = true;
      rom_size -= 0x2000;
    }
  }

  if(has_dsp2) {
    if((size & 0x7fff) == 0x2000) {
      firmware_appended = true;
      rom_size -= 0x2000;
    }
  }

  if(has_dsp3) {
    if((size & 0x7fff) == 0x2000) {
      firmware_appended = true;
      rom_size -= 0x2000;
    }
  }

  if(has_dsp4) {
    if((size & 0x7fff) == 0x2000) {
      firmware_appended = true;
      rom_size -= 0x2000;
    }
  }

  if(has_st010) {
    if((size & 0xffff) == 0xd000) {
      firmware_appended = true;
      rom_size -= 0xd000;
    }
  }

  if(has_st011) {
    if((size & 0xffff) == 0xd000) {
      firmware_appended = true;
      rom_size -= 0xd000;
    }
  }

  if(has_st018) {
    if((size & 0x3ffff) == 0x28000) {
      firmware_appended = true;
      rom_size -= 0x28000;
    }
  }
}
Esempio n. 13
0
//--------------------------------------------------------------------------
//
//      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);
  }

}