Esempio n. 1
0
static int idaapi 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("$ h8");
      helper.supval(0, device, sizeof(device));
      inf.mf = 1;
    default:
      break;

    /* +++ START TYPEINFO CALLBACKS +++ */
    // see module/{i960,hppa}/reg.cpp starting on line 253
    // Decorate/undecorate a C symbol name
    // Arguments:
    // const til_t *ti    - pointer to til
    // const char *name   - name of symbol
    // const type_t *type - type of symbol. If NULL then it will try to guess.
    // char *outbuf       - output buffer
    // size_t bufsize     - size of the output buffer
    // bool mangle        - true-mangle, false-unmangle
    // cm_t cc            - real calling convention for VOIDARG functions
    // returns: true if success
    case processor_t::decorate_name:
      {
        const til_t *ti    = va_arg(va, const til_t *);
        const char *name   = va_arg(va, const char *);
        const type_t *type = va_arg(va, const type_t *);
        char *outbuf       = va_arg(va, char *);
        size_t bufsize     = va_arg(va, size_t);
        bool mangle        = va_argi(va, bool);
        cm_t real_cc       = va_argi(va, cm_t);
        return gen_decorate_name(ti, name, type, outbuf, bufsize, mangle, real_cc);
      }

    // Setup default type libraries (called after loading a new file into the database)
    // The processor module may load tils, setup memory model and perform other actions
    // required to set up the type system.
    // args:    none
    // returns: nothing
    case processor_t::setup_til:
      {
      }

    // Purpose: get prefix and size of 'segment based' ptr type (something like
    // char _ss *ptr). See description in typeinf.hpp.
    // Other modules simply set the pointer to NULL and return 0
    // Ilfak confirmed that this approach is correct for the H8.
    // Used only for BTMT_CLOSURE types, doubtful you will encounter them for H8.
    // Arguments:
    // unsigned int ptrt    - ...
    // const char **ptrname - output arg
    // returns: size of type
    case processor_t::based_ptr:
      {
        /*unsigned int ptrt =*/ va_arg(va, unsigned int);
        char **ptrname    = va_arg(va, char **);
        *ptrname = NULL;
        return 0;
      }

    // The H8 supports normal (64KB addressing, 16 bits) and advanced mode
    // (16MB addressing, 24 bits).  However, according to the Renesas technical
    // documentation, certain instructions accept 32-bit pointer values where
    // the upper 8 bits are "reserved".  Ilfak confirms that "4+1" is fine.
    // Used only for BTMT_CLOSURE types, doubtful you will encounter them for H8.
    case processor_t::max_ptr_size:
      {
        return 4+1;
      }

    // get default enum size
    // args:  cm_t cm
    // returns: sizeof(enum)
    case processor_t::get_default_enum_size:
      {
        // cm_t cm        =  va_argi(va, cm_t);
        return inf.cc.size_e;
      }

    case processor_t::use_stkarg_type:
      {
        ea_t ea            = va_arg(va, ea_t);
        const type_t *type = va_arg(va, const type_t *);
        const char *name   = va_arg(va, const char *);
        return h8_use_stkvar_type(ea, type, name);
      }

    // calculate number of purged bytes by the given function type
    // For cdecl functions, 'purged bytes' is always zero
    // See the IDA Pro Book, 2e, at the end of pp. 107 for details
    // args: type_t *type - must be function type
    // returns: number of bytes purged from the stack + 2
    case processor_t::calc_purged_bytes:
      {
        //e.g. const type_t t_int[] = { BT_INT, 0 };
        //const type_t *type = va_arg(va, const type_t *); // must be BT_FUNC
        return 0+2;
      }

    case processor_t::calc_arglocs2:
      {
        const type_t *type = va_arg(va, const type_t *);
        cm_t cc            = va_argi(va, cm_t);
        varloc_t *arglocs  = va_arg(va, varloc_t *);
        return h8_calc_arglocs(type, cc, arglocs);
      }

    /* +++ END TYPEINFO CALLBACKS +++ */

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

    case processor_t::newfile:   // new file loaded
      load_symbols();
      break;

    case processor_t::oldfile:   // old file loaded
      load_symbols();
      break;

    case processor_t::closebase:
    case processor_t::savebase:
      helper.supset(0, device);
      break;

    case processor_t::newprc:    // new processor type
      ptype = ptypes[va_arg(va, int)];
      setflag(ph.flag, PR_DEFSEG32, ptype & ADV);
      break;

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

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

    case processor_t::is_jump_func:
      {
        const func_t *pfn = va_arg(va, const func_t *);
        ea_t *jump_target = va_arg(va, ea_t *);
        return is_jump_func(pfn, jump_target);
      }

    case processor_t::is_sane_insn:
      return is_sane_insn(va_arg(va, int));

    case processor_t::may_be_func:
                                // can a function start here?
                                // arg: none, the instruction is in 'cmd'
                                // returns: probability 0..100
                                // 'cmd' structure is filled upon the entrace
                                // the idp module is allowed to modify 'cmd'
      return may_be_func();

  }
  va_end(va);
  return 1;
}
Esempio n. 2
0
int idaapi DBG_Callback(void *ud, int notification_code, va_list va)
{
  // This hook gets called from the kernel. Ensure we hold the GIL.
  PYW_GIL_GET;

  class DBG_Hooks *proxy = (class DBG_Hooks *)ud;
  debug_event_t *event;
  int code = 0;

  try
  {
    switch (notification_code)
    {
    case dbg_process_start:
      event = va_arg(va, debug_event_t *);
      proxy->dbg_process_start(event->pid,
        event->tid,
        event->ea,
        event->modinfo.name,
        event->modinfo.base,
        event->modinfo.size);
      break;

    case dbg_process_exit:
      event = va_arg(va, debug_event_t *);
      proxy->dbg_process_exit(
        event->pid,
        event->tid,
        event->ea,
        event->exit_code);
      break;

    case dbg_process_attach:
      event = va_arg(va, debug_event_t *);
      proxy->dbg_process_attach(
        event->pid,
        event->tid,
        event->ea,
        event->modinfo.name,
        event->modinfo.base,
        event->modinfo.size);
      break;

    case dbg_process_detach:
      event = va_arg(va, debug_event_t *);
      proxy->dbg_process_detach(
        event->pid,
        event->tid,
        event->ea);
      break;

    case dbg_thread_start:
      event = va_arg(va, debug_event_t *);
      proxy->dbg_thread_start(
        event->pid,
        event->tid,
        event->ea);
      break;

    case dbg_thread_exit:
      event = va_arg(va, debug_event_t *);
      proxy->dbg_thread_exit(
        event->pid,
        event->tid,
        event->ea,
        event->exit_code);
      break;

    case dbg_library_load:
      event = va_arg(va, debug_event_t *);
      proxy->dbg_library_load(
        event->pid,
        event->tid,
        event->ea,
        event->modinfo.name,
        event->modinfo.base,
        event->modinfo.size);
      break;

    case dbg_library_unload:
      event = va_arg(va, debug_event_t *);
      proxy->dbg_library_unload(
        event->pid,
        event->tid,
        event->ea,
        event->info);
      break;

    case dbg_information:
      event = va_arg(va, debug_event_t *);
      proxy->dbg_information(
        event->pid,
        event->tid,
        event->ea,
        event->info);
      break;

    case dbg_exception:
    {
      event = va_arg(va, debug_event_t *);
      int *warn = va_arg(va, int *);
      *warn = proxy->dbg_exception(
        event->pid,
        event->tid,
        event->ea,
        event->exc.code,
        event->exc.can_cont,
        event->exc.ea,
        event->exc.info);
      break;
    }

    case dbg_suspend_process:
      proxy->dbg_suspend_process();
      break;

    case dbg_bpt:
    {
      thid_t tid = va_arg(va, thid_t);
      ea_t breakpoint_ea = va_arg(va, ea_t);
      int *warn = va_arg(va, int *);
      *warn = proxy->dbg_bpt(tid, breakpoint_ea);
      break;
    }

    case dbg_trace:
    {
      thid_t tid = va_arg(va, thid_t);
      ea_t ip = va_arg(va, ea_t);
      code = proxy->dbg_trace(tid, ip);
      break;
    }

    case dbg_request_error:
    {
      int failed_command = (int)va_argi(va, ui_notification_t);
      int failed_dbg_notification = (int)va_argi(va, dbg_notification_t);
      proxy->dbg_request_error(failed_command, failed_dbg_notification);
      break;
    }

    case dbg_step_into:
      proxy->dbg_step_into();
      break;

    case dbg_step_over:
      proxy->dbg_step_over();
      break;

    case dbg_run_to:
      event = va_arg(va, debug_event_t *);
      proxy->dbg_run_to(
        event->pid,
        event->tid,
        event->ea);
      break;

    case dbg_step_until_ret:
      proxy->dbg_step_until_ret();
      break;
    }
  }
  catch (Swig::DirectorException &e)
  {
    msg("Exception in DBG Hook function: %s\n", e.getMessage());
    if (PyErr_Occurred())
      PyErr_Print();
  }
  return code;
}
Esempio n. 3
0
// The kernel event notifications
// Here you may take desired actions upon some kernel events
static int idaapi 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::init:
		inf.mf = 1;
		helper.create("$ fr");
	default:
		break;

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

	case processor_t::newfile:
		choose_device();
		set_device_name(device, IORESP_ALL);
		break;

	case processor_t::oldfile:
		{
			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.supset(-1, device);
		break;

	case processor_t::is_basic_block_end:
		return is_basic_block_end() ? 2 : 0;


#ifdef FR_TYPEINFO_SUPPORT
		// +++ TYPE CALLBACKS
	case processor_t::max_ptr_size:
		return 4+1;

	case processor_t::get_default_enum_size: // get default enum size
		// args:  cm_t cm
		// returns: sizeof(enum)
		{
			//        cm_t cm        =  va_argi(va, cm_t);
			return 1; // inf.cc.size_e;
		}

	case processor_t::based_ptr:
		{
			uint ptrt      = va_arg(va, unsigned int); qnotused(ptrt);
			char **ptrname = va_arg(va, char **);
			*ptrname = NULL;
			return 0;                       // returns: size of type
		}

	case processor_t::get_stkarg_offset2:
		// get offset from SP to the first stack argument
		// args: none
		// returns: the offset+2
		return 0x00 + 2;

	case processor_t::calc_cdecl_purged_bytes2:
		// calculate number of purged bytes after call
		{
			//ea_t ea = va_arg(va, ea_t);
			return 0x00 + 2;
		}

#endif // FR_TYPEINFO_SUPPORT 
#ifdef FR_TINFO_SUPPORT
	case processor_t::decorate_name3:
		{
			qstring *outbuf  = va_arg(va, qstring *);
			const char *name = va_arg(va, const char *);
			bool mangle      = va_argi(va, bool);
			cm_t cc          = va_argi(va, cm_t);
			return gen_decorate_name3(outbuf, name, mangle, cc) ? 2 : 0;
		}

	case processor_t::calc_retloc3:
		//msg("calc_retloc3\n");
		{
			const tinfo_t *type = va_arg(va, const tinfo_t *);
			cm_t cc             = va_argi(va, cm_t);
			argloc_t *retloc    = va_arg(va, argloc_t *);
			return calc_fr_retloc(*type, cc, retloc) ? 2 : -1;
		}
		break;  

	case processor_t::calc_varglocs3:
		return 1; // not implemented
		break;

	case processor_t::calc_arglocs3:
		{
			//msg("calc_arglocs3\n");
			func_type_data_t *fti = va_arg(va, func_type_data_t *);
			return calc_fr_arglocs(fti) ? 2 : -1;
		}

	case processor_t::use_stkarg_type3:
		{
			//msg("use_stkarg_type3\n");
			ea_t ea               = va_arg(va, ea_t);
			const funcarg_t *arg  = va_arg(va, const funcarg_t* );
		}
		return false;
		break;

	case processor_t::use_regarg_type3:
		//msg("use_regarg_type3\n");
		{
			int *used                 = va_arg(va, int *);
			ea_t ea                   = va_arg(va, ea_t);
			const funcargvec_t *rargs = va_arg(va, const funcargvec_t *);
			*used = use_fr_regarg_type(ea, *rargs);
			return 2;
		}
		break;

	case processor_t::use_arg_types3:
		{
			ea_t ea               = va_arg(va, ea_t);
			func_type_data_t *fti = va_arg(va, func_type_data_t *);
			funcargvec_t *rargs   = va_arg(va, funcargvec_t *);
			use_fr_arg_types(ea, fti, rargs);
			return 2;
		}
#ifdef IDA65
	case processor_t::get_fastcall_regs2:
	case processor_t::get_varcall_regs2:
		{
			const int **regs = va_arg(va, const int **);
			return get_fr_fastcall_regs(regs) + 2;
		}

	case processor_t::get_thiscall_regs2:
		{
			const int **regs = va_arg(va, const int **);
			*regs = NULL;
			return 2;
		}
#else
	case processor_t::get_fastcall_regs3:
	case processor_t::get_varcall_regs3:
		{
			const int *regs;
			get_fr_fastcall_regs(&regs);
			callregs_t *callregs = va_arg(va, callregs_t *);
			callregs->set(ARGREGS_INDEPENDENT, regs, NULL);
			return callregs->nregs + 2;
		}

	case processor_t::get_thiscall_regs3:
		{
			callregs_t *callregs = va_arg(va, callregs_t *);
			callregs->reset();
			return 2;
		}
#endif IDA65
#endif // FR_TINFO_SUPPORT
	}

    va_end(va);

    return(1);
}
Esempio n. 4
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("$ hppa");
      inf.mf = 1;         // always big endian
      syscalls = read_ioports(&nsyscalls, "hpux.cfg", NULL, 0, NULL);
      break;

    case processor_t::term:
      free_ioports(syscalls, nsyscalls);
      break;

    case processor_t::newfile:      // new file loaded
      handle_new_flags();
      setup_got();
      break;

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

    case processor_t::newprc:    // new processor type
      break;

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

    case processor_t::newseg:    // new segment
      {
        segment_t *sptr = va_arg(va, segment_t *);
        sptr->defsr[ rVds-ph.regFirstSreg] = find_selector(sptr->sel);
        sptr->defsr[DPSEG-ph.regFirstSreg] = 0;
      }
      break;

    case processor_t::is_sane_insn:
      return is_sane_insn(va_arg(va, int));

    case processor_t::may_be_func:
                                // can a function start here?
                                // arg: none, the instruction is in 'cmd'
                                // returns: probability 0..100
                                // 'cmd' structure is filled upon the entrace
                                // the idp module is allowed to modify 'cmd'
      return may_be_func();

    case processor_t::is_basic_block_end:
      return is_basic_block_end() ? 2 : 0;

