cleaned the code...

merge-requests/5/head
_xeroxz 3 years ago
parent 82f17aba3a
commit 5bf0732d7f

@ -59,23 +59,23 @@ set(vmprofiler-qt_SOURCES "")
list(APPEND vmprofiler-qt_SOURCES
"src/qvminspector.ui"
"src/qvminspector.qrc"
"src/QVMInspector.cpp"
"src/QVirtualMachineHandlers.cpp"
"src/QVirtualMachineInstructions.cpp"
"src/QVirtualRoutines.cpp"
"src/darkstyle/DarkStyle.cpp"
"src/darkstyle/framelesswindow/framelesswindow.cpp"
"src/darkstyle/framelesswindow/windowdragger.cpp"
"src/darkstyle/mainwindow.cpp"
"src/main.cpp"
"src/QVMInspector.h"
"src/QVirtualMachineHandlers.h"
"src/QVirtualMachineInstructions.h"
"src/QVirtualRoutines.h"
"src/qvm_handlers.cpp"
"src/qvm_inspector.cpp"
"src/qvm_virtual_instructions.cpp"
"src/qvm_virtual_routines.cpp"
"src/darkstyle/DarkStyle.h"
"src/darkstyle/framelesswindow/framelesswindow.h"
"src/darkstyle/framelesswindow/windowdragger.h"
"src/darkstyle/mainwindow.h"
"src/qvm_handlers.h"
"src/qvm_inspector.h"
"src/qvm_virtual_instructions.h"
"src/qvm_virtual_routines.h"
"src/icon.rc"
"src/darkstyle/mainwindow.ui"
"src/darkstyle/framelesswindow.qrc"

@ -1,18 +0,0 @@
#pragma once
#include "QVMInspector.h"
class QVirtualMachineHandlers : public QObject
{
Q_OBJECT
public:
explicit QVirtualMachineHandlers( QVMInspector *MainWindow );
private:
Ui::QVMProfilerClass *ui;
QVMInspector *MainWindow;
void UpdateTransforms( vm::handler::handler_t &vm_handler );
void UpdateInstrs( vm::handler::handler_t &vm_handler );
private slots:
void OnSelect();
};

@ -1,21 +0,0 @@
#pragma once
#include "QVMInspector.h"
class QVirtualMachineInstructions : public QObject
{
Q_OBJECT
public:
explicit QVirtualMachineInstructions( QVMInspector *MainWindow );
private:
Ui::QVMProfilerClass *ui;
QVMInspector *MainWindow;
void UpdateNativeRegisters( vm::instrs::virt_instr_t *virt_instr );
void UpdateVirtualRegisters( 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:
void OnSelect();
};

@ -1,66 +0,0 @@
#include "QVirtualRoutines.h"
QVirtualRoutines::QVirtualRoutines( QVMInspector *MainWindow ) : MainWindow( MainWindow ), ui( &MainWindow->ui )
{
connect( ui->virtual_machine_enters, &QTreeWidget::itemSelectionChanged, this, &QVirtualRoutines::OnSelect );
}
void QVirtualRoutines::UpdateVirtualMachineEnter( 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 QVirtualRoutines::UpdateCalcJmp( 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 QVirtualRoutines::OnSelect()
{
if ( ui->virtual_machine_enters->selectedItems().empty() )
return;
if ( MainWindow->g_vm_ctx )
delete MainWindow->g_vm_ctx;
auto item = ui->virtual_machine_enters->selectedItems()[ 0 ];
if ( !item )
return;
auto EntryRva = item->data( 0, Qt::UserRole ).value< std::uint32_t >();
MainWindow->g_vm_ctx = new vm::ctx_t( MainWindow->ModuleBase, MainWindow->ImgBase, MainWindow->ImgSize, EntryRva );
if ( !MainWindow->g_vm_ctx->init() )
{
MainWindow->DbgMsg( "[!] failed to init vm::ctx_t...\n" );
return;
}
UpdateVirtualMachineEnter( MainWindow->g_vm_ctx );
UpdateCalcJmp( MainWindow->g_vm_ctx );
}

@ -1,18 +0,0 @@
#pragma once
#include "QVMInspector.h"
class QVirtualRoutines : public QObject
{
Q_OBJECT
public:
explicit QVirtualRoutines( QVMInspector *MainWindow );
private:
Ui::QVMProfilerClass *ui;
QVMInspector *MainWindow;
void UpdateVirtualMachineEnter(vm::ctx_t* g_vm_ctx);
void UpdateCalcJmp( vm::ctx_t *g_vm_ctx );
private slots:
void OnSelect();
};

@ -3,10 +3,10 @@
#include <QTextStream>
#include <QtWidgets/QApplication>
#include "QVMInspector.h"
#include "QVirtualMachineHandlers.h"
#include "QVirtualMachineInstructions.h"
#include "QVirtualRoutines.h"
#include "qvm_inspector.h"
#include "qvm_handlers.h"
#include "qvm_virtual_instructions.h"
#include "qvm_virtual_routines.h"
#include "darkstyle/DarkStyle.h"
#include "darkstyle/framelesswindow/framelesswindow.h"
@ -16,12 +16,12 @@ int WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int
QApplication::setStyle( new DarkStyle );
FramelessWindow FW;
const auto MainWindow = new QVMInspector;
QVirtualMachineInstructions VirtInstrsPanel( MainWindow );
QVirtualMachineHandlers VirtHandlerPanel( MainWindow );
QVirtualRoutines VirtualRoutinesPanel( MainWindow );
const auto g_main_window = new qvm_inspector;
qvm_virtual_instructions VirtInstrsPanel( g_main_window );
qvm_handlers VirtHandlerPanel( g_main_window );
qvm_virtual_routines VirtualRoutinesPanel( g_main_window );
FW.setContent( MainWindow );
FW.setContent( g_main_window );
FW.setWindowIcon( QIcon( "icon.ico" ) );
FW.show();
return app.exec();

@ -1,12 +1,12 @@
#include "QVirtualMachineHandlers.h"
#include "qvm_handlers.h"
QVirtualMachineHandlers::QVirtualMachineHandlers( QVMInspector *MainWindow )
: MainWindow( MainWindow ), ui( &MainWindow->ui )
qvm_handlers::qvm_handlers( qvm_inspector *g_main_window )
: g_main_window( g_main_window ), ui( &g_main_window->ui )
{
connect( ui->virt_handlers_tree, &QTreeWidget::itemSelectionChanged, this, &QVirtualMachineHandlers::OnSelect );
connect( ui->virt_handlers_tree, &QTreeWidget::itemSelectionChanged, this, &qvm_handlers::on_select );
}
void QVirtualMachineHandlers::UpdateTransforms( vm::handler::handler_t &vm_handler )
void qvm_handlers::update_transforms( vm::handler::handler_t &vm_handler )
{
char buffer[ 256 ];
ZydisFormatter formatter;
@ -53,7 +53,7 @@ void QVirtualMachineHandlers::UpdateTransforms( vm::handler::handler_t &vm_handl
}
}
void QVirtualMachineHandlers::UpdateInstrs( vm::handler::handler_t &vm_handler )
void qvm_handlers::update_instrs( vm::handler::handler_t &vm_handler )
{
char buffer[ 256 ];
ZydisFormatter formatter;
@ -66,17 +66,17 @@ void QVirtualMachineHandlers::UpdateInstrs( vm::handler::handler_t &vm_handler )
for ( const auto &instr : vm_handler_instrs )
{
auto new_instr = new QTreeWidgetItem();
new_instr->setText( 0, QString::number( ( instr.addr - MainWindow->ModuleBase ) + MainWindow->ImgBase, 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 ),
( instr.addr - MainWindow->ModuleBase ) + MainWindow->ImgBase );
( instr.addr - g_main_window->module_base ) + g_main_window->img_base );
new_instr->setText( 1, buffer );
ui->virt_handler_instrs_tree->addTopLevelItem( new_instr );
}
}
void QVirtualMachineHandlers::OnSelect()
void qvm_handlers::on_select()
{
if ( ui->virt_handlers_tree->selectedItems().empty() )
return;
@ -86,10 +86,10 @@ void QVirtualMachineHandlers::OnSelect()
if ( !item )
return;
if ( !MainWindow->g_vm_ctx )
if ( !g_main_window->g_vm_ctx )
return;
const auto handler_idx = item->data( 0, Qt::UserRole ).value< std::uint8_t >();
UpdateInstrs( MainWindow->g_vm_ctx->vm_handlers[ handler_idx ] );
UpdateTransforms( MainWindow->g_vm_ctx->vm_handlers[ handler_idx ] );
update_instrs( g_main_window->g_vm_ctx->vm_handlers[ handler_idx ] );
update_transforms( g_main_window->g_vm_ctx->vm_handlers[ handler_idx ] );
}

@ -0,0 +1,18 @@
#pragma once
#include "qvm_inspector.h"
class qvm_handlers : public QObject
{
Q_OBJECT
public:
explicit qvm_handlers( qvm_inspector *g_main_window );
private:
Ui::QVMProfilerClass *ui;
qvm_inspector *g_main_window;
void update_transforms( vm::handler::handler_t &vm_handler );
void update_instrs( vm::handler::handler_t &vm_handler );
private slots:
void on_select();
};

@ -1,6 +1,6 @@
#include "QVMInspector.h"
#include "qvm_inspector.h"
QVMInspector::QVMInspector( QWidget *parent ) : QMainWindow( parent ), FileHeader( nullptr ), g_vm_ctx( nullptr )
qvm_inspector::qvm_inspector( QWidget *parent ) : QMainWindow( parent ), file_header( nullptr ), g_vm_ctx( nullptr )
{
ui.setupUi( this );
ui.virt_instrs->setColumnWidth( 0, 180 );
@ -9,120 +9,118 @@ QVMInspector::QVMInspector( QWidget *parent ) : QMainWindow( parent ), FileHeade
ui.virt_instrs->setColumnWidth( 3, 200 );
ui.virtual_machine_enters->setColumnWidth( 0, 180 );
connect( ui.action_open, &QAction::triggered, this, &QVMInspector::OnOpen );
connect( ui.action_close, &QAction::triggered, this, &QVMInspector::OnClose );
connect( ui.action_open, &QAction::triggered, this, &qvm_inspector::on_open );
connect( ui.action_close, &QAction::triggered, this, &qvm_inspector::on_close );
}
void QVMInspector::OnClose()
void qvm_inspector::on_close()
{
exit( 0 );
}
void QVMInspector::OnOpen()
void qvm_inspector::on_open()
{
if ( FileHeader )
free( FileHeader );
if ( file_header )
free( file_header );
FileHeader = nullptr;
ImgBase = 0u, ModuleBase = 0u;
file_header = nullptr;
img_base = 0u, module_base = 0u;
file_path = QFileDialog::getOpenFileName(
auto file_path = QFileDialog::getOpenFileName(
this, tr( "open vmp2 file" ), std::filesystem::current_path().string().c_str(), tr( "vmp2 file (*.vmp2)" ) );
const auto &_file_path = file_path.toStdString();
if ( file_path.isEmpty() )
{
DbgMsg( "invalid vmp2 file... no file selected..." );
dbg_msg( "invalid vmp2 file... no file selected..." );
return;
}
if ( !std::filesystem::exists( _file_path ) )
if ( !std::filesystem::exists( file_path.toStdString() ) )
{
DbgMsg( "vmp2 file does not exist..." );
dbg_msg( "vmp2 file does not exist..." );
return;
}
const auto file_size = std::filesystem::file_size( _file_path );
const auto file_size = std::filesystem::file_size( file_path.toStdString() );
if ( !file_size )
{
DbgMsg( "invalid vmp2 file size..." );
dbg_msg( "invalid vmp2 file size..." );
return;
}
QFile open_file( file_path );
FileHeader = reinterpret_cast< vmp2::v4::FileHeader * >( malloc( file_size ) );
file_header = reinterpret_cast< vmp2::v4::file_header * >( malloc( file_size ) );
if ( !open_file.open( QIODevice::ReadOnly ) )
{
DbgMsg( "failed to open vmp2 file..." );
dbg_msg( "failed to open vmp2 file..." );
return;
}
memcpy( FileHeader, open_file.readAll().data(), file_size );
memcpy( file_header, open_file.readAll().data(), file_size );
if ( !InitData() )
if ( !init_data() )
{
DbgMsg( "failed to init vmp2 file data..." );
dbg_msg( "failed to init vmp2 file data..." );
return;
}
}
void QVMInspector::DbgPrint( QString dbg_output )
void qvm_inspector::dbg_print( QString dbg_output )
{
ui.dbg_output_window->appendPlainText( dbg_output );
}
void QVMInspector::DbgMsg( QString dbg_output )
void qvm_inspector::dbg_msg( QString dbg_output )
{
QMessageBox msg_box;
msg_box.setText( dbg_output );
msg_box.exec();
DbgPrint( dbg_output );
dbg_print( dbg_output );
}
bool QVMInspector::InitData()
bool qvm_inspector::init_data()
{
if ( FileHeader->magic != VMP_MAGIC )
if ( file_header->magic != VMP_MAGIC )
{
DbgMsg( "invalid magic bytes for vmp2 file..." );
dbg_msg( "invalid magic bytes for vmp2 file..." );
return false;
}
DbgPrint( "valid magic bytes for vmp2 file..." );
dbg_print( "valid magic bytes for vmp2 file..." );
if ( FileHeader->version != vmp2::version_t::v4 )
if ( file_header->version != vmp2::version_t::v4 )
{
DbgMsg( "invalid vmp2 file version... "
"this vminspector is compiled for version 4...\n" );
dbg_msg( "invalid vmp2 file version... "
"this vminspector is compiled for version 4...\n" );
return false;
}
ImgBase = FileHeader->ImgBase;
ImgSize = FileHeader->module_size;
ModuleBase = reinterpret_cast< std::uintptr_t >( FileHeader ) + FileHeader->module_offset;
img_base = file_header->image_base;
img_size = file_header->module_size;
module_base = reinterpret_cast< std::uintptr_t >( file_header ) + file_header->module_offset;
if ( !SerializeVmp2( VirtRtns ) )
if ( !serialize_vmp2( virt_rtns ) )
{
DbgMsg( "failed to serialize vmp2 file format...\n" );
dbg_msg( "failed to serialize vmp2 file format...\n" );
return false;
}
UpdateUI();
update_ui();
return true;
}
void QVMInspector::UpdateUI()
void qvm_inspector::update_ui()
{
ui.virtual_machine_enters->clear();
for ( auto &[ rtn_rva, rtn_blks ] : VirtRtns )
for ( auto &[ rtn_rva, rtn_blks ] : virt_rtns )
{
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( 0, QString( "rtn_%1" ).arg( rtn_rva + file_header->image_base, 0, 16 ) );
new_item->setText( 1, QString( "%1" ).arg( rtn_rva + file_header->image_base, 0, 16 ) );
new_item->setText( 2, QString( "%1" ).arg( rtn_blks.size() ) );
new_item->setData( 0, Qt::UserRole, QVariant( rtn_rva ) );
@ -138,22 +136,22 @@ void QVMInspector::UpdateUI()
}
}
bool QVMInspector::SerializeVmp2( std::vector< rtn_data_t > &VirtRtns )
bool qvm_inspector::serialize_vmp2( std::vector< rtn_data_t > &virt_rtns )
{
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" );
return false;
}
auto first_rtn = reinterpret_cast< vmp2::v4::rtn_t * >( reinterpret_cast< std::uintptr_t >( FileHeader ) +
FileHeader->rtn_offset );
auto first_rtn = reinterpret_cast< vmp2::v4::rtn_t * >( reinterpret_cast< std::uintptr_t >( file_header ) +
file_header->rtn_offset );
for ( auto [ rtn_block, rtn_idx ] = std::pair{ first_rtn, 0ull }; rtn_idx < FileHeader->rtn_count;
for ( auto [ rtn_block, rtn_idx ] = std::pair{ first_rtn, 0ull }; rtn_idx < file_header->rtn_count;
++rtn_idx, rtn_block = reinterpret_cast< vmp2::v4::rtn_t * >(
reinterpret_cast< std::uintptr_t >( rtn_block ) + rtn_block->size ) )
{
VirtRtns.push_back( { rtn_block->vm_enter_offset, {} } );
virt_rtns.push_back( { rtn_block->vm_enter_offset, {} } );
for ( auto [ code_block, block_idx ] = std::pair{ &rtn_block->code_blocks[ 0 ], 0ull };
block_idx < rtn_block->code_block_count;
++block_idx, code_block = reinterpret_cast< vmp2::v4::code_block_t * >(
@ -173,9 +171,14 @@ bool QVMInspector::SerializeVmp2( std::vector< rtn_data_t > &VirtRtns )
for ( auto idx = 0u; idx < code_block->vinstr_count; ++idx )
_code_block.vinstrs.push_back( block_vinstrs[ idx ] );
VirtRtns.back().rtn_blks.push_back( _code_block );
virt_rtns.back().rtn_blks.push_back( _code_block );
}
}
return true;
}
}
void qvm_inspector::update_virtual_instructions( std::uintptr_t rtn_addr, QTreeWidgetItem *parent )
{
}

@ -24,32 +24,31 @@ struct rtn_data_t
std::vector< vm::instrs::code_block_t > rtn_blks;
};
class QVMInspector : public QMainWindow
class qvm_inspector : public QMainWindow
{
friend class QVirtualMachineInstructions;
friend class QVirtualMachineHandlers;
friend class QVirtualRoutines;
friend class qvm_virtual_instructions;
friend class qvm_handlers;
friend class qvm_virtual_routines;
Q_OBJECT
public:
QVMInspector( QWidget *parent = Q_NULLPTR );
qvm_inspector( QWidget *parent = Q_NULLPTR );
private slots:
void OnOpen();
void OnClose();
void on_open();
void on_close();
private:
void DbgPrint( QString DbgOutput );
void DbgMsg( QString DbgOutput );
void UpdateUI();
bool SerializeVmp2( std::vector< rtn_data_t > &VirtRtns );
bool InitData();
void dbg_print( QString DbgOutput );
void dbg_msg( QString DbgOutput );
void update_ui();
bool serialize_vmp2( std::vector< rtn_data_t > &virt_rtns );
void update_virtual_instructions( std::uintptr_t rtn_addr, QTreeWidgetItem *parent = nullptr );
bool init_data();
Ui::QVMProfilerClass ui;
QString file_path;
std::uint64_t ImgBase, ModuleBase, ImgSize;
std::uint64_t img_base, module_base, img_size;
vm::ctx_t *g_vm_ctx;
vmp2::v4::FileHeader *FileHeader;
std::vector< rtn_data_t > VirtRtns;
vmp2::v4::file_header *file_header;
std::vector< rtn_data_t > virt_rtns;
};

@ -1,12 +1,12 @@
#include "QVirtualMachineInstructions.h"
#include "qvm_virtual_instructions.h"
QVirtualMachineInstructions::QVirtualMachineInstructions( QVMInspector *MainWindow )
: MainWindow( MainWindow ), ui( &MainWindow->ui )
qvm_virtual_instructions::qvm_virtual_instructions( qvm_inspector *g_main_window )
: g_main_window( g_main_window ), ui( &g_main_window->ui )
{
connect( ui->virt_instrs, &QTreeWidget::itemSelectionChanged, this, &QVirtualMachineInstructions::OnSelect );
connect( ui->virt_instrs, &QTreeWidget::itemSelectionChanged, this, &qvm_virtual_instructions::on_select );
}
void QVirtualMachineInstructions::OnSelect()
void qvm_virtual_instructions::on_select()
{
if ( ui->virt_instrs->selectedItems().empty() )
return;
@ -21,13 +21,13 @@ void QVirtualMachineInstructions::OnSelect()
if ( !virt_instr )
return;
UpdateNativeRegisters( virt_instr );
UpdateVirtualRegisters( virt_instr );
UpdateVirtualStack( virt_instr );
UpdateVMHandlerInfo( virt_instr );
update_native_registers( virt_instr );
update_virtual_registers( virt_instr );
update_virtual_stack( virt_instr );
update_vmhandler_info( virt_instr );
}
void QVirtualMachineInstructions::UpdateNativeRegisters( vm::instrs::virt_instr_t *virt_instr )
void qvm_virtual_instructions::update_native_registers( vm::instrs::virt_instr_t *virt_instr )
{
const auto &trace_data = virt_instr->trace_data;
@ -53,14 +53,14 @@ void QVirtualMachineInstructions::UpdateNativeRegisters( vm::instrs::virt_instr_
ui->native_regs->topLevelItem( 16 )->child( 8 )->setText( 1, QString::number( flags.interrupt_enable_flag ) );
}
void QVirtualMachineInstructions::UpdateVirtualRegisters( vm::instrs::virt_instr_t *virt_instr )
void qvm_virtual_instructions::update_virtual_registers( vm::instrs::virt_instr_t *virt_instr )
{
const auto &trace_data = virt_instr->trace_data;
// set VIP in virtual registers window...
ui->virt_regs->topLevelItem( 0 )->setText(
1, QString::number( ( trace_data.vip - MainWindow->FileHeader->ModuleBase ) + MainWindow->FileHeader->ImgBase,
16 ) );
1, QString::number(
( trace_data.vip - g_main_window->file_header->module_base ) + g_main_window->file_header->image_base, 16 ) );
// set VSP in virtual registers window...
ui->virt_regs->topLevelItem( 1 )->setText( 1, QString::number( trace_data.regs.rbp, 16 ) );
@ -73,7 +73,7 @@ void QVirtualMachineInstructions::UpdateVirtualRegisters( vm::instrs::virt_instr
ui->virt_regs->topLevelItem( idx )->setText( 1, QString::number( trace_data.vregs.qword[ idx - 4 ], 16 ) );
}
void QVirtualMachineInstructions::UpdateVirtualStack( vm::instrs::virt_instr_t *virt_instr )
void qvm_virtual_instructions::update_virtual_stack( vm::instrs::virt_instr_t *virt_instr )
{
ui->virt_stack->clear();
const auto &trace_data = virt_instr->trace_data;
@ -87,23 +87,23 @@ void QVirtualMachineInstructions::UpdateVirtualStack( vm::instrs::virt_instr_t *
}
}
void QVirtualMachineInstructions::UpdateVMHandlerInfo( vm::instrs::virt_instr_t *virt_instr )
void qvm_virtual_instructions::update_vmhandler_info( vm::instrs::virt_instr_t *virt_instr )
{
char buffer[ 256 ];
ZydisFormatter formatter;
ZydisFormatterInit( &formatter, ZYDIS_FORMATTER_STYLE_INTEL );
ui->vm_handler_instrs->clear();
const auto &vm_handler_instrs = MainWindow->g_vm_ctx->vm_handlers[ virt_instr->opcode ].instrs;
const auto &vm_handler_instrs = g_main_window->g_vm_ctx->vm_handlers[ virt_instr->opcode ].instrs;
// display vm handler instructions...
for ( const auto &instr : vm_handler_instrs )
{
auto new_instr = new QTreeWidgetItem();
new_instr->setText( 0, QString::number( ( instr.addr - MainWindow->ModuleBase ) + MainWindow->ImgBase, 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 ),
( instr.addr - MainWindow->ModuleBase ) + MainWindow->ImgBase );
( instr.addr - g_main_window->module_base ) + g_main_window->img_base );
new_instr->setText( 1, buffer );
ui->vm_handler_instrs->addTopLevelItem( new_instr );
@ -111,7 +111,7 @@ void QVirtualMachineInstructions::UpdateVMHandlerInfo( vm::instrs::virt_instr_t
// display vm handler transformations...
ui->vm_handler_transforms->clear();
const auto &vm_handler_transforms = MainWindow->g_vm_ctx->vm_handlers[ virt_instr->opcode ].transforms;
const auto &vm_handler_transforms = g_main_window->g_vm_ctx->vm_handlers[ virt_instr->opcode ].transforms;
for ( auto [ transform_type, transform_instr ] : vm_handler_transforms )
{

@ -0,0 +1,21 @@
#pragma once
#include "qvm_inspector.h"
class qvm_virtual_instructions : public QObject
{
Q_OBJECT
public:
explicit qvm_virtual_instructions( qvm_inspector *g_main_window );
private:
Ui::QVMProfilerClass *ui;
qvm_inspector *g_main_window;
void update_native_registers( vm::instrs::virt_instr_t *virt_instr );
void update_virtual_registers( vm::instrs::virt_instr_t *virt_instr );
void update_virtual_stack( vm::instrs::virt_instr_t *virt_instr );
void update_vmhandler_info( vm::instrs::virt_instr_t *virt_instr );
private slots:
void on_select();
};

@ -0,0 +1,105 @@
#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 );
g_main_window->update_virtual_instructions( g_main_window->img_base + entry_rva );
}

@ -0,0 +1,19 @@
#pragma once
#include "qvm_inspector.h"
class qvm_virtual_routines : public QObject
{
Q_OBJECT
public:
explicit qvm_virtual_routines( qvm_inspector *g_main_window );
private:
Ui::QVMProfilerClass *ui;
qvm_inspector *g_main_window;
void update_vm_enter( vm::ctx_t *g_vm_ctx );
void update_calc_jmp( vm::ctx_t *g_vm_ctx );
void update_vm_handlers( vm::ctx_t *g_vm_ctx );
private slots:
void on_select();
};

@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>1089</width>
<width>1247</width>
<height>849</height>
</rect>
</property>
@ -27,7 +27,7 @@
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>2</number>
<number>1</number>
</property>
<widget class="QWidget" name="virtual_instructions_tab">
<attribute name="title">
@ -44,8 +44,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>428</width>
<height>408</height>
<width>1203</width>
<height>610</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
@ -414,8 +414,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>98</width>
<height>89</height>
<width>556</width>
<height>149</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
@ -703,7 +703,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>1089</width>
<width>1247</width>
<height>21</height>
</rect>
</property>

Loading…
Cancel
Save