cleaned the code a bunch more...

merge-requests/11/head
_xeroxz 3 years ago
parent ae9f255180
commit 13fef335fe

@ -119,7 +119,33 @@ namespace vm::handler
extern vm::handler::profile_t lregq;
extern vm::handler::profile_t lregdw;
/// <summary>
/// mov rax, [rsi]
/// xor rax, rbx ; transformation
/// bswap rax ; transformation
/// lea rsi, [rsi+8] ; advance VIP…
/// rol rax, 0Ch ; transformation
/// inc rax ; transformation
/// xor rbx, rax ; transformation (update rolling decrypt key)
/// sub rbp, 8
/// mov [rbp+0], rax
/// </summary>
extern vm::handler::profile_t lconstq;
/// <summary>
/// mov eax, [rsi-0x04]
/// bswap eax
/// add eax, ebx
/// dec eax
/// neg eax
/// xor eax, 0x2FFD187C
/// push rbx
/// add [rsp], eax
/// pop rbx
/// sub rbp, 0x04
/// mov [rbp], eax
/// add rsi, 0xFFFFFFFFFFFFFFFC
/// </summary>
extern vm::handler::profile_t lconstdw;
extern vm::handler::profile_t lconstw;
@ -130,7 +156,21 @@ namespace vm::handler
extern vm::handler::profile_t lconstwsxq;
extern vm::handler::profile_t lconstwsxdw;
/// <summary>
/// mov rax, [rbp+0]
/// add [rbp+8], rax
/// pushfq
/// pop qword ptr [rbp+0]
/// </summary>
extern vm::handler::profile_t addq;
/// <summary>
/// mov ax, [rbp]
/// sub rbp, 0x06
/// add [rbp+0x08], ax
/// pushfq
/// pop [rbp]
/// </summary>
extern vm::handler::profile_t adddw;
extern vm::handler::profile_t addw;
@ -152,10 +192,36 @@ namespace vm::handler
extern vm::handler::profile_t shrw;
extern vm::handler::profile_t lrflags;
/// <summary>
/// mov rdx, [rbp]
/// add rbp, 0x08
/// call rdx
/// </summary>
extern vm::handler::profile_t call;
extern vm::handler::profile_t pushvsp;
extern vm::handler::profile_t mulq;
/// <summary>
/// mov rdx, [rbp]
/// mov rax, [rbp+0x08]
/// div [rbp+0x10]
/// mov [rbp+0x08], rdx
/// mov [rbp+0x10], rax
/// pushfq
/// pop [rbp]
/// </summary>
extern vm::handler::profile_t divq;
/// <summary>
/// mov esi, [rbp]
/// add rbp, 0x08
/// lea r12, [0x0000000000048F29]
/// mov rax, 0x00 ; image base bytes above 32bits...
/// add rsi, rax
/// mov rbx, rsi ; update decrypt key
/// add rsi, [rbp] ; add module base address
/// </summary>
extern vm::handler::profile_t jmp;
extern vm::handler::profile_t vmexit;

@ -1,62 +1,56 @@
#include <vmprofiler.hpp>
namespace vm
namespace vm::calc_jmp
{
namespace calc_jmp
bool get( zydis_routine_t &vm_entry, zydis_routine_t &calc_jmp )
{
bool get( zydis_routine_t &vm_entry, zydis_routine_t &calc_jmp )
{
auto result = vm::util::get_fetch_operand( vm_entry );
auto result = vm::util::get_fetch_operand( vm_entry );
if ( !result.has_value() )
return false;
if ( !result.has_value() )
return false;
calc_jmp.insert( calc_jmp.end(), result.value(), vm_entry.end() );
return true;
}
calc_jmp.insert( calc_jmp.end(), result.value(), vm_entry.end() );
return true;
}
std::optional< vmp2::exec_type_t > get_advancement( const zydis_routine_t &calc_jmp )
{
auto result =
std::find_if( calc_jmp.begin(), calc_jmp.end(), []( const zydis_instr_t &instr_data ) -> bool {
// look for any instruction with RSI being the first operand and its being written too..
return instr_data.instr.operands[ 0 ].actions & ZYDIS_OPERAND_ACTION_WRITE &&
instr_data.instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr_data.instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RSI;
} );
std::optional< vmp2::exec_type_t > get_advancement( const zydis_routine_t &calc_jmp )
{
auto result = std::find_if( calc_jmp.begin(), calc_jmp.end(), []( const zydis_instr_t &instr_data ) -> bool {
// look for any instruction with RSI being the first operand and its being written too..
return instr_data.instr.operands[ 0 ].actions & ZYDIS_OPERAND_ACTION_WRITE &&
instr_data.instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr_data.instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RSI;
} );
if ( result == calc_jmp.end() )
return {};
if ( result == calc_jmp.end() )
return {};
const auto &instr = result->instr;
const auto &instr = result->instr;
switch ( instr.mnemonic )
{
case ZYDIS_MNEMONIC_LEA:
// if operand type is memory, then return advancement type
// based off of the disposition value... (neg == backward, pos == forward)
if ( instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY )
return instr.operands[ 1 ].mem.disp.value > 0 ? vmp2::exec_type_t::forward
: vmp2::exec_type_t::backward;
break;
case ZYDIS_MNEMONIC_ADD:
if ( instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE )
return instr.operands[ 1 ].imm.value.s > 0 ? vmp2::exec_type_t::forward
: vmp2::exec_type_t::backward;
break;
case ZYDIS_MNEMONIC_SUB:
if ( instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE )
return instr.operands[ 1 ].imm.value.s > 0 ? vmp2::exec_type_t::backward
: vmp2::exec_type_t::forward;
break;
case ZYDIS_MNEMONIC_INC:
return vmp2::exec_type_t::forward;
case ZYDIS_MNEMONIC_DEC:
return vmp2::exec_type_t::backward;
default:
break;
}
return {};
switch ( instr.mnemonic )
{
case ZYDIS_MNEMONIC_LEA:
// if operand type is memory, then return advancement type
// based off of the disposition value... (neg == backward, pos == forward)
if ( instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY )
return instr.operands[ 1 ].mem.disp.value > 0 ? vmp2::exec_type_t::forward
: vmp2::exec_type_t::backward;
break;
case ZYDIS_MNEMONIC_ADD:
if ( instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE )
return instr.operands[ 1 ].imm.value.s > 0 ? vmp2::exec_type_t::forward : vmp2::exec_type_t::backward;
break;
case ZYDIS_MNEMONIC_SUB:
if ( instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE )
return instr.operands[ 1 ].imm.value.s > 0 ? vmp2::exec_type_t::backward : vmp2::exec_type_t::forward;
break;
case ZYDIS_MNEMONIC_INC:
return vmp2::exec_type_t::forward;
case ZYDIS_MNEMONIC_DEC:
return vmp2::exec_type_t::backward;
default:
break;
}
} // namespace calc_jmp
} // namespace vm
return {};
}
} // namespace vm::calc_jmp

