beginning to change things to upper case + added some more code to

update virtual routines...
merge-requests/5/head
_xeroxz 3 years ago
parent 86ca2e31e0
commit e7e8433681

@ -77,6 +77,7 @@ list(APPEND vmprofiler-qt_SOURCES
"src/darkstyle/mainwindow.h" "src/darkstyle/mainwindow.h"
"src/darkstyle/mainwindow.ui" "src/darkstyle/mainwindow.ui"
"src/darkstyle/framelesswindow.qrc" "src/darkstyle/framelesswindow.qrc"
"src/darkstyle/framelesswindow/framelesswindow.ui"
"dependencies/ia32-doc/out/ia32.hpp" "dependencies/ia32-doc/out/ia32.hpp"
) )

@ -29,6 +29,7 @@ sources = [
"src/darkstyle/**.h", "src/darkstyle/**.h",
"src/darkstyle/mainwindow.ui", "src/darkstyle/mainwindow.ui",
"src/darkstyle/framelesswindow.qrc", "src/darkstyle/framelesswindow.qrc",
"src/darkstyle/framelesswindow/framelesswindow.ui",
"dependencies/ia32-doc/out/ia32.hpp" "dependencies/ia32-doc/out/ia32.hpp"
] ]

@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>1737</width> <width>1311</width>
<height>1157</height> <height>897</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">

@ -14,9 +14,9 @@ int WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int
QApplication app( __argc, __argv ); QApplication app( __argc, __argv );
QApplication::setStyle( new DarkStyle ); QApplication::setStyle( new DarkStyle );
FramelessWindow frameless_window; FramelessWindow frameless_window;
const auto window = new qvminspector_t; const auto window = new QVMInspector;
qvirt_instrs_t virt_instr( window ); QVirtualMachineInstructions virt_instr( window );
qvirt_handlers_t virt_handlers( window ); QVirtualMachineHandlers virt_handlers( window );
frameless_window.setContent( window ); frameless_window.setContent( window );
frameless_window.setWindowIcon( QIcon( "icon.ico" ) ); frameless_window.setWindowIcon( QIcon( "icon.ico" ) );

