updated to newest vmprofiler, upgraded to .vmp2 v2

merge-requests/1/merge v1.5
_xeroxz 4 years ago
parent 27e905aff0
commit bdabaca7a3

@ -1 +1 @@
Subproject commit 5129d39eb726e32a80417165ec37b597357664d4 Subproject commit 4cc033468e9f3b3583d07f307b9f5e9179db8762

@ -143,7 +143,7 @@
color:rgb(153,153,153);</string> color:rgb(153,153,153);</string>
</property> </property>
<property name="text"> <property name="text">
<string>VMProtect 2 - Virtual Instruction Trace Inspector</string> <string>VMProtect 2 - Virtual Instruction Inspector (v1.5)</string>
</property> </property>
<property name="alignment"> <property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set> <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>

@ -1,21 +1,20 @@
#include "QVMProfiler.h" #include "QVMProfiler.h"
QVMProfiler::QVMProfiler(QWidget *parent) QVMProfiler::QVMProfiler( QWidget *parent ) : QMainWindow( parent ), TraceFileBlob( nullptr ), VMCtx( nullptr )
: QMainWindow(parent),
TraceFileBlob(nullptr),
VMCtx(nullptr)
{ {
ui.setupUi(this); ui.setupUi( this );
} }
void QVMProfiler::on_actionCloseProgram_triggered() void QVMProfiler::on_actionCloseProgram_triggered()
{ exit(0); } {
exit( 0 );
}
void QVMProfiler::on_actionOpen_VMTrace_triggered() void QVMProfiler::on_actionOpen_VMTrace_triggered()
{ {
if (TraceFileBlob && VMCtx) if ( TraceFileBlob && VMCtx )
{ {
free(TraceFileBlob); free( TraceFileBlob );
TraceFileBlob = nullptr; TraceFileBlob = nullptr;
TraceFileHeader = nullptr; TraceFileHeader = nullptr;
TraceEntryList = nullptr; TraceEntryList = nullptr;
@ -30,158 +29,113 @@ void QVMProfiler::on_actionOpen_VMTrace_triggered()
delete VMCtx; delete VMCtx;
} }
TraceFilePath = QFileDialog::getOpenFileName(this, TraceFilePath = QFileDialog::getOpenFileName( this, tr( "Open Trace" ), "C:\\", tr( "VMTrace Files (*.vmp2)" ) );
tr("Open Trace"), "C:\\", tr("VMTrace Files (*.vmp2)"));
if (TraceFilePath.isEmpty())
{
DbgMessage("Invalid Trace File... No File Selected...");
return;
}
if (!std::filesystem::exists(TraceFilePath.toStdString().c_str()))
{
DbgMessage("Trace File Doesnt Exist...");
return;
}
VMProtectedFilePath = QFileDialog::getOpenFileName(this,
tr("Open VMProtected File"), "C:\\");
if (VMProtectedFilePath.isEmpty()) if ( TraceFilePath.isEmpty() )
{ {
DbgMessage("Invalid VMProtected File... No File Selected..."); DbgMessage( "Invalid Trace File... No File Selected..." );
return; return;
} }
if (!std::filesystem::exists(VMProtectedFilePath.toStdString().c_str())) if ( !std::filesystem::exists( TraceFilePath.toStdString().c_str() ) )
{ {
DbgMessage("VMProtected File Doesnt Exist..."); DbgMessage( "Trace File Doesnt Exist..." );
return; return;
} }
bool Success = false; const auto TraceFileSize = std::filesystem::file_size( TraceFilePath.toStdString().c_str() );
auto VMEntryRvaStr = QInputDialog::getText(0, "Input",
"VMEntry Relative Virtual Address:", QLineEdit::Normal, "", &Success);
if (!Success || VMEntryRvaStr.isEmpty()) if ( !TraceFileSize )
{ {
DbgMessage("Invalid VMEntry Relative Virtual Address..."); DbgMessage( "Invalid Trace File Size..." );
return; return;
} }
auto ImageBaseStr = QInputDialog::getText(0, "Input", QFile File( TraceFilePath );
"Image Base:", QLineEdit::Normal, "", &Success); TraceFileBlob = malloc( TraceFileSize );
DbgMessage( QString( "Loading Trace File %1..." ).arg( TraceFilePath ) );
if (!Success || ImageBaseStr.isEmpty()) if(!File.open( QIODevice::ReadOnly ))
{ {
DbgMessage("Invalid Image Base..."); DbgMessage( "Failed To Open Trace File..." );
return; return;
} }
VMEntryRva = VMEntryRvaStr.toULongLong(nullptr, 16); memcpy( TraceFileBlob, File.readAll().data(), TraceFileSize );
ImageBase = ImageBaseStr.toULongLong(nullptr, 16);
ModuleBase = reinterpret_cast<std::uintptr_t>( if ( !InitTraceData() )
LoadLibraryExA(VMProtectedFilePath.toStdString().c_str(),
NULL, DONT_RESOLVE_DLL_REFERENCES));
const auto TraceFileSize =
std::filesystem::file_size(
TraceFilePath.toStdString().c_str());
if (!TraceFileSize)
{ {
DbgMessage("Invalid Trace File Size..."); DbgMessage( "Failed To Init Trace Data..." );
return;
}
DbgMessage(QString("Loading Trace File %1...").arg(TraceFilePath));
// could use a QFile for all of this...
const auto FileSize =
std::filesystem::file_size(
TraceFilePath.toStdString().c_str());
// could use a QFile for all of this...
TraceFileBlob = malloc(FileSize);
std::ifstream TFile(TraceFilePath.toStdString().c_str(), std::ios::binary);
TFile.read((char*)TraceFileBlob, FileSize);
TFile.close();
if (!InitTraceData())
{
DbgMessage("Failed To Init Trace Data...");
return; return;
} }
UpdateUI(); UpdateUI();
} }
void QVMProfiler::DbgPrint(QString DbgOutput) void QVMProfiler::DbgPrint( QString DbgOutput )
{ {
ui.DbgOutputWindow->appendPlainText(DbgOutput); ui.DbgOutputWindow->appendPlainText( DbgOutput );
} }
void QVMProfiler::DbgMessage(QString DbgOutput) void QVMProfiler::DbgMessage( QString DbgOutput )
{ {
QMessageBox MsgBox; QMessageBox MsgBox;
MsgBox.setText(DbgOutput); MsgBox.setText( DbgOutput );
MsgBox.exec(); MsgBox.exec();
DbgPrint(DbgOutput); DbgPrint( DbgOutput );
} }
bool QVMProfiler::InitTraceData() bool QVMProfiler::InitTraceData()
{ {
TraceFileHeader = TraceFileHeader = reinterpret_cast< vmp2::v2::file_header * >( TraceFileBlob );
reinterpret_cast<vmp2::file_header*>(TraceFileBlob); TraceEntryList = reinterpret_cast< vmp2::v2::entry_t * >( reinterpret_cast< std::uintptr_t >( TraceFileBlob ) +
TraceFileHeader->entry_offset );
TraceEntryList =
reinterpret_cast<vmp2::entry_t*>(
reinterpret_cast<std::uintptr_t>(
TraceFileBlob) + TraceFileHeader->entry_offset);
const auto TraceMagicBytes = &TraceFileHeader->magic; const auto TraceMagicBytes = &TraceFileHeader->magic;
if (memcmp(TraceMagicBytes, "VMP2", sizeof "VMP2" - 1) != 0) if ( memcmp( TraceMagicBytes, "VMP2", sizeof "VMP2" - 1 ) != 0 )
{ {
DbgMessage("Trace File Magic Bytes Are Invalid...\n"); DbgMessage( "Trace File Magic Bytes Are Invalid...\n" );
return false; return false;
} }
DbgPrint("Trace File Magic Bytes Are Valid...."); VMEntryRva = TraceFileHeader->vm_entry_rva;
if (!vm::util::flatten(VMEntry, VMEntryRva + ModuleBase)) ImageBase = TraceFileHeader->image_base;
ModuleBase = reinterpret_cast< std::uintptr_t >( TraceFileHeader ) + TraceFileHeader->module_offset;
DbgPrint( "Trace File Magic Bytes Are Valid...." );
if ( !vm::util::flatten( VMEntry, VMEntryRva + ModuleBase ) )
{ {
DbgMessage("Failed To Flatten VMEntry...\n"); DbgMessage( "Failed To Flatten VMEntry...\n" );
return false; return false;
} }
vm::util::deobfuscate(VMEntry); vm::util::deobfuscate( VMEntry );
DbgPrint("Flattened VMEntry..."); DbgPrint( "Flattened VMEntry..." );
DbgPrint("Deobfuscated VMEntry..."); DbgPrint( "Deobfuscated VMEntry..." );
char buffer[256]; char buffer[ 256 ];
ZydisFormatter formatter; ZydisFormatter formatter;
ZydisFormatterInit(&formatter, ZYDIS_FORMATTER_STYLE_INTEL); ZydisFormatterInit( &formatter, ZYDIS_FORMATTER_STYLE_INTEL );
for (auto& Instr : VMEntry) for ( auto &Instr : VMEntry )
{ {
ZydisFormatterFormatInstruction(&formatter, &Instr.instr, buffer, sizeof(buffer), ZydisFormatterFormatInstruction( &formatter, &Instr.instr, buffer, sizeof( buffer ),
(Instr.addr - TraceFileHeader->module_base) + ImageBase); ( Instr.addr - TraceFileHeader->module_base ) + ImageBase );
DbgPrint(QString("> %1 %2").arg( DbgPrint( QString( "> %1 %2" )
QString::number((Instr.addr - TraceFileHeader->module_base) + ImageBase, 16)).arg(buffer)); .arg( QString::number( ( Instr.addr - TraceFileHeader->module_base ) + ImageBase, 16 ) )
.arg( buffer ) );
} }
VMHandlerTable = vm::handler::table::get(VMEntry); VMHandlerTable = vm::handler::table::get( VMEntry );
if (!vm::handler::get_all(ModuleBase, ImageBase, VMEntry, VMHandlerTable, VMHandlers)) if ( !vm::handler::get_all( ModuleBase, ImageBase, VMEntry, VMHandlerTable, VMHandlers ) )
{ {
DbgMessage("Failed To Get All VM Handler Meta Data...\n"); DbgMessage( "Failed To Get All VM Handler Meta Data...\n" );
return false; return false;
} }
DbgPrint("Located All VM Handlers..."); DbgPrint( "Located All VM Handlers..." );
VMCtx = new vm::vmctx_t(TraceFileHeader, VMCtx = new vm::vmctx_t( TraceFileHeader, TraceEntryList, VMHandlers, ModuleBase, ImageBase );
TraceEntryList, VMHandlers, ModuleBase, ImageBase);
return true; return true;
} }
@ -189,151 +143,136 @@ bool QVMProfiler::InitTraceData()
void QVMProfiler::UpdateUI() void QVMProfiler::UpdateUI()
{ {
ui.VirtualInstructionTree->clear(); ui.VirtualInstructionTree->clear();
for (auto [VirtInstr, TraceEntry] = VMCtx->step(); TraceEntry && !VirtInstr.empty(); for ( auto [ VirtInstr, TraceEntry ] = VMCtx->step(); TraceEntry && !VirtInstr.empty();
std::tie(VirtInstr, TraceEntry) = VMCtx->step()) std::tie( VirtInstr, TraceEntry ) = VMCtx->step() )
{ {
auto InstructionTraceData = new QTreeWidgetItem(); auto InstructionTraceData = new QTreeWidgetItem();
InstructionTraceData->setText(0, QString::number((TraceEntry->vip - TraceFileHeader->module_base) + ImageBase, 16)); InstructionTraceData->setText(
0, QString::number( ( TraceEntry->vip - TraceFileHeader->module_base ) + ImageBase, 16 ) );
if (VMHandlers[TraceEntry->handler_idx].imm_size) if ( VMHandlers[ TraceEntry->handler_idx ].imm_size )
{ {
QString SecondOperandBytes; QString SecondOperandBytes;
auto numByteOperand = VMHandlers[TraceEntry->handler_idx].imm_size / 8; auto numByteOperand = VMHandlers[ TraceEntry->handler_idx ].imm_size / 8;
auto spaceIdx = VirtInstr.find(" ") + 1; auto spaceIdx = VirtInstr.find( " " ) + 1;
auto ImmValue = QString(VirtInstr.substr( auto ImmValue =
spaceIdx, VirtInstr.size() - spaceIdx).c_str()).toULongLong(nullptr, 16); QString( VirtInstr.substr( spaceIdx, VirtInstr.size() - spaceIdx ).c_str() ).toULongLong( nullptr, 16 );
for (auto idx = 0u; idx < numByteOperand; ++idx) for ( auto idx = 0u; idx < numByteOperand; ++idx )
{ {
SecondOperandBytes.append(QString::number(*( SecondOperandBytes.append(
reinterpret_cast<std::uint8_t*>(&ImmValue) + idx), 16)); QString::number( *( reinterpret_cast< std::uint8_t * >( &ImmValue ) + idx ), 16 ) );
SecondOperandBytes.append(" "); SecondOperandBytes.append( " " );
} }
InstructionTraceData->setText(1, QString::number( InstructionTraceData->setText(
TraceEntry->handler_idx, 16).append(" - ").append(SecondOperandBytes)); 1, QString::number( TraceEntry->handler_idx, 16 ).append( " - " ).append( SecondOperandBytes ) );
} }
else else
{ {
// else we just put the first operand byte (vm handler index)... // else we just put the first operand byte (vm handler index)...
InstructionTraceData->setText(1, QString::number(TraceEntry->handler_idx, 16)); InstructionTraceData->setText( 1, QString::number( TraceEntry->handler_idx, 16 ) );
} }
InstructionTraceData->setText(2, VirtInstr.c_str()); InstructionTraceData->setText( 2, VirtInstr.c_str() );
ui.VirtualInstructionTree->addTopLevelItem(InstructionTraceData); ui.VirtualInstructionTree->addTopLevelItem( InstructionTraceData );
} }
ui.VirtualInstructionTree->topLevelItem(0)->setSelected(true); ui.VirtualInstructionTree->topLevelItem( 0 )->setSelected( true );
} }
void QVMProfiler::on_VirtualInstructionTree_itemSelectionChanged() void QVMProfiler::on_VirtualInstructionTree_itemSelectionChanged()
{ {
auto SelectedItem = ui.VirtualInstructionTree->selectedItems()[0]; auto SelectedItem = ui.VirtualInstructionTree->selectedItems()[ 0 ];
auto VIPAddr = SelectedItem->data(0, 0).toString().toULongLong(nullptr, 16); auto VIPAddr = SelectedItem->data( 0, 0 ).toString().toULongLong( nullptr, 16 );
vmp2::entry_t* Entry = nullptr; vmp2::v2::entry_t *Entry = nullptr;
for (auto idx = 0u; idx < TraceFileHeader->entry_count; ++idx) for ( auto idx = 0u; idx < TraceFileHeader->entry_count; ++idx )
{ {
if ((TraceEntryList[idx].vip - TraceFileHeader->module_base) + ImageBase == VIPAddr) if ( ( TraceEntryList[ idx ].vip - TraceFileHeader->module_base ) + ImageBase == VIPAddr )
{ {
Entry = &TraceEntryList[idx]; Entry = &TraceEntryList[ idx ];
break; break;
} }
} }
ui.VirtualRegisterTree->topLevelItem(0)->setText(1, ui.VirtualRegisterTree->topLevelItem( 0 )->setText(
QString::number((Entry->vip - TraceFileHeader->module_base) + ImageBase, 16)); 1, QString::number( ( Entry->vip - TraceFileHeader->module_base ) + ImageBase, 16 ) );
ui.VirtualRegisterTree->topLevelItem(1)->setText(1, ui.VirtualRegisterTree->topLevelItem( 1 )->setText( 1, QString::number( Entry->regs.rbp, 16 ) );
QString::number(Entry->regs.rbp, 16));
ui.VirtualRegisterTree->topLevelItem(2)->setText(1, ui.VirtualRegisterTree->topLevelItem( 2 )->setText( 1, QString::number( Entry->decrypt_key, 16 ) );
QString::number(Entry->decrypt_key, 16));
for (auto idx = 4; idx < 28; ++idx) for ( auto idx = 4; idx < 28; ++idx )
ui.VirtualRegisterTree->topLevelItem(idx)->setText(1, ui.VirtualRegisterTree->topLevelItem( idx )->setText( 1, QString::number( Entry->vregs.qword[ idx - 4 ], 16 ) );
QString::number(Entry->vregs.qword[idx - 4], 16));
for (auto idx = 0u; idx < 15; ++idx) for ( auto idx = 0u; idx < 15; ++idx )
ui.NativeRegisterTree->topLevelItem(idx)->setText(1, ui.NativeRegisterTree->topLevelItem( idx )->setText( 1, QString::number( Entry->regs.raw[ idx ], 16 ) );
QString::number(Entry->regs.raw[idx], 16));
ui.NativeRegisterTree->topLevelItem( ui.NativeRegisterTree->topLevelItem( 16 )->setText( 1, QString::number( Entry->regs.rflags, 16 ) );
16)->setText(1, QString::number(Entry->regs.rflags, 16));
rflags flags; rflags flags;
flags.flags = Entry->regs.rflags; flags.flags = Entry->regs.rflags;
ui.NativeRegisterTree->topLevelItem(16)->child(0)->setText( ui.NativeRegisterTree->topLevelItem( 16 )->child( 0 )->setText( 1, QString::number( flags.zero_flag ) );
1, QString::number(flags.zero_flag));
ui.NativeRegisterTree->topLevelItem(16)->child(1)->setText( ui.NativeRegisterTree->topLevelItem( 16 )->child( 1 )->setText( 1, QString::number( flags.parity_flag ) );
1, QString::number(flags.parity_flag));
ui.NativeRegisterTree->topLevelItem(16)->child(2)->setText( ui.NativeRegisterTree->topLevelItem( 16 )->child( 2 )->setText( 1, QString::number( flags.auxiliary_carry_flag ) );
1, QString::number(flags.auxiliary_carry_flag));
ui.NativeRegisterTree->topLevelItem(16)->child(3)->setText( ui.NativeRegisterTree->topLevelItem( 16 )->child( 3 )->setText( 1, QString::number( flags.overflow_flag ) );
1, QString::number(flags.overflow_flag));
ui.NativeRegisterTree->topLevelItem(16)->child(4)->setText( ui.NativeRegisterTree->topLevelItem( 16 )->child( 4 )->setText( 1, QString::number( flags.sign_flag ) );
1, QString::number(flags.sign_flag));
ui.NativeRegisterTree->topLevelItem(16)->child(5)->setText( ui.NativeRegisterTree->topLevelItem( 16 )->child( 5 )->setText( 1, QString::number( flags.direction_flag ) );
1, QString::number(flags.direction_flag));
ui.NativeRegisterTree->topLevelItem(16)->child(6)->setText( ui.NativeRegisterTree->topLevelItem( 16 )->child( 6 )->setText( 1, QString::number( flags.carry_flag ) );
1, QString::number(flags.carry_flag));
ui.NativeRegisterTree->topLevelItem(16)->child(7)->setText( ui.NativeRegisterTree->topLevelItem( 16 )->child( 7 )->setText( 1, QString::number( flags.trap_flag ) );
1, QString::number(flags.trap_flag));
ui.NativeRegisterTree->topLevelItem(16)->child(8)->setText( ui.NativeRegisterTree->topLevelItem( 16 )->child( 8 )->setText( 1, QString::number( flags.interrupt_enable_flag ) );
1, QString::number(flags.interrupt_enable_flag));
ui.VirtualStackTree->clear(); ui.VirtualStackTree->clear();
for (auto idx = 0u; idx < sizeof(Entry->vsp) / 8; ++idx) for ( auto idx = 0u; idx < sizeof( Entry->vsp ) / 8; ++idx )
{ {
auto newEntry = new QTreeWidgetItem(); auto newEntry = new QTreeWidgetItem();
newEntry->setText(0, QString::number(Entry->regs.rbp - (idx * 8), 16)); newEntry->setText( 0, QString::number( Entry->regs.rbp - ( idx * 8 ), 16 ) );
newEntry->setText(1, QString::number(Entry->vsp.qword[idx], 16)); newEntry->setText( 1, QString::number( Entry->vsp.qword[ idx ], 16 ) );
ui.VirtualStackTree->addTopLevelItem(newEntry); ui.VirtualStackTree->addTopLevelItem( newEntry );
} }
ui.VMHandlerInstructionsTree->clear(); ui.VMHandlerInstructionsTree->clear();
auto InstrVec = &VMHandlers[Entry->handler_idx].instrs; auto InstrVec = &VMHandlers[ Entry->handler_idx ].instrs;
char buffer[256]; char buffer[ 256 ];
ZydisFormatter formatter; ZydisFormatter formatter;
ZydisFormatterInit(&formatter, ZYDIS_FORMATTER_STYLE_INTEL); ZydisFormatterInit( &formatter, ZYDIS_FORMATTER_STYLE_INTEL );
for (auto idx = 0u; idx < InstrVec->size(); ++idx) for ( auto idx = 0u; idx < InstrVec->size(); ++idx )
{ {
auto newEntry = new QTreeWidgetItem(); auto newEntry = new QTreeWidgetItem();
newEntry->setText(0, QString::number( newEntry->setText( 0, QString::number( ( InstrVec->at( idx ).addr - ModuleBase ) + ImageBase, 16 ) );
(InstrVec->at(idx).addr - ModuleBase) + ImageBase, 16));
ZydisFormatterFormatInstruction(&formatter, &InstrVec->at(idx).instr, ZydisFormatterFormatInstruction( &formatter, &InstrVec->at( idx ).instr, buffer, sizeof( buffer ),
buffer, sizeof(buffer), (InstrVec->at(idx).addr - ModuleBase) + ImageBase); ( InstrVec->at( idx ).addr - ModuleBase ) + ImageBase );
newEntry->setText(1, buffer); newEntry->setText( 1, buffer );
ui.VMHandlerInstructionsTree->addTopLevelItem(newEntry); ui.VMHandlerInstructionsTree->addTopLevelItem( newEntry );
} }
ui.VMHandlerTransformationsTree->clear(); ui.VMHandlerTransformationsTree->clear();
auto HandlerTransforms = &VMHandlers[Entry->handler_idx].transforms; auto HandlerTransforms = &VMHandlers[ Entry->handler_idx ].transforms;
for (auto [TransformType, TransformInstr] : *HandlerTransforms) for ( auto [ TransformType, TransformInstr ] : *HandlerTransforms )
{ {
if (TransformType == vm::transform::type::generic0 && if ( TransformType == vm::transform::type::generic0 && TransformInstr.mnemonic == ZYDIS_MNEMONIC_INVALID )
TransformInstr.mnemonic == ZYDIS_MNEMONIC_INVALID)
continue; continue;
auto newEntry = new QTreeWidgetItem(); auto newEntry = new QTreeWidgetItem();
switch (TransformType) switch ( TransformType )
{ {
case vm::transform::type::rolling_key: case vm::transform::type::rolling_key:
{ {
newEntry->setText(0, "Key Transform"); newEntry->setText( 0, "Key Transform" );
break; break;
} }
case vm::transform::type::generic0: case vm::transform::type::generic0:
@ -341,22 +280,21 @@ void QVMProfiler::on_VirtualInstructionTree_itemSelectionChanged()
case vm::transform::type::generic2: case vm::transform::type::generic2:
case vm::transform::type::generic3: case vm::transform::type::generic3:
{ {
newEntry->setText(0, "Generic"); newEntry->setText( 0, "Generic" );
break; break;
} }
case vm::transform::type::update_key: case vm::transform::type::update_key:
{ {
newEntry->setText(0, "Update Key"); newEntry->setText( 0, "Update Key" );
break; break;
} }
default: default:
throw std::invalid_argument("invalid transformation type..."); throw std::invalid_argument( "invalid transformation type..." );
} }
ZydisFormatterFormatInstruction(&formatter, &TransformInstr, ZydisFormatterFormatInstruction( &formatter, &TransformInstr, buffer, sizeof( buffer ), NULL );
buffer, sizeof(buffer), NULL);
newEntry->setText(1, buffer); newEntry->setText( 1, buffer );
ui.VMHandlerTransformationsTree->addTopLevelItem(newEntry); ui.VMHandlerTransformationsTree->addTopLevelItem( newEntry );
} }
} }