@ -1,306 +1,302 @@
#include <vmprofiler.hpp>
namespace vm
namespace vm::handler
{
namespace handler
bool get( zydis_routine_t &calc_jmp, zydis_routine_t &vm_handler, std::uintptr_t handler_addr )
{
bool get( zydis_routine_t &calc_jmp, zydis_routine_t &vm_handler, std::uintptr_t handler_addr )
if ( !vm::util::flatten( vm_handler, handler_addr ) )
return false;
vm::util::deobfuscate( vm_handler );
static const auto calc_jmp_check = [ & ]( std::uintptr_t addr ) -> bool {
for ( const auto &[ instr, instr_raw, instr_addr ] : calc_jmp )
if ( instr_addr == addr )
return true;
return false;
};
// find LEA RAX, [RDI+0xE0], else determine if the instruction is inside of calc_jmp...
auto result = std::find_if( vm_handler.begin(), vm_handler.end(), []( const zydis_instr_t &instr ) -> bool {
return instr.instr.mnemonic == ZYDIS_MNEMONIC_LEA &&
instr.instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX &&
instr.instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RDI &&
instr.instr.operands[ 1 ].mem.disp.value == 0xE0
? true
: calc_jmp_check( instr.addr );
} );
// remove calc_jmp from the vm handler vector...
if ( result != vm_handler.end() )
vm_handler.erase( result, vm_handler.end() );
else // locate the last mov al, [rsi],
// then remove all instructions after that...
{
if ( !vm::util::flatten( vm_handler, handler_addr ) )
return false;
vm::util::deobfuscate( vm_handler );
static const auto calc_jmp_check = [ & ]( std::uintptr_t addr ) -> bool {
for ( const auto &[ instr, instr_raw, instr_addr ] : calc_jmp )
if ( instr_addr == addr )
return true;
return false;
};
// find LEA RAX, [RDI+0xE0], else determine if the instruction is inside of calc_jmp...
auto result = std::find_if( vm_handler.begin(), vm_handler.end(), []( const zydis_instr_t &instr ) -> bool {
return instr.instr.mnemonic == ZYDIS_MNEMONIC_LEA &&
instr.instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX &&
instr.instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RDI &&
instr.instr.operands[ 1 ].mem.disp.value == 0xE0
? true
: calc_jmp_check( instr.addr );
} );
zydis_routine_t::iterator last = vm_handler.end();
result = vm_handler.begin();
// remove calc_jmp from the vm handler vector...
if ( result != vm_handler.end() )
vm_handler.erase( result, vm_handler.end() );
else // locate the last mov al, [rsi],
// then remove all instructions after that...
while ( result != vm_handler.end() )
{
zydis_routine_t::iterator last = vm_handler.end();
result = vm_handler.begin();
while ( result != vm_handler.end() )
{
result = std::find_if( ++result, vm_handler.end(), []( const zydis_instr_t &instr_data ) -> bool {
// mov/movsx/movzx rax/eax/ax/al, [rsi]
return instr_data.instr.operand_count > 1 &&
( instr_data.instr.mnemonic == ZYDIS_MNEMONIC_MOV ||
instr_data.instr.mnemonic == ZYDIS_MNEMONIC_MOVSX ||
instr_data.instr.mnemonic == ZYDIS_MNEMONIC_MOVZX ) &&
instr_data.instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
util::reg::to64( instr_data.instr.operands[ 0 ].reg.value ) == ZYDIS_REGISTER_RAX &&
instr_data.instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr_data.instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RSI;
} );
if ( result != vm_handler.end() )
last = result;
}
if ( last != vm_handler.end() )
vm_handler.erase( last, vm_handler.end() );
result = std::find_if( ++result, vm_handler.end(), []( const zydis_instr_t &instr_data ) -> bool {
// mov/movsx/movzx rax/eax/ax/al, [rsi]
return instr_data.instr.operand_count > 1 &&
( instr_data.instr.mnemonic == ZYDIS_MNEMONIC_MOV ||
instr_data.instr.mnemonic == ZYDIS_MNEMONIC_MOVSX ||
instr_data.instr.mnemonic == ZYDIS_MNEMONIC_MOVZX ) &&
instr_data.instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
util::reg::to64( instr_data.instr.operands[ 0 ].reg.value ) == ZYDIS_REGISTER_RAX &&
instr_data.instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr_data.instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RSI;
} );
if ( result != vm_handler.end() )
last = result;
}
return true;
if ( last != vm_handler.end() )
vm_handler.erase( last, vm_handler.end() );
}
return true;
}
bool get_all( std::uintptr_t module_base, std::uintptr_t image_base, zydis_routine_t &vm_entry,
std::uintptr_t *vm_handler_table, std::vector< vm::handler::handler_t > &vm_handlers )
{
zydis_decoded_instr_t instr;
if ( !vm::handler::table::get_transform( vm_entry, &instr ) )
return false;
zydis_routine_t calc_jmp;
if ( !vm::calc_jmp::get( vm_entry, calc_jmp ) )
return false;
bool get_all( std::uintptr_t module_base, std::uintptr_t image_base, zydis_routine_t &vm_entry,
std::uintptr_t *vm_handler_table, std::vector< vm::handler::handler_t > &vm_handlers )
for ( auto idx = 0u; idx < 256; ++idx )
{
zydis_decoded_instr_t instr;
if ( !vm::handler::table::get_transform( vm_entry, &instr ) )
handler_t vm_handler;
vm::transform::map_t transforms;
zydis_routine_t vm_handler_instrs;
const auto decrypt_val = vm::handler::table::decrypt( instr, vm_handler_table[ idx ] );
if ( !vm::handler::get( calc_jmp, vm_handler_instrs, ( decrypt_val - image_base ) + module_base ) )
return false;
zydis_routine_t calc_jmp;
if ( !vm::calc_jmp::get( vm_entry, calc_jmp ) )
const auto has_imm = vm::handler::has_imm( vm_handler_instrs );
const auto imm_size = vm::handler::imm_size( vm_handler_instrs );
if ( has_imm &&
( !vm::handler::get_operand_transforms( vm_handler_instrs, transforms ) || !imm_size.has_value() ) )
return false;
for ( auto idx = 0u; idx < 256; ++idx )
{
handler_t vm_handler;
vm::transform::map_t transforms;
zydis_routine_t vm_handler_instrs;
vm_handler.address = ( decrypt_val - image_base ) + module_base;
vm_handler.instrs = vm_handler_instrs;
vm_handler.imm_size = imm_size.value();
vm_handler.transforms = transforms;
vm_handler.profile = vm::handler::get_profile( vm_handler );
vm_handlers.push_back( vm_handler );
}
const auto decrypt_val = vm::handler::table::decrypt( instr, vm_handler_table[ idx ] );
if ( !vm::handler::get( calc_jmp, vm_handler_instrs, ( decrypt_val - image_base ) + module_base ) )
return false;
return true;
}
const auto has_imm = vm::handler::has_imm( vm_handler_instrs );
const auto imm_size = vm::handler::imm_size( vm_handler_instrs );
bool has_imm( const zydis_routine_t &vm_handler )
{
zydis_instr_t instr_data;
return vm::util::get_fetch_operand( vm_handler, instr_data );
}
if ( has_imm && ( !vm::handler::get_operand_transforms( vm_handler_instrs, transforms ) ||
!imm_size.has_value() ) )
return false;
std::optional< std::uint8_t > imm_size( const zydis_routine_t &vm_handler )
{
zydis_instr_t instr_data;
if ( !vm::util::get_fetch_operand( vm_handler, instr_data ) )
return {};
vm_handler.address = ( decrypt_val - image_base ) + module_base;
vm_handler.instrs = vm_handler_instrs;
vm_handler.imm_size = imm_size.value();
vm_handler.transforms = transforms;
vm_handler.profile = vm::handler::get_profile( vm_handler );
vm_handlers.push_back( vm_handler );
}
return instr_data.instr.operands[ 1 ].size;
}
return true;
}
bool get_operand_transforms( zydis_routine_t &vm_handler, transform::map_t &transforms )
{
auto imm_fetch = vm::util::get_fetch_operand( vm_handler );
bool has_imm( const zydis_routine_t &vm_handler )
{
zydis_instr_t instr_data;
return vm::util::get_fetch_operand( vm_handler, instr_data );
}
if ( !imm_fetch.has_value() )
return false;
std::optional< std::uint8_t > imm_size( const zydis_routine_t &vm_handler )
{
zydis_instr_t instr_data;
if ( !vm::util::get_fetch_operand( vm_handler, instr_data ) )
return {};
// this finds the first transformation which looks like:
// transform rax, rbx <--- note these registers can be smaller so we to64 them...
auto transform_instr =
std::find_if( imm_fetch.value(), vm_handler.end(), []( const zydis_instr_t &instr_data ) -> bool {
return vm::transform::valid( instr_data.instr.mnemonic ) &&
instr_data.instr.operands[ 0 ].actions & ZYDIS_OPERAND_ACTION_WRITE &&
util::reg::compare( instr_data.instr.operands[ 0 ].reg.value, ZYDIS_REGISTER_RAX ) &&
util::reg::compare( instr_data.instr.operands[ 1 ].reg.value, ZYDIS_REGISTER_RBX );
} );
return instr_data.instr.operands[ 1 ].size;
}
if ( transform_instr == vm_handler.end() )
return false;
bool get_operand_transforms( zydis_routine_t &vm_handler, transform::map_t &transforms )
{
auto imm_fetch = vm::util::get_fetch_operand( vm_handler );
// look for a primer/instruction that alters RAX prior to the 5 transformations...
auto generic0 =
std::find_if( imm_fetch.value(), transform_instr, []( const zydis_instr_t &instr_data ) -> bool {
return vm::transform::valid( instr_data.instr.mnemonic ) &&
instr_data.instr.operands[ 0 ].actions & ZYDIS_OPERAND_ACTION_WRITE &&
util::reg::compare( instr_data.instr.operands[ 0 ].reg.value, ZYDIS_REGISTER_RAX ) &&
!util::reg::compare( instr_data.instr.operands[ 1 ].reg.value, ZYDIS_REGISTER_RBX );
} );
if ( !imm_fetch.has_value() )
return false;
zydis_decoded_instr_t nogeneric0;
nogeneric0.mnemonic = ZYDIS_MNEMONIC_INVALID;
transforms[ transform::type::generic0 ] = generic0 != transform_instr ? generic0->instr : nogeneric0;
// last transformation is the same as the first except src and dest are swwapped...
transforms[ transform::type::rolling_key ] = transform_instr->instr;
auto instr_copy = transform_instr->instr;
instr_copy.operands[ 0 ].reg.value = transform_instr->instr.operands[ 1 ].reg.value;
instr_copy.operands[ 1 ].reg.value = transform_instr->instr.operands[ 0 ].reg.value;
transforms[ transform::type::update_key ] = instr_copy;
// this finds the first transformation which looks like:
// transform rax, rbx <--- note these registers can be smaller so we to64 them...
auto transform_instr =
std::find_if( imm_fetch.value(), vm_handler.end(), []( const zydis_instr_t &instr_data ) -> bool {
// three generic transformations...
for ( auto idx = static_cast< unsigned >( vm::transform::type::generic1 );
idx < static_cast< unsigned >( vm::transform::type::update_key ); ++idx )
{
transform_instr =
std::find_if( ++transform_instr, vm_handler.end(), []( const zydis_instr_t &instr_data ) -> bool {
return vm::transform::valid( instr_data.instr.mnemonic ) &&
instr_data.instr.operands[ 0 ].actions & ZYDIS_OPERAND_ACTION_WRITE &&
util::reg::compare( instr_data.instr.operands[ 0 ].reg.value, ZYDIS_REGISTER_RAX ) &&
util::reg::compare( instr_data.instr.operands[ 1 ].reg.value, ZYDIS_REGISTER_RBX );
util::reg::compare( instr_data.instr.operands[ 0 ].reg.value, ZYDIS_REGISTER_RAX );
} );
if ( transform_instr == vm_handler.end() )
return false;
// look for a primer/instruction that alters RAX prior to the 5 transformations...
auto generic0 = std::find_if( imm_fetch.value(), transform_instr, []( const zydis_instr_t &instr_data ) -> bool {
return vm::transform::valid( instr_data.instr.mnemonic ) &&
instr_data.instr.operands[ 0 ].actions & ZYDIS_OPERAND_ACTION_WRITE &&
util::reg::compare( instr_data.instr.operands[ 0 ].reg.value, ZYDIS_REGISTER_RAX ) &&
!util::reg::compare( instr_data.instr.operands[ 1 ].reg.value, ZYDIS_REGISTER_RBX );
} );
transforms[ static_cast< vm::transform::type >( idx ) ] = transform_instr->instr;
}
zydis_decoded_instr_t nogeneric0;
nogeneric0.mnemonic = ZYDIS_MNEMONIC_INVALID;
transforms[ transform::type::generic0 ] = generic0 != transform_instr ? generic0->instr : nogeneric0;
return true;
}
// last transformation is the same as the first except src and dest are swwapped...
transforms[ transform::type::rolling_key ] = transform_instr->instr;
auto instr_copy = transform_instr->instr;
instr_copy.operands[ 0 ].reg.value = transform_instr->instr.operands[ 1 ].reg.value;
instr_copy.operands[ 1 ].reg.value = transform_instr->instr.operands[ 0 ].reg.value;
transforms[ transform::type::update_key ] = instr_copy;
vm::handler::profile_t *get_profile( handler_t &vm_handler )
{
static const auto vcontains = []( vm::handler::profile_t *vprofile, handler_t *vm_handler ) -> bool {
if ( vprofile->imm_size != vm_handler->imm_size )
return false;
zydis_routine_t::iterator contains = vm_handler->instrs.begin();
// three generic transformations...
for ( auto idx = static_cast< unsigned >( vm::transform::type::generic1 );
idx < static_cast< unsigned >( vm::transform::type::update_key ); ++idx )
for ( auto &instr : vprofile->signature )
{
transform_instr =
std::find_if( ++transform_instr, vm_handler.end(), []( const zydis_instr_t &instr_data ) -> bool {
return vm::transform::valid( instr_data.instr.mnemonic ) &&
instr_data.instr.operands[ 0 ].actions & ZYDIS_OPERAND_ACTION_WRITE &&
util::reg::compare( instr_data.instr.operands[ 0 ].reg.value, ZYDIS_REGISTER_RAX );
} );
if ( transform_instr == vm_handler.end() )
return false;
contains =
std::find_if( contains, vm_handler->instrs.end(),
[ & ]( zydis_instr_t &instr_data ) -> bool { return instr( instr_data.instr ); } );
transforms[ static_cast< vm::transform::type >( idx ) ] = transform_instr->instr;
if ( contains == vm_handler->instrs.end() )
return false;
}
return true;
}
};
vm::handler::profile_t *get_profile( handler_t &vm_handler )
{
static const auto vcontains = []( vm::handler::profile_t *vprofile, handler_t *vm_handler ) -> bool {
if ( vprofile->imm_size != vm_handler->imm_size )
return false;
zydis_routine_t::iterator contains = vm_handler->instrs.begin();
for ( auto profile : vm::handler::profile::all )
if ( vcontains( profile, &vm_handler ) )
return profile;
for ( auto &instr : vprofile->signature )
{
contains =
std::find_if( contains, vm_handler->instrs.end(), [ & ]( zydis_instr_t &instr_data ) -> bool {
return instr( instr_data.instr );
} );
return nullptr;
}
if ( contains == vm_handler->instrs.end() )
return false;
}
vm::handler::profile_t *get_profile( vm::handler::mnemonic_t mnemonic )
{
auto result =
std::find_if( vm::handler::profile::all.begin(), vm::handler::profile::all.end(),
[ & ]( vm::handler::profile_t *profile ) -> bool { return profile->mnemonic == mnemonic; } );
return true;
};
return result != vm::handler::profile::all.end() ? *result : nullptr;
}
for ( auto profile : vm::handler::profile::all )
if ( vcontains( profile, &vm_handler ) )
return profile;
namespace table
{
std::uintptr_t *get( const zydis_routine_t &vm_entry )
{
const auto result =
std::find_if( vm_entry.begin(), vm_entry.end(), []( const zydis_instr_t &instr_data ) -> bool {
const auto instr = &instr_data.instr;
// lea r12, vm_handlers... (always r12)...
return instr->mnemonic == ZYDIS_MNEMONIC_LEA &&
instr->operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr->operands[ 0 ].reg.value == ZYDIS_REGISTER_R12 &&
!instr->raw.sib.base; // no register used for the sib base...
} );
return nullptr;
}
if ( result == vm_entry.end() )
return nullptr;
vm::handler::profile_t *get_profile( vm::handler::mnemonic_t mnemonic )
{
auto result = std::find_if(
vm::handler::profile::all.begin(), vm::handler::profile::all.end(),
[ & ]( vm::handler::profile_t *profile ) -> bool { return profile->mnemonic == mnemonic; } );
auto ptr = 0ull;
ZydisCalcAbsoluteAddress( &result->instr, &result->instr.operands[ 1 ], result->addr, &ptr );
return result != vm::handler::profile::all.end() ? *result : nullptr;
return reinterpret_cast< std::uintptr_t * >( ptr );
}
namespace table
bool get_transform( const zydis_routine_t &vm_entry, zydis_decoded_instr_t *transform_instr )
{
std::uintptr_t *get( const zydis_routine_t &vm_entry )
{
const auto result =
std::find_if( vm_entry.begin(), vm_entry.end(), []( const zydis_instr_t &instr_data ) -> bool {
const auto instr = &instr_data.instr;
// lea r12, vm_handlers... (always r12)...
return instr->mnemonic == ZYDIS_MNEMONIC_LEA &&
instr->operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr->operands[ 0 ].reg.value == ZYDIS_REGISTER_R12 &&
!instr->raw.sib.base; // no register used for the sib base...
} );
if ( result == vm_entry.end() )
return nullptr;
auto ptr = 0ull;
ZydisCalcAbsoluteAddress( &result->instr, &result->instr.operands[ 1 ], result->addr, &ptr );
return reinterpret_cast< std::uintptr_t * >( ptr );
}
auto handler_fetch =
std::find_if( vm_entry.begin(), vm_entry.end(), [ & ]( const zydis_instr_t &instr_data ) -> bool {
const auto instr = &instr_data.instr;
return instr->mnemonic == ZYDIS_MNEMONIC_MOV && instr->operand_count == 2 &&
instr->operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr->operands[ 1 ].mem.base == ZYDIS_REGISTER_R12 &&
instr->operands[ 1 ].mem.index == ZYDIS_REGISTER_RAX &&
instr->operands[ 1 ].mem.scale == 8 &&
instr->operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
( instr->operands[ 0 ].reg.value == ZYDIS_REGISTER_RDX ||
instr->operands[ 0 ].reg.value == ZYDIS_REGISTER_RCX );
} );
bool get_transform( const zydis_routine_t &vm_entry, zydis_decoded_instr_t *transform_instr )
{
auto handler_fetch =
std::find_if( vm_entry.begin(), vm_entry.end(), [ & ]( const zydis_instr_t &instr_data ) -> bool {
const auto instr = &instr_data.instr;
return instr->mnemonic == ZYDIS_MNEMONIC_MOV && instr->operand_count == 2 &&
instr->operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr->operands[ 1 ].mem.base == ZYDIS_REGISTER_R12 &&
instr->operands[ 1 ].mem.index == ZYDIS_REGISTER_RAX &&
instr->operands[ 1 ].mem.scale == 8 &&
instr->operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
( instr->operands[ 0 ].reg.value == ZYDIS_REGISTER_RDX ||
instr->operands[ 0 ].reg.value == ZYDIS_REGISTER_RCX );
} );
// check to see if we found the fetch instruction and if the next instruction
// is not the end of the vector...
if ( handler_fetch == vm_entry.end() ||
// must be RCX or RDX... else something went wrong...
( handler_fetch->instr.operands[ 0 ].reg.value != ZYDIS_REGISTER_RCX &&
handler_fetch->instr.operands[ 0 ].reg.value != ZYDIS_REGISTER_RDX ) )
return false;
// check to see if we found the fetch instruction and if the next instruction
// is not the end of the vector...
if ( handler_fetch == vm_entry.end() ||
// must be RCX or RDX... else something went wrong...
( handler_fetch->instr.operands[ 0 ].reg.value != ZYDIS_REGISTER_RCX &&
handler_fetch->instr.operands[ 0 ].reg.value != ZYDIS_REGISTER_RDX ) )
return false;
// find the next instruction that writes to RCX or RDX...
// the register is determined by the vm handler fetch above...
auto handler_transform =
std::find_if( handler_fetch, vm_entry.end(), [ & ]( const zydis_instr_t &instr_data ) -> bool {
return vm::transform::valid( instr_data.instr.mnemonic ) &&
instr_data.instr.operands[ 0 ].reg.value ==
handler_fetch->instr.operands[ 0 ].reg.value &&
instr_data.instr.operands[ 0 ].actions & ZYDIS_OPERAND_ACTION_WRITE;
} );
if ( handler_transform == vm_entry.end() )
return false;
// find the next instruction that writes to RCX or RDX...
// the register is determined by the vm handler fetch above...
auto handler_transform =
std::find_if( handler_fetch, vm_entry.end(), [ & ]( const zydis_instr_t &instr_data ) -> bool {
return vm::transform::valid( instr_data.instr.mnemonic ) &&
instr_data.instr.operands[ 0 ].reg.value == handler_fetch->instr.operands[ 0 ].reg.value &&
instr_data.instr.operands[ 0 ].actions & ZYDIS_OPERAND_ACTION_WRITE;
} );
*transform_instr = handler_transform->instr;
return true;
}
if ( handler_transform == vm_entry.end() )
return false;
std::uint64_t encrypt( zydis_decoded_instr_t &transform_instr, std::uint64_t val )
{
assert( transform_instr.operands[ 0 ].size == 64,
"invalid transformation for vm handler table entries..." );
*transform_instr = handler_transform->instr;
return true;
}
const auto operation = vm::transform::inverse[ transform_instr.mnemonic ];
const auto bitsize = transform_instr.operands[ 0 ].size;
const auto imm =
vm::transform::has_imm( &transform_instr ) ? transform_instr.operands[ 1 ].imm.value.u : 0u;
std::uint64_t encrypt( zydis_decoded_instr_t &transform_instr, std::uint64_t val )
{
assert( transform_instr.operands[ 0 ].size == 64,
"invalid transformation for vm handler table entries..." );
return vm::transform::apply( bitsize, operation, val, imm );
}
const auto operation = vm::transform::inverse[ transform_instr.mnemonic ];
const auto bitsize = transform_instr.operands[ 0 ].size;
const auto imm =
vm::transform::has_imm( &transform_instr ) ? transform_instr.operands[ 1 ].imm.value.u : 0u;
std::uint64_t decrypt( zydis_decoded_instr_t &transform_instr, std::uint64_t val )
{
assert( transform_instr.operands[ 0 ].size == 64,
"invalid transformation for vm handler table entries..." );
return vm::transform::apply( bitsize, operation, val, imm );
}
const auto operation = transform_instr.mnemonic;
const auto bitsize = transform_instr.operands[ 0 ].size;
const auto imm =
vm::transform::has_imm( &transform_instr ) ? transform_instr.operands[ 1 ].imm.value.u : 0u;
std::uint64_t decrypt( zydis_decoded_instr_t &transform_instr, std::uint64_t val )
{
assert( transform_instr.operands[ 0 ].size == 64,
"invalid transformation for vm handler table entries..." );
return vm::transform::apply( bitsize, operation, val, imm );
}
} // namespace table
} // namespace handler
} // namespace vm
const auto operation = transform_instr.mnemonic;
const auto bitsize = transform_instr.operands[ 0 ].size;
const auto imm =
vm::transform::has_imm( &transform_instr ) ? transform_instr.operands[ 1 ].imm.value.u : 0u;
return vm::transform::apply( bitsize, operation, val, imm );
}
} // namespace table
} // namespace vm::handler

