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" );