From 06356e966807c81886892a291190d8b872c2ca60 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Fri, 11 Jun 2021 22:44:37 -0700 Subject: [PATCH] added qvirt_handlers.cpp which will handle updating the vm handlers tab... --- src/main.cpp | 2 + src/qvirt_handlers.cpp | 92 +++++++++++++++++++++++++++++ src/qvirt_handlers.h | 19 ++++++ src/qvminspector.cpp | 96 +++++++++++------------------- src/qvminspector.h | 7 +-- src/qvminspector.ui | 106 ++++++++++++++++++++++++++++++++-- vmprofiler-qt.vcxproj | 6 +- vmprofiler-qt.vcxproj.filters | 12 +++- 8 files changed, 261 insertions(+), 79 deletions(-) create mode 100644 src/qvirt_handlers.cpp create mode 100644 src/qvirt_handlers.h diff --git a/src/main.cpp b/src/main.cpp index bda59f8..edcb6d3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5,6 +5,7 @@ #include "qvminspector.h" #include "qvirt_instrs.h" +#include "qvirt_handlers.h" #include "framelesswindow.h" #include "DarkStyle.h" @@ -15,6 +16,7 @@ int main(int argc, char *argv[]) FramelessWindow frameless_window; const auto window = new qvminspector_t; qvirt_instrs_t virt_instr( window ); + qvirt_handlers_t virt_handlers( window ); frameless_window.setContent( window ); frameless_window.setWindowIcon(QIcon("icon.ico")); diff --git a/src/qvirt_handlers.cpp b/src/qvirt_handlers.cpp new file mode 100644 index 0000000..47ef49a --- /dev/null +++ b/src/qvirt_handlers.cpp @@ -0,0 +1,92 @@ +#include "qvirt_handlers.h" + +qvirt_handlers_t::qvirt_handlers_t( qvminspector_t *vminspector ) : vminspector( vminspector ), ui( &vminspector->ui ) +{ + connect( ui->virt_handlers_tree, &QTreeWidget::itemSelectionChanged, this, &qvirt_handlers_t::on_select ); +} + +void qvirt_handlers_t::update_transforms( vm::handler::handler_t &vm_handler ) +{ + char buffer[ 256 ]; + ZydisFormatter formatter; + ZydisFormatterInit( &formatter, ZYDIS_FORMATTER_STYLE_INTEL ); + + ui->virt_handler_transforms_tree->clear(); + const auto &vm_handler_transforms = 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 ) + continue; + + auto new_transform_entry = new qtree_widget_item_t(); + + switch ( transform_type ) + { + case vm::transform::type::rolling_key: + { + new_transform_entry->setText( 0, "Key Transform" ); + break; + } + case vm::transform::type::generic0: + case vm::transform::type::generic1: + case vm::transform::type::generic2: + case vm::transform::type::generic3: + { + new_transform_entry->setText( 0, "Generic" ); + break; + } + case vm::transform::type::update_key: + { + new_transform_entry->setText( 0, "Update Key" ); + break; + } + default: + throw std::invalid_argument( "invalid transformation type..." ); + } + + ZydisFormatterFormatInstruction( &formatter, &transform_instr, buffer, sizeof( buffer ), NULL ); + + new_transform_entry->setText( 1, buffer ); + ui->virt_handler_transforms_tree->addTopLevelItem( new_transform_entry ); + } +} + +void qvirt_handlers_t::update_instrs( vm::handler::handler_t &vm_handler ) +{ + char buffer[ 256 ]; + ZydisFormatter formatter; + ZydisFormatterInit( &formatter, ZYDIS_FORMATTER_STYLE_INTEL ); + + ui->virt_handler_instrs_tree->clear(); + const auto &vm_handler_instrs = vm_handler.instrs; + + // display vm handler instructions... + for ( const auto &instr : vm_handler_instrs ) + { + auto new_instr = new qtree_widget_item_t(); + new_instr->setText( + 0, qstring_t::number( ( instr.addr - vminspector->module_base ) + vminspector->image_base, 16 ) ); + + ZydisFormatterFormatInstruction( &formatter, &instr.instr, buffer, sizeof( buffer ), + ( instr.addr - vminspector->module_base ) + vminspector->image_base ); + + new_instr->setText( 1, buffer ); + ui->virt_handler_instrs_tree->addTopLevelItem( new_instr ); + } +} + +void qvirt_handlers_t::on_select() +{ + auto item = ui->virt_handlers_tree->selectedItems()[ 0 ]; + + if ( !item ) + return; + + if ( !vminspector->vmctx ) + return; + + const auto handler_idx = item->data( 0, Qt::UserRole ).value< std::uint8_t >(); + update_instrs( vminspector->vmctx->vm_handlers[ handler_idx ] ); + update_transforms( vminspector->vmctx->vm_handlers[ handler_idx ] ); +} \ No newline at end of file diff --git a/src/qvirt_handlers.h b/src/qvirt_handlers.h new file mode 100644 index 0000000..2022692 --- /dev/null +++ b/src/qvirt_handlers.h @@ -0,0 +1,19 @@ +#pragma once +#define NOMINMAX +#include "qvminspector.h" + +class qvirt_handlers_t : public QObject +{ + Q_OBJECT + public: + explicit qvirt_handlers_t( qvminspector_t *vminspector ); + + private: + Ui::QVMProfilerClass *ui; + qvminspector_t *vminspector; + void update_transforms( vm::handler::handler_t &vm_handler ); + void update_instrs( vm::handler::handler_t &vm_handler ); + + private slots: + void on_select(); +}; \ No newline at end of file diff --git a/src/qvminspector.cpp b/src/qvminspector.cpp index 336c355..1d7e89c 100644 --- a/src/qvminspector.cpp +++ b/src/qvminspector.cpp @@ -11,7 +11,6 @@ qvminspector_t::qvminspector_t( qwidget_t *parent ) : qmain_window_t( parent ), connect( ui.action_open, &QAction::triggered, this, &qvminspector_t::on_open ); connect( ui.action_close, &QAction::triggered, this, &qvminspector_t::on_close ); connect( ui.lift_all_button, &QAction::triggered, this, &qvminspector_t::on_lift_all ); - connect( ui.lift_specific_block_button, &QAction::triggered, this, &qvminspector_t::on_lift_block ); } void qvminspector_t::on_lift_all() @@ -53,13 +52,8 @@ void qvminspector_t::on_lift_all() auto vinstr = &code_block->vinstr[ idx ]; if ( vinstr->mnemonic_t == vm::handler::INVALID ) { - std::printf( "> unable to lift to VTIL... unknown virtual instruction handler #%d... " - "please define a vm handler profile for this virtual instruction and try again..." - " you can also create your first contribution to this open source project by submitting" - " a merge request with your changes! :)\n", - vinstr->opcode ); - - return; + rtn->nop(); + continue; } const auto result = std::find_if( @@ -68,13 +62,8 @@ void qvminspector_t::on_lift_all() if ( result == vm::lifters::all.end() ) { - std::printf( "> unable to lift to VTIL... unknown virtual instruction handler lifter for #%d... " - "please define a vm handler lifter for this vm handler and try again..." - " you can also create your first contribution to this open source project by submitting" - " a merge request with your changes! :)\n", - vinstr->opcode ); - - return; + rtn->nop(); + continue; } // lift the virtual instruction... @@ -86,37 +75,6 @@ void qvminspector_t::on_lift_all() vtil::debug::dump( first ); } -void qvminspector_t::on_lift_block() -{ - if ( !file_header ) - return; - - auto lift_block_select = new QDialog(); - auto layout = new QVBoxLayout(); - - for ( auto [ code_block, code_block_num ] = std::tuple{ first_block, 0u }; - code_block_num < file_header->code_block_count; - code_block = reinterpret_cast< vmp2::v3::code_block_t * >( reinterpret_cast< std::uintptr_t >( code_block ) + - code_block->next_block_offset ), - ++code_block_num ) - { - auto new_button = new QPushButton(); - new_button->setText( - QString( "block_%1" ) - .arg( ABS_TO_IMG( code_block->vip_begin, file_header->module_base, file_header->image_base ), 0u, - 16 ) ); - - new_button->setProperty( - "addr", ABS_TO_IMG( code_block->vip_begin, file_header->module_base, file_header->image_base ) ); - - layout->addWidget( new_button ); - } - - lift_block_select->setWindowTitle( "Select A Block" ); - lift_block_select->setLayout( layout ); - lift_block_select->exec(); -} - void qvminspector_t::on_close() { exit( 0 ); @@ -161,7 +119,6 @@ void qvminspector_t::on_open() qfile_t open_file( file_path ); file_header = reinterpret_cast< vmp2::v3::file_header * >( malloc( file_size ) ); - dbg_msg( qstring_t( "loading vmp2 file %1..." ).arg( file_path ) ); if ( !open_file.open( QIODevice::ReadOnly ) ) { @@ -214,9 +171,10 @@ bool qvminspector_t::init_data() vm_entry_rva = file_header->vm_entry_rva; image_base = file_header->image_base; + image_size = file_header->module_size; module_base = reinterpret_cast< std::uintptr_t >( file_header ) + file_header->module_offset; - vmctx = new vm::ctx_t( module_base, image_base, image_base, vm_entry_rva ); + vmctx = new vm::ctx_t( module_base, image_base, image_size, vm_entry_rva ); if ( !vmctx->init() ) { @@ -356,6 +314,34 @@ void qvminspector_t::add_branch_children( qtree_widget_item_t *item, std::uintpt void qvminspector_t::update_ui() { + // add vm handlers to the vm handler tree... + ui.virt_handlers_tree->clear(); + for ( auto idx = 0u; idx < vmctx->vm_handlers.size(); ++idx ) + { + auto new_handler_entry = new qtree_widget_item_t; + new_handler_entry->setData( 0, Qt::UserRole, idx ); + new_handler_entry->setText( 0, QString( "%1" ).arg( idx ) ); + new_handler_entry->setText( + 1, QString( "%1" ).arg( + ABS_TO_IMG( vmctx->vm_handlers[ idx ].address, module_base, file_header->image_base ), 0, 16 ) ); + + new_handler_entry->setText( 2, vmctx->vm_handlers[ idx ].profile ? vmctx->vm_handlers[ idx ].profile->name + : "UNDEFINED" ); + + new_handler_entry->setText( 3, QString( "%1" ).arg( vmctx->vm_handlers[ idx ].imm_size ) ); + + if ( vmctx->vm_handlers[ idx ].profile && vmctx->vm_handlers[ idx ].imm_size ) + new_handler_entry->setText( 4, vmctx->vm_handlers[ idx ].profile->extention == + vm::handler::extention_t::sign_extend + ? "SIGN EXTENDED" + : "ZERO EXTENDED" ); + else + new_handler_entry->setText( 4, "UNDEFINED" ); + + ui.virt_handlers_tree->addTopLevelItem( new_handler_entry ); + } + ui.virt_handlers_tree->topLevelItem( 0 )->setSelected( true ); + // for each code block insert their virtual instructions // into the virtual instruction tree... also put meta data about the code // block above the virtual instructions... if the code block has a JCC (with two branches) @@ -470,18 +456,4 @@ void qvminspector_t::update_ui() finish: // bad code... ui.virt_instrs->topLevelItem( 0 )->setSelected( true ); -} - -bool qvminspector_t::event( QEvent *event ) -{ - if ( event->type() == QEvent::KeyPress ) - { - auto kevent = static_cast< QKeyEvent * >( event ); - if ( kevent->key() == Qt::Key::Key_F5 ) - { - - return true; - } - } - return false; } \ No newline at end of file diff --git a/src/qvminspector.h b/src/qvminspector.h index 2eaf615..cffd635 100644 --- a/src/qvminspector.h +++ b/src/qvminspector.h @@ -28,6 +28,7 @@ using qmsg_box_t = QMessageBox; class qvminspector_t : public qmain_window_t { friend class qvirt_instrs_t; + friend class qvirt_handlers_t; Q_OBJECT public: qvminspector_t( qwidget_t *parent = Q_NULLPTR ); @@ -36,10 +37,6 @@ class qvminspector_t : public qmain_window_t void on_open(); void on_close(); void on_lift_all(); - void on_lift_block(); - - protected: - bool event( QEvent *event ); private: void dbg_print( qstring_t DbgOutput ); @@ -51,7 +48,7 @@ class qvminspector_t : public qmain_window_t Ui::QVMProfilerClass ui; qstring_t file_path; qstring_t VMProtectedFilePath; - std::uint64_t image_base, vm_entry_rva, module_base; + std::uint64_t image_base, vm_entry_rva, module_base, image_size; vm::ctx_t *vmctx; vmp2::v3::file_header *file_header; diff --git a/src/qvminspector.ui b/src/qvminspector.ui index ca9e741..26fa6a6 100644 --- a/src/qvminspector.ui +++ b/src/qvminspector.ui @@ -7,7 +7,7 @@ 0 0 1496 - 1038 + 1093 @@ -29,7 +29,7 @@ 0 - + Virtual Instructions @@ -45,7 +45,7 @@ 0 0 1452 - 799 + 854 @@ -415,7 +415,7 @@ 0 0 672 - 210 + 228 @@ -508,6 +508,101 @@ Virtual Machine Handlers + + + + + Virtual Machine Handler List + + + + + + + Index + + + + + Address + + + + + Name + + + + + Imm Size + + + + + Sign Extended Imm + + + + + + + + + + + Virtual Machine Handler Information + + + + + + Virtual Machine Handler Instructions + + + + + + + Address + + + + + Instruction + + + + + + + + + + + Virtual Machine Handler Transforms + + + + + + + Address + + + + + Instruction + + + + + + + + + + + @@ -533,7 +628,6 @@ VTIL - @@ -599,7 +693,7 @@ Close - + Lift Specific Block diff --git a/vmprofiler-qt.vcxproj b/vmprofiler-qt.vcxproj index 8a53167..623c921 100644 --- a/vmprofiler-qt.vcxproj +++ b/vmprofiler-qt.vcxproj @@ -44,12 +44,10 @@ + - - - @@ -67,6 +65,8 @@ + + diff --git a/vmprofiler-qt.vcxproj.filters b/vmprofiler-qt.vcxproj.filters index 32375cd..b6359a4 100644 --- a/vmprofiler-qt.vcxproj.filters +++ b/vmprofiler-qt.vcxproj.filters @@ -42,11 +42,11 @@ Source Files\darkstyle + + Source Files + - - Header Files - Header Files @@ -59,6 +59,12 @@ Header Files\darkstyle\framelesswindow + + Header Files + + + Header Files +