@ -1,91 +1,73 @@
#include <vmprofiler.hpp>
namespace vm
namespace vm::handler::profile
{
namespace handler
{
namespace profile
{
vm::handler::profile_t addq = {
// ADD [RBP+8], RAX
// PUSHFQ
// POP [RBP]
"ADDQ",
ADDQ,
NULL,
{ { // ADD [RBP+8], RAX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_ADD &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 0 ].mem.disp.value == 0x8 &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RAX;
},
// PUSHFQ
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_PUSHFQ;
},
// POP [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_POP &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP;
} } } };
vm::handler::profile_t addq = {
// ADD [RBP+8], RAX
// PUSHFQ
// POP [RBP]
"ADDQ",
ADDQ,
NULL,
{ { // ADD [RBP+8], RAX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_ADD && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 0 ].mem.disp.value == 0x8 &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RAX;
},
// PUSHFQ
[]( const zydis_decoded_instr_t &instr ) -> bool { return instr.mnemonic == ZYDIS_MNEMONIC_PUSHFQ; },
// POP [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_POP && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP;
} } } };
vm::handler::profile_t adddw = {
// ADD [RBP+8], EAX
// PUSHFQ
// POP [RBP]
"ADDDW",
ADDDW,
NULL,
{ { // ADD [RBP+8], EAX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_ADD &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 0 ].mem.disp.value == 0x8 &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_EAX;
},
// PUSHFQ
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_PUSHFQ;
},
// POP [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_POP &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP;
} } } };
vm::handler::profile_t adddw = {
// ADD [RBP+8], EAX
// PUSHFQ
// POP [RBP]
"ADDDW",
ADDDW,
NULL,
{ { // ADD [RBP+8], EAX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_ADD && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 0 ].mem.disp.value == 0x8 &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_EAX;
},
// PUSHFQ
[]( const zydis_decoded_instr_t &instr ) -> bool { return instr.mnemonic == ZYDIS_MNEMONIC_PUSHFQ; },
// POP [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_POP && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP;
} } } };
vm::handler::profile_t addw = {
// ADD [RBP+8], AX
// PUSHFQ
// POP [RBP]
"ADDW",
ADDW,
NULL,
{ { // ADD [RBP+8], AX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_ADD &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 0 ].mem.disp.value == 0x8 &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_AX;
},
// PUSHFQ
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_PUSHFQ;
},
// POP [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_POP &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP;
} } } };
} // namespace profile
} // namespace handler
} // namespace vm
vm::handler::profile_t addw = {
// ADD [RBP+8], AX
// PUSHFQ
// POP [RBP]
"ADDW",
ADDW,
NULL,
{ { // ADD [RBP+8], AX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_ADD && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 0 ].mem.disp.value == 0x8 &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_AX;
},
// PUSHFQ
[]( const zydis_decoded_instr_t &instr ) -> bool { return instr.mnemonic == ZYDIS_MNEMONIC_PUSHFQ; },
// POP [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_POP && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP;
} } } };
} // namespace vm::handler::profile

@ -1,40 +1,34 @@
#include <vmprofiler.hpp>
namespace vm
namespace vm::handler::profile
{
namespace handler
{
namespace profile
{
vm::handler::profile_t call = {
// MOV RDX, [RBP]
// ADD RBP, 0x8
// CALL RDX
"CALL",
CALL,
NULL,
{ { // MOV RDX, [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RDX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
},
// ADD RBP, 0x8
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_ADD &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
instr.operands[ 1 ].imm.value.u == 0x8;
},
// CALL RDX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_CALL &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RDX;
} } } };
}
} // namespace handler
} // namespace vm
vm::handler::profile_t call = {
// MOV RDX, [RBP]
// ADD RBP, 0x8
// CALL RDX
"CALL",
CALL,
NULL,
{ { // MOV RDX, [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RDX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
},
// ADD RBP, 0x8
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_ADD &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
instr.operands[ 1 ].imm.value.u == 0x8;
},
// CALL RDX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_CALL &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RDX;
} } } };
} // namespace vm::handler::profile

