Beispiel #1
0
//--------------------------------------------------------------------------
bool idaapi menu_callback(void *ud)
{
  graph_viewer_t *gv = (graph_viewer_t *)ud;
  mutable_graph_t *g = get_viewer_graph(gv);
  int code = askbuttons_c("Circle", "Tree", "Digraph", 1, "Please select layout type");
  bgcolor_t c = 0x44FF55;
  set_node_info(g->gid, 7, &c, NULL, "Hello from plugin!");
  g->current_layout = code + 2;
  g->circle_center = point_t(200, 200);
  g->circle_radius = 200;
  g->redo_layout();
  refresh_viewer(gv);
  return true;
}
Beispiel #2
0
int struct_init(ea_t addr, ea_t base, size_t size)
{
	char buf[1024];
	strace_t *st = strace;

	// skip if this alloc has already been identified
	while(st)
	{
		if(st->addr == addr)
			return 0;
		st = st->next;
	}

	if(!size && options.detect_size)
	{
		if((size = analyze_struct_size(addr)) < 0)
			if(options.verbose)
				msg("[idastruct] could not auto-detect structure size\n");
	}
	
	// failsafe -- if size wasn't detected, just ask for it
	if(!size)
	{
		if(!asklong((sval_t *)&size, "Structure size"))
		{
			if(options.verbose)
				msg("[idastruct] structure size unknown .. skipping\n");
			return -1;
		}
	}
	

	// check call history for action to take on this call
	if(allocator_call_hist(addr) != -1)
		return -1;

	// this call has not been traced or permanently skipped
	get_disasm(addr, buf, 1024);
	int ref = askbuttons_c(NULL, NULL, "Skip once", 0, 
		"Create structure reference at this call:\n\n%s        (%d bytes @ 0x%08x)",
		buf, size, base);

	// skip once 
	if(ref == -1)
		return -1;

	// save action for this call
	struct _alloc_hist *cur = (struct _alloc_hist *)qcalloc(1, sizeof(struct _alloc_hist));
	if(!cur)
	{
		msg("[idastruct] error: could not store allocator state\n");
		return -1;
	}
	cur->addr = addr;
	cur->cstruct = ref;

	// insert into history
	cur->next = alloc_hist;
	alloc_hist = cur;  

	// user decided to not trace structure
	if(ref == 0)
		return -1; 

	// create structure trace
	st = (strace_t *)qcalloc(1, sizeof(strace_t));
	if(!st)
	{
		msg("[idastruct] error: could not allocate memory\n");
		return -1;
	}

	st->addr = addr;
	st->size = size;
	st->base = base;
	st->sptr = struct_create(st->size);
	if(!st->sptr)
		return -1;

	if(options.verbose)
	{
		msg("[idastruct] structure initialized\n");
		msg("            code origin:    0x%08x\n", addr);
		msg("            structure base: 0x%08x\n", st->base);
		msg("            structure size: %d bytes\n", st->size);
	}

	// push struct trace
	st->next = strace; 
	strace = st; 	

	return 0;
}
Beispiel #3
0
//--------------------------------------------------------------------------
// ipath==input file path
static bool ask_user_and_copy(const char *ipath)
{
  // check if the input file exists at the current dir of the remote host
  const char *input_file = ipath;
#if DEBUGGER_ID != DEBUGGER_ID_ARM_EPOC_USER
  input_file = qbasename(input_file);
#endif
  int fn = -1;
  // try to open remote file in the current dir if not tried before
  if ( input_file != ipath )
    fn = s_open_file(input_file, NULL, true);
  if ( fn != -1 )
  {
    s_close_file(fn);
    switch ( askbuttons_c("~U~se found",
                          "~C~opy new",
                          "Cancel",
                          1,
                          "IDA could not find the remote file %s.\n"
                          "But it could find remote file %s.\n"
                          "Do you want to use the found file?",
                          ipath, input_file) )
    {
      case 1:
        set_root_filename(input_file);
        return true;
      case -1:
        return false;
    }
    // the user wants to overwrite the old file
  }
  else
  {
    if ( askyn_c(1, "HIDECANCEL\n"
                    "The remote file %s could not be found.\n"
                    "Do you want IDA to copy the executable to the remote computer?",
                    ipath) <= 0 )
      return false;
  }

  // We are to copy the input file to the remote computer's current directory
  const char *lname = ipath;
  // check if the file path is valid on the local system
  if ( !qfileexist(lname) )
  {
    lname = askfile_c(false, lname, "Please select the file to copy");
    if ( lname == NULL )
      return false;
  }
#if DEBUGGER_ID == DEBUGGER_ID_ARM_EPOC_USER
  const char *rname = input_file;
#else
  const char *rname = qbasename(lname);
#endif
  int code = copy_to_remote(lname, rname);
  if ( code != 0 )
  {
#if DEBUGGER_ID == DEBUGGER_ID_ARM_WINCE_USER
    // Windows CE does not have errno and uses GetLastError()
    const char *err = winerr(code);
#else
    const char *err = qerrstr(code);
#endif
    warning("Failed to copy %s -> %s\n%s", lname, rname, err);
  }
  set_root_filename(rname);
  return true;
}
Beispiel #4
0
//--------------------------------------------------------------------------
// 1-ok, 0-failed, -1-error
static int idaapi get_debug_event(debug_event_t *event, bool ida_is_idle)
{
  int code = s_get_debug_event(event, ida_is_idle);
  if ( code == 1 )
  {
    // determine rebasing - we can't do that reliabily remotely, because:
    // - 'is_dll' is not passed to attach_process(), and we can't modify
    //   the protocol without breaking compatibility
    // - 'input_file_path' is undefined if attach_process() but process_get_info()
    //   was not called (if debugger started from the command line with PID)
    switch ( event->eid )
    {
      case PROCESS_ATTACH:
#if DEBUGGER_ID == DEBUGGER_ID_ARM_WINCE_USER
        info("AUTOHIDE REGISTRY\n"
             "Successfully attached to the process.\n"
             "Now you can browse the process memory and set breakpoints.\n");
#endif
        // no break
      case PROCESS_START:
        event->modinfo.rebase_to = is_dll ? BADADDR : event->modinfo.base;
      default:
        break;

      case LIBRARY_LOAD:
        {
          // get input module info
          char full_input_file[QMAXFILE];
          dbg_get_input_path(full_input_file, sizeof(full_input_file));
          char *base_input_file = qbasename(full_input_file);

          // get current module info
          char *full_modname = event->modinfo.name;
          char *base_modname = qbasename(full_modname);

          // we compare basenames and then full path
          // if they have same base names, then we ask the user
          if ( stricmp(base_input_file, base_modname) == 0 )
          {
            // let us compare full path now, if they match, then rebase
            bool rebase = stricmp(full_input_file, full_modname) == 0;

            // no match, we may have same names different files
            if ( !rebase )
            {
              static const char dbg_module_conflict[] =
                "TITLE Debugger warning\n"
                "ICON WARNING\n"
                "HIDECANCEL\n"
                "AUTOHIDE DATABASE\n"
                "Debugger found two modules with same base name but different paths\n"
                "This could happen if the program loads the module from a path different than the specified input file\n"
                "\n"
                "Is the loaded file <%s> the same as the input file <%s>?\n";

              rebase = askbuttons_c("~S~ame", "~N~ot the same", NULL, 1, dbg_module_conflict, full_modname, full_input_file) == 1;
            }
            if ( rebase )
              event->modinfo.rebase_to = event->modinfo.base;
          }
          break;
        }
    }
  }
  return code;
}
Beispiel #5
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();
}