@ -1,11 +1,12 @@
#include "qvirt_handlers.h" #include "qvirt_handlers.h"
qvirt_handlers_t::qvirt_handlers_t( qvminspector_t *vminspector ) : vminspector( vminspector ), ui( &vminspector->ui ) QVirtualMachineHandlers::QVirtualMachineHandlers( QVMInspector *MainWindow )
: MainWindow( MainWindow ), ui( &MainWindow->ui )
{ {
connect( ui->virt_handlers_tree, &QTreeWidget::itemSelectionChanged, this, &qvirt_handlers_t::on_select ); connect( ui->virt_handlers_tree, &QTreeWidget::itemSelectionChanged, this, &QVirtualMachineHandlers::OnSelect );
} }
void qvirt_handlers_t::update_transforms( vm::handler::handler_t &vm_handler ) void QVirtualMachineHandlers::UpdateTransforms( vm::handler::handler_t &vm_handler )
{ {
char buffer[ 256 ]; char buffer[ 256 ];
ZydisFormatter formatter; ZydisFormatter formatter;
@ -19,7 +20,7 @@ void qvirt_handlers_t::update_transforms( vm::handler::handler_t &vm_handler )
if ( transform_type == vm::transform::type::generic0 && transform_instr.mnemonic == ZYDIS_MNEMONIC_INVALID ) if ( transform_type == vm::transform::type::generic0 && transform_instr.mnemonic == ZYDIS_MNEMONIC_INVALID )
continue; continue;
auto new_transform_entry = new qtree_widget_item_t(); auto new_transform_entry = new QTreeWidgetItem();
switch ( transform_type ) switch ( transform_type )
{ {
@ -52,7 +53,7 @@ void qvirt_handlers_t::update_transforms( vm::handler::handler_t &vm_handler )
} }
} }
void qvirt_handlers_t::update_instrs( vm::handler::handler_t &vm_handler ) void QVirtualMachineHandlers::UpdateInstrs( vm::handler::handler_t &vm_handler )
{ {
char buffer[ 256 ]; char buffer[ 256 ];
ZydisFormatter formatter; ZydisFormatter formatter;
@ -64,19 +65,18 @@ void qvirt_handlers_t::update_instrs( vm::handler::handler_t &vm_handler )
// display vm handler instructions... // display vm handler instructions...
for ( const auto &instr : vm_handler_instrs ) for ( const auto &instr : vm_handler_instrs )
{ {
auto new_instr = new qtree_widget_item_t(); auto new_instr = new QTreeWidgetItem();
new_instr->setText( new_instr->setText( 0, QString::number( ( instr.addr - MainWindow->ModuleBase ) + MainWindow->ImgBase, 16 ) );
0, qstring_t::number( ( instr.addr - vminspector->module_base ) + vminspector->image_base, 16 ) );
ZydisFormatterFormatInstruction( &formatter, &instr.instr, buffer, sizeof( buffer ), ZydisFormatterFormatInstruction( &formatter, &instr.instr, buffer, sizeof( buffer ),
( instr.addr - vminspector->module_base ) + vminspector->image_base ); ( instr.addr - MainWindow->ModuleBase ) + MainWindow->ImgBase );
new_instr->setText( 1, buffer ); new_instr->setText( 1, buffer );
ui->virt_handler_instrs_tree->addTopLevelItem( new_instr ); ui->virt_handler_instrs_tree->addTopLevelItem( new_instr );
} }
} }
void qvirt_handlers_t::on_select() void QVirtualMachineHandlers::OnSelect()
{ {
if ( ui->virt_handlers_tree->selectedItems().empty() ) if ( ui->virt_handlers_tree->selectedItems().empty() )
return; return;
@ -86,10 +86,10 @@ void qvirt_handlers_t::on_select()
if ( !item ) if ( !item )
return; return;
if ( !vminspector->vmctx ) if ( !MainWindow->vmctx )
return; return;
const auto handler_idx = item->data( 0, Qt::UserRole ).value< std::uint8_t >(); const auto handler_idx = item->data( 0, Qt::UserRole ).value< std::uint8_t >();
update_instrs( vminspector->vmctx->vm_handlers[ handler_idx ] ); UpdateInstrs( MainWindow->vmctx->vm_handlers[ handler_idx ] );
update_transforms( vminspector->vmctx->vm_handlers[ handler_idx ] ); UpdateTransforms( MainWindow->vmctx->vm_handlers[ handler_idx ] );
} }

@ -2,18 +2,18 @@
#define NOMINMAX #define NOMINMAX
#include "qvminspector.h" #include "qvminspector.h"
class qvirt_handlers_t : public QObject class QVirtualMachineHandlers : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit qvirt_handlers_t( qvminspector_t *vminspector ); explicit QVirtualMachineHandlers( QVMInspector *MainWindow );
private: private:
Ui::QVMProfilerClass *ui; Ui::QVMProfilerClass *ui;
qvminspector_t *vminspector; QVMInspector *MainWindow;
void update_transforms( vm::handler::handler_t &vm_handler ); void UpdateTransforms( vm::handler::handler_t &vm_handler );
void update_instrs( vm::handler::handler_t &vm_handler ); void UpdateInstrs( vm::handler::handler_t &vm_handler );
private slots: private slots:
void on_select(); void OnSelect();
}; };