@ -1,74 +1,58 @@
#include <vmprofiler.hpp>
namespace vm
namespace vm::handler::profile
{
namespace handler
{
namespace profile
{
vm::handler::profile_t divq = {
// MOV RDX, [RBP]
// MOV RAX, [RBP+0x8]
// DIV [RBP+0x10]
// MOV [RBP+0x8], RDX
// MOV [RBP+0x10], RAX
// PUSHFQ
// POP [RBP]
"DIVQ",
DIVQ,
NULL,
{ { // MOV RDX, [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RDX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
},
// MOV RAX, [RBP+0x8]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].mem.index == 0x8;
},
// DIV [RBP+0x10]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_DIV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 0 ].mem.index == 0x10;
},
// MOV [RBP+0x8], RDX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 0 ].mem.index == 0x8 &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RDX;
},
// MOV [RBP+0x10], RAX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 0 ].mem.index == 0x10 &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RAX;
},
// PUSHFQ
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_PUSHFQ;
},
// POP [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_POP &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP;
} } } };
}
} // namespace handler
} // namespace vm
vm::handler::profile_t divq = {
// MOV RDX, [RBP]
// MOV RAX, [RBP+0x8]
// DIV [RBP+0x10]
// MOV [RBP+0x8], RDX
// MOV [RBP+0x10], RAX
// PUSHFQ
// POP [RBP]
"DIVQ",
DIVQ,
NULL,
{ { // MOV RDX, [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RDX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
},
// MOV RAX, [RBP+0x8]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP && instr.operands[ 1 ].mem.index == 0x8;
},
// DIV [RBP+0x10]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_DIV && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP && instr.operands[ 0 ].mem.index == 0x10;
},
// MOV [RBP+0x8], RDX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP && instr.operands[ 0 ].mem.index == 0x8 &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RDX;
},
// MOV [RBP+0x10], RAX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP && instr.operands[ 0 ].mem.index == 0x10 &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RAX;
},
// PUSHFQ
[]( const zydis_decoded_instr_t &instr ) -> bool { return instr.mnemonic == ZYDIS_MNEMONIC_PUSHFQ; },
// POP [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_POP && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP;
} } } };
} // namespace vm::handler::profile

@ -1,51 +1,45 @@
#include <vmprofiler.hpp>
namespace vm
namespace vm::handler::profile
{
namespace handler
{
namespace profile
{
vm::handler::profile_t jmp = {
// MOV ESI, [RBP]
// ADD RSI, RAX
// MOV RBX, RSI
// ADD RSI, [RBP]
"JMP",
JMP,
NULL,
{ { // MOV ESI, [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_ESI &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
},
// ADD RSI, RAX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_ADD &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RSI &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RAX;
},
// MOV RBX, RSI
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RSI;
},
// ADD RSI, [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_ADD &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RSI &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
} } } };
}
} // namespace handler
} // namespace vm
vm::handler::profile_t jmp = {
// MOV ESI, [RBP]
// ADD RSI, RAX
// MOV RBX, RSI
// ADD RSI, [RBP]
"JMP",
JMP,
NULL,
{ { // MOV ESI, [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_ESI &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
},
// ADD RSI, RAX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_ADD &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RSI &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RAX;
},
// MOV RBX, RSI
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RSI;
},
// ADD RSI, [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_ADD &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RSI &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
} } } };
} // namespace vm::handler::profile

@ -1,239 +1,222 @@
#include <vmprofiler.hpp>
namespace vm
namespace vm::handler::profile
{
namespace handler
{
namespace profile
{
vm::handler::profile_t lconstq = {
// MOV RAX, [RSI]
// SUB RBP, 8
// MOV [RBP], RAX
"LCONSTQ",
LCONSTQ,
64,
{ { // SUB RBP, 8
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
instr.operands[ 1 ].imm.value.u == 0x8;
},
// MOV [RBP], RAX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RAX;
} } } };
vm::handler::profile_t lconstq = {
// MOV RAX, [RSI]
// SUB RBP, 8
// MOV [RBP], RAX
"LCONSTQ",
LCONSTQ,
64,
{ { // SUB RBP, 8
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
instr.operands[ 1 ].imm.value.u == 0x8;
},
// MOV [RBP], RAX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RAX;
} } } };
vm::handler::profile_t lconstdw = {
// SUB RBP, 4
// MOV [RBP], EAX
"LCONSTDW",
LCONSTDW,
32,
{ { // SUB RBP, 4
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
instr.operands[ 1 ].imm.value.u == 0x4;
},
// MOV [RBP], EAX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_EAX;
} } } };
vm::handler::profile_t lconstdw = {
// SUB RBP, 4
// MOV [RBP], EAX
"LCONSTDW",
LCONSTDW,
32,
{ { // SUB RBP, 4
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
instr.operands[ 1 ].imm.value.u == 0x4;
},
// MOV [RBP], EAX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_EAX;
} } } };
vm::handler::profile_t lconstw = {
// SUB RBP, 2
// MOV [RBP], AX
"LCONSTW",
LCONSTW,
16,
{ { // SUB RBP, 2
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
instr.operands[ 1 ].imm.value.u == 0x2;
},
// MOV [RBP], AX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_AX;
} } } };
vm::handler::profile_t lconstw = {
// SUB RBP, 2
// MOV [RBP], AX
"LCONSTW",
LCONSTW,
16,
{ { // SUB RBP, 2
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
instr.operands[ 1 ].imm.value.u == 0x2;
},
// MOV [RBP], AX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_AX;
} } } };
vm::handler::profile_t lconstbzxw = {
// MOV AL, [RSI]
// SUB RBP, 2
// MOV [RBP], AX
"LCONSTBZXW",
LCONSTBZXW,
8,
{ { // SUB RBP, 2
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
instr.operands[ 1 ].imm.value.u == 0x2;
},
// MOV [RBP], AX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_AX;
} } } };
vm::handler::profile_t lconstbzxw = {
// MOV AL, [RSI]
// SUB RBP, 2
// MOV [RBP], AX
"LCONSTBZXW",
LCONSTBZXW,
8,
{ { // SUB RBP, 2
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
instr.operands[ 1 ].imm.value.u == 0x2;
},
// MOV [RBP], AX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_AX;
} } } };
vm::handler::profile_t lconstbsxdw = {
// CWDE
// SUB RBP, 4
// MOV [RBP], EAX
"LCONSTBSXDW",
LCONSTBSXDW,
8,
{ { // CWDE
[]( const zydis_decoded_instr_t &instr ) -> bool { return instr.mnemonic == ZYDIS_MNEMONIC_CWDE; },
// SUB RBP, 4
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
instr.operands[ 1 ].imm.value.u == 0x4;
},
// MOV [RBP], EAX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_EAX;
} } },
vm::handler::extention_t::sign_extend };
vm::handler::profile_t lconstbsxdw = {
// CWDE
// SUB RBP, 4
// MOV [RBP], EAX
"LCONSTBSXDW",
LCONSTBSXDW,
8,
{ { // CWDE
[]( const zydis_decoded_instr_t &instr ) -> bool { return instr.mnemonic == ZYDIS_MNEMONIC_CWDE; },
// SUB RBP, 4
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
instr.operands[ 1 ].imm.value.u == 0x4;
},
// MOV [RBP], EAX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_EAX;
} } },
vm::handler::extention_t::sign_extend };
vm::handler::profile_t lconstbsxq = {
// CDQE
// SUB RBP, 0x8
// MOV [RBP], RAX
"LCONSTBSXQ",
LCONSTBSXQ,
8,
{ { // CDQE
[]( const zydis_decoded_instr_t &instr ) -> bool { return instr.mnemonic == ZYDIS_MNEMONIC_CDQE; },
// SUB RBP, 0x8
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
instr.operands[ 1 ].imm.value.u == 0x8;
},
// MOV [RBP], RAX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RAX;
} } },
vm::handler::extention_t::sign_extend };
vm::handler::profile_t lconstbsxq = {
// CDQE
// SUB RBP, 0x8
// MOV [RBP], RAX
"LCONSTBSXQ",
LCONSTBSXQ,
8,
{ { // CDQE
[]( const zydis_decoded_instr_t &instr ) -> bool { return instr.mnemonic == ZYDIS_MNEMONIC_CDQE; },
// SUB RBP, 0x8
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
instr.operands[ 1 ].imm.value.u == 0x8;
},
// MOV [RBP], RAX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RAX;
} } },
vm::handler::extention_t::sign_extend };
vm::handler::profile_t lconstdwsxq = {
// CDQE
// SUB RBP, 8
// MOV [RBP], RAX
"LCONSTDWSXQ",
LCONSTDWSXQ,
32,
{ // CDQE
[]( const zydis_decoded_instr_t &instr ) -> bool { return instr.mnemonic == ZYDIS_MNEMONIC_CDQE; },
// SUB RBP, 8
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
instr.operands[ 1 ].imm.value.u == 0x8;
},
// MOV [RBP], RAX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RAX;
} },
vm::handler::extention_t::sign_extend };
vm::handler::profile_t lconstdwsxq = {
// CDQE
// SUB RBP, 8
// MOV [RBP], RAX
"LCONSTDWSXQ",
LCONSTDWSXQ,
32,
{ // CDQE
[]( const zydis_decoded_instr_t &instr ) -> bool { return instr.mnemonic == ZYDIS_MNEMONIC_CDQE; },
// SUB RBP, 8
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_SUB && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE && instr.operands[ 1 ].imm.value.u == 0x8;
},
// MOV [RBP], RAX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RAX;
} },
vm::handler::extention_t::sign_extend };
vm::handler::profile_t lconstwsxq = {
// CDQE
// SUB RBP, 8
// MOV [RBP], RAX
"LCONSTWSXQ",
LCONSTWSXQ,
16,
{ { // CDQE
[]( const zydis_decoded_instr_t &instr ) -> bool { return instr.mnemonic == ZYDIS_MNEMONIC_CDQE; },
// SUB RBP, 8
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
instr.operands[ 1 ].imm.value.u == 0x8;
},
// MOV [RBP], RAX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RAX;
} } },
vm::handler::extention_t::sign_extend };
vm::handler::profile_t lconstwsxq = {
// CDQE
// SUB RBP, 8
// MOV [RBP], RAX
"LCONSTWSXQ",
LCONSTWSXQ,
16,
{ { // CDQE
[]( const zydis_decoded_instr_t &instr ) -> bool { return instr.mnemonic == ZYDIS_MNEMONIC_CDQE; },
// SUB RBP, 8
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
instr.operands[ 1 ].imm.value.u == 0x8;
},
// MOV [RBP], RAX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RAX;
} } },
vm::handler::extention_t::sign_extend };
vm::handler::profile_t lconstwsxdw = {
// CWDE
// SUB RBP, 4
// MOV [RBP], EAX
"LCONSTWSXDW",
LCONSTWSXDW,
16,
{ { // CWDE
[]( const zydis_decoded_instr_t &instr ) -> bool { return instr.mnemonic == ZYDIS_MNEMONIC_CWDE; },
// SUB RBP, 4
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
instr.operands[ 1 ].imm.value.u == 0x4;
},
// MOV [RBP], EAX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_EAX;
} } },
vm::handler::extention_t::sign_extend };
} // namespace profile
} // namespace handler
} // namespace vm
vm::handler::profile_t lconstwsxdw = {
// CWDE
// SUB RBP, 4
// MOV [RBP], EAX
"LCONSTWSXDW",
LCONSTWSXDW,
16,
{ { // CWDE
[]( const zydis_decoded_instr_t &instr ) -> bool { return instr.mnemonic == ZYDIS_MNEMONIC_CWDE; },
// SUB RBP, 4
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
instr.operands[ 1 ].imm.value.u == 0x4;
},
// MOV [RBP], EAX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_EAX;
} } },
vm::handler::extention_t::sign_extend };
} // namespace vm::handler::profile

