|
|
|
#include "qvm_virtual_routines.h"
|
|
|
|
|
|
|
|
qvm_virtual_routines::qvm_virtual_routines( qvm_inspector *g_main_window )
|
|
|
|
: g_main_window( g_main_window ), ui( &g_main_window->ui )
|
|
|
|
{
|
|
|
|
connect( ui->virtual_machine_enters, &QTreeWidget::itemSelectionChanged, this, &qvm_virtual_routines::on_select );
|
|
|
|
}
|
|
|
|
|
|
|
|
void qvm_virtual_routines::update_vm_enter( vm::ctx_t *g_vm_ctx )
|
|
|
|
{
|
|
|
|
char buffer[ 256 ];
|
|
|
|
ZydisFormatter formatter;
|
|
|
|
ZydisFormatterInit( &formatter, ZYDIS_FORMATTER_STYLE_INTEL );
|
|
|
|
|
|
|
|
ui->virtual_machine_enter_instrs->clear();
|
|
|
|
for ( auto [ instr, raw, addr ] : g_vm_ctx->vm_entry )
|
|
|
|
{
|
|
|
|
ZydisFormatterFormatInstruction( &formatter, &instr, buffer, sizeof( buffer ), addr );
|
|
|
|
auto newItem = new QTreeWidgetItem();
|
|
|
|
newItem->setText( 0, QString::number( addr, 16 ) );
|
|
|
|
newItem->setText( 1, buffer );
|
|
|
|
ui->virtual_machine_enter_instrs->addTopLevelItem( newItem );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void qvm_virtual_routines::update_calc_jmp( vm::ctx_t *g_vm_ctx )
|
|
|
|
{
|
|
|
|
char buffer[ 256 ];
|
|
|
|
ZydisFormatter formatter;
|
|
|
|
ZydisFormatterInit( &formatter, ZYDIS_FORMATTER_STYLE_INTEL );
|
|
|
|
|
|
|
|
ui->virtual_machine_enter_calc_jmp->clear();
|
|
|
|
for ( auto [ instr, raw, addr ] : g_vm_ctx->calc_jmp )
|
|
|
|
{
|
|
|
|
ZydisFormatterFormatInstruction( &formatter, &instr, buffer, sizeof( buffer ), addr );
|
|
|
|
auto newItem = new QTreeWidgetItem();
|
|
|
|
newItem->setText( 0, QString::number( addr, 16 ) );
|
|
|
|
newItem->setText( 1, buffer );
|
|
|
|
ui->virtual_machine_enter_calc_jmp->addTopLevelItem( newItem );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void qvm_virtual_routines::update_vm_handlers( vm::ctx_t *g_vm_ctx )
|
|
|
|
{
|
|
|
|
ui->virt_handlers_tree->clear();
|
|
|
|
for ( auto idx = 0u; idx < g_vm_ctx->vm_handlers.size(); ++idx )
|
|
|
|
{
|
|
|
|
auto newItem = new QTreeWidgetItem;
|
|
|
|
newItem->setData( 0, Qt::UserRole, idx );
|
|
|
|
newItem->setText( 0, QString( "%1" ).arg( idx ) );
|
|
|
|
newItem->setText( 1, QString( "%1" ).arg( ABS_TO_IMG( g_vm_ctx->vm_handlers[ idx ].address,
|
|
|
|
g_main_window->file_header->module_base,
|
|
|
|
g_main_window->file_header->image_base ),
|
|
|
|
0, 16 ) );
|
|
|
|
|
|
|
|
newItem->setText( 2, g_vm_ctx->vm_handlers[ idx ].profile ? g_vm_ctx->vm_handlers[ idx ].profile->name
|
|
|
|
: "UNDEFINED" );
|
|
|
|
|
|
|
|
newItem->setText( 3, QString( "%1" ).arg( g_vm_ctx->vm_handlers[ idx ].imm_size ) );
|
|
|
|
|
|
|
|
if ( g_vm_ctx->vm_handlers[ idx ].profile && g_vm_ctx->vm_handlers[ idx ].imm_size )
|
|
|
|
newItem->setText( 4,
|
|
|
|
g_vm_ctx->vm_handlers[ idx ].profile->extention == vm::handler::extention_t::sign_extend
|
|
|
|
? "SIGN EXTENDED"
|
|
|
|
: "ZERO EXTENDED" );
|
|
|
|
else
|
|
|
|
newItem->setText( 4, "UNDEFINED" );
|
|
|
|
|
|
|
|
ui->virt_handlers_tree->addTopLevelItem( newItem );
|
|
|
|
}
|
|
|
|
ui->virt_handlers_tree->topLevelItem( 0 )->setSelected( true );
|
|
|
|
}
|
|
|
|
|
|
|
|
void qvm_virtual_routines::on_select()
|
|
|
|
{
|
|
|
|
if ( ui->virtual_machine_enters->selectedItems().empty() )
|
|
|
|
return;
|
|
|
|
|
|
|
|
auto item = ui->virtual_machine_enters->selectedItems()[ 0 ];
|
|
|
|
|
|
|
|
if ( !item || !item->childCount() )
|
|
|
|
return;
|
|
|
|
|
|
|
|
auto entry_rva = item->data( 0, Qt::UserRole ).value< std::uint32_t >();
|
|
|
|
|
|
|
|
if ( !entry_rva )
|
|
|
|
return;
|
|
|
|
|
|
|
|
if ( g_main_window->g_vm_ctx )
|
|
|
|
delete g_main_window->g_vm_ctx;
|
|
|
|
|
|
|
|
g_main_window->g_vm_ctx =
|
|
|
|
new vm::ctx_t( g_main_window->module_base, g_main_window->img_base, g_main_window->img_size, entry_rva );
|
|
|
|
|
|
|
|
if ( !g_main_window->g_vm_ctx->init() )
|
|
|
|
{
|
|
|
|
g_main_window->dbg_msg( "[!] failed to init vm::ctx_t...\n" );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
update_vm_enter( g_main_window->g_vm_ctx );
|
|
|
|
update_calc_jmp( g_main_window->g_vm_ctx );
|
|
|
|
update_vm_handlers( g_main_window->g_vm_ctx );
|
|
|
|
|
|
|
|
ui->virt_instrs->clear();
|
|
|
|
g_main_window->code_block_addrs.clear();
|
|
|
|
g_main_window->update_virtual_instructions( entry_rva );
|
|
|
|
}
|