@ -1,33 +1,33 @@
#pragma once #pragma once
#include <QtWidgets/QFileDialog> #include <QtWidgets/QFileDialog>
#include <QtWidgets/QInputDialog.h>
#include <QtWidgets/QMainWindow> #include <QtWidgets/QMainWindow>
#include <QtWidgets/QMessageBox.h> #include <QtWidgets/QMessageBox.h>
#include <QtWidgets/QInputDialog.h>
#include <Windows.h> #include <Windows.h>
#include <filesystem> #include <filesystem>
#include <fstream> #include <fstream>
#include <vmprofiler.hpp> #include <vmprofiler.hpp>
#include "ia32.hpp"
#include "ui_QVMProfiler.h" #include "ui_QVMProfiler.h"
#include "vmp2.hpp"
#include "vmctx.h" #include "vmctx.h"
#include "ia32.hpp" #include "vmp2.hpp"
class QVMProfiler : public QMainWindow class QVMProfiler : public QMainWindow
{ {
Q_OBJECT Q_OBJECT
public: public:
QVMProfiler(QWidget *parent = Q_NULLPTR); QVMProfiler( QWidget *parent = Q_NULLPTR );
private slots: private slots:
void on_actionOpen_VMTrace_triggered(); void on_actionOpen_VMTrace_triggered();
void on_actionCloseProgram_triggered(); void on_actionCloseProgram_triggered();
void on_VirtualInstructionTree_itemSelectionChanged(); void on_VirtualInstructionTree_itemSelectionChanged();
private: private:
void DbgPrint(QString DbgOutput); void DbgPrint( QString DbgOutput );
void DbgMessage(QString DbgOutput); void DbgMessage( QString DbgOutput );
void UpdateUI(); void UpdateUI();
bool InitTraceData(); bool InitTraceData();
@ -36,13 +36,13 @@ private:
QString VMProtectedFilePath; QString VMProtectedFilePath;
std::uint64_t ImageBase, VMEntryRva, ModuleBase; std::uint64_t ImageBase, VMEntryRva, ModuleBase;
std::vector<vm::handler::handler_t> VMHandlers; std::vector< vm::handler::handler_t > VMHandlers;
zydis_routine_t VMEntry; zydis_routine_t VMEntry;
std::uintptr_t* VMHandlerTable; std::uintptr_t *VMHandlerTable;
vm::vmctx_t* VMCtx; vm::vmctx_t *VMCtx;
void* TraceFileBlob; void *TraceFileBlob;
vmp2::file_header* TraceFileHeader; vmp2::v2::file_header *TraceFileHeader;
vmp2::entry_t* TraceEntryList; vmp2::v2::entry_t *TraceEntryList;
}; };