@ -1,36 +1,27 @@
#include <vmprofiler.hpp>
namespace vm
namespace vm::handler::profile
{
namespace handler
{
namespace profile
{
vm::handler::profile_t lrflags = {
// PUSH [RBP]
// ADD RBP, 0x8
// POPFQ
"LRFLAGS",
LRFLAGS,
NULL,
{ { // PUSH [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_PUSH &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP;
},
// ADD RBP, 0x8
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_ADD &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
instr.operands[ 1 ].imm.value.u == 0x8;
},
// POPFQ
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_POPFQ;
} } } };
}
} // namespace handler
} // namespace vm
vm::handler::profile_t lrflags = {
// PUSH [RBP]
// ADD RBP, 0x8
// POPFQ
"LRFLAGS",
LRFLAGS,
NULL,
{ { // PUSH [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_PUSH && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP;
},
// ADD RBP, 0x8
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_ADD &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
instr.operands[ 1 ].imm.value.u == 0x8;
},
// POPFQ
[]( const zydis_decoded_instr_t &instr ) -> bool { return instr.mnemonic == ZYDIS_MNEMONIC_POPFQ; } } } };
} // namespace vm::handler::profile

@ -1,81 +1,73 @@
#include <vmprofiler.hpp>
namespace vm
namespace vm::handler::profile
{
namespace handler
{
namespace profile
{
vm::handler::profile_t lregq = {
// MOV RDX, [RAX+RDI]
// SUB RBP, 8
// MOV [RBP], RDX
"LREGQ",
LREGQ,
8,
{ { // MOV RDX, [RAX+RDI] or MOV RDX, [RDI+RAX]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RDX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
( instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RAX ||
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RDI ) &&
( instr.operands[ 1 ].mem.index == ZYDIS_REGISTER_RDI ||
instr.operands[ 1 ].mem.index == ZYDIS_REGISTER_RAX );
},
// SUB RBP, 8
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
instr.operands[ 1 ].imm.value.u == 0x8;
},
// MOV [RBP], RDX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RDX;
} } } };
vm::handler::profile_t lregq = {
// MOV RDX, [RAX+RDI]
// SUB RBP, 8
// MOV [RBP], RDX
"LREGQ",
LREGQ,
8,
{ { // MOV RDX, [RAX+RDI] or MOV RDX, [RDI+RAX]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RDX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
( instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RAX ||
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RDI ) &&
( instr.operands[ 1 ].mem.index == ZYDIS_REGISTER_RDI ||
instr.operands[ 1 ].mem.index == ZYDIS_REGISTER_RAX );
},
// SUB RBP, 8
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
instr.operands[ 1 ].imm.value.u == 0x8;
},
// MOV [RBP], RDX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RDX;
} } } };
vm::handler::profile_t lregdw = {
// MOVZX AL, [RSI]
// MOV RDX, [RAX + RDI]
// SUB RBP, 0x4
// MOV [RBP], EDX
"LREGDW",
LREGDW,
8,
{ { // MOV RDX, [RAX + RDI] or MOV RDX, [RDI + RAX]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_EDX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
( instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RAX ||
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RDI ) &&
( instr.operands[ 1 ].mem.index == ZYDIS_REGISTER_RAX ||
instr.operands[ 1 ].mem.index == ZYDIS_REGISTER_RDI );
},
// SUB RBP, 0x4
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
instr.operands[ 1 ].imm.value.u == 0x4;
},
// MOV [RBP], EDX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_EDX;
} } } };
} // namespace profile
} // namespace handler
} // namespace vm
vm::handler::profile_t lregdw = {
// MOVZX AL, [RSI]
// MOV RDX, [RAX + RDI]
// SUB RBP, 0x4
// MOV [RBP], EDX
"LREGDW",
LREGDW,
8,
{ { // MOV RDX, [RAX + RDI] or MOV RDX, [RDI + RAX]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_EDX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
( instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RAX ||
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RDI ) &&
( instr.operands[ 1 ].mem.index == ZYDIS_REGISTER_RAX ||
instr.operands[ 1 ].mem.index == ZYDIS_REGISTER_RDI );
},
// SUB RBP, 0x4
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
instr.operands[ 1 ].imm.value.u == 0x4;
},
// MOV [RBP], EDX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_EDX;
} } } };
} // namespace vm::handler::profile

@ -1,73 +1,61 @@
#include <vmprofiler.hpp>
namespace vm
namespace vm::handler::profile
{
namespace handler
{
namespace profile
{
vm::handler::profile_t mulq = {
// MOV RAX, [RBP+0x8]
// SUB RBP, 0x8
// MUL RDX
// MOV [RBP+0x8], RDX
// MOV [RBP+0x10], RAX
// PUSHFQ
// POP [RBP]
"MULQ",
MULQ,
NULL,
{ { // MOV RAX, [RBP+0x8]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].mem.disp.value == 0x8;
},
// SUB RBP, 0x8
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
instr.operands[ 1 ].imm.value.u == 0x8;
},
// MUL RDX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MUL &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RDX;
},
// MOV [RBP+0x8], RDX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 0 ].mem.disp.value == 0x8 &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RDX;
},
// MOV [RBP+0x10], RAX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 0 ].mem.disp.value == 0x10 &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RAX;
},
// PUSHFQ
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_PUSHFQ;
},
// POP [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_POP &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP;
} } } };
}
} // namespace handler
} // namespace vm
vm::handler::profile_t mulq = {
// MOV RAX, [RBP+0x8]
// SUB RBP, 0x8
// MUL RDX
// MOV [RBP+0x8], RDX
// MOV [RBP+0x10], RAX
// PUSHFQ
// POP [RBP]
"MULQ",
MULQ,
NULL,
{ { // MOV RAX, [RBP+0x8]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP && instr.operands[ 1 ].mem.disp.value == 0x8;
},
// SUB RBP, 0x8
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
instr.operands[ 1 ].imm.value.u == 0x8;
},
// MUL RDX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MUL &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RDX;
},
// MOV [RBP+0x8], RDX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 0 ].mem.disp.value == 0x8 &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RDX;
},
// MOV [RBP+0x10], RAX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 0 ].mem.disp.value == 0x10 &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RAX;
},
// PUSHFQ
[]( const zydis_decoded_instr_t &instr ) -> bool { return instr.mnemonic == ZYDIS_MNEMONIC_PUSHFQ; },
// POP [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_POP && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP;
} } } };
} // namespace vm::handler::profile

@ -1,183 +1,161 @@
#include <vmprofiler.hpp>
namespace vm
namespace vm::handler::profile
{
namespace handler
{
namespace profile
{
vm::handler::profile_t nandq = {
// MOV RAX, [RBP]
// MOV RDX, [RBP+8]
// NOT RAX
// NOT RDX
// AND RAX, RDX
// MOV [RBP], RAX
// PUSHFQ
// POP [RBP]
"NANDQ",
NANDQ,
NULL,
{ { // MOV RAX, [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
},
// MOV RDX, [RBP+8]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RDX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].mem.disp.value == 0x8;
},
// NOT RAX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_NOT &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX;
},
// NOT RDX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_NOT &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RDX;
},
// AND RAX, RDX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_AND &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RDX;
},
// MOV [RBP], RAX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RAX;
},
// PUSHFQ
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_PUSHFQ;
},
// POP [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_POP &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP;
} } } };
vm::handler::profile_t nandq = {
// MOV RAX, [RBP]
// MOV RDX, [RBP+8]
// NOT RAX
// NOT RDX
// AND RAX, RDX
// MOV [RBP], RAX
// PUSHFQ
// POP [RBP]
"NANDQ",
NANDQ,
NULL,
{ { // MOV RAX, [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
},
// MOV RDX, [RBP+8]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RDX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP && instr.operands[ 1 ].mem.disp.value == 0x8;
},
// NOT RAX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_NOT &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX;
},
// NOT RDX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_NOT &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RDX;
},
// AND RAX, RDX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_AND &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RDX;
},
// MOV [RBP], RAX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RAX;
},
// PUSHFQ
[]( const zydis_decoded_instr_t &instr ) -> bool { return instr.mnemonic == ZYDIS_MNEMONIC_PUSHFQ; },
// POP [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_POP && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP;
} } } };
vm::handler::profile_t nanddw = {
// NOT QWORD PTR [RBP]
// MOV EAX, [RBP]
// SUB RBP, 0x4
// AND [RBP+0x8], EAX
// PUSHFQ
// POP [RBP]
"NANDDW",
NANDDW,
NULL,
{ { // NOT QWORD PTR [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_NOT &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].size == 64 && instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP;
},
// MOV EAX, [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_EAX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
},
// SUB RBP, 0x4
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
instr.operands[ 1 ].imm.value.u == 0x4;
},
// AND [RBP+0x8], EAX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_AND &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 0 ].mem.disp.value == 0x8 &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_EAX;
},
// PUSHFQ
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_PUSHFQ;
},
// POP [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_POP &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP;
} } } };
vm::handler::profile_t nanddw = {
// NOT QWORD PTR [RBP]
// MOV EAX, [RBP]
// SUB RBP, 0x4
// AND [RBP+0x8], EAX
// PUSHFQ
// POP [RBP]
"NANDDW",
NANDDW,
NULL,
{ { // NOT QWORD PTR [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_NOT && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].size == 64 && instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP;
},
// MOV EAX, [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_EAX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
},
// SUB RBP, 0x4
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
instr.operands[ 1 ].imm.value.u == 0x4;
},
// AND [RBP+0x8], EAX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_AND && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 0 ].mem.disp.value == 0x8 &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_EAX;
},
// PUSHFQ
[]( const zydis_decoded_instr_t &instr ) -> bool { return instr.mnemonic == ZYDIS_MNEMONIC_PUSHFQ; },
// POP [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_POP && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP;
} } } };
vm::handler::profile_t nandw = {
// NOT DWORD PTR [RBP]
// MOV AX, [RBP]
// SUB RBP, 0x6
// AND [RBP+0x8], AX
// PUSHFQ
// POP [RBP]
"NANDW",
NANDW,
NULL,
{ { // NOT DWORD PTR [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_NOT &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].size == 32 &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP;
},
// MOV AX, [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_AX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
},
// SUB RBP, 0x6
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
instr.operands[ 1 ].imm.value.u == 0x6;
},
// AND [RBP+0x8], AX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_AND &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 0 ].mem.disp.value == 0x8 &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_AX;
},
// PUSHFQ
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_PUSHFQ;
},
// POP [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_POP &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP;
} } } };
} // namespace profile
} // namespace handler
} // namespace vm
vm::handler::profile_t nandw = {
// NOT DWORD PTR [RBP]
// MOV AX, [RBP]
// SUB RBP, 0x6
// AND [RBP+0x8], AX
// PUSHFQ
// POP [RBP]
"NANDW",
NANDW,
NULL,
{ { // NOT DWORD PTR [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_NOT && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].size == 32 && instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP;
},
// MOV AX, [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_AX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
},
// SUB RBP, 0x6
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
instr.operands[ 1 ].imm.value.u == 0x6;
},
// AND [RBP+0x8], AX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_AND && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 0 ].mem.disp.value == 0x8 &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_AX;
},
// PUSHFQ
[]( const zydis_decoded_instr_t &instr ) -> bool { return instr.mnemonic == ZYDIS_MNEMONIC_PUSHFQ; },
// POP [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_POP && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP;
} } } };
} // namespace vm::handler::profile

@ -1,41 +1,34 @@
#include <vmprofiler.hpp>
namespace vm
namespace vm::handler::profile
{
namespace handler
{
namespace profile
{
vm::handler::profile_t pushvsp = {
// MOV RAX, RBP
// SUB RBP, 8
"PUSHVSP",
PUSHVSP,
NULL,
{ { // MOV RAX, RBP
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RBP;
},
// SUB RBP, 8
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
instr.operands[ 1 ].imm.value.u == 0x8;
},
// MOV [RBP], RAX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RAX;
} } } };
}
} // namespace handler
} // namespace vm
vm::handler::profile_t pushvsp = {
// MOV RAX, RBP
// SUB RBP, 8
"PUSHVSP",
PUSHVSP,
NULL,
{ { // MOV RAX, RBP
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RBP;
},
// SUB RBP, 8
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
instr.operands[ 1 ].imm.value.u == 0x8;
},
// MOV [RBP], RAX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RAX;
} } } };
} // namespace vm::handler::profile

