You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
vmprofiler-qt/src/vmctx.cpp

87 lines
3.3 KiB

#include "vmctx.h"
namespace vm
{
vmctx_t::vmctx_t( vmp2::file_header *file_header, vmp2::entry_t *entry_list,
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 ),
vm_handlers( vm_handlers ), idx( 0 )
{}
std::pair< std::string, const vmp2::entry_t * > vmctx_t::step() const
{
if ( idx >= file_header->entry_count )
return {};
auto vm_handler = vm_handlers[ entry_list[ idx ].handler_idx ];
if ( vm_handler.imm_size )
{
const auto operand = get_imm( file_header->advancement, entry_list[ idx ].vip, vm_handler.imm_size / 8 );
auto [ decrypted_operand, rolling_key ] =
vm::instrs::decrypt_operand( vm_handler.transforms, operand, entry_list[ idx ].decrypt_key );
if ( vm_handler.profile )
{
if ( vm_handler.profile->extention == vm::handler::extention_t::sign_extend )
{
switch ( vm_handler.imm_size )
{
case 8:
if ( ( u8 )( decrypted_operand >> 7 ) )
decrypted_operand += ~0xFFull;
break;
case 16:
if ( ( u16 )( decrypted_operand >> 15 ) )
decrypted_operand += ~0xFFFFull;
break;
case 32:
if ( ( u32 )( decrypted_operand >> 31 ) )
decrypted_operand += ~0xFFFFFFFFull;
break;
default:
throw std::invalid_argument( "invalid imm size for sign extention...\n" );
}
}
}
char buff[ 256 ];
if ( vm_handler.profile )
snprintf( buff, sizeof buff, "%s 0x%p", vm_handler.profile->name, decrypted_operand );
else
snprintf( buff, sizeof buff, "UNK(%d) 0x%p", entry_list[ idx ].handler_idx, decrypted_operand );
return { buff, &entry_list[ idx++ ] };
}
if ( vm_handler.profile )
return { vm_handler.profile->name, &entry_list[ idx++ ] };
char buff[ 256 ];
snprintf( buff, sizeof buff, "UNK(%d)", entry_list[ idx ].handler_idx );
return { buff, &entry_list[ idx++ ] };
}
std::uintptr_t vmctx_t::get_imm( vmp2::exec_type_t exec_type_t, std::uint32_t vip_offset,
std::uint8_t imm_size ) const
{
std::uintptr_t operand = 0u;
if ( file_header->advancement == vmp2::exec_type_t::forward )
{
const auto operand_ptr =
reinterpret_cast< void * >( ( entry_list[ idx ].vip - file_header->module_base ) + module_base );
memcpy( &operand, operand_ptr, imm_size );
}
else
{
const auto operand_ptr = reinterpret_cast< void * >(
( ( entry_list[ idx ].vip - file_header->module_base ) + module_base ) - imm_size );
memcpy( &operand, operand_ptr, imm_size );
}
return operand;
}
} // namespace vm