Example #1
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 #2
0
File: reg.cpp Project: nealey/vera
//----------------------------------------------------------------------
static void apply_symbols(void)
{
  free_mappings();
  if ( dataseg != BADADDR )
  {
    for ( int i=0; i < numports; i++ )
    {
      ea_t ea = calc_data_mem(ports[i].address);
      segment_t *s = getseg(ea);
      if ( s == NULL || s->type != SEG_IMEM )
        continue;
      doByte(ea, 1);
      const char *name = ports[i].name;
      if ( !set_name(ea, name, SN_NOWARN) )
        set_cmt(ea, name, 0);
    }
    for ( segment_t *d = getseg(dataseg); d != NULL; d = get_next_seg(d->startEA) )
    {
      if ( d->type != SEG_IMEM )
        continue;
      ea_t ea = d->startEA;
      ea_t dataend = d->endEA;
      while ( 1 )
      {
        ea = next_unknown(ea, dataend);
        if ( ea == BADADDR )
          break;
        ea_t end = nextthat(ea, dataend, f_isHead, NULL);
        if ( end == BADADDR )
          end = dataend;
        doByte(ea, end-ea);
      }
    }
    create_mappings();
  }
}
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
unsigned int loadIntoIdb(FILE *dll) {
   _IMAGE_DOS_HEADER dos, *pdos;
   _IMAGE_NT_HEADERS nt, *pnt;
   _IMAGE_SECTION_HEADER sect, *psect;
   unsigned int exp_size, exp_rva, exp_fileoff;
   _IMAGE_EXPORT_DIRECTORY *expdir = NULL;
   unsigned int len, handle;
   
   if (fread(&dos, sizeof(_IMAGE_DOS_HEADER), 1, dll) != 1) {
      return 0xFFFFFFFF;
   }
   if (dos.e_magic != 0x5A4D || fseek(dll, dos.e_lfanew, SEEK_SET)) {
      return 0xFFFFFFFF;
   }
   if (fread(&nt, sizeof(_IMAGE_NT_HEADERS), 1, dll) != 1) {
      return 0xFFFFFFFF;
   }
   if (nt.Signature != 0x4550) {
      return 0xFFFFFFFF;
   }
   if (fread(&sect, sizeof(_IMAGE_SECTION_HEADER), 1, dll) != 1) {
      return 0xFFFFFFFF;
   }
   //read all header bytes into buff
   len = sect.PointerToRawData;
   unsigned char *dat = (unsigned char*)malloc(len);
   if (dat == NULL || fseek(dll, 0, SEEK_SET) || fread(dat, len, 1, dll) != 1) {
      free(dat);
      return 0xFFFFFFFF;
   }
   pdos = (_IMAGE_DOS_HEADER*)dat;
   pnt = (_IMAGE_NT_HEADERS*)(dat + pdos->e_lfanew);
   handle = pnt->OptionalHeader.ImageBase;
   psect = (_IMAGE_SECTION_HEADER*)(pnt + 1);

   //now loop to find hole large enough to accomodate image
   //try ImageBase first
   bool found = false;
   bool triedDefault = handle == 0x10000000;
   do {
      msg("Trying base address of 0x%x\n", handle);
      segment_t *s = getseg(handle);
      if (s == NULL) {
#if (IDA_SDK_VERSION < 530)
         segment_t *n = (segment_t *)segs.getn_area(segs.get_next_area(handle));
#else
         segment_t *n = get_next_seg(handle);
#endif
         if (n != NULL) {
            unsigned int moduleEnd = getModuleEnd(n->startEA);
            if (moduleEnd == 0xffffffff) {
               moduleEnd = n->endEA;
            }
            if ((n->startEA - handle) >= nt.OptionalHeader.SizeOfImage) {
               found = true;
            }
            else {
               handle = (moduleEnd + 0x10000) & ~0xffff;
            }
         }
         else if ((0x80000000 - handle) >= nt.OptionalHeader.SizeOfImage) {
            found = true;
         }
      }
      else {
         unsigned int moduleEnd = getModuleEnd(s->startEA);
         if (moduleEnd == 0xffffffff) {
            moduleEnd = s->endEA;
         }
         handle = (moduleEnd + 0x10000) & ~0xffff;
      }

      if (!found && (handle >= 0x80000000 || (0x80000000 - handle) < nt.OptionalHeader.SizeOfImage)) {
         if (triedDefault) {
            //no room to load this library
            free(dat);
            return 0xFFFFFFFF;
         }
         else {
            handle = 0x10000000;
            triedDefault = true;
         }
      }
   } while (!found);

   createSegment(handle, len, dat);

   applyPEHeaderTemplates(handle);

   exp_rva = nt.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
   exp_size = nt.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
   if (exp_rva && exp_size) {
      exp_fileoff = rvaToFileOffset(psect, nt.FileHeader.NumberOfSections, exp_rva);
      expdir = (_IMAGE_EXPORT_DIRECTORY*)malloc(exp_size);
   }
   if (expdir == NULL || fseek(dll, exp_fileoff, SEEK_SET) || fread(expdir, exp_size, 1, dll) != 1) {
      free(dat);
      free(expdir);
      return 0xFFFFFFFF;
   }
   
   createSegment(handle + exp_rva, exp_size, (unsigned char*)expdir);

   if (expdir->AddressOfFunctions < exp_rva || expdir->AddressOfFunctions >= (exp_rva + exp_size)) {
      //EAT lies outside directory bounds
      msg("EAT lies outside directory bounds\n");
   }
   if (expdir->AddressOfNames != 0 && expdir->AddressOfNames < exp_rva || expdir->AddressOfNames >= (exp_rva + exp_size)) {
      //ENT lies outside directory bounds
      msg("ENT lies outside directory bounds\n");
   }
   if (expdir->AddressOfNameOrdinals != 0 && expdir->AddressOfNameOrdinals < exp_rva || expdir->AddressOfNameOrdinals >= (exp_rva + exp_size)) {
      //EOT lies outside directory bounds
      msg("EOT lies outside directory bounds\n");
   }

   free(dat);
   free(expdir);
   return handle;
}
Example #7
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 #8
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 #9
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;
}