@ -2,113 +2,115 @@
namespace vm
namespace vm
{
{
namespace handler
namespace handler
{
{
table_t : : table_t ( u64 * table_addr , edit_entry_t edit_entry )
table_t : : table_t ( u64 module_base , u64 image_base , u32 table_rva , vm : : handler : : edit_entry_t edit_entry ,
:
vm : : decrypt_handler_t decrypt_handler , vm : : encrypt_handler_t encrypt_handler )
table_addr ( table_addr ) ,
: module_base ( module_base ) , image_base ( image_base ) , table_rva ( table_rva ) , edit_entry ( edit_entry ) ,
edit_entry ( edit_entry )
decrypt_handler ( decrypt_handler ) , encrypt_handler ( encrypt_handler )
{ }
{
table_addr = reinterpret_cast < u64 * > ( module_base + table_rva ) ;
u64 table_t : : get_entry ( u8 idx ) const
for ( auto idx = 0u ; idx < 256 ; + + idx )
{
{
return table_addr [ idx ] ;
entry_t entry ;
}
entry . decrypted = decrypt ( idx ) ;
entry . encrypted = get_entry ( idx ) ;
entry_t table_t : : get_meta_data ( u8 idx ) const
entry . virt = ( entry . decrypted - image_base ) + module_base ;
{
entry . callback = nullptr ;
return handlers [ idx ] ;
handlers [ idx ] = entry ;
}
}
}
void table_t : : set_entry ( u8 idx , u64 entry )
{
u64 table_t : : get_entry ( u8 idx ) const
edit_entry ( table_addr + idx , entry ) ;
{
}
return table_addr [ idx ] ;
}
void table_t : : set_meta_data ( u8 idx , const entry_t & entry )
{
entry_t table_t : : get_meta_data ( u8 idx ) const
handlers [ idx ] = entry ;
{
}
return handlers [ idx ] ;
}
void table_t : : set_callback ( u8 idx , entry_callback_t callback )
{
void table_t : : set_entry ( u8 idx , u64 entry )
handlers [ idx ] . callback = callback ;
{
}
edit_entry ( table_addr + idx , entry ) ;
}
}
hook_t : : hook_t (
void table_t : : set_meta_data ( u8 idx , const entry_t & entry )
u64 module_base ,
{
u64 image_base ,
handlers [ idx ] = entry ;
decrypt_handler_t decrypt_handler ,
}
encrypt_handler_t encrypt_handler ,
vm : : handler : : table_t * vm_handler_table
void table_t : : set_callback ( u8 idx , entry_callback_t callback )
)
{
:
handlers [ idx ] . callback = callback ;
decrypt_handler ( decrypt_handler ) ,
}
encrypt_handler ( encrypt_handler ) ,
handler_table ( vm_handler_table ) ,
u64 table_t : : decrypt ( u8 idx )
module_base ( module_base ) ,
{
image_base ( image_base )
return decrypt_handler ( get_entry ( idx ) ) ;
{
}
for ( auto idx = 0u ; idx < 256 ; + + idx )
{
u64 table_t : : encrypt ( u64 val )
vm : : handler : : entry_t entry =
{
vm_handler_table - > get_meta_data ( idx ) ;
return encrypt_handler ( val ) ;
}
entry . encrypted = vm_handler_table - > get_entry ( idx ) ;
} // namespace handler
entry . decrypted = decrypt ( entry . encrypted ) ;
entry . virt = ( entry . decrypted - image_base ) + module_base ;
hook_t : : hook_t ( void ) : table_count ( 0 )
vm_handler_table - > set_meta_data ( idx , entry ) ;
{
}
for ( auto idx = 0u ; idx < 10 ; + + idx )
handler_tables [ idx ] = nullptr ;
vm : : g_vmctx = this ;
}
vtrap_encrypted = encrypt (
( reinterpret_cast < std : : uintptr_t > (
void hook_t : : add_table ( vm : : handler : : table_t * table )
& __vtrap ) - module_base ) + image_base ) ;
{
}
handler_tables [ table_count ] = table ;
+ + table_count ;
u64 hook_t : : encrypt ( u64 val ) const
}
{
return encrypt_handler ( val ) ;
void hook_t : : start ( void )
}
{
for ( auto idx = 0u ; idx < table_count ; + + idx )
u64 hook_t : : decrypt ( u64 val ) const
{
{
auto enc_trap_hndlr = handler_tables [ idx ] - > encrypt (
return decrypt_handler ( val ) ;
( reinterpret_cast < std : : uintptr_t > ( & __vtrap ) - handler_tables [ idx ] - > module_base ) +
}
handler_tables [ idx ] - > image_base ) ;
void hook_t : : set_trap ( u64 val ) const
for ( auto table_idx = 0u ; table_idx < 256 ; + + table_idx )
{
handler_tables [ idx ] - > set_entry ( table_idx , enc_trap_hndlr ) ;
for ( auto idx = 0u ; idx < 256 ; + + idx )
}
handler_table - > set_entry ( idx , val ) ;
}
}
void hook_t : : stop ( void )
void hook_t : : start ( ) const
{
{
for ( auto idx = 0u ; idx < table_count ; + + idx )
for ( auto idx = 0u ; idx < 256 ; + + idx )
for ( auto table_idx = 0u ; table_idx < 256 ; + + table_idx )
handler_table - > set_entry ( idx , vtrap_encrypted ) ;
handler_tables [ idx ] - > set_entry ( table_idx , // restore vm handler table encrypted values...
}
handler_tables [ idx ] - > get_meta_data ( table_idx ) . encrypted ) ;
}
void hook_t : : stop ( ) const
{
} // namespace vm
for ( auto idx = 0u ; idx < 256 ; + + idx )
{
void vtrap_wrapper ( vm : : registers * regs , u8 handler_idx )
const auto handler_entry =
handler_table - > get_meta_data ( idx ) . encrypted ;
handler_table - > set_entry ( idx , handler_entry ) ;
}
}
}
void vtrap_wrapper ( vm : : registers * regs , u8 handler_idx )
{
{
regs - > vm_handler = vm : : g_vmctx - >
// r12: vm handler linear virtual address
handler_table - > get_meta_data ( handler_idx ) . virt ;
// r13: module base linear virtual address
auto table_rva = regs - > r12 - ( regs - > r13 + vm : : g_vmctx - > handler_tables [ 0 ] - > image_base ) ;
const auto callback = vm : : g_vmctx - >
handler_table - > get_meta_data ( handler_idx ) . callback ;
// can only be a max of 10 vms... so idx < 10...
for ( auto idx = 0u ; idx < 10 ; + + idx )
// per-virtual instruction callbacks...
{
if ( callback ) callback ( regs , handler_idx ) ;
if ( vm : : g_vmctx - > handler_tables [ idx ] & & vm : : g_vmctx - > handler_tables [ idx ] - > table_rva = = table_rva )
{
regs - > vm_handler = vm : : g_vmctx - > handler_tables [ idx ] - > get_meta_data ( handler_idx ) . virt ;
const auto callback = vm : : g_vmctx - > handler_tables [ idx ] - > get_meta_data ( handler_idx ) . callback ;
// per-virtual instruction callbacks...
if ( callback )
callback ( regs , handler_idx ) ;
return ;
}
}
}
}