@ -1,66 +1,57 @@
#include <vmprofiler.hpp>
namespace vm
namespace vm::handler::profile
{
namespace handler
{
namespace profile
{
vm::handler::profile_t readq = {
// MOV RAX, [RAX]
// MOV [RBP], RAX
"READQ",
READQ,
NULL,
{ {
// MOV RAX, [RAX]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RAX;
},
// MOV [RBP], RAX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RAX;
} } } };
vm::handler::profile_t readq = {
// MOV RAX, [RAX]
// MOV [RBP], RAX
"READQ",
READQ,
NULL,
{ { // MOV RAX, [RAX]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RAX;
},
// MOV [RBP], RAX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RAX;
} } } };
vm::handler::profile_t readdw = {
// ADD RBP, 0x4
// MOV EAX, [RAX]
// MOV [RBP], EAX
"READDW",
READDW,
NULL,
{ { // ADD RBP, 0x4
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_ADD &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
instr.operands[ 1 ].imm.value.u == 0x4;
},
// MOV EAX, [RAX]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_EAX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RAX;
},
// MOV [RBP], EAX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_EAX;
} } } };
}
} // namespace handler
} // namespace vm
vm::handler::profile_t readdw = {
// ADD RBP, 0x4
// MOV EAX, [RAX]
// MOV [RBP], EAX
"READDW",
READDW,
NULL,
{ { // ADD RBP, 0x4
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_ADD &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
instr.operands[ 1 ].imm.value.u == 0x4;
},
// MOV EAX, [RAX]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_EAX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RAX;
},
// MOV [RBP], EAX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_EAX;
} } } };
} // namespace vm::handler::profile

@ -1,138 +1,122 @@
#include <vmprofiler.hpp>
namespace vm
namespace vm::handler::profile
{
namespace handler
{
namespace profile
{
vm::handler::profile_t shlq = {
// MOV RAX, [RBP]
// MOV CL, [RBP+0x8]
// SUB RBP, 0x6
// SHL RAX, CL
// MOV [RBP+0x8], RAX
// PUSHFQ
// POP [RBP]
"SHLQ",
SHLQ,
NULL,
{ { // MOV RAX, [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
},
// MOV CL, [RBP+0x8]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_CL &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].mem.disp.value == 0x8;
},
// SUB RBP, 0x6
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
instr.operands[ 1 ].imm.value.u == 0x6;
},
// SHL RAX, CL
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_SHL &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_CL;
},
// MOV [RBP+0x8], RAX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 0 ].mem.disp.value == 0x8 &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RAX;
},
// PUSHFQ
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_PUSHFQ;
},
// POP [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_POP &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP;
} } } };
vm::handler::profile_t shlq = {
// MOV RAX, [RBP]
// MOV CL, [RBP+0x8]
// SUB RBP, 0x6
// SHL RAX, CL
// MOV [RBP+0x8], RAX
// PUSHFQ
// POP [RBP]
"SHLQ",
SHLQ,
NULL,
{ { // MOV RAX, [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
},
// MOV CL, [RBP+0x8]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_CL &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP && instr.operands[ 1 ].mem.disp.value == 0x8;
},
// SUB RBP, 0x6
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
instr.operands[ 1 ].imm.value.u == 0x6;
},
// SHL RAX, CL
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_SHL &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_CL;
},
// MOV [RBP+0x8], RAX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 0 ].mem.disp.value == 0x8 &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RAX;
},
// PUSHFQ
[]( const zydis_decoded_instr_t &instr ) -> bool { return instr.mnemonic == ZYDIS_MNEMONIC_PUSHFQ; },
// POP [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_POP && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP;
} } } };
vm::handler::profile_t shldw = {
// MOV EAX, [RBP]
// MOV CL, [RBP+0x4]
// SUB RBP, 0x6
// SHL EAX, CL
// MOV [RBP+0x8], EAX
// PUSHFQ
// POP [RBP]
"SHLQ",
SHLQ,
NULL,
{ { // MOV EAX, [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_EAX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
},
// MOV CL, [RBP+0x4]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_CL &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].mem.disp.value == 0x4;
},
// SUB RBP, 0x6
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
instr.operands[ 1 ].imm.value.u == 0x6;
},
// SHL EAX, CL
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_SHL &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_EAX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_CL;
},
// MOV [RBP+0x8], EAX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 0 ].mem.disp.value == 0x8 &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_EAX;
},
// PUSHFQ
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_PUSHFQ;
},
// POP [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_POP &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP;
} } } };
} // namespace profile
} // namespace handler
} // namespace vm
vm::handler::profile_t shldw = {
// MOV EAX, [RBP]
// MOV CL, [RBP+0x4]
// SUB RBP, 0x6
// SHL EAX, CL
// MOV [RBP+0x8], EAX
// PUSHFQ
// POP [RBP]
"SHLQ",
SHLQ,
NULL,
{ { // MOV EAX, [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_EAX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
},
// MOV CL, [RBP+0x4]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_CL &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP && instr.operands[ 1 ].mem.disp.value == 0x4;
},
// SUB RBP, 0x6
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
instr.operands[ 1 ].imm.value.u == 0x6;
},
// SHL EAX, CL
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_SHL &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_EAX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_CL;
},
// MOV [RBP+0x8], EAX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 0 ].mem.disp.value == 0x8 &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_EAX;
},
// PUSHFQ
[]( const zydis_decoded_instr_t &instr ) -> bool { return instr.mnemonic == ZYDIS_MNEMONIC_PUSHFQ; },
// POP [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_POP && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP;
} } } };
} // namespace vm::handler::profile

@ -1,138 +1,122 @@
#include <vmprofiler.hpp>
namespace vm
namespace vm::handler::profile
{
namespace handler
{
namespace profile
{
vm::handler::profile_t shrq = {
// MOV RAX, [RBP]
// MOV CL, [RBP+0x8]
// SUB RBP, 0x6
// SHR RAX, CL
// MOV [RBP+0x8], RAX
// PUSHFQ
// POP [RBP]
"SHRQ",
SHRQ,
NULL,
{ { // MOV RAX, [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
},
// MOV CL, [RBP+0x8]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_CL &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].mem.disp.value == 0x8;
},
// SUB RBP, 0x6
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
instr.operands[ 1 ].imm.value.u == 0x6;
},
// SHR RAX, CL
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_SHR &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_CL;
},
// MOV [RBP+0x8], RAX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 0 ].mem.disp.value == 0x8 &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RAX;
},
// PUSHFQ
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_PUSHFQ;
},
// POP [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_POP &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP;
} } } };
vm::handler::profile_t shrw = {
// MOV AX, [RBP]
// MOV CL, [RBP+0x2]
// SUB RBP, 0x6
// SHR AX, CL
// MOV [RBP+0x8], AX
// PUSHFQ
// POP [RBP]
"SHRW",
SHRW,
NULL,
{ { // MOV AX, [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_AX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
},
// MOV CL, [RBP+0x2]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_CL &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].mem.disp.value == 0x2;
},
// SUB RBP, 0x6
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
instr.operands[ 1 ].imm.value.u == 0x6;
},
// SHR AX, CL
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_SHR &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_AX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_CL;
},
// MOV [RBP+0x8], AX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 0 ].mem.disp.value == 0x8 &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_AX;
},
// PUSHFQ
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_PUSHFQ;
},
// POP [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_POP &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP;
} } } };
}
} // namespace handler
} // namespace vm
vm::handler::profile_t shrq = {
// MOV RAX, [RBP]
// MOV CL, [RBP+0x8]
// SUB RBP, 0x6
// SHR RAX, CL
// MOV [RBP+0x8], RAX
// PUSHFQ
// POP [RBP]
"SHRQ",
SHRQ,
NULL,
{ { // MOV RAX, [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
},
// MOV CL, [RBP+0x8]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_CL &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP && instr.operands[ 1 ].mem.disp.value == 0x8;
},
// SUB RBP, 0x6
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
instr.operands[ 1 ].imm.value.u == 0x6;
},
// SHR RAX, CL
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_SHR &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_CL;
},
// MOV [RBP+0x8], RAX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 0 ].mem.disp.value == 0x8 &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RAX;
},
// PUSHFQ
[]( const zydis_decoded_instr_t &instr ) -> bool { return instr.mnemonic == ZYDIS_MNEMONIC_PUSHFQ; },
// POP [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_POP && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP;
} } } };
vm::handler::profile_t shrw = {
// MOV AX, [RBP]
// MOV CL, [RBP+0x2]
// SUB RBP, 0x6
// SHR AX, CL
// MOV [RBP+0x8], AX
// PUSHFQ
// POP [RBP]
"SHRW",
SHRW,
NULL,
{ { // MOV AX, [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_AX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
},
// MOV CL, [RBP+0x2]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_CL &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP && instr.operands[ 1 ].mem.disp.value == 0x2;
},
// SUB RBP, 0x6
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
instr.operands[ 1 ].imm.value.u == 0x6;
},
// SHR AX, CL
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_SHR &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_AX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_CL;
},
// MOV [RBP+0x8], AX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 0 ].mem.disp.value == 0x8 &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_AX;
},
// PUSHFQ
[]( const zydis_decoded_instr_t &instr ) -> bool { return instr.mnemonic == ZYDIS_MNEMONIC_PUSHFQ; },
// POP [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_POP && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP;
} } } };
} // namespace vm::handler::profile