@ -1,11 +1,12 @@
#include "qvirt_instrs.h" #include "qvirt_instrs.h"
qvirt_instrs_t::qvirt_instrs_t( qvminspector_t *vminspector ) : vminspector( vminspector ), ui( &vminspector->ui ) QVirtualMachineInstructions::QVirtualMachineInstructions( QVMInspector *MainWindow )
: MainWindow( MainWindow ), ui( &MainWindow->ui )
{ {
connect( ui->virt_instrs, &QTreeWidget::itemSelectionChanged, this, &qvirt_instrs_t::on_select ); connect( ui->virt_instrs, &QTreeWidget::itemSelectionChanged, this, &QVirtualMachineInstructions::OnSelect );
} }
void qvirt_instrs_t::on_select() void QVirtualMachineInstructions::OnSelect()
{ {
if ( ui->virt_instrs->selectedItems().empty() ) if ( ui->virt_instrs->selectedItems().empty() )
return; return;
@ -20,13 +21,13 @@ void qvirt_instrs_t::on_select()
if ( !virt_instr ) if ( !virt_instr )
return; return;
update_native_regs( virt_instr ); UpdateNativeRegisters( virt_instr );
update_virtual_regs( virt_instr ); UpdateVirtualRegisters( virt_instr );
update_virtual_stack( virt_instr ); UpdateVirtualStack( virt_instr );
update_vm_handler_info( virt_instr ); UpdateVMHandlerInfo( virt_instr );
} }
void qvirt_instrs_t::update_native_regs( vm::instrs::virt_instr_t *virt_instr ) void QVirtualMachineInstructions::UpdateNativeRegisters( vm::instrs::virt_instr_t *virt_instr )
{ {
const auto &trace_data = virt_instr->trace_data; const auto &trace_data = virt_instr->trace_data;
@ -52,15 +53,14 @@ void qvirt_instrs_t::update_native_regs( vm::instrs::virt_instr_t *virt_instr )
ui->native_regs->topLevelItem( 16 )->child( 8 )->setText( 1, QString::number( flags.interrupt_enable_flag ) ); ui->native_regs->topLevelItem( 16 )->child( 8 )->setText( 1, QString::number( flags.interrupt_enable_flag ) );
} }
void qvirt_instrs_t::update_virtual_regs( vm::instrs::virt_instr_t *virt_instr ) void QVirtualMachineInstructions::UpdateVirtualRegisters( vm::instrs::virt_instr_t *virt_instr )
{ {
const auto &trace_data = virt_instr->trace_data; const auto &trace_data = virt_instr->trace_data;
// 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, 1, QString::number( ( trace_data.vip - MainWindow->FileHeader->ModuleBase ) + MainWindow->FileHeader->ImgBase,
QString::number( 16 ) );
( trace_data.vip - vminspector->file_header->module_base ) + vminspector->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 ) );
@ -73,38 +73,37 @@ void qvirt_instrs_t::update_virtual_regs( vm::instrs::virt_instr_t *virt_instr )
ui->virt_regs->topLevelItem( idx )->setText( 1, QString::number( trace_data.vregs.qword[ idx - 4 ], 16 ) ); ui->virt_regs->topLevelItem( idx )->setText( 1, QString::number( trace_data.vregs.qword[ idx - 4 ], 16 ) );
} }
void qvirt_instrs_t::update_virtual_stack( vm::instrs::virt_instr_t *virt_instr ) void QVirtualMachineInstructions::UpdateVirtualStack( vm::instrs::virt_instr_t *virt_instr )
{ {
ui->virt_stack->clear(); ui->virt_stack->clear();
const auto &trace_data = virt_instr->trace_data; const auto &trace_data = virt_instr->trace_data;
for ( auto idx = 0u; idx < sizeof( trace_data.vsp ) / 8; ++idx ) for ( auto idx = 0u; idx < sizeof( trace_data.vsp ) / 8; ++idx )
{ {
auto new_stack_entry = new qtree_widget_item_t(); auto new_stack_entry = new QTreeWidgetItem();
new_stack_entry->setText( 0, qstring_t::number( trace_data.regs.rbp + ( idx * 8 ), 16 ) ); new_stack_entry->setText( 0, QString::number( trace_data.regs.rbp + ( idx * 8 ), 16 ) );
new_stack_entry->setText( 1, qstring_t::number( trace_data.vsp.qword[ idx ], 16 ) ); new_stack_entry->setText( 1, QString::number( trace_data.vsp.qword[ idx ], 16 ) );
ui->virt_stack->addTopLevelItem( new_stack_entry ); ui->virt_stack->addTopLevelItem( new_stack_entry );
} }
} }
void qvirt_instrs_t::update_vm_handler_info( vm::instrs::virt_instr_t *virt_instr ) void QVirtualMachineInstructions::UpdateVMHandlerInfo( vm::instrs::virt_instr_t *virt_instr )
{ {
char buffer[ 256 ]; char buffer[ 256 ];
ZydisFormatter formatter; ZydisFormatter formatter;
ZydisFormatterInit( &formatter, ZYDIS_FORMATTER_STYLE_INTEL ); ZydisFormatterInit( &formatter, ZYDIS_FORMATTER_STYLE_INTEL );
ui->vm_handler_instrs->clear(); ui->vm_handler_instrs->clear();
const auto &vm_handler_instrs = vminspector->vmctx->vm_handlers[ virt_instr->opcode ].instrs; const auto &vm_handler_instrs = MainWindow->vmctx->vm_handlers[ virt_instr->opcode ].instrs;
// display vm handler instructions... // display vm handler instructions...
for ( const auto &instr : vm_handler_instrs ) for ( const auto &instr : vm_handler_instrs )
{ {
auto new_instr = new qtree_widget_item_t(); auto new_instr = new QTreeWidgetItem();
new_instr->setText( new_instr->setText( 0, QString::number( ( instr.addr - MainWindow->ModuleBase ) + MainWindow->ImgBase, 16 ) );
0, qstring_t::number( ( instr.addr - vminspector->module_base ) + vminspector->image_base, 16 ) );
ZydisFormatterFormatInstruction( &formatter, &instr.instr, buffer, sizeof( buffer ), ZydisFormatterFormatInstruction( &formatter, &instr.instr, buffer, sizeof( buffer ),
( instr.addr - vminspector->module_base ) + vminspector->image_base ); ( instr.addr - MainWindow->ModuleBase ) + MainWindow->ImgBase );
new_instr->setText( 1, buffer ); new_instr->setText( 1, buffer );
ui->vm_handler_instrs->addTopLevelItem( new_instr ); ui->vm_handler_instrs->addTopLevelItem( new_instr );
@ -112,14 +111,14 @@ void qvirt_instrs_t::update_vm_handler_info( vm::instrs::virt_instr_t *virt_inst
// display vm handler transformations... // display vm handler transformations...
ui->vm_handler_transforms->clear(); ui->vm_handler_transforms->clear();
const auto &vm_handler_transforms = vminspector->vmctx->vm_handlers[ virt_instr->opcode ].transforms; const auto &vm_handler_transforms = MainWindow->vmctx->vm_handlers[ virt_instr->opcode ].transforms;
for ( auto [ transform_type, transform_instr ] : vm_handler_transforms ) for ( auto [ transform_type, transform_instr ] : vm_handler_transforms )
{ {
if ( transform_type == vm::transform::type::generic0 && transform_instr.mnemonic == ZYDIS_MNEMONIC_INVALID ) if ( transform_type == vm::transform::type::generic0 && transform_instr.mnemonic == ZYDIS_MNEMONIC_INVALID )
continue; continue;
auto new_transform_entry = new qtree_widget_item_t(); auto new_transform_entry = new QTreeWidgetItem();
switch ( transform_type ) switch ( transform_type )
{ {

@ -2,20 +2,21 @@
#define NOMINMAX #define NOMINMAX
#include "qvminspector.h" #include "qvminspector.h"
class qvirt_instrs_t : public QObject class QVirtualMachineInstructions : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit qvirt_instrs_t( qvminspector_t *vminspector ); explicit QVirtualMachineInstructions( QVMInspector *MainWindow );
private: private:
Ui::QVMProfilerClass *ui; Ui::QVMProfilerClass *ui;
qvminspector_t *vminspector; QVMInspector *MainWindow;
void update_native_regs( vm::instrs::virt_instr_t *virt_instr );
void update_virtual_regs( vm::instrs::virt_instr_t *virt_instr ); void UpdateNativeRegisters( vm::instrs::virt_instr_t *virt_instr );
void update_virtual_stack( vm::instrs::virt_instr_t *virt_instr ); void UpdateVirtualRegisters( vm::instrs::virt_instr_t *virt_instr );
void update_vm_handler_info( vm::instrs::virt_instr_t *virt_instr ); void UpdateVirtualStack( vm::instrs::virt_instr_t *virt_instr );
void UpdateVMHandlerInfo( vm::instrs::virt_instr_t *virt_instr );
private slots: private slots:
void on_select(); void OnSelect();
}; };

@ -1,29 +1,30 @@
#include "qvminspector.h" #include "qvminspector.h"
qvminspector_t::qvminspector_t( qwidget_t *parent ) : qmain_window_t( parent ), file_header( nullptr ), vmctx( nullptr ) QVMInspector::QVMInspector( QWidget *parent ) : QMainWindow( parent ), FileHeader( nullptr ), vmctx( nullptr )
{ {
ui.setupUi( this ); ui.setupUi( this );
ui.virt_instrs->setColumnWidth( 0, 180 ); ui.virt_instrs->setColumnWidth( 0, 180 );
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 );
ui.virtual_machine_enters->setColumnWidth( 0, 180 );
connect( ui.action_open, &QAction::triggered, this, &qvminspector_t::on_open ); connect( ui.action_open, &QAction::triggered, this, &QVMInspector::OnOpen );
connect( ui.action_close, &QAction::triggered, this, &qvminspector_t::on_close ); connect( ui.action_close, &QAction::triggered, this, &QVMInspector::OnClose );
} }
void qvminspector_t::on_close() void QVMInspector::OnClose()
{ {
exit( 0 ); exit( 0 );
} }
void qvminspector_t::on_open() void QVMInspector::OnOpen()
{ {
if ( file_header ) if ( FileHeader )
free( file_header ); free( FileHeader );
file_header = nullptr; FileHeader = nullptr;
image_base = 0u, vm_entry_rva = 0u, module_base = 0u; ImgBase = 0u, ModuleBase = 0u;
file_path = QFileDialog::getOpenFileName( file_path = QFileDialog::getOpenFileName(
this, tr( "open vmp2 file" ), std::filesystem::current_path().string().c_str(), tr( "vmp2 file (*.vmp2)" ) ); this, tr( "open vmp2 file" ), std::filesystem::current_path().string().c_str(), tr( "vmp2 file (*.vmp2)" ) );
@ -32,13 +33,13 @@ void qvminspector_t::on_open()
if ( file_path.isEmpty() ) if ( file_path.isEmpty() )
{ {
dbg_msg( "invalid vmp2 file... no file selected..." ); DbgMsg( "invalid vmp2 file... no file selected..." );
return; return;
} }
if ( !std::filesystem::exists( _file_path ) ) if ( !std::filesystem::exists( _file_path ) )
{ {
dbg_msg( "vmp2 file does not exist..." ); DbgMsg( "vmp2 file does not exist..." );
return; return;
} }
@ -46,96 +47,112 @@ void qvminspector_t::on_open()
if ( !file_size ) if ( !file_size )
{ {
dbg_msg( "invalid vmp2 file size..." ); DbgMsg( "invalid vmp2 file size..." );
return; return;
} }
qfile_t open_file( file_path ); QFile open_file( file_path );
file_header = reinterpret_cast< vmp2::v4::file_header * >( malloc( file_size ) ); FileHeader = reinterpret_cast< vmp2::v4::FileHeader * >( malloc( file_size ) );
if ( !open_file.open( QIODevice::ReadOnly ) ) if ( !open_file.open( QIODevice::ReadOnly ) )
{ {
dbg_msg( "failed to open vmp2 file..." ); DbgMsg( "failed to open vmp2 file..." );
return; return;
} }
memcpy( file_header, open_file.readAll().data(), file_size ); memcpy( FileHeader, open_file.readAll().data(), file_size );
if ( !init_data() ) if ( !InitData() )
{ {
dbg_msg( "failed to init vmp2 file data..." ); DbgMsg( "failed to init vmp2 file data..." );
return; return;
} }
} }
void qvminspector_t::dbg_print( qstring_t dbg_output ) void QVMInspector::DbgPrint( QString dbg_output )
{ {
ui.dbg_output_window->appendPlainText( dbg_output ); ui.dbg_output_window->appendPlainText( dbg_output );
} }
void qvminspector_t::dbg_msg( qstring_t dbg_output ) void QVMInspector::DbgMsg( QString dbg_output )
{ {
qmsg_box_t msg_box; QMessageBox msg_box;
msg_box.setText( dbg_output ); msg_box.setText( dbg_output );
msg_box.exec(); msg_box.exec();
dbg_print( dbg_output ); DbgPrint( dbg_output );
} }
bool qvminspector_t::init_data() bool QVMInspector::InitData()
{ {
if ( file_header->magic != VMP_MAGIC ) if ( FileHeader->magic != VMP_MAGIC )
{ {
dbg_msg( "invalid magic bytes for vmp2 file..." ); DbgMsg( "invalid magic bytes for vmp2 file..." );
return false; return false;
} }
dbg_print( "valid magic bytes for vmp2 file..." ); DbgPrint( "valid magic bytes for vmp2 file..." );
if ( file_header->version != vmp2::version_t::v4 ) if ( FileHeader->version != vmp2::version_t::v4 )
{ {
dbg_msg( "invalid vmp2 file version... " DbgMsg( "invalid vmp2 file version... "
"this vminspector is compiled for version 4...\n" ); "this vminspector is compiled for version 4...\n" );
return false; return false;
} }
vm_entry_rva = file_header->vm_entry_rva; ImgBase = FileHeader->ImgBase;
image_base = file_header->image_base; ImgSize = FileHeader->module_size;
image_size = file_header->module_size; ModuleBase = reinterpret_cast< std::uintptr_t >( FileHeader ) + FileHeader->module_offset;
module_base = reinterpret_cast< std::uintptr_t >( file_header ) + file_header->module_offset; if ( !SerializeVmp2( VirtRtns ) )
return true; {
} DbgMsg( "failed to serialize vmp2 file format...\n" );
return false;
void qvminspector_t::add_branch_children( qtree_widget_item_t *item, std::uintptr_t branch_addr ) }
{
UpdateUI();
return true;
} }
void qvminspector_t::update_ui() void QVMInspector::UpdateUI()
{ {
ui.virtual_machine_enters->clear();
for ( auto &[ rtn_rva, rtn_blks ] : VirtRtns )
{
auto new_item = new QTreeWidgetItem();
new_item->setText( 0, QString( "rtn_%1" ).arg( rtn_rva + FileHeader->ImgBase, 0, 16 ) );
new_item->setText( 1, QString( "%1" ).arg( rtn_rva + FileHeader->ImgBase, 0, 16 ) );
new_item->setText( 2, QString( "%1" ).arg( rtn_blks.size() ) );
std::for_each( rtn_blks.begin(), rtn_blks.end(), [ & ]( vm::instrs::code_block_t &code_blk ) {
auto new_child = new QTreeWidgetItem();
new_child->setText( 0, QString( "blk_%1" ).arg( code_blk.vip_begin, 0, 16 ) );
new_child->setText( 1, QString( "%1" ).arg( code_blk.vip_begin, 0, 16 ) );
new_child->setText( 2, QString( "%1" ).arg( code_blk.vinstrs.size() ) );
new_item->addChild( new_child );
} );
ui.virtual_machine_enters->addTopLevelItem( new_item );
}
} }
bool qvminspector_t::serialize_vmp2( std::vector< rtn_data_t > &virt_rtns, std::vector< std::uint8_t > &vmp2file ) bool QVMInspector::SerializeVmp2( std::vector< rtn_data_t > &VirtRtns )
{ {
const auto file_header = reinterpret_cast< vmp2::v4::file_header * >( vmp2file.data() ); if ( FileHeader->version != vmp2::version_t::v4 )
if ( file_header->version != vmp2::version_t::v4 )
{ {
std::printf( "[!] invalid vmp2 file version... this build uses v3...\n" ); std::printf( "[!] invalid vmp2 file version... this build uses v3...\n" );
return false; return false;
} }
auto first_rtn = reinterpret_cast< vmp2::v4::rtn_t * >( reinterpret_cast< std::uintptr_t >( file_header ) + auto first_rtn = reinterpret_cast< vmp2::v4::rtn_t * >( reinterpret_cast< std::uintptr_t >( FileHeader ) +
file_header->rtn_offset ); FileHeader->rtn_offset );
for ( auto [ rtn_block, rtn_idx ] = std::pair{ first_rtn, 0ull }; rtn_idx < file_header->rtn_count; for ( auto [ rtn_block, rtn_idx ] = std::pair{ first_rtn, 0ull }; rtn_idx < FileHeader->rtn_count;
++rtn_idx, rtn_block = reinterpret_cast< vmp2::v4::rtn_t * >( ++rtn_idx, rtn_block = reinterpret_cast< vmp2::v4::rtn_t * >(
reinterpret_cast< std::uintptr_t >( rtn_block ) + rtn_block->size ) ) reinterpret_cast< std::uintptr_t >( rtn_block ) + rtn_block->size ) )
{ {
virt_rtns.push_back( { rtn_block->vm_enter_offset, {} } ); VirtRtns.push_back( { rtn_block->vm_enter_offset, {} } );
for ( auto [ code_block, block_idx ] = std::pair{ &rtn_block->code_blocks[ 0 ], 0ull }; for ( auto [ code_block, block_idx ] = std::pair{ &rtn_block->code_blocks[ 0 ], 0ull };
block_idx < rtn_block->code_block_count; block_idx < rtn_block->code_block_count;
++block_idx, code_block = reinterpret_cast< vmp2::v4::code_block_t * >( ++block_idx, code_block = reinterpret_cast< vmp2::v4::code_block_t * >(
@ -155,7 +172,7 @@ bool qvminspector_t::serialize_vmp2( std::vector< rtn_data_t > &virt_rtns, std::
for ( auto idx = 0u; idx < code_block->vinstr_count; ++idx ) for ( auto idx = 0u; idx < code_block->vinstr_count; ++idx )
_code_block.vinstrs.push_back( block_vinstrs[ idx ] ); _code_block.vinstrs.push_back( block_vinstrs[ idx ] );
virt_rtns.back().rtn_blks.push_back( _code_block ); VirtRtns.back().rtn_blks.push_back( _code_block );
} }
} }

@ -19,43 +19,37 @@
#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 * )
using qmain_window_t = QMainWindow;
using qwidget_t = QWidget;
using qstring_t = QString;
using qfile_t = QFile;
using qtree_widget_item_t = QTreeWidgetItem;
using qmsg_box_t = QMessageBox;
struct rtn_data_t struct rtn_data_t
{ {
std::uint32_t rtn_rva; std::uint32_t rtn_rva;
std::vector< vm::instrs::code_block_t > rtn_blks; std::vector< vm::instrs::code_block_t > rtn_blks;
}; };
class qvminspector_t : public qmain_window_t class QVMInspector : public QMainWindow
{ {
friend class qvirt_instrs_t; friend class QVirtualMachineInstructions;
friend class qvirt_handlers_t; friend class QVirtualMachineHandlers;
Q_OBJECT Q_OBJECT
public: public:
qvminspector_t( qwidget_t *parent = Q_NULLPTR ); QVMInspector( QWidget *parent = Q_NULLPTR );
static bool serialize_vmp2( std::vector< rtn_data_t > &virt_rtns, std::vector< std::uint8_t > &vmp2file );
private slots: private slots:
void on_open(); void OnOpen();
void on_close(); void OnClose();
private: private:
void dbg_print( qstring_t DbgOutput ); void DbgPrint( QString DbgOutput );
void dbg_msg( qstring_t DbgOutput ); void DbgMsg( QString DbgOutput );
void update_ui(); void UpdateUI();
void add_branch_children( qtree_widget_item_t *item, std::uintptr_t branch_addr ); bool SerializeVmp2( std::vector< rtn_data_t > &VirtRtns );
bool init_data(); bool InitData();
Ui::QVMProfilerClass ui; Ui::QVMProfilerClass ui;
qstring_t file_path; QString file_path;
qstring_t VMProtectedFilePath;
std::uint64_t image_base, vm_entry_rva, module_base, image_size; std::uint64_t ImgBase, ModuleBase, ImgSize;
vm::ctx_t *vmctx; vm::ctx_t *vmctx;
vmp2::v4::file_header *file_header;
vmp2::v4::FileHeader *FileHeader;
std::vector< rtn_data_t > VirtRtns;
}; };

@ -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">
@ -44,8 +44,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>1370</width> <width>428</width>
<height>854</height> <height>408</height>
</rect> </rect>
</property> </property>
<layout class="QHBoxLayout" name="horizontalLayout_2"> <layout class="QHBoxLayout" name="horizontalLayout_2">
@ -414,8 +414,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>631</width> <width>98</width>
<height>228</height> <height>89</height>
</rect> </rect>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_3"> <layout class="QVBoxLayout" name="verticalLayout_3">
@ -629,14 +629,9 @@
</column> </column>
<column> <column>
<property name="text"> <property name="text">
<string>Number Of Code Blocks</string> <string>Number Of Nodes</string>
</property> </property>
</column> </column>
<item>
<property name="text">
<string/>
</property>
</item>
</widget> </widget>
</item> </item>
</layout> </layout>
@ -666,11 +661,6 @@
<string>Instruction</string> <string>Instruction</string>
</property> </property>
</column> </column>
<item>
<property name="text">
<string/>
</property>
</item>
</widget> </widget>
</item> </item>
</layout> </layout>
@ -694,11 +684,6 @@
<string>Instruction</string> <string>Instruction</string>
</property> </property>
</column> </column>
<item>
<property name="text">
<string/>
</property>
</item>
</widget> </widget>
</item> </item>
</layout> </layout>

Loading…
Cancel
Save