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.
87 lines
3.3 KiB
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
|