Example #1
0
//----------------------------------------------------------------------
// функция оповещения
static int notify(int msgnum,void *arg,...)
{ // Various messages:
  qnotused(arg);
  switch ( msgnum ) {
  // новый файл
  case IDP_NEWFILE:
      inf.mf = 0;                                       // MSB last
      inf.nametype = NM_SHORT;
      segment_t *sptr = get_first_seg();
      if ( sptr != NULL ) {
	if ( sptr->startEA-get_segm_base(sptr) == 0 ) {
	  inf.beginEA = sptr->startEA;
	  inf.startIP = 0;
	}
      }
      // основной сегмент - кодовый
      set_segm_class(get_first_seg(), "CODE");
      break;
    // создание нового сегмента
    case IDP_NEWSEG:    {
                        segment_t *seg;
                        seg=((segment_t *)arg);
                        // установим регистры по умолчанию
                        seg->defsr[rVds-ph.regFirstSreg] = 0;
                        break;
                        }
  }
  return 1;
}
Example #2
0
//--------------------------------------------------------------------------
static void create_segment_registers(void)
{
  for ( segment_t *s=get_first_seg(); s != NULL; s=get_next_seg(s->startEA) )
  {
    segreg_t *sr = getSRarea(s->startEA);
    if ( sr == NULL )
    {
      segreg_t sr;
      memset(&sr, 0, sizeof(sr));
      sr.startEA = s->startEA;
      sr.endEA   = s->endEA;
      sr.settags(SR_autostart);
      SRareas.create_area(&sr);
    }
  }
}
Example #3
0
File: reg.cpp Project: 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);
}
Example #4
0
File: reg.cpp Project: nealey/vera
// The kernel event notifications
// Here you may take desired actions upon some kernel events
static int notify(processor_t::idp_notify msgid, ...)
{
    va_list va;
    va_start(va, msgid);

    // A well behavior 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:
            helper.create("$ m7700");
            if ( choose_device() )
                set_device_name(device, IORESP_ALL);
            //  Set the default segment register values :
            //      -1 (badsel) for DR
            //      0 for fM and fX
            for ( segment_t *s=get_first_seg(); s != NULL; s=get_next_seg(s->startEA) )
            {
                SetDefaultRegisterValue(s, rDR, BADSEL);
                SetDefaultRegisterValue(s, rfM, 0);
                SetDefaultRegisterValue(s, rfX, 0);
            }
            info(m7700_help_message);
            break;

        case processor_t::term:
            free_ioports(ports, numports);
        default:
            break;

        case processor_t::newprc:
            ptype = processor_subtype_t(va_arg(va, int));
            break;

        case processor_t::setsgr:
          {
            ea_t ea1 = va_arg(va, ea_t);
            ea_t ea2 = va_arg(va, ea_t);
            int reg  = va_arg(va, int);
            sel_t v  = va_arg(va, sel_t);
            sel_t ov = va_arg(va, sel_t);
            if ( (reg == rfM || reg == rfX) && v != ov )
              set_sreg_at_next_code(ea1, ea2, reg, ov);
          }
          break;

        case processor_t::oldfile:
            helper.create("$ m7700");
            {
              char buf[MAXSTR];
              if ( helper.supval(-1, buf, sizeof(buf)) > 0 )
                set_device_name(buf, IORESP_ALL);
            }
            break;

        case processor_t::savebase:
        case processor_t::closebase:
            helper.supset(-1, device);
            break;
    }

    va_end(va);

    return(1);
}
Example #5
0
//--------------------------------------------------------------------------
// 0 - run uunp interactively
// 1 - run without questions
// 2 - run manual reconstruction
void idaapi run(int arg)
{
  if ( arg == 2 )
  {
    area_t impdir = area_t(0, 0);
    ea_t oep;

    netnode n;

    // Settings never stored before?
    if ( n.create("$ uunp") )
    {
      // Populate default values
      oep = get_screen_ea();
      segment_t *s = getseg(oep);
      if ( s != NULL )
      {
        oep_area.startEA = s->startEA;
        oep_area.endEA = s->endEA;
      }
    }
    else
    {
      // Restore previous settings
      oep              = n.altval(0);
      oep_area.startEA = n.altval(1);
      oep_area.endEA   = n.altval(2);
      impdir.startEA   = n.altval(3);
      impdir.endEA     = n.altval(4);
    }
    if ( !AskUsingForm_c(
      "Reconstruction parameters\n"
      "\n"
      "  <~O~riginal entrypoint:N:128:32::>\n"
      "  <Code ~s~tart address:N:128:32::>\n"
      "  <Code ~e~nd address  :N:128:32::>\n"
      "\n"
      "  <IAT s~t~art address:N:128:32::>\n"
      "  <IAT e~n~d address:N:128:32::>\n"
      "\n",
      &oep,
      &oep_area.startEA, &oep_area.endEA,
      &impdir.startEA, &impdir.endEA) )
    {
      // Cancelled?
      return;
    }

    // Invalid settings?
    if ( impdir.startEA == 0 || impdir.endEA == 0 )
    {
      msg("Invalid import address table boundaries");
      return;
    }

    // Store settings
    n.altset(0, oep);
    n.altset(1, oep_area.startEA);
    n.altset(2, oep_area.endEA);
    n.altset(3, impdir.startEA);
    n.altset(4, impdir.endEA);

    if ( !create_impdir(impdir) )
      return;

    // reanalyze the unpacked code
    do_unknown_range(oep_area.startEA, oep_area.size(), DOUNK_EXPAND);
    auto_make_code(oep);
    noUsed(oep_area.startEA, oep_area.endEA);
    auto_mark_range(oep_area.startEA, oep_area.endEA, AU_FINAL);

    // mark the program's entry point
    move_entry(oep);

    take_memory_snapshot(true);
    return;
  }

  // Determine the original entry point area
  for ( segment_t *s = get_first_seg(); s != NULL; s=get_next_seg(s->startEA) )
  {
    if ( s->type != SEG_GRP )
    {
      oep_area = *s;
      break;
    }
  }

  if (    arg == 0
       && askyn_c(0,
              "HIDECANCEL\n"
              "AUTOHIDE REGISTRY\n"
              "Universal PE unpacker\n"
              "\n"
              "IMPORTANT INFORMATION, PLEASE READ CAREFULLY!\n"
              "\n"
              "This plugin will start the program execution and try to suspend it\n"
              "as soon as the packer finishes its work. Since there might be many\n"
              "variations in packers and packing methods, the execution might go out\n"
              "of control. There are many ways how things can go wrong, but since you\n"
              "have the source code of this plugin, you can modify it as you wish.\n"
              "\n"
              "Do you really want to launch the program?\n") <= 0 )
    {
      return;
    }

  success = false;

  set_file_ext(resfile, sizeof(resfile), database_idb, "res");
  if ( arg == 0
    && !AskUsingForm_c(
        "Uunp parameters\n"
        "IDA will suspend the program when the execution reaches\n"
        "the original entry point area. The default values are in\n"
        "this dialog box. Please verify them and correct if you wish.\n"
        "\n"
        "ORIGINAL ENTRY POINT AREA\n"
        "  <~S~tart address:N:128:32::>\n"
        "  <~E~nd address  :N:128:32::>\n"
        "\n"
        "OUTPUT RESOURCE FILE NAME\n"
        "  <~R~esource file:A:256:32::>\n"
        "\n",
        &oep_area.startEA,
        &oep_area.endEA,
        resfile) )
  {
    return;
  }

  if ( !hook_to_notification_point(HT_DBG, callback, NULL) )
  {
    warning("Could not hook to notification point\n");
    return;
  }

  if ( dbg == NULL )
    load_debugger("win32", false);

  // Let's start the debugger
  if ( !run_to(inf.beginEA) )
  {
    warning("Sorry, could not start the process");
    unhook_from_notification_point(HT_DBG, callback, NULL);
  }
}
Example #6
0
File: reg.cpp Project: nealey/vera
static int notify(processor_t::idp_notify msgid, ...)
{
  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("$ tms320c3x");
      inf.mf = 1; // MSB first
      inf.wide_high_byte_first = 1;
      init_analyzer();
      break;

    case processor_t::term:
      free_ioports(ports, numports);
    default:
      break;

    case processor_t::newfile:   // new file loaded
      inf.wide_high_byte_first = 0;
      {
        segment_t *s0 = get_first_seg();
        if ( s0 != NULL )
        {
          set_segm_name(s0, "CODE");
          segment_t *s1 = get_next_seg(s0->startEA);
          for (int i = dp; i <= rVds; i++)
          {
            SetDefaultRegisterValue(s0, i, BADSEL);
            SetDefaultRegisterValue(s1, i, BADSEL);
          }
        }
      }
      select_device(IORESP_ALL);
      break;

    case processor_t::oldfile:   // old file loaded
      inf.wide_high_byte_first = 0;
      idpflags = (ushort)helper.altval(-1);
      {
        char buf[MAXSTR];
        if ( helper.supval(-1, buf, sizeof(buf)) > 0 )
          set_device_name(buf, IORESP_NONE);
      }
      break;

    case processor_t::closebase:
    case processor_t::savebase:
      helper.altset(-1, idpflags);
      break;

    case processor_t::is_basic_block_end:
      return is_basic_block_end() ? 2 : 0;
  }
  va_end(va);
  return 1;
}
Example #7
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();
}
Example #8
0
File: reg.cpp Project: 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::init:
      inf.mf = 1;                                 // MSB first
    default:
      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 + 0xC;
            inf.startIP = 0xC;

            for( int i = 0; i < qnumber(entries); i++ )
            {
              ea_t ea = sptr->startEA + entries[i].off;
              if( isEnabled(ea) )
              {
                doWord( ea, 2 );
// ig: set_op_type - внутренняя функция, ее нельзя использовать
//                set_op_type( ea, offflag(), 0 );
                set_offset( ea, 0, sptr->startEA );
                ea_t ea1 = sptr->startEA + get_word( ea );
                auto_make_proc( ea1 );
                set_name( ea, entries[i].name );
// ig: так получше будет?
                set_cmt( sptr->startEA+get_word(ea), entries[i].cmt, 1 );
              }
            }
          }

          set_segm_class( sptr, "CODE" );
        }

        segment_t s;
        ea_t bottom = toEA( inf.baseaddr, 0 );
        intmem       = s.startEA = freechunk( bottom, 256, 0xF );
        s.endEA      = s.startEA + 256;
        s.sel        = allocate_selector( s.startEA >> 4 );
        s.type       = SEG_IMEM;                    // internal memory
        add_segm_ex( &s, "INTMEM", NULL, ADDSEG_OR_DIE);

        const predefined_t *ptr;
        for( ptr = iregs; ptr->name != NULL; ptr++ )
        {
          ea_t ea = intmem + 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 );
        }
      }
      break;

    case processor_t::oldfile:
      sel_t sel;
      if( atos( "INTMEM", &sel) ) intmem = specialSeg(sel);
      break;

    case processor_t::newseg:
      {                 // default DS is equal to CS
        segment_t *sptr = va_arg(va, segment_t *);
        sptr->defsr[rVds-ph.regFirstSreg] = sptr->sel;
      }
  }
  va_end(va);

  return(1);
}
Example #9
0
File: reg.cpp Project: nealey/vera
static int notify(processor_t::idp_notify msgid, ...)
{
  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("$ pic");
      helper.supval(0, device, sizeof(device));
    default:
      break;

    case processor_t::term:
      free_mappings();
      free_ioports(ports, numports);
      break;

    case processor_t::newfile:   // new file loaded
      {
        segment_t *s0 = get_first_seg();
        if ( s0 != NULL )
        {
          set_segm_name(s0, "CODE");
          dataseg = AdditionalSegment(0x200, 0, "DATA");
          segment_t *s1 = get_next_seg(s0->startEA);
          SetDefaultRegisterValue(s0, BANK, 0);
          SetDefaultRegisterValue(s1, BANK, 0);
          SetDefaultRegisterValue(s0, PCLATH, 0);
          SetDefaultRegisterValue(s1, PCLATH, 0);
          SetDefaultRegisterValue(s0, PCLATU, 0);
          SetDefaultRegisterValue(s1, PCLATU, 0);
          setup_device(IORESP_INT);
          apply_symbols();
        }
      }
      break;

    case processor_t::oldfile:   // old file loaded
      idpflags = (ushort)helper.altval(-1);
      dataseg  = helper.altval(0);
      create_mappings();
      for ( segment_t *s=get_first_seg(); s != NULL; s=get_next_seg(s->startEA) )
      {
        if ( s->defsr[PCLATH-ph.regFirstSreg] == BADSEL )
          s->defsr[PCLATH-ph.regFirstSreg] = 0;
      }
      break;

    case processor_t::closebase:
    case processor_t::savebase:
      helper.altset(0,  dataseg);
      helper.altset(-1, idpflags);
      helper.supset(0,  device);
      break;

    case processor_t::newprc:    // new processor type
      {
        int n = va_arg(va, int);
        static bool set = false;
        if ( set )
          return 0;
        set = true;
        if ( ptypes[n] != ptype )
        {
          ptype = ptypes[n];
          ph.cnbits = 12 + 2*n;
        }
        switch ( ptype )
        {
          case PIC12:
            register_names[PCLATH] = "status";
            cfgname = "pic12.cfg";
            break;
          case PIC14:
            cfgname = "pic14.cfg";
            break;
          case PIC16:
            register_names[BANK] = "bsr";
            cfgname = "pic16.cfg";
            idpflags = 0;
            ph.cnbits = 8;
            ph.regLastSreg = PCLATU;
            break;
          default:
            error("interr in setprc");
            break;
        }
      }
      break;

    case processor_t::newasm:    // new assembler type
      break;

    case processor_t::newseg:    // new segment
      break;

  }
  va_end(va);
  return 1;
}
Example #10
0
static int notify(processor_t::idp_notify msgid, ...)
{
  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:
//      __emit__(0xCC);   // debugger trap
      helper.create("$ f2mc");
      {
        char buf[MAXSTR];
        if ( helper.supval(0, buf, sizeof(buf)) > 0 )
          f2mc_set_device_name(buf, IORESP_NONE);
      }
      inf.wide_high_byte_first = 1;
      break;

    case processor_t::term:
      free_ioports(ports, numports);
    default:
      break;

    case processor_t::newfile:   // new file loaded
      set_segm_name(get_first_seg(), "CODE");
      if ( choose_ioport_device(cfgname, device, sizeof(device), parse_area_line0) )
        f2mc_set_device_name(device, IORESP_ALL);
      for ( int i = DTB; i <= rVds; i++ )
      {
        for ( segment_t *s=get_first_seg(); s != NULL; s=get_next_seg(s->startEA) )
          SetDefaultRegisterValue(s, i, 0);
      }
      break;

    case processor_t::oldfile:   // old file loaded
      idpflags = (ushort)helper.altval(-1);
      break;

    case processor_t::closebase:
    case processor_t::savebase:
      helper.altset(-1, idpflags);
      break;

    case processor_t::newprc:    // new processor type
      {
        ptype = ptypes[va_arg(va, int)];
        switch ( ptype )
        {
          case F2MC16L:
            cfgname = "f2mc16l.cfg";
            break;
          case F2MC16LX:
            cfgname = "f2mc16lx.cfg";
            break;
          default:
            error("interr: setprc");
            break;
        }
        device[0] = '\0';
        if ( get_first_seg() != NULL )
          choose_device(NULL, 0);
      }
      break;

    case processor_t::newasm:    // new assembler type
      break;

    case processor_t::newseg:    // new segment
      break;

  }
  va_end(va);
  return 1;
}
Example #11
0
File: reg.cpp Project: nealey/vera
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);
}