Esempio n. 1
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. 2
0
File: reg.cpp Progetto: nealey/vera
static int notify(processor_t::idp_notify msgid, ...)   // Various messages
{
  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::newfile:
      {
// ig: вообще у меня теперь такая точка зрения:
//     не надо в коде задавать вид имен.
//     при желании это можно сделать в ida.cfg:
//      #ifdef __80196__
//        DUMMY_NAMES_TYPE = NM_SHORT
//      #endif

        segment_t *sptr = get_first_seg();
        if( sptr != NULL )    set_segm_class( sptr, "CODE" );

        ea_t ea, ea1;

        for( int i = 0; i < qnumber(entries); i++ )
        {
          ea = toEA( inf.baseaddr, entries[i].off );

          if( isEnabled(ea) )
          {
            switch( entries[i].type )
            {
              case I196F_BTS:
                doByte( ea, entries[i+1].off-entries[i].off );
                set_cmt( ea, entries[i].cmt, 0 );
                break;

              case I196F_CMT:
                if( entries[i].cmt )
                  add_long_cmt( ea, 1, "%s", entries[i].cmt );
                else
                  describe( ea, 1, "" );
                break;

              case I196F_OFF:
                doWord( ea, 2 );
                set_offset( ea, 0, toEA( inf.baseaddr, 0 ) );

                ea1 = toEA( inf.baseaddr, get_word( ea ) );
                auto_make_proc( ea1 );
//dash: long_cmt здесь не смотрится, так как рисуется до заголовка
//      хорошо бы поставить func_cmt, но к этому моменту функций еще нет
//      как быть?
//ig: воспользоваться простым комментарием
//    при создании функции комментарий перетащится
                set_cmt( ea1, entries[i].cmt, 1 );
            }

            set_name( ea, entries[i].name );
          }
        }

        ea = toEA( inf.baseaddr, 0x2080 );
        if( isEnabled( ea ) )
        {
          inf.beginEA = ea;
          inf.startIP = 0x2080;
        }

        segment_t s;
        s.startEA = toEA( inf.baseaddr, 0 );
        s.endEA   = toEA( inf.baseaddr, 0x400 );
        s.sel     = inf.baseaddr;
        s.type    = SEG_IMEM;                         // internal memory
// ig: лучше искать дырку не от нуля, а от базы загрузки
//      ea_t bottom = toEA( inf.baseaddr, 0 );
//      intmem    = s.startEA = freechunk( bottom, 1024, 0xF );
//      s.endEA   = s.startEA + 1024;
//      s.sel     = ushort(s.startEA >> 4);
// dash: дырку искать не пришлось, но я оставил это как пример на будущее
        add_segm_ex( &s, "INTMEM", NULL, ADDSEG_OR_DIE);

        predefined_t *ptr;
        for( ptr = iregs; ptr->name != NULL; ptr++ )
        {
          ea_t ea = toEA( inf.baseaddr, ptr->addr );
          ea_t oldea = get_name_ea( BADADDR, ptr->name );
          if( oldea != ea )
          {
            if( oldea != BADADDR )    set_name( oldea, NULL );
            do_unknown( ea, DOUNK_EXPAND );
            set_name( ea, ptr->name );
          }
          if( ptr->cmt != NULL )      set_cmt( ea, ptr->cmt, 1 );
        }
      }
//      do16bit( 0x18, 2 );           // SP always word
      break;

    case processor_t::oldfile:
      for ( segment_t *s=get_first_seg(); s != NULL; s=get_next_seg(s->startEA) )
      {
        if ( getSRarea(s->startEA) == NULL )
        {
          segreg_t sr;
          sr.startEA = s->startEA;
          sr.endEA   = s->endEA;
          sr.reg(WSR)  = 0;
          sr.reg(WSR1) = 0;
          sr.reg(rVds) = inf.baseaddr;
          sr.settags(SR_autostart);
          SRareas.create_area(&sr);
        }
      }
      break;

    case processor_t::newseg:
                      // default DS is equal to Base Address
      (va_arg(va, segment_t *))->defsr[rVds-ph.regFirstSreg] = inf.baseaddr;
      break;

    case processor_t::newprc:
      extended = va_arg(va,int) != 0;
      if ( !extended )
        ph.flag &= ~PR_SEGS;
      else
        ph.flag |= PR_SEGS;
    default:
      break;
  }
  va_end(va);

  return(1);
}
Esempio n. 3
0
//--------------------------------------------------------------------------
// Process debugging information item and try to incorporate it into
// the database.
// NOTE: This function does not process all debugging information.
//        It knows only about some types of debugingo.
static size_t process_item(uchar *di, size_t disize, section_t *sect)
{
  uchar *const end = di + disize;
  uint32 fw = *(uint32 *)di;
  if ( mf )
    fw = swap32(fw);
  size_t len = fw >> 16;
  if ( len == 0 || len > disize )
    return 0;
  switch ( fw & 0xFFFF )
  {
    case AIF_DEB_SECT:  // section
      if ( disize < sizeof(section_t) )
        return 0;
      sect = (section_t *)di;
      if ( mf )
        swap_section(sect);
      if ( sect->debugsize != 0 )
        len = sect->debugsize;
      switch ( sect->lang )
      {
        case LANG_C:
          add_long_cmt(sect->codestart,1,"C source level debugging data is present");
          break;
        case LANG_PASCAL:
          add_long_cmt(sect->codestart,1,"Pascal source level debugging data is present");
          break;
        case LANG_FORTRAN:
          add_long_cmt(sect->codestart,1,"Fortran-77 source level debugging data is present");
          break;
        case LANG_ASM:
          add_long_cmt(sect->codestart,1,"ARM assembler line number data is present");
          break;
      }
      if ( sect->lang == LANG_NONE )
      {
        size_t nsyms = size_t(sect->name);
        dsym_t *ds = (dsym_t *)(sect+1);
        char *str = (char *)(ds+nsyms);
        if ( str >= (char *)end )
          return 0;
        bool use_pascal = swap_symbols(ds, str, end, nsyms);
        for ( int i=0; i < nsyms; i++,ds++ )
        {
          if ( ds->sym & ASD_16BITSYM ) continue;
          size_t off = size_t(ds->sym & ASD_SYMOFF);
          char *name = str + off + use_pascal;
          if ( name < str || name >= (char *)end )
            continue;
          if ( special_name(name) )
            continue;
          if ( ds->sym & ASD_ABSSYM ) // if the symbol is absolute
          {
            add_pgm_cmt("%s = 0x%X", name, ds->value);
          }
          else if ( isEnabled(ds->value) )
          {
            if ( ds->sym & ASD_GLOBSYM )
            {
              add_entry(ds->value, ds->value, name, is_true_text_symbol(ds, name));
            }
            else
            {
              do_name_anyway(ds->value, name);
              if ( is_true_text_symbol(ds, name) )
                auto_make_code(ds->value);
            }
          }
        }
      }
      else
      {
        char name[64];
        const uchar *nptr = (const uchar *)&sect->name;
        size_t namelen = *nptr++;
        namelen = qmin(namelen, sizeof(name) - 1);
        namelen = qmin(namelen, end - nptr);
        memcpy(name, nptr, namelen); //lint !e670
        name[namelen] = '\0';
        if ( sect->codestart != 0 )
          add_long_cmt(sect->codestart,1,"Section \"%s\", size 0x%X",name,sect->codesize);
        if ( sect->datastart != 0 )
          add_long_cmt(sect->datastart,1,"Section \"%s\", size 0x%X",name,sect->datasize);
      }
#if 0
      if ( sect->fileinfo != 0 ) {      // fileinfo is present?
        process_item(di+size_t(sect->fileinfo),sect);
      }
#endif
      break;
    case AIF_DEB_FDEF:  // procedure/function definition
      deb(IDA_DEBUG_LDR, "procedure/function definition\n");
      break;
    case AIF_DEB_ENDP:  // endproc
      deb(IDA_DEBUG_LDR, "endproc\n");
      break;
    case AIF_DEB_VAR:   // variable
      deb(IDA_DEBUG_LDR, "variable\n");
      break;
    case AIF_DEB_TYPE:  // type
      deb(IDA_DEBUG_LDR, "type\n");
      break;
    case AIF_DEB_STRU:  // struct
      deb(IDA_DEBUG_LDR, "struct\n");
      break;
    case AIF_DEB_ARRAY: // array
      deb(IDA_DEBUG_LDR, "array\n");
      break;
    case AIF_DEB_RANGE: // subrange
      deb(IDA_DEBUG_LDR, "subrange\n");
      break;
    case AIF_DEB_SET:   // set
      deb(IDA_DEBUG_LDR, "set\n");
      break;
    case AIF_DEB_FILE:  // fileinfo
      deb(IDA_DEBUG_LDR, "fileinfo\n");
      break;
    case AIF_DEB_CENUM: // contiguous enumeration
      deb(IDA_DEBUG_LDR, "contiguous enumeration\n");
      break;
    case AIF_DEB_DENUM: // discontiguous enumeration
      deb(IDA_DEBUG_LDR, "discontiguous enumeration\n");
      break;
    case AIF_DEB_FDCL:  // procedure/function declaration
      deb(IDA_DEBUG_LDR, "procedure/function declaration\n");
      break;
    case AIF_DEB_SCOPE: // begin naming scope
      deb(IDA_DEBUG_LDR, "begin naming scope\n");
      break;
    case AIF_DEB_ENDS:  // end naming scope
      deb(IDA_DEBUG_LDR, "end naming scope\n");
      break;
    case AIF_DEB_BITF:  // bitfield
      deb(IDA_DEBUG_LDR, "bitfield\n");
      break;
    case AIF_DEB_MACRO: // macro definition
      deb(IDA_DEBUG_LDR, "macro definition\n");
      break;
    case AIF_DEB_ENDM:  // macro undefinition
      deb(IDA_DEBUG_LDR, "macro undefinition\n");
      break;
    case AIF_DEB_CLASS: // class
      deb(IDA_DEBUG_LDR, "class\n");
      break;
    case AIF_DEB_UNION: // union
      deb(IDA_DEBUG_LDR, "union\n");
      break;
    case AIF_DEB_FPMAP: // FP map fragment
      deb(IDA_DEBUG_LDR, "FP map fragment\n");
      break;
    default:
      msg("unknown (0x%d.)!!!\n", fw & 0xFFFF);
      break;
  }
  return len;
}