diff --git a/dependencies/vmprofiler b/dependencies/vmprofiler index 573cc04..0511401 160000 --- a/dependencies/vmprofiler +++ b/dependencies/vmprofiler @@ -1 +1 @@ -Subproject commit 573cc04fc1804ac328b555bb1136d132d858a6fe +Subproject commit 051140175db16b38acee882cfca714b4a1000a41 diff --git a/src/darkstyle/framelesswindow/framelesswindow.ui b/src/darkstyle/framelesswindow/framelesswindow.ui index 7751a56..87648a2 100644 --- a/src/darkstyle/framelesswindow/framelesswindow.ui +++ b/src/darkstyle/framelesswindow/framelesswindow.ui @@ -143,7 +143,7 @@ color:rgb(153,153,153); - VMProtect 2 - Virtual Instruction Inspector (v1.8 BETA) + VMProtect 2 - Virtual Instruction Inspector - v2.0 Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter diff --git a/src/qvm_inspector.cpp b/src/qvm_inspector.cpp index 8e66589..4321662 100644 --- a/src/qvm_inspector.cpp +++ b/src/qvm_inspector.cpp @@ -204,7 +204,6 @@ void qvm_inspector::update_virtual_instructions( std::uintptr_t rtn_addr, std::u for ( auto &vinstr : code_blk->vinstrs ) { 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(); // virtual instruction image base'ed rva... (column 1)... @@ -251,7 +250,7 @@ void qvm_inspector::update_virtual_instructions( std::uintptr_t rtn_addr, std::u .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 entry_rva = g_vm_ctx->vm_handlers[ vinstr.opcode ].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 ]; @@ -273,13 +272,24 @@ void qvm_inspector::update_virtual_instructions( std::uintptr_t rtn_addr, std::u } update_virtual_instructions( rtn_addr, code_blk->jcc.block_addr[ 0 ], branch_entry1 ); + + 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[ 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; + auto entry_rva = g_vm_ctx->vm_handlers[ vinstr.opcode ].address - module_base; virt_instr_entry->setText( 3, QString( "; { 0x%1 }" ).arg( code_blk->jcc.block_addr[ 0 ], 0, 16 ) ); if ( g_vm_ctx ) @@ -292,7 +302,37 @@ void qvm_inspector::update_virtual_instructions( std::uintptr_t rtn_addr, std::u return; } - update_virtual_instructions( rtn_addr, code_blk->jcc.block_addr[ 0 ], parent ); + auto branch_entry1 = new QTreeWidgetItem(); + branch_entry1->setText( 0, QString( "0x%1" ).arg( code_blk->jcc.block_addr[ 0 ], 0, 16 ) ); + branch_entry1->setText( 3, QString( "; blk_0x%1" ).arg( code_blk->jcc.block_addr[ 0 ], 0, 16 ) ); + update_virtual_instructions( rtn_addr, code_blk->jcc.block_addr[ 0 ], branch_entry1 ); + virt_instr_entry->addChild( branch_entry1 ); + break; + } + case vm::instrs::jcc_type::switch_case: + { + auto entry_rva = g_vm_ctx->vm_handlers[ vinstr.opcode ].address - module_base; + + 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; + } + + for ( auto branch_addr : code_blk->jcc.block_addr ) + { + virt_instr_entry->setText( 3, QString( "; switch case" ) ); + + auto branch_entry = new QTreeWidgetItem(); + branch_entry->setText( 0, QString( "0x%1" ).arg( branch_addr, 0, 16 ) ); + + update_virtual_instructions( rtn_addr, branch_addr, branch_entry ); + virt_instr_entry->addChild( branch_entry ); + } break; } default: diff --git a/src/qvm_virtual_routines.cpp b/src/qvm_virtual_routines.cpp index ca64e63..a230dd5 100644 --- a/src/qvm_virtual_routines.cpp +++ b/src/qvm_virtual_routines.cpp @@ -15,9 +15,11 @@ void qvm_virtual_routines::update_vm_enter( vm::ctx_t *g_vm_ctx ) ui->virtual_machine_enter_instrs->clear(); for ( auto [ instr, raw, addr ] : g_vm_ctx->vm_entry ) { - ZydisFormatterFormatInstruction( &formatter, &instr, buffer, sizeof( buffer ), addr ); + ZydisFormatterFormatInstruction( &formatter, &instr, buffer, sizeof( buffer ), + ( addr - g_main_window->module_base ) + g_vm_ctx->image_base ); + auto newItem = new QTreeWidgetItem(); - newItem->setText( 0, QString::number( addr, 16 ) ); + newItem->setText( 0, QString::number( ( addr - g_main_window->module_base ) + g_vm_ctx->image_base, 16 ) ); newItem->setText( 1, buffer ); ui->virtual_machine_enter_instrs->addTopLevelItem( newItem ); } @@ -32,9 +34,11 @@ void qvm_virtual_routines::update_calc_jmp( vm::ctx_t *g_vm_ctx ) ui->virtual_machine_enter_calc_jmp->clear(); for ( auto [ instr, raw, addr ] : g_vm_ctx->calc_jmp ) { - ZydisFormatterFormatInstruction( &formatter, &instr, buffer, sizeof( buffer ), addr ); + ZydisFormatterFormatInstruction( &formatter, &instr, buffer, sizeof( buffer ), + ( addr - g_main_window->module_base ) + g_vm_ctx->image_base ); + auto newItem = new QTreeWidgetItem(); - newItem->setText( 0, QString::number( addr, 16 ) ); + newItem->setText( 0, QString::number( ( addr - g_main_window->module_base ) + g_vm_ctx->image_base, 16 ) ); newItem->setText( 1, buffer ); ui->virtual_machine_enter_calc_jmp->addTopLevelItem( newItem ); } @@ -48,10 +52,10 @@ void qvm_virtual_routines::update_vm_handlers( vm::ctx_t *g_vm_ctx ) 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( 1, + QString( "%1" ).arg( ( g_vm_ctx->vm_handlers[ idx ].address - g_main_window->module_base ) + + g_main_window->img_base, + 0, 16 ) ); newItem->setText( 2, g_vm_ctx->vm_handlers[ idx ].profile ? g_vm_ctx->vm_handlers[ idx ].profile->name : "UNDEFINED" );