@ -2,13 +2,13 @@
namespace vm namespace vm
{ {
vmctx_t::vmctx_t( vmp2::file_header *file_header, vmp2::entry_t *entry_list, vmctx_t::vmctx_t( vmp2::v2::file_header *file_header, vmp2::v2::entry_t *entry_list,
std::vector< vm::handler::handler_t > &vm_handlers, std::uintptr_t module_base, std::uintptr_t image_base ) std::vector< vm::handler::handler_t > &vm_handlers, std::uintptr_t module_base, std::uintptr_t image_base )
: module_base( module_base ), image_base( image_base ), entry_list( entry_list ), file_header( file_header ), : module_base( module_base ), image_base( image_base ), entry_list( entry_list ), file_header( file_header ),
vm_handlers( vm_handlers ), idx( 0 ) vm_handlers( vm_handlers ), idx( 0 )
{} {}
std::pair< std::string, const vmp2::entry_t * > vmctx_t::step() const std::pair< std::string, const vmp2::v2::entry_t * > vmctx_t::step() const
{ {
if ( idx >= file_header->entry_count ) if ( idx >= file_header->entry_count )
return {}; return {};

@ -6,19 +6,19 @@ namespace vm
class vmctx_t class vmctx_t
{ {
public: public:
explicit vmctx_t( vmp2::file_header *file_header, vmp2::entry_t *entry_list, explicit vmctx_t( vmp2::v2::file_header *file_header, vmp2::v2::entry_t *entry_list,
std::vector< vm::handler::handler_t > &vm_handlers, std::uintptr_t module_base, std::vector< vm::handler::handler_t > &vm_handlers, std::uintptr_t module_base,
std::uintptr_t image_base ); std::uintptr_t image_base );
std::pair< std::string, const vmp2::entry_t * > step() const; std::pair< std::string, const vmp2::v2::entry_t * > step() const;
private: private:
std::uintptr_t get_imm( vmp2::exec_type_t exec_type_t, std::uint32_t vip_offset, std::uint8_t imm_size ) const; std::uintptr_t get_imm( vmp2::exec_type_t exec_type_t, std::uint32_t vip_offset, std::uint8_t imm_size ) const;
mutable std::uint32_t idx; mutable std::uint32_t idx;
const std::uintptr_t image_base, module_base; const std::uintptr_t image_base, module_base;
const vmp2::entry_t *entry_list; const vmp2::v2::entry_t *entry_list;
const vmp2::file_header *file_header; const vmp2::v2::file_header *file_header;
std::vector< vm::handler::handler_t > vm_handlers; std::vector< vm::handler::handler_t > vm_handlers;
}; };
} // namespace vm } // namespace vm

@ -182,10 +182,13 @@
<ProjectReference Include="..\dependencies\vmprofiler\dependencies\zydis\msvc\zydis\Zydis.vcxproj"> <ProjectReference Include="..\dependencies\vmprofiler\dependencies\zydis\msvc\zydis\Zydis.vcxproj">
<Project>{88a23124-5640-35a0-b890-311d7a67a7d2}</Project> <Project>{88a23124-5640-35a0-b890-311d7a67a7d2}</Project>
</ProjectReference> </ProjectReference>
<ProjectReference Include="..\dependencies\vmprofiler\src\vmprofiler.vcxproj"> <ProjectReference Include="..\dependencies\vmprofiler\vmprofiler.vcxproj">
<Project>{d0b6092a-9944-4f24-9486-4b7dae372619}</Project> <Project>{d0b6092a-9944-4f24-9486-4b7dae372619}</Project>
</ProjectReference> </ProjectReference>
</ItemGroup> </ItemGroup>
<ItemGroup>
<None Include="..\.clang-format" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Condition="Exists('$(QtMsBuild)\qt.targets')"> <ImportGroup Condition="Exists('$(QtMsBuild)\qt.targets')">
<Import Project="$(QtMsBuild)\qt.targets" /> <Import Project="$(QtMsBuild)\qt.targets" />

@ -259,4 +259,9 @@
<Filter>Resource Files</Filter> <Filter>Resource Files</Filter>
</ResourceCompile> </ResourceCompile>
</ItemGroup> </ItemGroup>
<ItemGroup>
<None Include="..\.clang-format">
<Filter>Resource Files</Filter>
</None>
</ItemGroup>
</Project> </Project>

@ -7,7 +7,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vmprofiler-qt", "src\vmprof
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Zydis", "dependencies\vmprofiler\dependencies\zydis\msvc\zydis\Zydis.vcxproj", "{88A23124-5640-35A0-B890-311D7A67A7D2}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Zydis", "dependencies\vmprofiler\dependencies\zydis\msvc\zydis\Zydis.vcxproj", "{88A23124-5640-35A0-B890-311D7A67A7D2}"
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vmprofiler", "dependencies\vmprofiler\src\vmprofiler.vcxproj", "{D0B6092A-9944-4F24-9486-4B7DAE372619}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vmprofiler", "dependencies\vmprofiler\vmprofiler.vcxproj", "{D0B6092A-9944-4F24-9486-4B7DAE372619}"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -148,50 +148,50 @@ Global
{D0B6092A-9944-4F24-9486-4B7DAE372619}.DBG|x64.ActiveCfg = DBG|x64 {D0B6092A-9944-4F24-9486-4B7DAE372619}.DBG|x64.ActiveCfg = DBG|x64
{D0B6092A-9944-4F24-9486-4B7DAE372619}.DBG|x64.Build.0 = DBG|x64 {D0B6092A-9944-4F24-9486-4B7DAE372619}.DBG|x64.Build.0 = DBG|x64
{D0B6092A-9944-4F24-9486-4B7DAE372619}.DBG|x86.ActiveCfg = DBG|x64 {D0B6092A-9944-4F24-9486-4B7DAE372619}.DBG|x86.ActiveCfg = DBG|x64
{D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug Kernel|x64.ActiveCfg = Release|x64 {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug Kernel|x64.ActiveCfg = DBG|x64
{D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug Kernel|x64.Build.0 = Release|x64 {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug Kernel|x64.Build.0 = DBG|x64
{D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug Kernel|x86.ActiveCfg = Release|x64 {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug Kernel|x86.ActiveCfg = DBG|x64
{D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug Kernel|x86.Build.0 = Release|x64 {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug Kernel|x86.Build.0 = DBG|x64
{D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MD DLL|x64.ActiveCfg = DBG|x64 {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MD DLL|x64.ActiveCfg = DBG|x64
{D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MD DLL|x64.Build.0 = DBG|x64 {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MD DLL|x64.Build.0 = DBG|x64
{D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MD DLL|x86.ActiveCfg = Release|x64 {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MD DLL|x86.ActiveCfg = DBG|x64
{D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MD DLL|x86.Build.0 = Release|x64 {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MD DLL|x86.Build.0 = DBG|x64
{D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MD|x64.ActiveCfg = Release|x64 {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MD|x64.ActiveCfg = DBG|x64
{D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MD|x64.Build.0 = Release|x64 {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MD|x64.Build.0 = DBG|x64
{D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MD|x86.ActiveCfg = Release|x64 {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MD|x86.ActiveCfg = DBG|x64
{D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MD|x86.Build.0 = Release|x64 {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MD|x86.Build.0 = DBG|x64
{D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MT DLL|x64.ActiveCfg = Release|x64 {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MT DLL|x64.ActiveCfg = DBG|x64
{D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MT DLL|x64.Build.0 = Release|x64 {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MT DLL|x64.Build.0 = DBG|x64
{D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MT DLL|x86.ActiveCfg = Release|x64 {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MT DLL|x86.ActiveCfg = DBG|x64
{D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MT DLL|x86.Build.0 = Release|x64 {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MT DLL|x86.Build.0 = DBG|x64
{D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MT|x64.ActiveCfg = Release|x64 {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MT|x64.ActiveCfg = DBG|x64
{D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MT|x64.Build.0 = Release|x64 {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MT|x64.Build.0 = DBG|x64
{D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MT|x86.ActiveCfg = Release|x64 {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MT|x86.ActiveCfg = DBG|x64
{D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MT|x86.Build.0 = Release|x64 {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MT|x86.Build.0 = DBG|x64
{D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug|x64.ActiveCfg = Release|x64 {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug|x64.ActiveCfg = DBG|x64
{D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug|x64.Build.0 = Release|x64 {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug|x64.Build.0 = DBG|x64
{D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug|x86.ActiveCfg = Release|x64 {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug|x86.ActiveCfg = DBG|x64
{D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug|x86.Build.0 = Release|x64 {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug|x86.Build.0 = DBG|x64
{D0B6092A-9944-4F24-9486-4B7DAE372619}.Release Kernel|x64.ActiveCfg = Release|x64 {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release Kernel|x64.ActiveCfg = Release|x64
{D0B6092A-9944-4F24-9486-4B7DAE372619}.Release Kernel|x64.Build.0 = Release|x64 {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release Kernel|x64.Build.0 = Release|x64
{D0B6092A-9944-4F24-9486-4B7DAE372619}.Release Kernel|x86.ActiveCfg = Release|x64 {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release Kernel|x86.ActiveCfg = DBG|x64
{D0B6092A-9944-4F24-9486-4B7DAE372619}.Release Kernel|x86.Build.0 = Release|x64 {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release Kernel|x86.Build.0 = DBG|x64
{D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MD DLL|x64.ActiveCfg = Release|x64 {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MD DLL|x64.ActiveCfg = Release|x64
{D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MD DLL|x64.Build.0 = Release|x64 {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MD DLL|x64.Build.0 = Release|x64
{D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MD DLL|x86.ActiveCfg = Release|x64 {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MD DLL|x86.ActiveCfg = DBG|x64
{D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MD DLL|x86.Build.0 = Release|x64 {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MD DLL|x86.Build.0 = DBG|x64
{D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MD|x64.ActiveCfg = Release|x64 {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MD|x64.ActiveCfg = Release|x64
{D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MD|x64.Build.0 = Release|x64 {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MD|x64.Build.0 = Release|x64
{D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MD|x86.ActiveCfg = Release|x64 {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MD|x86.ActiveCfg = DBG|x64
{D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MD|x86.Build.0 = Release|x64 {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MD|x86.Build.0 = DBG|x64
{D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MT DLL|x64.ActiveCfg = Release|x64 {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MT DLL|x64.ActiveCfg = Release|x64
{D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MT DLL|x64.Build.0 = Release|x64 {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MT DLL|x64.Build.0 = Release|x64
{D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MT DLL|x86.ActiveCfg = Release|x64 {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MT DLL|x86.ActiveCfg = DBG|x64
{D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MT DLL|x86.Build.0 = Release|x64 {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MT DLL|x86.Build.0 = DBG|x64
{D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MT|x64.ActiveCfg = Release|x64 {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MT|x64.ActiveCfg = Release|x64
{D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MT|x64.Build.0 = Release|x64 {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MT|x64.Build.0 = Release|x64
{D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MT|x86.ActiveCfg = Release|x64 {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MT|x86.ActiveCfg = DBG|x64
{D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MT|x86.Build.0 = Release|x64 {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MT|x86.Build.0 = DBG|x64
{D0B6092A-9944-4F24-9486-4B7DAE372619}.Release|x64.ActiveCfg = Release|x64 {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release|x64.ActiveCfg = Release|x64
{D0B6092A-9944-4F24-9486-4B7DAE372619}.Release|x64.Build.0 = Release|x64 {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release|x64.Build.0 = Release|x64
{D0B6092A-9944-4F24-9486-4B7DAE372619}.Release|x86.ActiveCfg = Release|x64 {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release|x86.ActiveCfg = Release|x64

Loading…
Cancel
Save