@ -1,115 +1,105 @@
#include <vmprofiler.hpp>
namespace vm
namespace vm::handler::profile
{
namespace handler
{
namespace profile
{
vm::handler::profile_t sregq = {
// MOV RDX, [RBP]
// ADD RBP, 8
// MOV [RAX+RDI], RDX
"SREGQ",
SREGQ,
8,
{ { // MOV RDX, [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RDX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
},
// ADD RBP, 8
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_ADD &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
instr.operands[ 1 ].imm.value.u == 8;
},
// MOV [RAX+RDI], RDX or MOV [RDI+RAX], RDX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
( instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RAX ||
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RDI ) &&
( instr.operands[ 0 ].mem.index == ZYDIS_REGISTER_RDI ||
instr.operands[ 0 ].mem.index == ZYDIS_REGISTER_RAX ) &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RDX;
} } } };
vm::handler::profile_t sregq = {
// MOV RDX, [RBP]
// ADD RBP, 8
// MOV [RAX+RDI], RDX
"SREGQ",
SREGQ,
8,
{ { // MOV RDX, [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RDX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
},
// ADD RBP, 8
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_ADD &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE && instr.operands[ 1 ].imm.value.u == 8;
},
// MOV [RAX+RDI], RDX or MOV [RDI+RAX], RDX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
( instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RAX ||
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RDI ) &&
( instr.operands[ 0 ].mem.index == ZYDIS_REGISTER_RDI ||
instr.operands[ 0 ].mem.index == ZYDIS_REGISTER_RAX ) &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RDX;
} } } };
vm::handler::profile_t sregdw = {
// MOV EDX, [RBP]
// ADD RBP, 0x4
// MOV [RAX+RDI], EDX
"SREGDW",
SREGDW,
8,
{ { // MOV EDX, [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_EDX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
},
// ADD RBP, 0x4
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_ADD &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
instr.operands[ 1 ].imm.value.u == 0x4;
},
// MOV [RAX+RDI], EDX or MOV [RDI+RAX], EDX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
( instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RAX ||
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RDI ) &&
( instr.operands[ 0 ].mem.index == ZYDIS_REGISTER_RAX ||
instr.operands[ 0 ].mem.index == ZYDIS_REGISTER_RDI ) &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_EDX;
} } } };
vm::handler::profile_t sregdw = {
// MOV EDX, [RBP]
// ADD RBP, 0x4
// MOV [RAX+RDI], EDX
"SREGDW",
SREGDW,
8,
{ { // MOV EDX, [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_EDX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
},
// ADD RBP, 0x4
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_ADD &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
instr.operands[ 1 ].imm.value.u == 0x4;
},
// MOV [RAX+RDI], EDX or MOV [RDI+RAX], EDX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
( instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RAX ||
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RDI ) &&
( instr.operands[ 0 ].mem.index == ZYDIS_REGISTER_RAX ||
instr.operands[ 0 ].mem.index == ZYDIS_REGISTER_RDI ) &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_EDX;
} } } };
vm::handler::profile_t sregw = {
// MOV DX, [RBP]
// ADD RBP, 0x2
// MOV [RAX+RDI], DX
"SREGW",
SREGW,
8,
{ { // MOV DX, [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_DX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
},
// ADD RBP, 0x2
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_ADD &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
instr.operands[ 1 ].imm.value.u == 0x2;
},
// MOV [RAX+RDI], DX or MOV [RDI+RAX], DX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
( instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RAX ||
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RDI ) &&
( instr.operands[ 0 ].mem.index == ZYDIS_REGISTER_RDI ||
instr.operands[ 0 ].mem.index == ZYDIS_REGISTER_RAX ) &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_DX;
} } } };
} // namespace profile
} // namespace handler
} // namespace vm
vm::handler::profile_t sregw = {
// MOV DX, [RBP]
// ADD RBP, 0x2
// MOV [RAX+RDI], DX
"SREGW",
SREGW,
8,
{ { // MOV DX, [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_DX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
},
// ADD RBP, 0x2
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_ADD &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
instr.operands[ 1 ].imm.value.u == 0x2;
},
// MOV [RAX+RDI], DX or MOV [RDI+RAX], DX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
( instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RAX ||
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RDI ) &&
( instr.operands[ 0 ].mem.index == ZYDIS_REGISTER_RDI ||
instr.operands[ 0 ].mem.index == ZYDIS_REGISTER_RAX ) &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_DX;
} } } };
} // namespace vm::handler::profile

@ -1,29 +1,21 @@
#include <vmprofiler.hpp>
namespace vm
namespace vm::handler::profile
{
namespace handler
{
namespace profile
{
vm::handler::profile_t vmexit = {
// MOV RSP, RBP
// RET
"VMEXIT",
VMEXIT,
NULL,
{ { // MOV RSP, RBP
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RSP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RBP;
},
// RET
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_RET;
} } } };
}
} // namespace handler
} // namespace vm
vm::handler::profile_t vmexit = {
// MOV RSP, RBP
// RET
"VMEXIT",
VMEXIT,
NULL,
{ { // MOV RSP, RBP
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RSP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RBP;
},
// RET
[]( const zydis_decoded_instr_t &instr ) -> bool { return instr.mnemonic == ZYDIS_MNEMONIC_RET; } } } };
} // namespace vm::handler::profile

@ -1,136 +1,124 @@
#include <vmprofiler.hpp>
namespace vm
namespace vm::handler::profile
{
namespace handler
{
namespace profile
{
vm::handler::profile_t writeq = {
// MOV RAX, [RBP]
// MOV RDX, [RBP+0x8]
// ADD RBP, 0x10
// MOV [RAX], RDX
"WRITEQ",
WRITEQ,
NULL,
{ { // MOV RAX, [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
},
// MOV RDX, [RBP+0x8]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RDX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].mem.disp.value == 0x8;
},
// ADD RBP, 0x10
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_ADD &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
instr.operands[ 1 ].imm.value.u == 0x10;
},
// MOV [RAX], RDX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RAX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RDX;
} } } };
vm::handler::profile_t writeq = {
// MOV RAX, [RBP]
// MOV RDX, [RBP+0x8]
// ADD RBP, 0x10
// MOV [RAX], RDX
"WRITEQ",
WRITEQ,
NULL,
{ { // MOV RAX, [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
},
// MOV RDX, [RBP+0x8]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RDX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP && instr.operands[ 1 ].mem.disp.value == 0x8;
},
// ADD RBP, 0x10
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_ADD &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
instr.operands[ 1 ].imm.value.u == 0x10;
},
// MOV [RAX], RDX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RAX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RDX;
} } } };
vm::handler::profile_t writedw = {
// MOV RAX, [RBP]
// MOV EDX, [RBP+0x8]
// ADD RBP, 0xC
// MOV [RAX], EDX
"WRITEDW",
WRITEDW,
NULL,
{ { // MOV RAX, [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
},
// MOV EDX, [RBP+0x8]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_EDX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].mem.disp.value == 0x8;
},
// ADD RBP, 0xC
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_ADD &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
instr.operands[ 1 ].imm.value.u == 0xC;
},
// MOV [RAX], EDX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RAX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_EDX;
} } } };
vm::handler::profile_t writedw = {
// MOV RAX, [RBP]
// MOV EDX, [RBP+0x8]
// ADD RBP, 0xC
// MOV [RAX], EDX
"WRITEDW",
WRITEDW,
NULL,
{ { // MOV RAX, [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
},
// MOV EDX, [RBP+0x8]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_EDX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP && instr.operands[ 1 ].mem.disp.value == 0x8;
},
// ADD RBP, 0xC
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_ADD &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
instr.operands[ 1 ].imm.value.u == 0xC;
},
// MOV [RAX], EDX
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RAX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_EDX;
} } } };
vm::handler::profile_t writeb = {
// MOV RAX, [RBP]
// MOV DL, [RBP+0x8]
// ADD RBP, 0xA
// MOV [RAX], DL
"WRITEB",
WRITEB,
NULL,
{ { // MOV RAX, [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
},
// MOV DL, [RBP+0x8]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_DL &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].mem.disp.value == 0x8;
},
// ADD RBP, 0xA
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_ADD &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
instr.operands[ 1 ].imm.value.u == 0xA;
},
// MOV [RAX], DL
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RAX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_DL;
} } } };
} // namespace profile
} // namespace handler
} // namespace vm
vm::handler::profile_t writeb = {
// MOV RAX, [RBP]
// MOV DL, [RBP+0x8]
// ADD RBP, 0xA
// MOV [RAX], DL
"WRITEB",
WRITEB,
NULL,
{ { // MOV RAX, [RBP]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
},
// MOV DL, [RBP+0x8]
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_DL &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP && instr.operands[ 1 ].mem.disp.value == 0x8;
},
// ADD RBP, 0xA
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_ADD &&
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
instr.operands[ 1 ].imm.value.u == 0xA;
},
// MOV [RAX], DL
[]( const zydis_decoded_instr_t &instr ) -> bool {
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RAX &&
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_DL;
} } } };
} // namespace vm::handler::profile

