示例#1
0
文件: reg.cpp 项目: nealey/vera
// create the mapping table
static void create_mappings(void)
{
  free_mappings();
  for ( int i=0; i < numports; i++ )
  {
    const char *name = ports[i].name;
    ea_t nameea = get_name_ea(BADADDR, name);
    if ( nameea != BADADDR && nameea > dataseg)
      add_mapping(ports[i].address, nameea-dataseg);
  }
}
示例#2
0
ea_t find_import_loc(const char *name)
{
	for (int i = 0; i < get_segm_qty(); i++) {
		segment_t *seg = getnseg(i);
		//msg("segment[%d]  %a %a\n", i, seg->startEA, seg->endEA); 
		if (seg->type == SEG_XTRN) {
			//msg("segment[%d]  == SEG_XTRN\n", i); 
			ea_t loc = get_name_ea(seg->startEA, name);
			if (loc != BADADDR) {
				return loc;
			}
		}
	}
	return BADADDR;	
}
示例#3
0
文件: reg.cpp 项目: 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);
}
示例#4
0
//--------------------------------------------------------------------------
static int idaapi callback(
    void * /*user_data*/,
    int notification_code,
    va_list va)
{
  static int stage = 0;
  static bool is_dll;
  static char needed_file[QMAXPATH];

  switch ( notification_code )
  {
    case dbg_process_start:
    case dbg_process_attach:
      get_input_file_path(needed_file, sizeof(needed_file));
      // no break
    case dbg_library_load:
      if ( stage == 0 )
      {
        const debug_event_t *pev = va_arg(va, const debug_event_t *);
        if ( !strieq(pev->modinfo.name, needed_file) )
          break;
        if ( notification_code == dbg_library_load )
          is_dll = true;
        // remember the current module bounds
        if ( pev->modinfo.rebase_to != BADADDR )
          curmod.startEA = pev->modinfo.rebase_to;
        else
          curmod.startEA = pev->modinfo.base;
        curmod.endEA = curmod.startEA + pev->modinfo.size;
        deb(IDA_DEBUG_PLUGIN, "UUNP: module space %a-%a\n", curmod.startEA, curmod.endEA);
        ++stage;
      }
      break;

    case dbg_library_unload:
      if ( stage != 0 && is_dll )
      {
        const debug_event_t *pev = va_arg(va, const debug_event_t *);
        if ( curmod.startEA == pev->modinfo.base
          || curmod.startEA == pev->modinfo.rebase_to )
        {
          deb(IDA_DEBUG_PLUGIN, "UUNP: unload unpacked module\n");
          if ( stage > 2 )
            enable_step_trace(false);
          stage = 0;
          curmod.startEA = 0;
          curmod.endEA = 0;
          _hide_wait_box();
        }
      }
      break;

    case dbg_run_to:   // Parameters: const debug_event_t *event
      dbg->stopped_at_debug_event(true);
      bp_gpa = get_name_ea(BADADDR, "kernel32_GetProcAddress");
#ifndef __X64__
      if( (LONG)GetVersion() < 0 )  // win9x mode -- use thunk's
      {
        is_9x = true;
        win9x_resolve_gpa_thunk();
      }
#endif
      if ( bp_gpa == BADADDR )
      {
        bring_debugger_to_front();
        warning("Sorry, could not find kernel32.GetProcAddress");
FORCE_STOP:
        stage = 4;  // last stage
        clear_requests_queue();
        request_exit_process();
        run_requests();
        break;
      }
      else if( !my_add_bpt(bp_gpa) )
      {
        bring_debugger_to_front();
        warning("Sorry, can not set bpt to kernel32.GetProcAddress");
        goto FORCE_STOP;
      }
      else
      {
        ++stage;
        set_wait_box("Waiting for a call to GetProcAddress()");
      }
      continue_process();
      break;

    case dbg_bpt:      // A user defined breakpoint was reached.
                       // Parameters: thid_t tid
                       //             ea_t        breakpoint_ea
                       //             int        *warn = -1
                       //             Return (in *warn):
                       //              -1 - to display a breakpoint warning dialog
                       //                   if the process is suspended.
                       //               0 - to never display a breakpoint warning dialog.
                       //               1 - to always display a breakpoint warning dialog.
      {
        thid_t tid = va_arg(va, thid_t); qnotused(tid);
        ea_t ea   = va_arg(va, ea_t);
        //int *warn = va_arg(va, int*);
        if ( stage == 2 )
        {
          if ( ea == bp_gpa )
          {
            regval_t rv;
            if ( get_reg_val(REGNAME_ESP, &rv) )
            {
              ea_t esp = ea_t(rv.ival);
              invalidate_dbgmem_contents(esp, 1024);
              ea_t gpa_caller = getPtr(esp);
              if ( !is_library_entry(gpa_caller) )
              {
                ea_t nameaddr;
                if ( ptrSz == 4 )
                {
                  nameaddr = get_long(esp+8);
                }
                else
                {
                  get_reg_val(REGNAME_ECX, &rv);
                  nameaddr = ea_t(rv.ival);
                }
                invalidate_dbgmem_contents(nameaddr, 1024);
                char name[MAXSTR];
                size_t len = get_max_ascii_length(nameaddr, ASCSTR_C, ALOPT_IGNHEADS);
                name[0] = '\0';
                get_ascii_contents2(nameaddr, len, ASCSTR_C, name, sizeof(name));
                if ( !ignore_win32_api(name) )
                {
                  deb(IDA_DEBUG_PLUGIN, "%a: found a call to GetProcAddress(%s)\n", gpa_caller, name);
                  if ( !my_del_bpt(bp_gpa) || !my_add_bpt(gpa_caller) )
                    error("Can not modify breakpoint");
                }
              }
            }
          }
          else if ( ea == bpt_ea )
          {
            my_del_bpt(ea);
            if ( !is_library_entry(ea) )
            {
              msg("Uunp: reached unpacker code at %a, switching to trace mode\n", ea);
              enable_step_trace(true);
              ++stage;
              uint64 eax;
              if ( get_reg_val(REGNAME_EAX, &eax) )
                an_imported_func = ea_t(eax);
              set_wait_box("Waiting for the unpacker to finish");
            }
            else
            {
              warning("%a: bpt in library code", ea); // how can it be?
              my_add_bpt(bp_gpa);
            }
          }
          // not our bpt? skip it
          else
          {
            // hide the wait box to allow others plugins to properly stop
            _hide_wait_box();
            break;
          }
        }
      }
      // while continue_process() would work here too, request+run is more universal
      // because they do not ignore the request queue
      request_continue_process();
      run_requests();
      break;

    case dbg_trace:    // A step occured (one instruction was executed). This event
                       // notification is only generated if step tracing is enabled.
                       // Parameter:  none
      if ( stage == 3 )
      {
        thid_t tid = va_arg(va, thid_t); qnotused(tid);
        ea_t ip   = va_arg(va, ea_t);

        // ip reached the OEP range?
        if ( oep_area.contains(ip) )
        {
          // stop the trace mode
          enable_step_trace(false);
          msg("Uunp: reached OEP %a\n", ip);
          set_wait_box("Reanalyzing the unpacked code");

          // reanalyze the unpacked code
          do_unknown_range(oep_area.startEA, oep_area.size(), DOUNK_EXPAND);
          auto_make_code(ip); // plan to make code
          noUsed(oep_area.startEA, oep_area.endEA); // plan to reanalyze
          auto_mark_range(oep_area.startEA, oep_area.endEA, AU_FINAL); // plan to analyze
          move_entry(ip); // mark the program's entry point

          _hide_wait_box();

          // inform the user
          bring_debugger_to_front();
          if ( askyn_c(1,
                       "HIDECANCEL\n"
                       "The universal unpacker has finished its work.\n"
                       "Do you want to take a memory snapshot and stop now?\n"
                       "(you can do it yourself if you want)\n") > 0 )
          {
            set_wait_box("Recreating the import table");
            invalidate_dbgmem_config();

            if ( is_9x )
              find_thunked_imports();

            create_impdir();

            set_wait_box("Storing resources to 'resource.res'");
            if ( resfile[0] != '\0' )
              extract_resource(resfile);

            _hide_wait_box();
            if ( take_memory_snapshot(true) )
              goto FORCE_STOP;
          }
          suspend_process();
          unhook_from_notification_point(HT_DBG, callback, NULL);
        }
      }
      break;

    case dbg_process_exit:
      {
        stage = 0;
        // stop the tracing
        _hide_wait_box();
        unhook_from_notification_point(HT_DBG, callback, NULL);
        if ( success )
          jumpto(inf.beginEA, -1);
        else
          tell_about_failure();
      }
      break;

    case dbg_exception:// Parameters: const debug_event_t *event
                       //             int                 *warn = -1
                       //             Return (in *warn):
                       //              -1 - to display an exception warning dialog
                       //                   if the process is suspended.
                       //               0 - to never display an exception warning dialog.
                       //               1 - to always display an exception warning dialog.

    {
//      const debug_event_t *event = va_arg(va, const debug_event_t *);
//      int *warn = va_arg(va, int *);
      // FIXME: handle code which uses SEH to unpack itself
      if ( askyn_c(1,
                   "AUTOHIDE DATABASE\n"
                   "HIDECANCEL\n"
                   "An exception occurred in the program.\n"
                   "UUNP does not support exceptions yet.\n"
                   "The execution has been suspended.\n"
                   "Do you want to continue the unpacking?") <= 0 )
      {
        _hide_wait_box();
        stage = 0;
        enable_step_trace(false); // stop the trace mode
        suspend_process();
      }
      else
      {
        continue_process();
      }
    }
    break;

    case dbg_request_error:
                       // An error occured during the processing of a request.
                       // Parameters: ui_notification_t  failed_command
                       //             dbg_notification_t failed_dbg_notification
      {
        ui_notification_t  failed_cmd = va_arg(va, ui_notification_t);
        dbg_notification_t failed_dbg_notification = va_arg(va, dbg_notification_t);
        _hide_wait_box();
        stage = 0;
        warning("dbg request error: command: %d notification: %d",
                        failed_cmd, failed_dbg_notification);
      }
      break;
  }
  return 0;
}
示例#5
0
int
RP_mapping::process_string(char *str, int ln)
{
  char *arg1, *arg2;
  for ( arg1 = arg2 = str; !isspace( *arg2) && *arg2; arg2++ )
    ;
  if ( !*arg2 )
   return 0;
  *arg2++ = 0x0;
  if ( !*arg2)
   return 0;
  for ( ; *arg2 && isspace(*arg2); arg2++ )
   ;
  if ( !*arg2 )
   return 0;
  // next - just trim all spaces at end
  char *ptr = arg2 + 1;
  for ( ; !isspace(*ptr) && *ptr; ptr++ )
   ;
  *ptr = 0x0;
  /* O`k, now arg1 contains address or name and arg2 contains name of struct */
  // first check for struct presence
  tid_t tid = get_struc_id(arg2);
  if ( BADADDR == tid )
  {
    if ( verbose )
      msg("Cannot find struct '%s'\n", arg2);
    return 0;
  }
  // next try to resolve first arg as name
  ea_t ea = get_name_ea(BADADDR, arg1);
  if ( ea != BADADDR )
  {
   /* first check for already presenting */
   dnode_t *again = is_presented(ea);
   if ( NULL != again )
   {
    if ( verbose )
      msg("Warning, address %X already in dictionary, overwrite\n", ea);
    dnode_put(again, (void *)tid);
   } else {
    /* place to dict new mapping name -> tid_t */
    dict_alloc_insert(mapping, (const void *)ea, (void *)tid);
   }
#ifdef RP_DEBUG
 msg("Mapping %X (%s) -> %s (%X) \n", ea, arg1, arg2, tid);
#endif
   return 1;
  }
  /* well may be we shold add yet one underscore at begin of name ? */
  {
   int len = strlen(arg1);
   char *dup = (char *)qalloc(len + 2);
   *dup = '_';
   strcpy(dup + 1, arg1);
   ea = get_name_ea(BADADDR, dup);
   if ( BADADDR != ea )
   {
     dnode_t *again = is_presented(ea);
     if ( NULL != again )
     {
      if ( verbose )
       msg("Warning, address %X already in dictionary, overwrite\n", ea);
      dnode_put(again, (void *)tid);
     } else {
      dict_alloc_insert(mapping, (const void *)ea, (void *)tid);
     }
#ifdef RP_DEBUG
 msg("Mapping %X (%s) -> %s (%X) \n", ea, dup, arg2, tid);
#endif
     qfree(dup);
     return 1;
   }
   qfree(dup);
  }
  /* well - may be we has address ? */
  if ( *arg1 == '0' && ( arg1[1] == 'x' || arg1[1] == 'X' ) )
  {
   arg1 += 2;
   if ( ! *arg1 )
   {
    if ( verbose )
      msg("Line %d. Bad address '%s'\n", ln, arg1 - 2);
    return 0;
   }
  }
  char *notused;
  ea = strtol(arg1, &notused, 0x10);
  if ( !ea )
  {
   if ( verbose )
     msg("Line %d. Bad address '%s'\n", ln, arg1);
   return 0;
  }
  // O`k it seems that we really has some address. Lets check it
  if ( NULL == getseg(ea) )
  {
   if ( verbose )
     msg("Line %d. Address %X is not in your file\n", ln, ea);
   return 0;
  }
  dnode_t *again = is_presented(ea);
  if ( NULL != again )
  {
   if ( verbose )
    msg("Warning, address %X already in dictionary, overwrite\n", ea);
   dnode_put(again, (void *)tid);
  } else {
   dict_alloc_insert(mapping, (const void *)ea, (void *)tid);
  }
#ifdef RP_DEBUG
 msg("Mapping %X -> %s (%X) \n", ea, arg2, tid);
#endif
  return 1;  
}
示例#6
0
文件: reg.cpp 项目: 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);
}
示例#7
0
void idaapi
PIC_run(int arg)
{
  ea_t curr_addr;
  int n_funcz, i;
  func_t *curr_func;

  if ( is_first )
  {
    got_addr = get_name_ea(BADADDR, got_name);
    if ( BADADDR == got_addr )
    {
      got_addr = get_name_ea(BADADDR,got_name1);
      if ( BADADDR != got_addr )
      {
        got_addr = get_long(got_addr);
      } else
      {
        got_addr = get_name_ea(BADADDR, got_name2);
      }
    }
    is_first = false;
    // 2 Nov 2005: dirty hack, bcs get_name_ea("_got") return BADADDR
    segment_t *s;
    if ( BADADDR == got_addr )
    {
      s = get_segm_by_name(".got");
      if ( s != NULL )
       got_addr = s->startEA; 
    }
    // 14 oct 2009
    s = get_segm_by_name(".got.plt");
    if ( s != NULL )
      got_plt_addr = s->startEA;
  }
  if ( BADADDR == got_addr )
  {
    msg("Cannot resolve _got address. Bad plugin initialization");
    return;
  }
#ifdef PIC_DEBUG
  RP_TRACE1( "got_addr %X\n", got_addr );
#endif
  switch (arg)
  {
   case 0: /* only function under current EA */
     curr_addr = get_screen_ea();
#ifdef PIC_DEBUG
     RP_TRACE1( "curr_addr %X\n", curr_addr );
#endif
     /* next I had to resolve function */
     curr_func = get_func(curr_addr);
     if ( NULL == curr_func )
     {
       warning("Cannot operate not on function, address %X\n", curr_addr);
       return;
     }
#if defined(PIC_DEBUG) || defined(PIC_SHOW)
     rp_log_fp = fopen(log_filename, "w+t");
#endif
     process_PIC(curr_func->startEA, curr_func->endEA);
#if defined(PIC_DEBUG) || defined(PIC_SHOW)
     if ( NULL != rp_log_fp )
     {
      fclose(rp_log_fp);
      rp_log_fp = NULL;
     }
#endif
    break;
   case 1: /* process all defined functions */
#if defined(PIC_DEBUG) || defined(PIC_SHOW)
     rp_log_fp = fopen(log_filename, "w+t");
#endif
     n_funcz = get_func_qty();
     if ( !n_funcz )
     {
       warning("No functions defined!");
       return;
     }
     for ( i = 0; i < n_funcz; i++ )
     {
       curr_func = getn_func(i);
       if ( NULL == curr_func )
       {
         RP_TRACE1("PIC: cannot get func N %d\n", i);
         continue;
       }
       process_PIC(curr_func->startEA, curr_func->endEA);
     }
#if defined(PIC_DEBUG) || defined(PIC_SHOW)
     if ( NULL != rp_log_fp )
     {
      fclose(rp_log_fp);
      rp_log_fp = NULL;
     }
#endif
    break;
   default:
     warning("PIC: Unknown arg %d", arg);
    break;
  } /* switch */
}