Files
2021-10-31 21:20:46 +02:00

113 lines
3.0 KiB
C++

#include <idp.hpp>
#include <dbg.hpp>
#include <loader.hpp>
//--------------------------------------------------------------------------
struct plugin_ctx_t : public plugmod_t, public event_listener_t
{
int g_nb_insn = 0;
const int g_max_insn = 20;
~plugin_ctx_t()
{
// listeners are uninstalled automatically
// when the owner module is unloaded
}
virtual bool idaapi run(size_t) override;
virtual ssize_t idaapi on_event(ssize_t code, va_list va) override;
};
//--------------------------------------------------------------------------
ssize_t idaapi plugin_ctx_t::on_event(ssize_t code, va_list va)
{
switch ( code )
{
case dbg_process_start:
// reset instruction counter
g_nb_insn = 0;
break;
case dbg_run_to:
msg("tracer: entrypoint reached\n");
enable_insn_trace(true);
// 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;
// A step occurred (one instruction was executed). This event
// notification is only generated if step tracing is enabled.
case dbg_trace:
{
/*thid_t tid =*/ va_arg(va, thid_t);
ea_t ip = va_arg(va, ea_t);
msg("[%d] tracing over: %a\n", g_nb_insn, ip);
if ( g_nb_insn == g_max_insn )
{
// stop the trace mode and suspend the process
disable_step_trace();
suspend_process();
msg("process suspended (traced %d instructions)\n", g_max_insn);
}
else
{
g_nb_insn++;
}
}
break;
case dbg_process_exit:
unhook_event_listener(HT_DBG, this);
break;
}
return 0;
}
//--------------------------------------------------------------------------
bool idaapi plugin_ctx_t::run(size_t)
{
if ( !hook_event_listener(HT_DBG, this) )
{
warning("Could not hook to notification point");
return true;
}
if ( dbg == NULL )
load_debugger("win32", false);
// Let's start the debugger
if ( !run_to(inf_get_start_ea()) )
unhook_event_listener(HT_DBG, this);
return true;
}
//--------------------------------------------------------------------------
static plugmod_t *idaapi init()
{
// Our plugin works only for x86 PE executables
if ( PH.id != PLFM_386 || inf_get_filetype() != f_PE )
return nullptr;
return new plugin_ctx_t;
}
//--------------------------------------------------------------------------
//
// PLUGIN DESCRIPTION BLOCK
//
//--------------------------------------------------------------------------
plugin_t PLUGIN =
{
IDP_INTERFACE_VERSION,
PLUGIN_MULTI, // The plugin can work with multiple idbs in parallel
init, // initialize
nullptr,
nullptr,
"Instruction tracer sample", // long comment about the plugin
"", // multiline help about the plugin
"tracer", // the preferred short name of the plugin
"", // the preferred hotkey to run the plugin
};