// +++ TYPE CALLBACKS (only 32-bit programs for the moment)
    case processor_t::decorate_name:
      {
        const til_t *ti    = va_arg(va, const til_t *);
        const char *name   = va_arg(va, const char *);
        const type_t *type = va_arg(va, const type_t *);
        char *outbuf       = va_arg(va, char *);
        size_t bufsize     = va_arg(va, size_t);
        bool mangle        = va_argi(va, bool);
        cm_t real_cc       = va_argi(va, cm_t);
        return gen_decorate_name(ti, name, type, outbuf, bufsize, mangle, real_cc);
      }

    case processor_t::max_ptr_size:
      return 4+1;

    case processor_t::based_ptr:
      {
        /*unsigned int ptrt =*/ va_arg(va, unsigned int);
        char **ptrname    = va_arg(va, char **);
        *ptrname = NULL;
        return 0;                       // returns: size of type
      }

    case processor_t::get_default_enum_size: // get default enum size
                                // args:  cm_t cm
                                // returns: sizeof(enum)
      {
//        cm_t cm        =  va_arg(va, cm_t);
        return inf.cc.size_e;
      }

    case processor_t::calc_arglocs:
      {
        const type_t **type = va_arg(va, const type_t **);
        ulong *arglocs      = va_arg(va, ulong *);
        int maxn            = va_arg(va, int);
        return hppa_calc_arglocs(*type, arglocs, maxn);
      }

    // this callback is never used because the stack pointer does not
    // change for each argument
    // we use ph.use_arg_types instead
    case processor_t::use_stkarg_type:
                                    // use information about a stack argument
      {
        return false;               // say failed all the time
                                    // so that the kernel attaches a comment
      }

    case processor_t::use_regarg_type:
      {
        ea_t ea                     = va_arg(va, ea_t);
        const type_t * const *types = va_arg(va, const type_t * const *);
        const char * const *names   = va_arg(va, const char * const *);
        const ulong *regs           = va_arg(va, const ulong *);
        int n                       = va_arg(va, int);
        return hppa_use_regvar_type(ea, types, names, regs, n);
      }

    case processor_t::use_arg_types:
      {
        ea_t ea                     = va_arg(va, ea_t);
        const type_t * const *types = va_arg(va, const type_t * const *);
        const char * const *names   = va_arg(va, const char * const *);
        const ulong *arglocs        = va_arg(va, const ulong *);
        int n                       = va_arg(va, int);
        const type_t **rtypes       = va_arg(va, const type_t **);
        const char **rnames         = va_arg(va, const char **);
        ulong *regs                 = va_arg(va, ulong *);
        int rn                      = va_arg(va, int);
        return hppa_use_arg_types(ea, types, names, arglocs, n,
                                  rtypes, rnames, regs, rn);
      }

    case processor_t::get_fastcall_regs:
      {
        const int **regs = va_arg(va, const int **);
        static const int fregs[] = { R26, R25, R24, R23, -1 };
        *regs = fregs;
        return qnumber(fregs) - 1;
      }

    case processor_t::get_thiscall_regs:
      {
        const int **regs = va_arg(va, const int **);
        *regs = NULL;
        return 0;
      }

    case processor_t::calc_cdecl_purged_bytes:
                                // calculate number of purged bytes after call
      {
        // ea_t ea                     = va_arg(va, ea_t);
        return 0;
      }

    case processor_t::get_stkarg_offset:
                                // get offset from SP to the first stack argument
                                // args: none
                                // returns: the offset
      return -0x34;

// --- TYPE CALLBACKS
    case processor_t::loader:
      break;
  }
  va_end(va);
  return 1;
}