191 lines
4.5 KiB
C++
191 lines
4.5 KiB
C++
//---------------------------------------------------------------------------
|
|
// Hex view sample plugin
|
|
|
|
#include <ida.hpp>
|
|
#include <idp.hpp>
|
|
#include <loader.hpp>
|
|
#include <kernwin.hpp>
|
|
|
|
//---------------------------------------------------------------------------
|
|
// hex data
|
|
class hex_data_t : public plugmod_t, public event_listener_t
|
|
{
|
|
TWidget *cv = nullptr;
|
|
TWidget *hexview = nullptr;
|
|
|
|
FILE *f = nullptr;
|
|
uint64 sz = 10000;
|
|
const uint align = 16;
|
|
|
|
public:
|
|
|
|
hex_data_t()
|
|
{
|
|
hook_event_listener(HT_VIEW, this);
|
|
}
|
|
~hex_data_t()
|
|
{
|
|
// listeners are uninstalled automatically
|
|
// when the owner module is unloaded
|
|
close();
|
|
}
|
|
|
|
virtual bool idaapi run(size_t) override;
|
|
virtual ssize_t idaapi on_event(ssize_t code, va_list va) override;
|
|
|
|
bool open(const char *fname)
|
|
{
|
|
close();
|
|
f = qfopen(fname, "rb");
|
|
if ( f == NULL )
|
|
return false;
|
|
// 64 bit functions could be used instead
|
|
qfseek(f, 0, SEEK_END);
|
|
sz = qftell(f);
|
|
return true;
|
|
}
|
|
|
|
void close()
|
|
{
|
|
cv = nullptr;
|
|
hexview = nullptr;
|
|
if ( f != nullptr )
|
|
{
|
|
qfclose(f);
|
|
f = nullptr;
|
|
sz = 0;
|
|
}
|
|
}
|
|
|
|
bool read(uint64 pos, void *buf, size_t bufsize)
|
|
{
|
|
// 64 bit functions could be used instead
|
|
if ( qfseek(f, pos, SEEK_SET) != 0 )
|
|
return false;
|
|
return qfread(f, buf, bufsize) == bufsize;
|
|
}
|
|
|
|
uint64 size() const
|
|
{
|
|
return sz;
|
|
}
|
|
|
|
int alignment() const
|
|
{
|
|
return align;
|
|
}
|
|
|
|
uval_t pos_to_line(uint64 pos) const
|
|
{
|
|
return pos / align;
|
|
}
|
|
|
|
uval_t maxline() const
|
|
{
|
|
return pos_to_line(sz - 1);
|
|
}
|
|
};
|
|
|
|
//---------------------------------------------------------------------------
|
|
// hex place
|
|
define_place_exported_functions(hex_place_t)
|
|
|
|
//-------------------------------------------------------------------------
|
|
class hex_place_t : public place_t
|
|
{
|
|
public:
|
|
hex_data_t *d;
|
|
uval_t n;
|
|
hex_place_t() : d(nullptr), n(0) { lnnum = 0; }
|
|
hex_place_t(hex_data_t *_d, uint64 pos = 0) : d(_d)
|
|
{
|
|
n = d->pos_to_line(pos);
|
|
lnnum = 0;
|
|
}
|
|
define_place_virtual_functions(hex_place_t)
|
|
};
|
|
#include "hexplace.cpp"
|
|
|
|
//--------------------------------------------------------------------------
|
|
ssize_t idaapi hex_data_t::on_event(ssize_t code, va_list va)
|
|
{
|
|
switch ( code )
|
|
{
|
|
case ui_widget_invisible:
|
|
{
|
|
TWidget *w = va_arg(va, TWidget *);
|
|
if ( w == hexview || w == cv )
|
|
{
|
|
close();
|
|
unhook_event_listener(HT_UI, this);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
// Create a custom view window
|
|
bool idaapi hex_data_t::run(size_t)
|
|
{
|
|
register_hex_place();
|
|
|
|
static const char title[] = "Sample hexview";
|
|
TWidget *widget = find_widget(title);
|
|
if ( widget != NULL )
|
|
{
|
|
warning("Hexview already open. Switching to it.");
|
|
activate_widget(widget, true);
|
|
return true;
|
|
}
|
|
|
|
// ask the user to select a file
|
|
char *filename = ask_file(false, NULL, "Select a file to display...");
|
|
if ( filename == NULL || filename[0] == 0 )
|
|
return true;
|
|
// open the file
|
|
if ( !open(filename) )
|
|
return true;
|
|
|
|
// create two place_t objects: for the minimal and maximal locations
|
|
hex_place_t s1(this);
|
|
hex_place_t s2(this, size() - 1);
|
|
// create a custom viewer
|
|
cv = create_custom_viewer(title, &s1, &s2, &s1, NULL, this, NULL, NULL);
|
|
// create a code viewer container for the custom view
|
|
hexview = create_code_viewer(cv);
|
|
// set the radix and alignment for the offsets
|
|
set_code_viewer_lines_radix(hexview, 16);
|
|
set_code_viewer_lines_alignment(hexview, size() > 0xFFFFFFFF ? 16 : 8);
|
|
// also set the ui event callback
|
|
hook_event_listener(HT_UI, this);
|
|
// finally display the form on the screen
|
|
display_widget(hexview, WOPN_DP_TAB|WOPN_RESTORE);
|
|
return true;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
static plugmod_t *idaapi init()
|
|
{
|
|
return new hex_data_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,
|
|
nullptr, // long comment about the plugin
|
|
nullptr, // multiline help about the plugin
|
|
"Sample hexview", // the preferred short name of the plugin
|
|
nullptr, // the preferred hotkey to run the plugin
|
|
};
|