crashing but getting there...

merge-requests/5/head
_xeroxz 3 years ago
parent b5fb4da5bb
commit b6a094cf12

@ -6,7 +6,7 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>1311</width> <width>1404</width>
<height>897</height> <height>897</height>
</rect> </rect>
</property> </property>

@ -3,12 +3,12 @@
#include <QTextStream> #include <QTextStream>
#include <QtWidgets/QApplication> #include <QtWidgets/QApplication>
#include "qvm_inspector.h" #include "darkstyle/DarkStyle.h"
#include "darkstyle/framelesswindow/framelesswindow.h"
#include "qvm_handlers.h" #include "qvm_handlers.h"
#include "qvm_inspector.h"
#include "qvm_virtual_instructions.h" #include "qvm_virtual_instructions.h"
#include "qvm_virtual_routines.h" #include "qvm_virtual_routines.h"
#include "darkstyle/DarkStyle.h"
#include "darkstyle/framelesswindow/framelesswindow.h"
int WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd ) int WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd )
{ {
@ -16,10 +16,10 @@ int WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int
QApplication::setStyle( new DarkStyle ); QApplication::setStyle( new DarkStyle );
FramelessWindow FW; FramelessWindow FW;
const auto g_main_window = new qvm_inspector; auto g_main_window = new qvm_inspector;
qvm_virtual_instructions VirtInstrsPanel( g_main_window ); qvm_virtual_instructions virt_instrs_panel( g_main_window );
qvm_handlers VirtHandlerPanel( g_main_window ); qvm_handlers virt_handler_panel( g_main_window );
qvm_virtual_routines VirtualRoutinesPanel( g_main_window ); qvm_virtual_routines virt_routine_panel( g_main_window );
FW.setContent( g_main_window ); FW.setContent( g_main_window );
FW.setWindowIcon( QIcon( "icon.ico" ) ); FW.setWindowIcon( QIcon( "icon.ico" ) );

@ -3,7 +3,7 @@
qvm_inspector::qvm_inspector( QWidget *parent ) : QMainWindow( parent ), file_header( nullptr ), g_vm_ctx( nullptr ) qvm_inspector::qvm_inspector( QWidget *parent ) : QMainWindow( parent ), file_header( nullptr ), g_vm_ctx( nullptr )
{ {
ui.setupUi( this ); ui.setupUi( this );
ui.virt_instrs->setColumnWidth( 0, 180 ); ui.virt_instrs->setColumnWidth( 0, 125 );
ui.virt_instrs->setColumnWidth( 1, 150 ); ui.virt_instrs->setColumnWidth( 1, 150 );
ui.virt_instrs->setColumnWidth( 2, 190 ); ui.virt_instrs->setColumnWidth( 2, 190 );
ui.virt_instrs->setColumnWidth( 3, 200 ); ui.virt_instrs->setColumnWidth( 3, 200 );
@ -178,7 +178,8 @@ bool qvm_inspector::serialize_vmp2( std::vector< rtn_data_t > &virt_rtns )
return true; return true;
} }
void qvm_inspector::update_virtual_instructions( std::uintptr_t rtn_addr, QTreeWidgetItem *parent ) void qvm_inspector::update_virtual_instructions( std::uintptr_t rtn_addr, std::uintptr_t blk_addr,
QTreeWidgetItem *parent )
{ {
auto _rtn = std::find_if( virt_rtns.begin(), virt_rtns.end(), auto _rtn = std::find_if( virt_rtns.begin(), virt_rtns.end(),
[ & ]( rtn_data_t &rtn ) -> bool { return rtn.rtn_rva == rtn_addr; } ); [ & ]( rtn_data_t &rtn ) -> bool { return rtn.rtn_rva == rtn_addr; } );
@ -186,11 +187,31 @@ void qvm_inspector::update_virtual_instructions( std::uintptr_t rtn_addr, QTreeW
if ( _rtn == virt_rtns.end() ) if ( _rtn == virt_rtns.end() )
return; return;
for ( const auto &vinstr : _rtn->rtn_blks[ 0 ].vinstrs ) auto code_blk = blk_addr ? std::find_if( _rtn->rtn_blks.begin(), _rtn->rtn_blks.end(),
[ & ]( const vm::instrs::code_block_t &code_block ) -> bool {
return code_block.vip_begin == blk_addr;
} )
: _rtn->rtn_blks.begin();
if ( code_blk == _rtn->rtn_blks.end() )
return;
if ( std::find( code_block_addrs.begin(), code_block_addrs.end(), code_blk->vip_begin ) != code_block_addrs.end() )
return;
code_block_addrs.push_back( code_blk->vip_begin );
for ( auto &vinstr : code_blk->vinstrs )
{ {
const auto profile = vm::handler::get_profile( vinstr.mnemonic_t ); const auto profile = vm::handler::get_profile( vinstr.mnemonic_t );
const auto &vm_handler = g_vm_ctx->vm_handlers[ vinstr.opcode ];
auto virt_instr_entry = new QTreeWidgetItem(); auto virt_instr_entry = new QTreeWidgetItem();
// virtual instruction image base'ed rva... (column 1)...
virt_instr_entry->setText(
0, QString( "0x%1" ).arg( QString::number(
( vinstr.trace_data.vip - file_header->module_base ) + file_header->image_base, 16 ) ) );
// virtual instruction operand bytes... (column 2)... // virtual instruction operand bytes... (column 2)...
QString operand_bytes; QString operand_bytes;
operand_bytes.append( QString( "%1" ).arg( vinstr.opcode, 0, 16 ) ); operand_bytes.append( QString( "%1" ).arg( vinstr.opcode, 0, 16 ) );
@ -220,6 +241,68 @@ void qvm_inspector::update_virtual_instructions( std::uintptr_t rtn_addr, QTreeW
virt_instr_entry->setText( virt_instr_entry->setText(
3, QString( "; vreg%1" ).arg( vinstr.operand.imm.u ? ( vinstr.operand.imm.u / 8 ) : 0u ) ); 3, QString( "; vreg%1" ).arg( vinstr.operand.imm.u ? ( vinstr.operand.imm.u / 8 ) : 0u ) );
ui.virt_instrs->addTopLevelItem( virt_instr_entry ); if ( vinstr.mnemonic_t == vm::handler::JMP )
{
switch ( code_blk->jcc.type )
{
case vm::instrs::jcc_type::branching:
{
virt_instr_entry->setText( 3, QString( "; { 0x%1, 0x%2 }" )
.arg( code_blk->jcc.block_addr[ 0 ], 0, 16 )
.arg( code_blk->jcc.block_addr[ 1 ], 0, 16 ) );
auto entry_rva = vm_handler.address - module_base;
auto branch_entry1 = new QTreeWidgetItem(), branch_entry2 = new QTreeWidgetItem();
const auto block1_addr = code_blk->jcc.block_addr[ 0 ];
const auto block2_addr = code_blk->jcc.block_addr[ 1 ];
branch_entry1->setText( 0, QString( "0x%1" ).arg( block1_addr, 0, 16 ) );
branch_entry1->setText( 3, QString( "; blk_0x%1" ).arg( block1_addr, 0, 16 ) );
branch_entry2->setText( 0, QString( "0x%1" ).arg( block2_addr, 0, 16 ) );
branch_entry2->setText( 3, QString( "; blk_0x%1" ).arg( block2_addr, 0, 16 ) );
if ( g_vm_ctx )
delete g_vm_ctx;
if ( !( g_vm_ctx = new vm::ctx_t( module_base, img_base, img_size, entry_rva ) )->init() )
{
dbg_print( QString( "> failed to init vm::ctx_t for jmp at = %1..." )
.arg( QString::number( code_blk->vip_begin, 16 ) ) );
return;
}
update_virtual_instructions( rtn_addr, code_blk->jcc.block_addr[ 0 ], branch_entry1 );
update_virtual_instructions( rtn_addr, code_blk->jcc.block_addr[ 1 ], branch_entry2 );
virt_instr_entry->addChildren( { branch_entry1, branch_entry2 } );
break;
}
case vm::instrs::jcc_type::absolute:
{
auto entry_rva = vm_handler.address - module_base;
virt_instr_entry->setText( 3, QString( "; { 0x%1 }" ).arg( code_blk->jcc.block_addr[ 0 ], 0, 16 ) );
if ( g_vm_ctx )
delete g_vm_ctx;
if ( !( g_vm_ctx = new vm::ctx_t( module_base, img_base, img_size, entry_rva ) )->init() )
{
dbg_print( QString( "> failed to init vm::ctx_t for jmp at = %1..." )
.arg( QString::number( code_blk->vip_begin, 16 ) ) );
return;
}
update_virtual_instructions( rtn_addr, code_blk->jcc.block_addr[ 0 ], parent );
break;
}
default:
break;
}
}
QVariant var;
var.setValue( vinstr );
virt_instr_entry->setData( 3, Qt::UserRole, var );
parent ? parent->addChild( virt_instr_entry ) : ui.virt_instrs->addTopLevelItem( virt_instr_entry );
} }
} }

@ -16,7 +16,7 @@
#include <vmprofiler.hpp> #include <vmprofiler.hpp>
#define ABS_TO_IMG( addr, mod_base, img_base ) ( addr - mod_base ) + img_base #define ABS_TO_IMG( addr, mod_base, img_base ) ( addr - mod_base ) + img_base
Q_DECLARE_METATYPE( vm::instrs::virt_instr_t * ) Q_DECLARE_METATYPE( vm::instrs::virt_instr_t )
struct rtn_data_t struct rtn_data_t
{ {
@ -42,7 +42,8 @@ class qvm_inspector : public QMainWindow
void dbg_msg( QString DbgOutput ); void dbg_msg( QString DbgOutput );
void update_ui(); void update_ui();
bool serialize_vmp2( std::vector< rtn_data_t > &virt_rtns ); bool serialize_vmp2( std::vector< rtn_data_t > &virt_rtns );
void update_virtual_instructions( std::uintptr_t rtn_addr, QTreeWidgetItem *parent = nullptr ); void update_virtual_instructions( std::uintptr_t rtn_addr, std::uintptr_t blk_addr = 0ull,
QTreeWidgetItem *parent = nullptr );
bool init_data(); bool init_data();
Ui::QVMProfilerClass ui; Ui::QVMProfilerClass ui;
@ -51,4 +52,5 @@ class qvm_inspector : public QMainWindow
vmp2::v4::file_header *file_header; vmp2::v4::file_header *file_header;
std::vector< rtn_data_t > virt_rtns; std::vector< rtn_data_t > virt_rtns;
std::vector< std::uintptr_t > code_block_addrs;
}; };

@ -16,15 +16,11 @@ void qvm_virtual_instructions::on_select()
if ( !item ) if ( !item )
return; return;
const auto virt_instr = item->data( 3, Qt::UserRole ).value< vm::instrs::virt_instr_t * >(); auto virt_instr = item->data( 3, Qt::UserRole ).value< vm::instrs::virt_instr_t >();
update_native_registers( &virt_instr );
if ( !virt_instr ) update_virtual_registers( &virt_instr );
return; update_virtual_stack( &virt_instr );
update_vmhandler_info( &virt_instr );
update_native_registers( virt_instr );
update_virtual_registers( virt_instr );
update_virtual_stack( virt_instr );
update_vmhandler_info( virt_instr );
} }
void qvm_virtual_instructions::update_native_registers( vm::instrs::virt_instr_t *virt_instr ) void qvm_virtual_instructions::update_native_registers( vm::instrs::virt_instr_t *virt_instr )
@ -59,8 +55,9 @@ void qvm_virtual_instructions::update_virtual_registers( vm::instrs::virt_instr_
// set VIP in virtual registers window... // set VIP in virtual registers window...
ui->virt_regs->topLevelItem( 0 )->setText( ui->virt_regs->topLevelItem( 0 )->setText(
1, QString::number( 1, QString::number( ( trace_data.vip - g_main_window->file_header->module_base ) +
( trace_data.vip - g_main_window->file_header->module_base ) + g_main_window->file_header->image_base, 16 ) ); g_main_window->file_header->image_base,
16 ) );
// set VSP in virtual registers window... // set VSP in virtual registers window...
ui->virt_regs->topLevelItem( 1 )->setText( 1, QString::number( trace_data.regs.rbp, 16 ) ); ui->virt_regs->topLevelItem( 1 )->setText( 1, QString::number( trace_data.regs.rbp, 16 ) );
@ -100,7 +97,8 @@ void qvm_virtual_instructions::update_vmhandler_info( vm::instrs::virt_instr_t *
for ( const auto &instr : vm_handler_instrs ) for ( const auto &instr : vm_handler_instrs )
{ {
auto new_instr = new QTreeWidgetItem(); auto new_instr = new QTreeWidgetItem();
new_instr->setText( 0, QString::number( ( instr.addr - g_main_window->module_base ) + g_main_window->img_base, 16 ) ); new_instr->setText(
0, QString::number( ( instr.addr - g_main_window->module_base ) + g_main_window->img_base, 16 ) );
ZydisFormatterFormatInstruction( &formatter, &instr.instr, buffer, sizeof( buffer ), ZydisFormatterFormatInstruction( &formatter, &instr.instr, buffer, sizeof( buffer ),
( instr.addr - g_main_window->module_base ) + g_main_window->img_base ); ( instr.addr - g_main_window->module_base ) + g_main_window->img_base );

@ -101,5 +101,8 @@ void qvm_virtual_routines::on_select()
update_vm_enter( g_main_window->g_vm_ctx ); update_vm_enter( g_main_window->g_vm_ctx );
update_calc_jmp( g_main_window->g_vm_ctx ); update_calc_jmp( g_main_window->g_vm_ctx );
update_vm_handlers( 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 ); g_main_window->update_virtual_instructions( entry_rva );
} }

@ -27,7 +27,7 @@
<item> <item>
<widget class="QTabWidget" name="tabWidget"> <widget class="QTabWidget" name="tabWidget">
<property name="currentIndex"> <property name="currentIndex">
<number>1</number> <number>2</number>
</property> </property>
<widget class="QWidget" name="virtual_instructions_tab"> <widget class="QWidget" name="virtual_instructions_tab">
<attribute name="title"> <attribute name="title">

Loading…
Cancel
Save