@ -1,47 +1,24 @@
#include <vmprofiler.hpp>
namespace vm
namespace vm::util
{
namespace util
namespace reg
{
namespace reg
zydis_register_t to64( zydis_register_t reg )
{
zydis_register_t to64( zydis_register_t reg )
{
return ZydisRegisterGetLargestEnclosing( ZYDIS_MACHINE_MODE_LONG_64, reg );
}
bool compare( zydis_register_t a, zydis_register_t b )
{
return to64( a ) == to64( b );
}
} // namespace reg
return ZydisRegisterGetLargestEnclosing( ZYDIS_MACHINE_MODE_LONG_64, reg );
}
bool get_fetch_operand( const zydis_routine_t &routine, zydis_instr_t &fetch_instr )
bool compare( zydis_register_t a, zydis_register_t b )
{
const auto result =
std::find_if( routine.begin(), routine.end(), []( const zydis_instr_t &instr_data ) -> bool {
// mov/movsx/movzx rax/eax/ax/al, [rsi]
return instr_data.instr.operand_count > 1 &&
( instr_data.instr.mnemonic == ZYDIS_MNEMONIC_MOV ||
instr_data.instr.mnemonic == ZYDIS_MNEMONIC_MOVSX ||
instr_data.instr.mnemonic == ZYDIS_MNEMONIC_MOVZX ) &&
instr_data.instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
util::reg::to64( instr_data.instr.operands[ 0 ].reg.value ) == ZYDIS_REGISTER_RAX &&
instr_data.instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr_data.instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RSI;
} );
if ( result == routine.end() )
return false;
fetch_instr = *result;
return true;
return to64( a ) == to64( b );
}
} // namespace reg
std::optional< zydis_routine_t::iterator > get_fetch_operand( zydis_routine_t &routine )
{
auto result = std::find_if( routine.begin(), routine.end(), []( const zydis_instr_t &instr_data ) -> bool {
bool get_fetch_operand( const zydis_routine_t &routine, zydis_instr_t &fetch_instr )
{
const auto result =
std::find_if( routine.begin(), routine.end(), []( const zydis_instr_t &instr_data ) -> bool {
// mov/movsx/movzx rax/eax/ax/al, [rsi]
return instr_data.instr.operand_count > 1 &&
( instr_data.instr.mnemonic == ZYDIS_MNEMONIC_MOV ||
@ -53,209 +30,229 @@ namespace vm
instr_data.instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RSI;
} );
if ( result == routine.end() )
return {};
if ( result == routine.end() )
return false;
return result;
}
fetch_instr = *result;
return true;
}
void print( const zydis_decoded_instr_t &instr )
std::optional< zydis_routine_t::iterator > get_fetch_operand( zydis_routine_t &routine )
{
auto result = std::find_if( routine.begin(), routine.end(), []( const zydis_instr_t &instr_data ) -> bool {
// mov/movsx/movzx rax/eax/ax/al, [rsi]
return instr_data.instr.operand_count > 1 &&
( instr_data.instr.mnemonic == ZYDIS_MNEMONIC_MOV ||
instr_data.instr.mnemonic == ZYDIS_MNEMONIC_MOVSX ||
instr_data.instr.mnemonic == ZYDIS_MNEMONIC_MOVZX ) &&
instr_data.instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
util::reg::to64( instr_data.instr.operands[ 0 ].reg.value ) == ZYDIS_REGISTER_RAX &&
instr_data.instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
instr_data.instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RSI;
} );
if ( result == routine.end() )
return {};
return result;
}
void print( const zydis_decoded_instr_t &instr )
{
char buffer[ 256 ];
ZydisFormatter formatter;
ZydisFormatterInit( &formatter, ZYDIS_FORMATTER_STYLE_INTEL );
ZydisFormatterFormatInstruction( &formatter, &instr, buffer, sizeof( buffer ), 0u );
std::puts( buffer );
}
void print( zydis_routine_t &routine )
{
char buffer[ 256 ];
ZydisFormatter formatter;
ZydisFormatterInit( &formatter, ZYDIS_FORMATTER_STYLE_INTEL );
for ( auto [ instr, raw, addr ] : routine )
{
char buffer[ 256 ];
ZydisFormatter formatter;
ZydisFormatterInit( &formatter, ZYDIS_FORMATTER_STYLE_INTEL );
ZydisFormatterFormatInstruction( &formatter, &instr, buffer, sizeof( buffer ), 0u );
std::puts( buffer );
ZydisFormatterFormatInstruction( &formatter, &instr, buffer, sizeof( buffer ), addr );
std::printf( "> 0x%p %s", addr, buffer );
}
}
void print( zydis_routine_t &routine )
bool is_jmp( const zydis_decoded_instr_t &instr )
{
switch ( instr.mnemonic )
{
char buffer[ 256 ];
ZydisFormatter formatter;
ZydisFormatterInit( &formatter, ZYDIS_FORMATTER_STYLE_INTEL );
for ( auto [ instr, raw, addr ] : routine )
{
ZydisFormatterFormatInstruction( &formatter, &instr, buffer, sizeof( buffer ), addr );
std::printf( "> 0x%p %s", addr, buffer );
}
case ZYDIS_MNEMONIC_JB:
case ZYDIS_MNEMONIC_JBE:
case ZYDIS_MNEMONIC_JCXZ:
case ZYDIS_MNEMONIC_JECXZ:
case ZYDIS_MNEMONIC_JKNZD:
case ZYDIS_MNEMONIC_JKZD:
case ZYDIS_MNEMONIC_JL:
case ZYDIS_MNEMONIC_JLE:
case ZYDIS_MNEMONIC_JMP:
case ZYDIS_MNEMONIC_JNB:
case ZYDIS_MNEMONIC_JNBE:
case ZYDIS_MNEMONIC_JNL:
case ZYDIS_MNEMONIC_JNLE:
case ZYDIS_MNEMONIC_JNO:
case ZYDIS_MNEMONIC_JNP:
case ZYDIS_MNEMONIC_JNS:
case ZYDIS_MNEMONIC_JNZ:
case ZYDIS_MNEMONIC_JO:
case ZYDIS_MNEMONIC_JP:
case ZYDIS_MNEMONIC_JRCXZ:
case ZYDIS_MNEMONIC_JS:
case ZYDIS_MNEMONIC_JZ:
return true;
default:
break;
}
return false;
}
bool is_jmp( const zydis_decoded_instr_t &instr )
bool flatten( zydis_routine_t &routine, std::uintptr_t routine_addr, bool keep_jmps )
{
ZydisDecoder decoder;
zydis_decoded_instr_t instr;
ZydisDecoderInit( &decoder, ZYDIS_MACHINE_MODE_LONG_64, ZYDIS_ADDRESS_WIDTH_64 );
while ( ZYAN_SUCCESS(
ZydisDecoderDecodeBuffer( &decoder, reinterpret_cast< void * >( routine_addr ), 0x1000, &instr ) ) )
{
switch ( instr.mnemonic )
{
case ZYDIS_MNEMONIC_JB:
case ZYDIS_MNEMONIC_JBE:
case ZYDIS_MNEMONIC_JCXZ:
case ZYDIS_MNEMONIC_JECXZ:
case ZYDIS_MNEMONIC_JKNZD:
case ZYDIS_MNEMONIC_JKZD:
case ZYDIS_MNEMONIC_JL:
case ZYDIS_MNEMONIC_JLE:
case ZYDIS_MNEMONIC_JMP:
case ZYDIS_MNEMONIC_JNB:
case ZYDIS_MNEMONIC_JNBE:
case ZYDIS_MNEMONIC_JNL:
case ZYDIS_MNEMONIC_JNLE:
case ZYDIS_MNEMONIC_JNO:
case ZYDIS_MNEMONIC_JNP:
case ZYDIS_MNEMONIC_JNS:
case ZYDIS_MNEMONIC_JNZ:
case ZYDIS_MNEMONIC_JO:
case ZYDIS_MNEMONIC_JP:
case ZYDIS_MNEMONIC_JRCXZ:
case ZYDIS_MNEMONIC_JS:
case ZYDIS_MNEMONIC_JZ:
// detect if we have already been at this instruction... if so that means there is a loop and we are
// going to just return...
if ( std::find_if( routine.begin(), routine.end(), [ & ]( const zydis_instr_t &zydis_instr ) -> bool {
return zydis_instr.addr == routine_addr;
} ) != routine.end() )
return true;
default:
break;
}
return false;
}
bool flatten( zydis_routine_t &routine, std::uintptr_t routine_addr, bool keep_jmps )
{
ZydisDecoder decoder;
zydis_decoded_instr_t instr;
ZydisDecoderInit( &decoder, ZYDIS_MACHINE_MODE_LONG_64, ZYDIS_ADDRESS_WIDTH_64 );
std::vector< u8 > raw_instr;
raw_instr.insert( raw_instr.begin(), ( u8 * )routine_addr, ( u8 * )routine_addr + instr.length );
while ( ZYAN_SUCCESS(
ZydisDecoderDecodeBuffer( &decoder, reinterpret_cast< void * >( routine_addr ), 0x1000, &instr ) ) )
if ( is_jmp( instr ) )
{
// detect if we have already been at this instruction... if so that means there is a loop and we are
// going to just return...
if ( std::find_if( routine.begin(), routine.end(), [ & ]( const zydis_instr_t &zydis_instr ) -> bool {
return zydis_instr.addr == routine_addr;
} ) != routine.end() )
return true;
std::vector< u8 > raw_instr;
raw_instr.insert( raw_instr.begin(), ( u8 * )routine_addr, ( u8 * )routine_addr + instr.length );
if ( is_jmp( instr ) )
{
if ( instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER )
{
routine.push_back( { instr, raw_instr, routine_addr } );
return true;
}
if ( keep_jmps )
routine.push_back( { instr, raw_instr, routine_addr } );
ZydisCalcAbsoluteAddress( &instr, &instr.operands[ 0 ], routine_addr, &routine_addr );
}
else if ( instr.mnemonic == ZYDIS_MNEMONIC_RET )
if ( instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER )
{
routine.push_back( { instr, raw_instr, routine_addr } );
return true;
}
else
{
if ( keep_jmps )
routine.push_back( { instr, raw_instr, routine_addr } );
routine_addr += instr.length;
}
ZydisCalcAbsoluteAddress( &instr, &instr.operands[ 0 ], routine_addr, &routine_addr );
}
else if ( instr.mnemonic == ZYDIS_MNEMONIC_RET )
{
routine.push_back( { instr, raw_instr, routine_addr } );
return true;
}
else
{
routine.push_back( { instr, raw_instr, routine_addr } );
routine_addr += instr.length;
}
return false;
}
return false;
}
void deobfuscate( zydis_routine_t &routine )
{
static const auto _uses = []( ZydisDecodedOperand &op, zydis_register_t reg ) -> bool {
switch ( op.type )
{
case ZYDIS_OPERAND_TYPE_MEMORY:
{
return reg::compare( op.mem.base, reg ) || reg::compare( op.mem.index, reg );
}
case ZYDIS_OPERAND_TYPE_REGISTER:
{
return reg::compare( op.reg.value, reg );
}
default:
break;
}
return false;
};
void deobfuscate( zydis_routine_t &routine )
{
static const auto _uses = []( ZydisDecodedOperand &op, zydis_register_t reg ) -> bool {
switch ( op.type )
{
case ZYDIS_OPERAND_TYPE_MEMORY:
{
return reg::compare( op.mem.base, reg ) || reg::compare( op.mem.index, reg );
}
case ZYDIS_OPERAND_TYPE_REGISTER:
{
return reg::compare( op.reg.value, reg );
}
default:
break;
}
return false;
};
static const auto _writes = []( zydis_decoded_instr_t &inst ) -> bool {
for ( auto idx = 0; idx < inst.operand_count; ++idx )
if ( inst.operands[ idx ].actions & ZYDIS_OPERAND_ACTION_MASK_WRITE )
return true;
static const auto _writes = []( zydis_decoded_instr_t &inst ) -> bool {
for ( auto idx = 0; idx < inst.operand_count; ++idx )
if ( inst.operands[ idx ].actions & ZYDIS_OPERAND_ACTION_MASK_WRITE )
return true;
return false;
};
return false;
};
static const auto _remove = []( zydis_routine_t &routine, zydis_routine_t::iterator itr,
zydis_register_t reg, u32 opcode_size ) -> void {
for ( ; itr >= routine.begin(); --itr )
static const auto _remove = []( zydis_routine_t &routine, zydis_routine_t::iterator itr, zydis_register_t reg,
u32 opcode_size ) -> void {
for ( ; itr >= routine.begin(); --itr )
{
const auto instruction = &itr->instr;
auto stop = false;
if ( instruction->mnemonic == ZYDIS_MNEMONIC_JMP )
continue;
for ( auto op_idx = 0u; op_idx < instruction->operand_count; ++op_idx )
{
const auto instruction = &itr->instr;
auto stop = false;
const auto op = &instruction->operands[ op_idx ];
if ( instruction->mnemonic == ZYDIS_MNEMONIC_JMP )
if ( !_uses( *op, reg ) )
continue;
for ( auto op_idx = 0u; op_idx < instruction->operand_count; ++op_idx )
if ( op->type == ZYDIS_OPERAND_TYPE_MEMORY )
{
const auto op = &instruction->operands[ op_idx ];
if ( !_uses( *op, reg ) )
continue;
stop = true;
continue;
}
if ( op->type == ZYDIS_OPERAND_TYPE_MEMORY )
{
stop = true;
continue;
}
if ( opcode_size < 32 && op->size > opcode_size )
continue;
if ( opcode_size < 32 && op->size > opcode_size )
continue;
op->actions &ZYDIS_OPERAND_ACTION_MASK_WRITE ? op->actions &= ~ZYDIS_OPERAND_ACTION_MASK_WRITE
: stop = true;
}
op->actions &ZYDIS_OPERAND_ACTION_MASK_WRITE ? op->actions &= ~ZYDIS_OPERAND_ACTION_MASK_WRITE
: stop = true;
}
if ( !_writes( *instruction ) )
routine.erase( itr );
if ( !_writes( *instruction ) )
routine.erase( itr );
else if ( stop )
break;
}
};
else if ( stop )
break;
}
};
for ( const auto &instr_data : routine )
{
if ( routine.empty() || routine.size() == 1 || instr_data.instr.mnemonic == ZYDIS_MNEMONIC_JMP )
continue;
for ( const auto &instr_data : routine )
for ( auto itr = routine.begin() + 1; itr != routine.end(); itr++ )
{
if ( routine.empty() || routine.size() == 1 || instr_data.instr.mnemonic == ZYDIS_MNEMONIC_JMP )
continue;
if ( itr->instr.mnemonic == ZYDIS_MNEMONIC_JMP || itr->instr.mnemonic == ZYDIS_MNEMONIC_RET )
break;
for ( auto itr = routine.begin() + 1; itr != routine.end(); itr++ )
// find the write operations that happen...
for ( auto idx = 0u; idx < itr->instr.operand_count; ++idx )
{
if ( itr->instr.mnemonic == ZYDIS_MNEMONIC_JMP || itr->instr.mnemonic == ZYDIS_MNEMONIC_RET )
break;
// find the write operations that happen...
for ( auto idx = 0u; idx < itr->instr.operand_count; ++idx )
{
const auto op = &itr->instr.operands[ idx ];
// if its a read, continue to next opcode...
if ( op->actions & ZYDIS_OPERAND_ACTION_MASK_READ )
continue;
const auto op = &itr->instr.operands[ idx ];
// if its a read, continue to next opcode...
if ( op->actions & ZYDIS_OPERAND_ACTION_MASK_READ )
continue;
// if its not a write then continue to next opcode...
if ( !( op->actions & ZYDIS_OPERAND_ACTION_MASK_WRITE ) )
continue;
// if its not a write then continue to next opcode...
if ( !( op->actions & ZYDIS_OPERAND_ACTION_MASK_WRITE ) )
continue;
// if this operand is not a register then we continue...
if ( op->type != ZYDIS_OPERAND_TYPE_REGISTER )
continue;
// if this operand is not a register then we continue...
if ( op->type != ZYDIS_OPERAND_TYPE_REGISTER )
continue;
// else we see if we can remove dead writes to this register...
_remove( routine, itr - 1, op->reg.value, op->size );
}
// else we see if we can remove dead writes to this register...
_remove( routine, itr - 1, op->reg.value, op->size );
}
}
}
} // namespace util
} // namespace vm
}
} // namespace vm::util
Loading…
Cancel
Save