parent
ae9f255180
commit
13fef335fe
@ -1,62 +1,56 @@
|
|||||||
#include <vmprofiler.hpp>
|
#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() )
|
if ( !result.has_value() )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
calc_jmp.insert( calc_jmp.end(), result.value(), vm_entry.end() );
|
calc_jmp.insert( calc_jmp.end(), result.value(), vm_entry.end() );
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional< vmp2::exec_type_t > get_advancement( const zydis_routine_t &calc_jmp )
|
std::optional< vmp2::exec_type_t > get_advancement( const zydis_routine_t &calc_jmp )
|
||||||
{
|
{
|
||||||
auto result =
|
auto result = std::find_if( calc_jmp.begin(), calc_jmp.end(), []( const zydis_instr_t &instr_data ) -> bool {
|
||||||
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..
|
||||||
// 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 &&
|
||||||
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 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
instr_data.instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RSI;
|
||||||
instr_data.instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RSI;
|
} );
|
||||||
} );
|
|
||||||
|
|
||||||
if ( result == calc_jmp.end() )
|
if ( result == calc_jmp.end() )
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
const auto &instr = result->instr;
|
const auto &instr = result->instr;
|
||||||
|
|
||||||
switch ( instr.mnemonic )
|
switch ( instr.mnemonic )
|
||||||
{
|
{
|
||||||
case ZYDIS_MNEMONIC_LEA:
|
case ZYDIS_MNEMONIC_LEA:
|
||||||
// if operand type is memory, then return advancement type
|
// if operand type is memory, then return advancement type
|
||||||
// based off of the disposition value... (neg == backward, pos == forward)
|
// based off of the disposition value... (neg == backward, pos == forward)
|
||||||
if ( instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY )
|
if ( instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY )
|
||||||
return instr.operands[ 1 ].mem.disp.value > 0 ? vmp2::exec_type_t::forward
|
return instr.operands[ 1 ].mem.disp.value > 0 ? vmp2::exec_type_t::forward
|
||||||
: vmp2::exec_type_t::backward;
|
: vmp2::exec_type_t::backward;
|
||||||
break;
|
break;
|
||||||
case ZYDIS_MNEMONIC_ADD:
|
case ZYDIS_MNEMONIC_ADD:
|
||||||
if ( instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE )
|
if ( instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE )
|
||||||
return instr.operands[ 1 ].imm.value.s > 0 ? vmp2::exec_type_t::forward
|
return instr.operands[ 1 ].imm.value.s > 0 ? vmp2::exec_type_t::forward : vmp2::exec_type_t::backward;
|
||||||
: vmp2::exec_type_t::backward;
|
break;
|
||||||
break;
|
case ZYDIS_MNEMONIC_SUB:
|
||||||
case ZYDIS_MNEMONIC_SUB:
|
if ( instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE )
|
||||||
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;
|
||||||
return instr.operands[ 1 ].imm.value.s > 0 ? vmp2::exec_type_t::backward
|
break;
|
||||||
: vmp2::exec_type_t::forward;
|
case ZYDIS_MNEMONIC_INC:
|
||||||
break;
|
return vmp2::exec_type_t::forward;
|
||||||
case ZYDIS_MNEMONIC_INC:
|
case ZYDIS_MNEMONIC_DEC:
|
||||||
return vmp2::exec_type_t::forward;
|
return vmp2::exec_type_t::backward;
|
||||||
case ZYDIS_MNEMONIC_DEC:
|
default:
|
||||||
return vmp2::exec_type_t::backward;
|
break;
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
}
|
||||||
} // namespace calc_jmp
|
return {};
|
||||||
} // namespace vm
|
}
|
||||||
|
} // namespace vm::calc_jmp
|
@ -1,306 +1,302 @@
|
|||||||
#include <vmprofiler.hpp>
|
#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 ) )
|
zydis_routine_t::iterator last = vm_handler.end();
|
||||||
return false;
|
result = vm_handler.begin();
|
||||||
|
|
||||||
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...
|
while ( result != vm_handler.end() )
|
||||||
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...
|
|
||||||
{
|
{
|
||||||
zydis_routine_t::iterator last = vm_handler.end();
|
result = std::find_if( ++result, vm_handler.end(), []( const zydis_instr_t &instr_data ) -> bool {
|
||||||
result = vm_handler.begin();
|
// mov/movsx/movzx rax/eax/ax/al, [rsi]
|
||||||
|
return instr_data.instr.operand_count > 1 &&
|
||||||
while ( result != vm_handler.end() )
|
( instr_data.instr.mnemonic == ZYDIS_MNEMONIC_MOV ||
|
||||||
{
|
instr_data.instr.mnemonic == ZYDIS_MNEMONIC_MOVSX ||
|
||||||
result = std::find_if( ++result, vm_handler.end(), []( const zydis_instr_t &instr_data ) -> bool {
|
instr_data.instr.mnemonic == ZYDIS_MNEMONIC_MOVZX ) &&
|
||||||
// mov/movsx/movzx rax/eax/ax/al, [rsi]
|
instr_data.instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
return instr_data.instr.operand_count > 1 &&
|
util::reg::to64( instr_data.instr.operands[ 0 ].reg.value ) == ZYDIS_REGISTER_RAX &&
|
||||||
( instr_data.instr.mnemonic == ZYDIS_MNEMONIC_MOV ||
|
instr_data.instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
instr_data.instr.mnemonic == ZYDIS_MNEMONIC_MOVSX ||
|
instr_data.instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RSI;
|
||||||
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 &&
|
if ( result != vm_handler.end() )
|
||||||
instr_data.instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
last = result;
|
||||||
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() );
|
|
||||||
}
|
}
|
||||||
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,
|
for ( auto idx = 0u; idx < 256; ++idx )
|
||||||
std::uintptr_t *vm_handler_table, std::vector< vm::handler::handler_t > &vm_handlers )
|
|
||||||
{
|
{
|
||||||
zydis_decoded_instr_t instr;
|
handler_t vm_handler;
|
||||||
if ( !vm::handler::table::get_transform( vm_entry, &instr ) )
|
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;
|
return false;
|
||||||
|
|
||||||
zydis_routine_t calc_jmp;
|
const auto has_imm = vm::handler::has_imm( vm_handler_instrs );
|
||||||
if ( !vm::calc_jmp::get( vm_entry, calc_jmp ) )
|
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;
|
return false;
|
||||||
|
|
||||||
for ( auto idx = 0u; idx < 256; ++idx )
|
vm_handler.address = ( decrypt_val - image_base ) + module_base;
|
||||||
{
|
vm_handler.instrs = vm_handler_instrs;
|
||||||
handler_t vm_handler;
|
vm_handler.imm_size = imm_size.value();
|
||||||
vm::transform::map_t transforms;
|
vm_handler.transforms = transforms;
|
||||||
zydis_routine_t vm_handler_instrs;
|
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 ] );
|
return true;
|
||||||
if ( !vm::handler::get( calc_jmp, vm_handler_instrs, ( decrypt_val - image_base ) + module_base ) )
|
}
|
||||||
return false;
|
|
||||||
|
|
||||||
const auto has_imm = vm::handler::has_imm( vm_handler_instrs );
|
bool has_imm( const zydis_routine_t &vm_handler )
|
||||||
const auto imm_size = vm::handler::imm_size( vm_handler_instrs );
|
{
|
||||||
|
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 ) ||
|
std::optional< std::uint8_t > imm_size( const zydis_routine_t &vm_handler )
|
||||||
!imm_size.has_value() ) )
|
{
|
||||||
return false;
|
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;
|
return instr_data.instr.operands[ 1 ].size;
|
||||||
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 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 )
|
if ( !imm_fetch.has_value() )
|
||||||
{
|
return false;
|
||||||
zydis_instr_t instr_data;
|
|
||||||
return vm::util::get_fetch_operand( vm_handler, instr_data );
|
|
||||||
}
|
|
||||||
|
|
||||||
std::optional< std::uint8_t > imm_size( const zydis_routine_t &vm_handler )
|
// this finds the first transformation which looks like:
|
||||||
{
|
// transform rax, rbx <--- note these registers can be smaller so we to64 them...
|
||||||
zydis_instr_t instr_data;
|
auto transform_instr =
|
||||||
if ( !vm::util::get_fetch_operand( vm_handler, instr_data ) )
|
std::find_if( imm_fetch.value(), vm_handler.end(), []( const zydis_instr_t &instr_data ) -> bool {
|
||||||
return {};
|
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 )
|
// look for a primer/instruction that alters RAX prior to the 5 transformations...
|
||||||
{
|
auto generic0 =
|
||||||
auto imm_fetch = vm::util::get_fetch_operand( vm_handler );
|
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() )
|
zydis_decoded_instr_t nogeneric0;
|
||||||
return false;
|
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:
|
// three generic transformations...
|
||||||
// transform rax, rbx <--- note these registers can be smaller so we to64 them...
|
for ( auto idx = static_cast< unsigned >( vm::transform::type::generic1 );
|
||||||
auto transform_instr =
|
idx < static_cast< unsigned >( vm::transform::type::update_key ); ++idx )
|
||||||
std::find_if( imm_fetch.value(), vm_handler.end(), []( const zydis_instr_t &instr_data ) -> bool {
|
{
|
||||||
|
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 ) &&
|
return vm::transform::valid( instr_data.instr.mnemonic ) &&
|
||||||
instr_data.instr.operands[ 0 ].actions & ZYDIS_OPERAND_ACTION_WRITE &&
|
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[ 0 ].reg.value, ZYDIS_REGISTER_RAX );
|
||||||
util::reg::compare( instr_data.instr.operands[ 1 ].reg.value, ZYDIS_REGISTER_RBX );
|
|
||||||
} );
|
} );
|
||||||
|
|
||||||
if ( transform_instr == vm_handler.end() )
|
if ( transform_instr == vm_handler.end() )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// look for a primer/instruction that alters RAX prior to the 5 transformations...
|
transforms[ static_cast< vm::transform::type >( idx ) ] = transform_instr->instr;
|
||||||
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 );
|
|
||||||
} );
|
|
||||||
|
|
||||||
zydis_decoded_instr_t nogeneric0;
|
return true;
|
||||||
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...
|
vm::handler::profile_t *get_profile( handler_t &vm_handler )
|
||||||
transforms[ transform::type::rolling_key ] = transform_instr->instr;
|
{
|
||||||
auto instr_copy = transform_instr->instr;
|
static const auto vcontains = []( vm::handler::profile_t *vprofile, handler_t *vm_handler ) -> bool {
|
||||||
instr_copy.operands[ 0 ].reg.value = transform_instr->instr.operands[ 1 ].reg.value;
|
if ( vprofile->imm_size != vm_handler->imm_size )
|
||||||
instr_copy.operands[ 1 ].reg.value = transform_instr->instr.operands[ 0 ].reg.value;
|
return false;
|
||||||
transforms[ transform::type::update_key ] = instr_copy;
|
|
||||||
|
zydis_routine_t::iterator contains = vm_handler->instrs.begin();
|
||||||
|
|
||||||
// three generic transformations...
|
for ( auto &instr : vprofile->signature )
|
||||||
for ( auto idx = static_cast< unsigned >( vm::transform::type::generic1 );
|
|
||||||
idx < static_cast< unsigned >( vm::transform::type::update_key ); ++idx )
|
|
||||||
{
|
{
|
||||||
transform_instr =
|
contains =
|
||||||
std::find_if( ++transform_instr, vm_handler.end(), []( const zydis_instr_t &instr_data ) -> bool {
|
std::find_if( contains, vm_handler->instrs.end(),
|
||||||
return vm::transform::valid( instr_data.instr.mnemonic ) &&
|
[ & ]( zydis_instr_t &instr_data ) -> bool { return instr( instr_data.instr ); } );
|
||||||
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;
|
|
||||||
|
|
||||||
transforms[ static_cast< vm::transform::type >( idx ) ] = transform_instr->instr;
|
if ( contains == vm_handler->instrs.end() )
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
};
|
||||||
|
|
||||||
vm::handler::profile_t *get_profile( handler_t &vm_handler )
|
for ( auto profile : vm::handler::profile::all )
|
||||||
{
|
if ( vcontains( profile, &vm_handler ) )
|
||||||
static const auto vcontains = []( vm::handler::profile_t *vprofile, handler_t *vm_handler ) -> bool {
|
return profile;
|
||||||
if ( vprofile->imm_size != vm_handler->imm_size )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
zydis_routine_t::iterator contains = vm_handler->instrs.begin();
|
|
||||||
|
|
||||||
for ( auto &instr : vprofile->signature )
|
return nullptr;
|
||||||
{
|
}
|
||||||
contains =
|
|
||||||
std::find_if( contains, vm_handler->instrs.end(), [ & ]( zydis_instr_t &instr_data ) -> bool {
|
|
||||||
return instr( instr_data.instr );
|
|
||||||
} );
|
|
||||||
|
|
||||||
if ( contains == vm_handler->instrs.end() )
|
vm::handler::profile_t *get_profile( vm::handler::mnemonic_t mnemonic )
|
||||||
return false;
|
{
|
||||||
}
|
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 )
|
namespace table
|
||||||
if ( vcontains( profile, &vm_handler ) )
|
{
|
||||||
return profile;
|
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 ptr = 0ull;
|
||||||
{
|
ZydisCalcAbsoluteAddress( &result->instr, &result->instr.operands[ 1 ], result->addr, &ptr );
|
||||||
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 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 )
|
auto handler_fetch =
|
||||||
{
|
std::find_if( vm_entry.begin(), vm_entry.end(), [ & ]( const zydis_instr_t &instr_data ) -> bool {
|
||||||
const auto result =
|
const auto instr = &instr_data.instr;
|
||||||
std::find_if( vm_entry.begin(), vm_entry.end(), []( const zydis_instr_t &instr_data ) -> bool {
|
return instr->mnemonic == ZYDIS_MNEMONIC_MOV && instr->operand_count == 2 &&
|
||||||
const auto instr = &instr_data.instr;
|
instr->operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
// lea r12, vm_handlers... (always r12)...
|
instr->operands[ 1 ].mem.base == ZYDIS_REGISTER_R12 &&
|
||||||
return instr->mnemonic == ZYDIS_MNEMONIC_LEA &&
|
instr->operands[ 1 ].mem.index == ZYDIS_REGISTER_RAX &&
|
||||||
instr->operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
instr->operands[ 1 ].mem.scale == 8 &&
|
||||||
instr->operands[ 0 ].reg.value == ZYDIS_REGISTER_R12 &&
|
instr->operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
!instr->raw.sib.base; // no register used for the sib base...
|
( instr->operands[ 0 ].reg.value == ZYDIS_REGISTER_RDX ||
|
||||||
} );
|
instr->operands[ 0 ].reg.value == ZYDIS_REGISTER_RCX );
|
||||||
|
} );
|
||||||
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 );
|
|
||||||
}
|
|
||||||
|
|
||||||
bool get_transform( const zydis_routine_t &vm_entry, zydis_decoded_instr_t *transform_instr )
|
// check to see if we found the fetch instruction and if the next instruction
|
||||||
{
|
// is not the end of the vector...
|
||||||
auto handler_fetch =
|
if ( handler_fetch == vm_entry.end() ||
|
||||||
std::find_if( vm_entry.begin(), vm_entry.end(), [ & ]( const zydis_instr_t &instr_data ) -> bool {
|
// must be RCX or RDX... else something went wrong...
|
||||||
const auto instr = &instr_data.instr;
|
( handler_fetch->instr.operands[ 0 ].reg.value != ZYDIS_REGISTER_RCX &&
|
||||||
return instr->mnemonic == ZYDIS_MNEMONIC_MOV && instr->operand_count == 2 &&
|
handler_fetch->instr.operands[ 0 ].reg.value != ZYDIS_REGISTER_RDX ) )
|
||||||
instr->operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
return false;
|
||||||
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;
|
|
||||||
|
|
||||||
// find the next instruction that writes to RCX or RDX...
|
// find the next instruction that writes to RCX or RDX...
|
||||||
// the register is determined by the vm handler fetch above...
|
// the register is determined by the vm handler fetch above...
|
||||||
auto handler_transform =
|
auto handler_transform =
|
||||||
std::find_if( handler_fetch, vm_entry.end(), [ & ]( const zydis_instr_t &instr_data ) -> bool {
|
std::find_if( handler_fetch, vm_entry.end(), [ & ]( const zydis_instr_t &instr_data ) -> bool {
|
||||||
return vm::transform::valid( instr_data.instr.mnemonic ) &&
|
return vm::transform::valid( instr_data.instr.mnemonic ) &&
|
||||||
instr_data.instr.operands[ 0 ].reg.value ==
|
instr_data.instr.operands[ 0 ].reg.value == handler_fetch->instr.operands[ 0 ].reg.value &&
|
||||||
handler_fetch->instr.operands[ 0 ].reg.value &&
|
instr_data.instr.operands[ 0 ].actions & ZYDIS_OPERAND_ACTION_WRITE;
|
||||||
instr_data.instr.operands[ 0 ].actions & ZYDIS_OPERAND_ACTION_WRITE;
|
} );
|
||||||
} );
|
|
||||||
|
|
||||||
if ( handler_transform == vm_entry.end() )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
*transform_instr = handler_transform->instr;
|
if ( handler_transform == vm_entry.end() )
|
||||||
return true;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
std::uint64_t encrypt( zydis_decoded_instr_t &transform_instr, std::uint64_t val )
|
*transform_instr = handler_transform->instr;
|
||||||
{
|
return true;
|
||||||
assert( transform_instr.operands[ 0 ].size == 64,
|
}
|
||||||
"invalid transformation for vm handler table entries..." );
|
|
||||||
|
|
||||||
const auto operation = vm::transform::inverse[ transform_instr.mnemonic ];
|
std::uint64_t encrypt( zydis_decoded_instr_t &transform_instr, std::uint64_t val )
|
||||||
const auto bitsize = transform_instr.operands[ 0 ].size;
|
{
|
||||||
const auto imm =
|
assert( transform_instr.operands[ 0 ].size == 64,
|
||||||
vm::transform::has_imm( &transform_instr ) ? transform_instr.operands[ 1 ].imm.value.u : 0u;
|
"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 )
|
return vm::transform::apply( bitsize, operation, val, imm );
|
||||||
{
|
}
|
||||||
assert( transform_instr.operands[ 0 ].size == 64,
|
|
||||||
"invalid transformation for vm handler table entries..." );
|
|
||||||
|
|
||||||
const auto operation = transform_instr.mnemonic;
|
std::uint64_t decrypt( zydis_decoded_instr_t &transform_instr, std::uint64_t val )
|
||||||
const auto bitsize = transform_instr.operands[ 0 ].size;
|
{
|
||||||
const auto imm =
|
assert( transform_instr.operands[ 0 ].size == 64,
|
||||||
vm::transform::has_imm( &transform_instr ) ? transform_instr.operands[ 1 ].imm.value.u : 0u;
|
"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;
|
||||||
} // namespace table
|
const auto imm =
|
||||||
} // namespace handler
|
vm::transform::has_imm( &transform_instr ) ? transform_instr.operands[ 1 ].imm.value.u : 0u;
|
||||||
} // namespace vm
|
|
||||||
|
return vm::transform::apply( bitsize, operation, val, imm );
|
||||||
|
}
|
||||||
|
} // namespace table
|
||||||
|
} // namespace vm::handler
|
@ -1,91 +1,73 @@
|
|||||||
#include <vmprofiler.hpp>
|
#include <vmprofiler.hpp>
|
||||||
|
|
||||||
namespace vm
|
namespace vm::handler::profile
|
||||||
{
|
{
|
||||||
namespace handler
|
vm::handler::profile_t addq = {
|
||||||
{
|
// ADD [RBP+8], RAX
|
||||||
namespace profile
|
// PUSHFQ
|
||||||
{
|
// POP [RBP]
|
||||||
vm::handler::profile_t addq = {
|
"ADDQ",
|
||||||
// ADD [RBP+8], RAX
|
ADDQ,
|
||||||
// PUSHFQ
|
NULL,
|
||||||
// POP [RBP]
|
{ { // ADD [RBP+8], RAX
|
||||||
"ADDQ",
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
ADDQ,
|
return instr.mnemonic == ZYDIS_MNEMONIC_ADD && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
NULL,
|
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
|
||||||
{ { // ADD [RBP+8], RAX
|
instr.operands[ 0 ].mem.disp.value == 0x8 &&
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_ADD &&
|
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RAX;
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
},
|
||||||
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
|
// PUSHFQ
|
||||||
instr.operands[ 0 ].mem.disp.value == 0x8 &&
|
[]( const zydis_decoded_instr_t &instr ) -> bool { return instr.mnemonic == ZYDIS_MNEMONIC_PUSHFQ; },
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
// POP [RBP]
|
||||||
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RAX;
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
},
|
return instr.mnemonic == ZYDIS_MNEMONIC_POP && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
// PUSHFQ
|
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP;
|
||||||
[]( 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 = {
|
vm::handler::profile_t adddw = {
|
||||||
// ADD [RBP+8], EAX
|
// ADD [RBP+8], EAX
|
||||||
// PUSHFQ
|
// PUSHFQ
|
||||||
// POP [RBP]
|
// POP [RBP]
|
||||||
"ADDDW",
|
"ADDDW",
|
||||||
ADDDW,
|
ADDDW,
|
||||||
NULL,
|
NULL,
|
||||||
{ { // ADD [RBP+8], EAX
|
{ { // ADD [RBP+8], EAX
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_ADD &&
|
return instr.mnemonic == ZYDIS_MNEMONIC_ADD && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
|
||||||
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
|
instr.operands[ 0 ].mem.disp.value == 0x8 &&
|
||||||
instr.operands[ 0 ].mem.disp.value == 0x8 &&
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_EAX;
|
||||||
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_EAX;
|
},
|
||||||
},
|
// PUSHFQ
|
||||||
// PUSHFQ
|
[]( const zydis_decoded_instr_t &instr ) -> bool { return instr.mnemonic == ZYDIS_MNEMONIC_PUSHFQ; },
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
// POP [RBP]
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_PUSHFQ;
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
},
|
return instr.mnemonic == ZYDIS_MNEMONIC_POP && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
// POP [RBP]
|
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_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 = {
|
vm::handler::profile_t addw = {
|
||||||
// ADD [RBP+8], AX
|
// ADD [RBP+8], AX
|
||||||
// PUSHFQ
|
// PUSHFQ
|
||||||
// POP [RBP]
|
// POP [RBP]
|
||||||
"ADDW",
|
"ADDW",
|
||||||
ADDW,
|
ADDW,
|
||||||
NULL,
|
NULL,
|
||||||
{ { // ADD [RBP+8], AX
|
{ { // ADD [RBP+8], AX
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_ADD &&
|
return instr.mnemonic == ZYDIS_MNEMONIC_ADD && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
|
||||||
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
|
instr.operands[ 0 ].mem.disp.value == 0x8 &&
|
||||||
instr.operands[ 0 ].mem.disp.value == 0x8 &&
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_AX;
|
||||||
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_AX;
|
},
|
||||||
},
|
// PUSHFQ
|
||||||
// PUSHFQ
|
[]( const zydis_decoded_instr_t &instr ) -> bool { return instr.mnemonic == ZYDIS_MNEMONIC_PUSHFQ; },
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
// POP [RBP]
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_PUSHFQ;
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
},
|
return instr.mnemonic == ZYDIS_MNEMONIC_POP && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
// POP [RBP]
|
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP;
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
} } } };
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_POP &&
|
} // namespace vm::handler::profile
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
|
||||||
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP;
|
|
||||||
} } } };
|
|
||||||
} // namespace profile
|
|
||||||
} // namespace handler
|
|
||||||
} // namespace vm
|
|
@ -1,40 +1,34 @@
|
|||||||
#include <vmprofiler.hpp>
|
#include <vmprofiler.hpp>
|
||||||
|
|
||||||
namespace vm
|
namespace vm::handler::profile
|
||||||
{
|
{
|
||||||
namespace handler
|
vm::handler::profile_t call = {
|
||||||
{
|
// MOV RDX, [RBP]
|
||||||
namespace profile
|
// ADD RBP, 0x8
|
||||||
{
|
// CALL RDX
|
||||||
vm::handler::profile_t call = {
|
"CALL",
|
||||||
// MOV RDX, [RBP]
|
CALL,
|
||||||
// ADD RBP, 0x8
|
NULL,
|
||||||
// CALL RDX
|
{ { // MOV RDX, [RBP]
|
||||||
"CALL",
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
CALL,
|
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
||||||
NULL,
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
{ { // MOV RDX, [RBP]
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RDX &&
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
},
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RDX &&
|
// ADD RBP, 0x8
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
|
return instr.mnemonic == ZYDIS_MNEMONIC_ADD &&
|
||||||
},
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
// ADD RBP, 0x8
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_ADD &&
|
instr.operands[ 1 ].imm.value.u == 0x8;
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
},
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
|
// CALL RDX
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
instr.operands[ 1 ].imm.value.u == 0x8;
|
return instr.mnemonic == ZYDIS_MNEMONIC_CALL &&
|
||||||
},
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
// CALL RDX
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RDX;
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
} } } };
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_CALL &&
|
} // namespace vm::handler::profile
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RDX;
|
|
||||||
} } } };
|
|
||||||
}
|
|
||||||
} // namespace handler
|
|
||||||
} // namespace vm
|
|
@ -1,74 +1,58 @@
|
|||||||
#include <vmprofiler.hpp>
|
#include <vmprofiler.hpp>
|
||||||
|
|
||||||
namespace vm
|
namespace vm::handler::profile
|
||||||
{
|
{
|
||||||
namespace handler
|
vm::handler::profile_t divq = {
|
||||||
{
|
// MOV RDX, [RBP]
|
||||||
namespace profile
|
// MOV RAX, [RBP+0x8]
|
||||||
{
|
// DIV [RBP+0x10]
|
||||||
vm::handler::profile_t divq = {
|
// MOV [RBP+0x8], RDX
|
||||||
// MOV RDX, [RBP]
|
// MOV [RBP+0x10], RAX
|
||||||
// MOV RAX, [RBP+0x8]
|
// PUSHFQ
|
||||||
// DIV [RBP+0x10]
|
// POP [RBP]
|
||||||
// MOV [RBP+0x8], RDX
|
"DIVQ",
|
||||||
// MOV [RBP+0x10], RAX
|
DIVQ,
|
||||||
// PUSHFQ
|
NULL,
|
||||||
// POP [RBP]
|
{ { // MOV RDX, [RBP]
|
||||||
"DIVQ",
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
DIVQ,
|
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
||||||
NULL,
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
{ { // MOV RDX, [RBP]
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RDX &&
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
},
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RDX &&
|
// MOV RAX, [RBP+0x8]
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
|
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
||||||
},
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
// MOV RAX, [RBP+0x8]
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX &&
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP && instr.operands[ 1 ].mem.index == 0x8;
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
},
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX &&
|
// DIV [RBP+0x10]
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP &&
|
return instr.mnemonic == ZYDIS_MNEMONIC_DIV && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
instr.operands[ 1 ].mem.index == 0x8;
|
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP && instr.operands[ 0 ].mem.index == 0x10;
|
||||||
},
|
},
|
||||||
// DIV [RBP+0x10]
|
// MOV [RBP+0x8], RDX
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_DIV &&
|
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP && instr.operands[ 0 ].mem.index == 0x8 &&
|
||||||
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
instr.operands[ 0 ].mem.index == 0x10;
|
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RDX;
|
||||||
},
|
},
|
||||||
// MOV [RBP+0x8], RDX
|
// MOV [RBP+0x10], RAX
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP && instr.operands[ 0 ].mem.index == 0x10 &&
|
||||||
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
instr.operands[ 0 ].mem.index == 0x8 &&
|
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RAX;
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
},
|
||||||
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RDX;
|
// PUSHFQ
|
||||||
},
|
[]( const zydis_decoded_instr_t &instr ) -> bool { return instr.mnemonic == ZYDIS_MNEMONIC_PUSHFQ; },
|
||||||
// MOV [RBP+0x10], RAX
|
// POP [RBP]
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
return instr.mnemonic == ZYDIS_MNEMONIC_POP && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP;
|
||||||
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
|
} } } };
|
||||||
instr.operands[ 0 ].mem.index == 0x10 &&
|
} // namespace vm::handler::profile
|
||||||
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
|
|
@ -1,51 +1,45 @@
|
|||||||
#include <vmprofiler.hpp>
|
#include <vmprofiler.hpp>
|
||||||
|
|
||||||
namespace vm
|
namespace vm::handler::profile
|
||||||
{
|
{
|
||||||
namespace handler
|
vm::handler::profile_t jmp = {
|
||||||
{
|
// MOV ESI, [RBP]
|
||||||
namespace profile
|
// ADD RSI, RAX
|
||||||
{
|
// MOV RBX, RSI
|
||||||
vm::handler::profile_t jmp = {
|
// ADD RSI, [RBP]
|
||||||
// MOV ESI, [RBP]
|
"JMP",
|
||||||
// ADD RSI, RAX
|
JMP,
|
||||||
// MOV RBX, RSI
|
NULL,
|
||||||
// ADD RSI, [RBP]
|
{ { // MOV ESI, [RBP]
|
||||||
"JMP",
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
JMP,
|
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
||||||
NULL,
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
{ { // MOV ESI, [RBP]
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_ESI &&
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
},
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_ESI &&
|
// ADD RSI, RAX
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
|
return instr.mnemonic == ZYDIS_MNEMONIC_ADD &&
|
||||||
},
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
// ADD RSI, RAX
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RSI &&
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_ADD &&
|
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RAX;
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
},
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RSI &&
|
// MOV RBX, RSI
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RAX;
|
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
||||||
},
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
// MOV RBX, RSI
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBX &&
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RSI;
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
},
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBX &&
|
// ADD RSI, [RBP]
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RSI;
|
return instr.mnemonic == ZYDIS_MNEMONIC_ADD &&
|
||||||
},
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
// ADD RSI, [RBP]
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RSI &&
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_ADD &&
|
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
} } } };
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RSI &&
|
} // namespace vm::handler::profile
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
|
||||||
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
|
|
||||||
} } } };
|
|
||||||
}
|
|
||||||
} // namespace handler
|
|
||||||
} // namespace vm
|
|
@ -1,239 +1,222 @@
|
|||||||
#include <vmprofiler.hpp>
|
#include <vmprofiler.hpp>
|
||||||
|
|
||||||
namespace vm
|
namespace vm::handler::profile
|
||||||
{
|
{
|
||||||
namespace handler
|
vm::handler::profile_t lconstq = {
|
||||||
{
|
// MOV RAX, [RSI]
|
||||||
namespace profile
|
// SUB RBP, 8
|
||||||
{
|
// MOV [RBP], RAX
|
||||||
vm::handler::profile_t lconstq = {
|
"LCONSTQ",
|
||||||
// MOV RAX, [RSI]
|
LCONSTQ,
|
||||||
// SUB RBP, 8
|
64,
|
||||||
// MOV [RBP], RAX
|
{ { // SUB RBP, 8
|
||||||
"LCONSTQ",
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
LCONSTQ,
|
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
|
||||||
64,
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
{ { // SUB RBP, 8
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
|
instr.operands[ 1 ].imm.value.u == 0x8;
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
},
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
|
// MOV [RBP], RAX
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
instr.operands[ 1 ].imm.value.u == 0x8;
|
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
},
|
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
|
||||||
// MOV [RBP], RAX
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RAX;
|
||||||
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 = {
|
vm::handler::profile_t lconstdw = {
|
||||||
// SUB RBP, 4
|
// SUB RBP, 4
|
||||||
// MOV [RBP], EAX
|
// MOV [RBP], EAX
|
||||||
"LCONSTDW",
|
"LCONSTDW",
|
||||||
LCONSTDW,
|
LCONSTDW,
|
||||||
32,
|
32,
|
||||||
{ { // SUB RBP, 4
|
{ { // SUB RBP, 4
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
|
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
|
||||||
instr.operands[ 1 ].imm.value.u == 0x4;
|
instr.operands[ 1 ].imm.value.u == 0x4;
|
||||||
},
|
},
|
||||||
// MOV [RBP], EAX
|
// MOV [RBP], EAX
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
|
||||||
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_EAX;
|
||||||
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_EAX;
|
} } } };
|
||||||
} } } };
|
|
||||||
|
|
||||||
vm::handler::profile_t lconstw = {
|
vm::handler::profile_t lconstw = {
|
||||||
// SUB RBP, 2
|
// SUB RBP, 2
|
||||||
// MOV [RBP], AX
|
// MOV [RBP], AX
|
||||||
"LCONSTW",
|
"LCONSTW",
|
||||||
LCONSTW,
|
LCONSTW,
|
||||||
16,
|
16,
|
||||||
{ { // SUB RBP, 2
|
{ { // SUB RBP, 2
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
|
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
|
||||||
instr.operands[ 1 ].imm.value.u == 0x2;
|
instr.operands[ 1 ].imm.value.u == 0x2;
|
||||||
},
|
},
|
||||||
// MOV [RBP], AX
|
// MOV [RBP], AX
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
|
||||||
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_AX;
|
||||||
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_AX;
|
} } } };
|
||||||
} } } };
|
|
||||||
|
|
||||||
vm::handler::profile_t lconstbzxw = {
|
vm::handler::profile_t lconstbzxw = {
|
||||||
// MOV AL, [RSI]
|
// MOV AL, [RSI]
|
||||||
// SUB RBP, 2
|
// SUB RBP, 2
|
||||||
// MOV [RBP], AX
|
// MOV [RBP], AX
|
||||||
"LCONSTBZXW",
|
"LCONSTBZXW",
|
||||||
LCONSTBZXW,
|
LCONSTBZXW,
|
||||||
8,
|
8,
|
||||||
{ { // SUB RBP, 2
|
{ { // SUB RBP, 2
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
|
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
|
||||||
instr.operands[ 1 ].imm.value.u == 0x2;
|
instr.operands[ 1 ].imm.value.u == 0x2;
|
||||||
},
|
},
|
||||||
// MOV [RBP], AX
|
// MOV [RBP], AX
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
|
||||||
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_AX;
|
||||||
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_AX;
|
} } } };
|
||||||
} } } };
|
|
||||||
|
|
||||||
vm::handler::profile_t lconstbsxdw = {
|
vm::handler::profile_t lconstbsxdw = {
|
||||||
// CWDE
|
// CWDE
|
||||||
// SUB RBP, 4
|
// SUB RBP, 4
|
||||||
// MOV [RBP], EAX
|
// MOV [RBP], EAX
|
||||||
"LCONSTBSXDW",
|
"LCONSTBSXDW",
|
||||||
LCONSTBSXDW,
|
LCONSTBSXDW,
|
||||||
8,
|
8,
|
||||||
{ { // CWDE
|
{ { // CWDE
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool { return instr.mnemonic == ZYDIS_MNEMONIC_CWDE; },
|
[]( const zydis_decoded_instr_t &instr ) -> bool { return instr.mnemonic == ZYDIS_MNEMONIC_CWDE; },
|
||||||
// SUB RBP, 4
|
// SUB RBP, 4
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
|
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
|
||||||
instr.operands[ 1 ].imm.value.u == 0x4;
|
instr.operands[ 1 ].imm.value.u == 0x4;
|
||||||
},
|
},
|
||||||
// MOV [RBP], EAX
|
// MOV [RBP], EAX
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
|
||||||
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_EAX;
|
||||||
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_EAX;
|
} } },
|
||||||
} } },
|
vm::handler::extention_t::sign_extend };
|
||||||
vm::handler::extention_t::sign_extend };
|
|
||||||
|
|
||||||
vm::handler::profile_t lconstbsxq = {
|
vm::handler::profile_t lconstbsxq = {
|
||||||
// CDQE
|
// CDQE
|
||||||
// SUB RBP, 0x8
|
// SUB RBP, 0x8
|
||||||
// MOV [RBP], RAX
|
// MOV [RBP], RAX
|
||||||
"LCONSTBSXQ",
|
"LCONSTBSXQ",
|
||||||
LCONSTBSXQ,
|
LCONSTBSXQ,
|
||||||
8,
|
8,
|
||||||
{ { // CDQE
|
{ { // CDQE
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool { return instr.mnemonic == ZYDIS_MNEMONIC_CDQE; },
|
[]( const zydis_decoded_instr_t &instr ) -> bool { return instr.mnemonic == ZYDIS_MNEMONIC_CDQE; },
|
||||||
// SUB RBP, 0x8
|
// SUB RBP, 0x8
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
|
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
|
||||||
instr.operands[ 1 ].imm.value.u == 0x8;
|
instr.operands[ 1 ].imm.value.u == 0x8;
|
||||||
},
|
},
|
||||||
// MOV [RBP], RAX
|
// MOV [RBP], RAX
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
|
||||||
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RAX;
|
||||||
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RAX;
|
} } },
|
||||||
} } },
|
vm::handler::extention_t::sign_extend };
|
||||||
vm::handler::extention_t::sign_extend };
|
|
||||||
|
|
||||||
vm::handler::profile_t lconstdwsxq = {
|
vm::handler::profile_t lconstdwsxq = {
|
||||||
// CDQE
|
// CDQE
|
||||||
// SUB RBP, 8
|
// SUB RBP, 8
|
||||||
// MOV [RBP], RAX
|
// MOV [RBP], RAX
|
||||||
"LCONSTDWSXQ",
|
"LCONSTDWSXQ",
|
||||||
LCONSTDWSXQ,
|
LCONSTDWSXQ,
|
||||||
32,
|
32,
|
||||||
{ // CDQE
|
{ // CDQE
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool { return instr.mnemonic == ZYDIS_MNEMONIC_CDQE; },
|
[]( const zydis_decoded_instr_t &instr ) -> bool { return instr.mnemonic == ZYDIS_MNEMONIC_CDQE; },
|
||||||
// SUB RBP, 8
|
// SUB RBP, 8
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
|
return instr.mnemonic == ZYDIS_MNEMONIC_SUB && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE && instr.operands[ 1 ].imm.value.u == 0x8;
|
||||||
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 {
|
||||||
// MOV [RBP], RAX
|
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RAX;
|
||||||
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
|
} },
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
vm::handler::extention_t::sign_extend };
|
||||||
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RAX;
|
|
||||||
} },
|
|
||||||
vm::handler::extention_t::sign_extend };
|
|
||||||
|
|
||||||
vm::handler::profile_t lconstwsxq = {
|
vm::handler::profile_t lconstwsxq = {
|
||||||
// CDQE
|
// CDQE
|
||||||
// SUB RBP, 8
|
// SUB RBP, 8
|
||||||
// MOV [RBP], RAX
|
// MOV [RBP], RAX
|
||||||
"LCONSTWSXQ",
|
"LCONSTWSXQ",
|
||||||
LCONSTWSXQ,
|
LCONSTWSXQ,
|
||||||
16,
|
16,
|
||||||
{ { // CDQE
|
{ { // CDQE
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool { return instr.mnemonic == ZYDIS_MNEMONIC_CDQE; },
|
[]( const zydis_decoded_instr_t &instr ) -> bool { return instr.mnemonic == ZYDIS_MNEMONIC_CDQE; },
|
||||||
// SUB RBP, 8
|
// SUB RBP, 8
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
|
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
|
||||||
instr.operands[ 1 ].imm.value.u == 0x8;
|
instr.operands[ 1 ].imm.value.u == 0x8;
|
||||||
},
|
},
|
||||||
// MOV [RBP], RAX
|
// MOV [RBP], RAX
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
|
||||||
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RAX;
|
||||||
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RAX;
|
} } },
|
||||||
} } },
|
vm::handler::extention_t::sign_extend };
|
||||||
vm::handler::extention_t::sign_extend };
|
|
||||||
|
|
||||||
vm::handler::profile_t lconstwsxdw = {
|
vm::handler::profile_t lconstwsxdw = {
|
||||||
// CWDE
|
// CWDE
|
||||||
// SUB RBP, 4
|
// SUB RBP, 4
|
||||||
// MOV [RBP], EAX
|
// MOV [RBP], EAX
|
||||||
"LCONSTWSXDW",
|
"LCONSTWSXDW",
|
||||||
LCONSTWSXDW,
|
LCONSTWSXDW,
|
||||||
16,
|
16,
|
||||||
{ { // CWDE
|
{ { // CWDE
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool { return instr.mnemonic == ZYDIS_MNEMONIC_CWDE; },
|
[]( const zydis_decoded_instr_t &instr ) -> bool { return instr.mnemonic == ZYDIS_MNEMONIC_CWDE; },
|
||||||
// SUB RBP, 4
|
// SUB RBP, 4
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
|
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
|
||||||
instr.operands[ 1 ].imm.value.u == 0x4;
|
instr.operands[ 1 ].imm.value.u == 0x4;
|
||||||
},
|
},
|
||||||
// MOV [RBP], EAX
|
// MOV [RBP], EAX
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
|
||||||
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_EAX;
|
||||||
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_EAX;
|
} } },
|
||||||
} } },
|
vm::handler::extention_t::sign_extend };
|
||||||
vm::handler::extention_t::sign_extend };
|
} // namespace vm::handler::profile
|
||||||
} // namespace profile
|
|
||||||
} // namespace handler
|
|
||||||
} // namespace vm
|
|
@ -1,36 +1,27 @@
|
|||||||
#include <vmprofiler.hpp>
|
#include <vmprofiler.hpp>
|
||||||
|
|
||||||
namespace vm
|
namespace vm::handler::profile
|
||||||
{
|
{
|
||||||
namespace handler
|
vm::handler::profile_t lrflags = {
|
||||||
{
|
// PUSH [RBP]
|
||||||
namespace profile
|
// ADD RBP, 0x8
|
||||||
{
|
// POPFQ
|
||||||
vm::handler::profile_t lrflags = {
|
"LRFLAGS",
|
||||||
// PUSH [RBP]
|
LRFLAGS,
|
||||||
// ADD RBP, 0x8
|
NULL,
|
||||||
// POPFQ
|
{ { // PUSH [RBP]
|
||||||
"LRFLAGS",
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
LRFLAGS,
|
return instr.mnemonic == ZYDIS_MNEMONIC_PUSH && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
NULL,
|
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP;
|
||||||
{ { // PUSH [RBP]
|
},
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
// ADD RBP, 0x8
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_PUSH &&
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
return instr.mnemonic == ZYDIS_MNEMONIC_ADD &&
|
||||||
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP;
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
},
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
|
||||||
// ADD RBP, 0x8
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
instr.operands[ 1 ].imm.value.u == 0x8;
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_ADD &&
|
},
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
// POPFQ
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
|
[]( const zydis_decoded_instr_t &instr ) -> bool { return instr.mnemonic == ZYDIS_MNEMONIC_POPFQ; } } } };
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
|
} // namespace vm::handler::profile
|
||||||
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
|
|
@ -1,81 +1,73 @@
|
|||||||
#include <vmprofiler.hpp>
|
#include <vmprofiler.hpp>
|
||||||
|
|
||||||
namespace vm
|
namespace vm::handler::profile
|
||||||
{
|
{
|
||||||
namespace handler
|
vm::handler::profile_t lregq = {
|
||||||
{
|
// MOV RDX, [RAX+RDI]
|
||||||
namespace profile
|
// SUB RBP, 8
|
||||||
{
|
// MOV [RBP], RDX
|
||||||
vm::handler::profile_t lregq = {
|
"LREGQ",
|
||||||
// MOV RDX, [RAX+RDI]
|
LREGQ,
|
||||||
// SUB RBP, 8
|
8,
|
||||||
// MOV [RBP], RDX
|
{ { // MOV RDX, [RAX+RDI] or MOV RDX, [RDI+RAX]
|
||||||
"LREGQ",
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
LREGQ,
|
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
||||||
8,
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
{ { // MOV RDX, [RAX+RDI] or MOV RDX, [RDI+RAX]
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RDX &&
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
( instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RAX ||
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RDI ) &&
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RDX &&
|
( instr.operands[ 1 ].mem.index == ZYDIS_REGISTER_RDI ||
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
instr.operands[ 1 ].mem.index == ZYDIS_REGISTER_RAX );
|
||||||
( instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RAX ||
|
},
|
||||||
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RDI ) &&
|
// SUB RBP, 8
|
||||||
( instr.operands[ 1 ].mem.index == ZYDIS_REGISTER_RDI ||
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
instr.operands[ 1 ].mem.index == ZYDIS_REGISTER_RAX );
|
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
|
||||||
},
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
// SUB RBP, 8
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
|
instr.operands[ 1 ].imm.value.u == 0x8;
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
},
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
|
// MOV [RBP], RDX
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
instr.operands[ 1 ].imm.value.u == 0x8;
|
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
},
|
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
|
||||||
// MOV [RBP], RDX
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RDX;
|
||||||
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 = {
|
vm::handler::profile_t lregdw = {
|
||||||
// MOVZX AL, [RSI]
|
// MOVZX AL, [RSI]
|
||||||
// MOV RDX, [RAX + RDI]
|
// MOV RDX, [RAX + RDI]
|
||||||
// SUB RBP, 0x4
|
// SUB RBP, 0x4
|
||||||
// MOV [RBP], EDX
|
// MOV [RBP], EDX
|
||||||
"LREGDW",
|
"LREGDW",
|
||||||
LREGDW,
|
LREGDW,
|
||||||
8,
|
8,
|
||||||
{ { // MOV RDX, [RAX + RDI] or MOV RDX, [RDI + RAX]
|
{ { // MOV RDX, [RAX + RDI] or MOV RDX, [RDI + RAX]
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_EDX &&
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_EDX &&
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
( instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RAX ||
|
( instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RAX ||
|
||||||
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RDI ) &&
|
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RDI ) &&
|
||||||
( instr.operands[ 1 ].mem.index == ZYDIS_REGISTER_RAX ||
|
( instr.operands[ 1 ].mem.index == ZYDIS_REGISTER_RAX ||
|
||||||
instr.operands[ 1 ].mem.index == ZYDIS_REGISTER_RDI );
|
instr.operands[ 1 ].mem.index == ZYDIS_REGISTER_RDI );
|
||||||
},
|
},
|
||||||
// SUB RBP, 0x4
|
// SUB RBP, 0x4
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
|
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
|
||||||
instr.operands[ 1 ].imm.value.u == 0x4;
|
instr.operands[ 1 ].imm.value.u == 0x4;
|
||||||
},
|
},
|
||||||
// MOV [RBP], EDX
|
// MOV [RBP], EDX
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
|
||||||
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_EDX;
|
||||||
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_EDX;
|
} } } };
|
||||||
} } } };
|
} // namespace vm::handler::profile
|
||||||
} // namespace profile
|
|
||||||
} // namespace handler
|
|
||||||
} // namespace vm
|
|
@ -1,73 +1,61 @@
|
|||||||
#include <vmprofiler.hpp>
|
#include <vmprofiler.hpp>
|
||||||
|
|
||||||
namespace vm
|
namespace vm::handler::profile
|
||||||
{
|
{
|
||||||
namespace handler
|
vm::handler::profile_t mulq = {
|
||||||
{
|
// MOV RAX, [RBP+0x8]
|
||||||
namespace profile
|
// SUB RBP, 0x8
|
||||||
{
|
// MUL RDX
|
||||||
vm::handler::profile_t mulq = {
|
// MOV [RBP+0x8], RDX
|
||||||
// MOV RAX, [RBP+0x8]
|
// MOV [RBP+0x10], RAX
|
||||||
// SUB RBP, 0x8
|
// PUSHFQ
|
||||||
// MUL RDX
|
// POP [RBP]
|
||||||
// MOV [RBP+0x8], RDX
|
"MULQ",
|
||||||
// MOV [RBP+0x10], RAX
|
MULQ,
|
||||||
// PUSHFQ
|
NULL,
|
||||||
// POP [RBP]
|
{ { // MOV RAX, [RBP+0x8]
|
||||||
"MULQ",
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
MULQ,
|
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
||||||
NULL,
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
{ { // MOV RAX, [RBP+0x8]
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX &&
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP && instr.operands[ 1 ].mem.disp.value == 0x8;
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
},
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX &&
|
// SUB RBP, 0x8
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP &&
|
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
|
||||||
instr.operands[ 1 ].mem.disp.value == 0x8;
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
},
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
|
||||||
// SUB RBP, 0x8
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
instr.operands[ 1 ].imm.value.u == 0x8;
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
|
},
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
// MUL RDX
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
|
return instr.mnemonic == ZYDIS_MNEMONIC_MUL &&
|
||||||
instr.operands[ 1 ].imm.value.u == 0x8;
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
},
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RDX;
|
||||||
// MUL RDX
|
},
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
// MOV [RBP+0x8], RDX
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_MUL &&
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RDX;
|
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
|
||||||
},
|
instr.operands[ 0 ].mem.disp.value == 0x8 &&
|
||||||
// MOV [RBP+0x8], RDX
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RDX;
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
},
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
// MOV [RBP+0x10], RAX
|
||||||
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
instr.operands[ 0 ].mem.disp.value == 0x8 &&
|
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
|
||||||
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RDX;
|
instr.operands[ 0 ].mem.disp.value == 0x10 &&
|
||||||
},
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
// MOV [RBP+0x10], RAX
|
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RAX;
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
},
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
// PUSHFQ
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
[]( const zydis_decoded_instr_t &instr ) -> bool { return instr.mnemonic == ZYDIS_MNEMONIC_PUSHFQ; },
|
||||||
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
|
// POP [RBP]
|
||||||
instr.operands[ 0 ].mem.disp.value == 0x10 &&
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
return instr.mnemonic == ZYDIS_MNEMONIC_POP && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RAX;
|
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP;
|
||||||
},
|
} } } };
|
||||||
// PUSHFQ
|
} // namespace vm::handler::profile
|
||||||
[]( 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
|
|
@ -1,183 +1,161 @@
|
|||||||
#include <vmprofiler.hpp>
|
#include <vmprofiler.hpp>
|
||||||
|
|
||||||
namespace vm
|
namespace vm::handler::profile
|
||||||
{
|
{
|
||||||
namespace handler
|
vm::handler::profile_t nandq = {
|
||||||
{
|
// MOV RAX, [RBP]
|
||||||
namespace profile
|
// MOV RDX, [RBP+8]
|
||||||
{
|
// NOT RAX
|
||||||
vm::handler::profile_t nandq = {
|
// NOT RDX
|
||||||
// MOV RAX, [RBP]
|
// AND RAX, RDX
|
||||||
// MOV RDX, [RBP+8]
|
// MOV [RBP], RAX
|
||||||
// NOT RAX
|
// PUSHFQ
|
||||||
// NOT RDX
|
// POP [RBP]
|
||||||
// AND RAX, RDX
|
"NANDQ",
|
||||||
// MOV [RBP], RAX
|
NANDQ,
|
||||||
// PUSHFQ
|
NULL,
|
||||||
// POP [RBP]
|
{ { // MOV RAX, [RBP]
|
||||||
"NANDQ",
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
NANDQ,
|
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
||||||
NULL,
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
{ { // MOV RAX, [RBP]
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX &&
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
},
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX &&
|
// MOV RDX, [RBP+8]
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
|
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
||||||
},
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
// MOV RDX, [RBP+8]
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RDX &&
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP && instr.operands[ 1 ].mem.disp.value == 0x8;
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
},
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RDX &&
|
// NOT RAX
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP &&
|
return instr.mnemonic == ZYDIS_MNEMONIC_NOT &&
|
||||||
instr.operands[ 1 ].mem.disp.value == 0x8;
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
},
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX;
|
||||||
// NOT RAX
|
},
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
// NOT RDX
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_NOT &&
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
return instr.mnemonic == ZYDIS_MNEMONIC_NOT &&
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX;
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
},
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RDX;
|
||||||
// NOT RDX
|
},
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
// AND RAX, RDX
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_NOT &&
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
return instr.mnemonic == ZYDIS_MNEMONIC_AND &&
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RDX;
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
},
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX &&
|
||||||
// AND RAX, RDX
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RDX;
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_AND &&
|
},
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
// MOV [RBP], RAX
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX &&
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RDX;
|
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
|
||||||
},
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
// MOV [RBP], RAX
|
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RAX;
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
},
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
// PUSHFQ
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
[]( const zydis_decoded_instr_t &instr ) -> bool { return instr.mnemonic == ZYDIS_MNEMONIC_PUSHFQ; },
|
||||||
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
|
// POP [RBP]
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RAX;
|
return instr.mnemonic == ZYDIS_MNEMONIC_POP && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
},
|
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP;
|
||||||
// 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 = {
|
vm::handler::profile_t nanddw = {
|
||||||
// NOT QWORD PTR [RBP]
|
// NOT QWORD PTR [RBP]
|
||||||
// MOV EAX, [RBP]
|
// MOV EAX, [RBP]
|
||||||
// SUB RBP, 0x4
|
// SUB RBP, 0x4
|
||||||
// AND [RBP+0x8], EAX
|
// AND [RBP+0x8], EAX
|
||||||
// PUSHFQ
|
// PUSHFQ
|
||||||
// POP [RBP]
|
// POP [RBP]
|
||||||
"NANDDW",
|
"NANDDW",
|
||||||
NANDDW,
|
NANDDW,
|
||||||
NULL,
|
NULL,
|
||||||
{ { // NOT QWORD PTR [RBP]
|
{ { // NOT QWORD PTR [RBP]
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_NOT &&
|
return instr.mnemonic == ZYDIS_MNEMONIC_NOT && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
instr.operands[ 0 ].size == 64 && instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP;
|
||||||
instr.operands[ 0 ].size == 64 && instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP;
|
},
|
||||||
},
|
// MOV EAX, [RBP]
|
||||||
// MOV EAX, [RBP]
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_EAX &&
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_EAX &&
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
|
||||||
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
|
},
|
||||||
},
|
// SUB RBP, 0x4
|
||||||
// SUB RBP, 0x4
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
|
instr.operands[ 1 ].imm.value.u == 0x4;
|
||||||
instr.operands[ 1 ].imm.value.u == 0x4;
|
},
|
||||||
},
|
// AND [RBP+0x8], EAX
|
||||||
// AND [RBP+0x8], EAX
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
return instr.mnemonic == ZYDIS_MNEMONIC_AND && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_AND &&
|
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
instr.operands[ 0 ].mem.disp.value == 0x8 &&
|
||||||
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
instr.operands[ 0 ].mem.disp.value == 0x8 &&
|
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_EAX;
|
||||||
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; },
|
||||||
// PUSHFQ
|
// POP [RBP]
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_PUSHFQ;
|
return instr.mnemonic == ZYDIS_MNEMONIC_POP && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
},
|
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP;
|
||||||
// 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 = {
|
vm::handler::profile_t nandw = {
|
||||||
// NOT DWORD PTR [RBP]
|
// NOT DWORD PTR [RBP]
|
||||||
// MOV AX, [RBP]
|
// MOV AX, [RBP]
|
||||||
// SUB RBP, 0x6
|
// SUB RBP, 0x6
|
||||||
// AND [RBP+0x8], AX
|
// AND [RBP+0x8], AX
|
||||||
// PUSHFQ
|
// PUSHFQ
|
||||||
// POP [RBP]
|
// POP [RBP]
|
||||||
"NANDW",
|
"NANDW",
|
||||||
NANDW,
|
NANDW,
|
||||||
NULL,
|
NULL,
|
||||||
{ { // NOT DWORD PTR [RBP]
|
{ { // NOT DWORD PTR [RBP]
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_NOT &&
|
return instr.mnemonic == ZYDIS_MNEMONIC_NOT && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
instr.operands[ 0 ].size == 32 && instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP;
|
||||||
instr.operands[ 0 ].size == 32 &&
|
},
|
||||||
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP;
|
// MOV AX, [RBP]
|
||||||
},
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
// MOV AX, [RBP]
|
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_AX &&
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_AX &&
|
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
|
||||||
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 {
|
||||||
// SUB RBP, 0x6
|
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
|
instr.operands[ 1 ].imm.value.u == 0x6;
|
||||||
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 {
|
||||||
// AND [RBP+0x8], AX
|
return instr.mnemonic == ZYDIS_MNEMONIC_AND && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_AND &&
|
instr.operands[ 0 ].mem.disp.value == 0x8 &&
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
|
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_AX;
|
||||||
instr.operands[ 0 ].mem.disp.value == 0x8 &&
|
},
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
// PUSHFQ
|
||||||
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_AX;
|
[]( const zydis_decoded_instr_t &instr ) -> bool { return instr.mnemonic == ZYDIS_MNEMONIC_PUSHFQ; },
|
||||||
},
|
// POP [RBP]
|
||||||
// PUSHFQ
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
return instr.mnemonic == ZYDIS_MNEMONIC_POP && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_PUSHFQ;
|
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP;
|
||||||
},
|
} } } };
|
||||||
// POP [RBP]
|
} // namespace vm::handler::profile
|
||||||
[]( 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
|
|
@ -1,41 +1,34 @@
|
|||||||
#include <vmprofiler.hpp>
|
#include <vmprofiler.hpp>
|
||||||
|
|
||||||
namespace vm
|
namespace vm::handler::profile
|
||||||
{
|
{
|
||||||
namespace handler
|
vm::handler::profile_t pushvsp = {
|
||||||
{
|
// MOV RAX, RBP
|
||||||
namespace profile
|
// SUB RBP, 8
|
||||||
{
|
"PUSHVSP",
|
||||||
vm::handler::profile_t pushvsp = {
|
PUSHVSP,
|
||||||
// MOV RAX, RBP
|
NULL,
|
||||||
// SUB RBP, 8
|
{ { // MOV RAX, RBP
|
||||||
"PUSHVSP",
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
PUSHVSP,
|
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
||||||
NULL,
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
{ { // MOV RAX, RBP
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX &&
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RBP;
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
},
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX &&
|
// SUB RBP, 8
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RBP;
|
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
|
||||||
},
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
// SUB RBP, 8
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
|
instr.operands[ 1 ].imm.value.u == 0x8;
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
},
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
|
// MOV [RBP], RAX
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
instr.operands[ 1 ].imm.value.u == 0x8;
|
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
},
|
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
|
||||||
// MOV [RBP], RAX
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RAX;
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
} } } };
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
} // namespace vm::handler::profile
|
||||||
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
|
|
@ -1,66 +1,57 @@
|
|||||||
#include <vmprofiler.hpp>
|
#include <vmprofiler.hpp>
|
||||||
|
|
||||||
namespace vm
|
namespace vm::handler::profile
|
||||||
{
|
{
|
||||||
namespace handler
|
vm::handler::profile_t readq = {
|
||||||
{
|
// MOV RAX, [RAX]
|
||||||
namespace profile
|
// MOV [RBP], RAX
|
||||||
{
|
"READQ",
|
||||||
vm::handler::profile_t readq = {
|
READQ,
|
||||||
// MOV RAX, [RAX]
|
NULL,
|
||||||
// MOV [RBP], RAX
|
{ { // MOV RAX, [RAX]
|
||||||
"READQ",
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
READQ,
|
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
||||||
NULL,
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
{ {
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX &&
|
||||||
// MOV RAX, [RAX]
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RAX;
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
},
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
// MOV [RBP], RAX
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX &&
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RAX;
|
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
|
||||||
},
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
// MOV [RBP], RAX
|
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_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 = {
|
vm::handler::profile_t readdw = {
|
||||||
// ADD RBP, 0x4
|
// ADD RBP, 0x4
|
||||||
// MOV EAX, [RAX]
|
// MOV EAX, [RAX]
|
||||||
// MOV [RBP], EAX
|
// MOV [RBP], EAX
|
||||||
"READDW",
|
"READDW",
|
||||||
READDW,
|
READDW,
|
||||||
NULL,
|
NULL,
|
||||||
{ { // ADD RBP, 0x4
|
{ { // ADD RBP, 0x4
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_ADD &&
|
return instr.mnemonic == ZYDIS_MNEMONIC_ADD &&
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
|
||||||
instr.operands[ 1 ].imm.value.u == 0x4;
|
instr.operands[ 1 ].imm.value.u == 0x4;
|
||||||
},
|
},
|
||||||
// MOV EAX, [RAX]
|
// MOV EAX, [RAX]
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_EAX &&
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_EAX &&
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RAX;
|
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RAX;
|
||||||
},
|
},
|
||||||
// MOV [RBP], EAX
|
// MOV [RBP], EAX
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
|
||||||
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_EAX;
|
||||||
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_EAX;
|
} } } };
|
||||||
} } } };
|
} // namespace vm::handler::profile
|
||||||
}
|
|
||||||
} // namespace handler
|
|
||||||
} // namespace vm
|
|
@ -1,138 +1,122 @@
|
|||||||
#include <vmprofiler.hpp>
|
#include <vmprofiler.hpp>
|
||||||
|
|
||||||
namespace vm
|
namespace vm::handler::profile
|
||||||
{
|
{
|
||||||
namespace handler
|
vm::handler::profile_t shlq = {
|
||||||
{
|
// MOV RAX, [RBP]
|
||||||
namespace profile
|
// MOV CL, [RBP+0x8]
|
||||||
{
|
// SUB RBP, 0x6
|
||||||
vm::handler::profile_t shlq = {
|
// SHL RAX, CL
|
||||||
// MOV RAX, [RBP]
|
// MOV [RBP+0x8], RAX
|
||||||
// MOV CL, [RBP+0x8]
|
// PUSHFQ
|
||||||
// SUB RBP, 0x6
|
// POP [RBP]
|
||||||
// SHL RAX, CL
|
"SHLQ",
|
||||||
// MOV [RBP+0x8], RAX
|
SHLQ,
|
||||||
// PUSHFQ
|
NULL,
|
||||||
// POP [RBP]
|
{ { // MOV RAX, [RBP]
|
||||||
"SHLQ",
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
SHLQ,
|
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
||||||
NULL,
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
{ { // MOV RAX, [RBP]
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX &&
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
},
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX &&
|
// MOV CL, [RBP+0x8]
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
|
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
||||||
},
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
// MOV CL, [RBP+0x8]
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_CL &&
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP && instr.operands[ 1 ].mem.disp.value == 0x8;
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
},
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_CL &&
|
// SUB RBP, 0x6
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP &&
|
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
|
||||||
instr.operands[ 1 ].mem.disp.value == 0x8;
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
},
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
|
||||||
// SUB RBP, 0x6
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
instr.operands[ 1 ].imm.value.u == 0x6;
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
|
},
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
// SHL RAX, CL
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
|
return instr.mnemonic == ZYDIS_MNEMONIC_SHL &&
|
||||||
instr.operands[ 1 ].imm.value.u == 0x6;
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
},
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX &&
|
||||||
// SHL RAX, CL
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_CL;
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_SHL &&
|
},
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
// MOV [RBP+0x8], RAX
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX &&
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_CL;
|
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
|
||||||
},
|
instr.operands[ 0 ].mem.disp.value == 0x8 &&
|
||||||
// MOV [RBP+0x8], RAX
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RAX;
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
},
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
// PUSHFQ
|
||||||
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
|
[]( const zydis_decoded_instr_t &instr ) -> bool { return instr.mnemonic == ZYDIS_MNEMONIC_PUSHFQ; },
|
||||||
instr.operands[ 0 ].mem.disp.value == 0x8 &&
|
// POP [RBP]
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RAX;
|
return instr.mnemonic == ZYDIS_MNEMONIC_POP && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
},
|
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP;
|
||||||
// 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 = {
|
vm::handler::profile_t shldw = {
|
||||||
// MOV EAX, [RBP]
|
// MOV EAX, [RBP]
|
||||||
// MOV CL, [RBP+0x4]
|
// MOV CL, [RBP+0x4]
|
||||||
// SUB RBP, 0x6
|
// SUB RBP, 0x6
|
||||||
// SHL EAX, CL
|
// SHL EAX, CL
|
||||||
// MOV [RBP+0x8], EAX
|
// MOV [RBP+0x8], EAX
|
||||||
// PUSHFQ
|
// PUSHFQ
|
||||||
// POP [RBP]
|
// POP [RBP]
|
||||||
"SHLQ",
|
"SHLQ",
|
||||||
SHLQ,
|
SHLQ,
|
||||||
NULL,
|
NULL,
|
||||||
{ { // MOV EAX, [RBP]
|
{ { // MOV EAX, [RBP]
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_EAX &&
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_EAX &&
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
|
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
|
||||||
},
|
},
|
||||||
// MOV CL, [RBP+0x4]
|
// MOV CL, [RBP+0x4]
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_CL &&
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_CL &&
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP &&
|
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP && instr.operands[ 1 ].mem.disp.value == 0x4;
|
||||||
instr.operands[ 1 ].mem.disp.value == 0x4;
|
},
|
||||||
},
|
// SUB RBP, 0x6
|
||||||
// SUB RBP, 0x6
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
|
instr.operands[ 1 ].imm.value.u == 0x6;
|
||||||
instr.operands[ 1 ].imm.value.u == 0x6;
|
},
|
||||||
},
|
// SHL EAX, CL
|
||||||
// SHL EAX, CL
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
return instr.mnemonic == ZYDIS_MNEMONIC_SHL &&
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_SHL &&
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_EAX &&
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_EAX &&
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_CL;
|
||||||
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_CL;
|
},
|
||||||
},
|
// MOV [RBP+0x8], EAX
|
||||||
// MOV [RBP+0x8], EAX
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
instr.operands[ 0 ].mem.disp.value == 0x8 &&
|
||||||
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
instr.operands[ 0 ].mem.disp.value == 0x8 &&
|
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_EAX;
|
||||||
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; },
|
||||||
// PUSHFQ
|
// POP [RBP]
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_PUSHFQ;
|
return instr.mnemonic == ZYDIS_MNEMONIC_POP && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
},
|
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP;
|
||||||
// POP [RBP]
|
} } } };
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
} // namespace vm::handler::profile
|
||||||
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
|
|
@ -1,138 +1,122 @@
|
|||||||
#include <vmprofiler.hpp>
|
#include <vmprofiler.hpp>
|
||||||
|
|
||||||
namespace vm
|
namespace vm::handler::profile
|
||||||
{
|
{
|
||||||
namespace handler
|
vm::handler::profile_t shrq = {
|
||||||
{
|
// MOV RAX, [RBP]
|
||||||
namespace profile
|
// MOV CL, [RBP+0x8]
|
||||||
{
|
// SUB RBP, 0x6
|
||||||
vm::handler::profile_t shrq = {
|
// SHR RAX, CL
|
||||||
// MOV RAX, [RBP]
|
// MOV [RBP+0x8], RAX
|
||||||
// MOV CL, [RBP+0x8]
|
// PUSHFQ
|
||||||
// SUB RBP, 0x6
|
// POP [RBP]
|
||||||
// SHR RAX, CL
|
"SHRQ",
|
||||||
// MOV [RBP+0x8], RAX
|
SHRQ,
|
||||||
// PUSHFQ
|
NULL,
|
||||||
// POP [RBP]
|
{ { // MOV RAX, [RBP]
|
||||||
"SHRQ",
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
SHRQ,
|
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
||||||
NULL,
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
{ { // MOV RAX, [RBP]
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX &&
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
},
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX &&
|
// MOV CL, [RBP+0x8]
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
|
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
||||||
},
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
// MOV CL, [RBP+0x8]
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_CL &&
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP && instr.operands[ 1 ].mem.disp.value == 0x8;
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
},
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_CL &&
|
// SUB RBP, 0x6
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP &&
|
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
|
||||||
instr.operands[ 1 ].mem.disp.value == 0x8;
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
},
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
|
||||||
// SUB RBP, 0x6
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
instr.operands[ 1 ].imm.value.u == 0x6;
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
|
},
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
// SHR RAX, CL
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
|
return instr.mnemonic == ZYDIS_MNEMONIC_SHR &&
|
||||||
instr.operands[ 1 ].imm.value.u == 0x6;
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
},
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX &&
|
||||||
// SHR RAX, CL
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_CL;
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_SHR &&
|
},
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
// MOV [RBP+0x8], RAX
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX &&
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_CL;
|
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
|
||||||
},
|
instr.operands[ 0 ].mem.disp.value == 0x8 &&
|
||||||
// MOV [RBP+0x8], RAX
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RAX;
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
},
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
// PUSHFQ
|
||||||
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
|
[]( const zydis_decoded_instr_t &instr ) -> bool { return instr.mnemonic == ZYDIS_MNEMONIC_PUSHFQ; },
|
||||||
instr.operands[ 0 ].mem.disp.value == 0x8 &&
|
// POP [RBP]
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RAX;
|
return instr.mnemonic == ZYDIS_MNEMONIC_POP && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
},
|
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP;
|
||||||
// PUSHFQ
|
} } } };
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_PUSHFQ;
|
vm::handler::profile_t shrw = {
|
||||||
},
|
// MOV AX, [RBP]
|
||||||
// POP [RBP]
|
// MOV CL, [RBP+0x2]
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
// SUB RBP, 0x6
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_POP &&
|
// SHR AX, CL
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
// MOV [RBP+0x8], AX
|
||||||
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP;
|
// PUSHFQ
|
||||||
} } } };
|
// POP [RBP]
|
||||||
|
"SHRW",
|
||||||
vm::handler::profile_t shrw = {
|
SHRW,
|
||||||
// MOV AX, [RBP]
|
NULL,
|
||||||
// MOV CL, [RBP+0x2]
|
{ { // MOV AX, [RBP]
|
||||||
// SUB RBP, 0x6
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
// SHR AX, CL
|
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
||||||
// MOV [RBP+0x8], AX
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
// PUSHFQ
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_AX &&
|
||||||
// POP [RBP]
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
"SHRW",
|
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
|
||||||
SHRW,
|
},
|
||||||
NULL,
|
// MOV CL, [RBP+0x2]
|
||||||
{ { // MOV AX, [RBP]
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_CL &&
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_AX &&
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP && instr.operands[ 1 ].mem.disp.value == 0x2;
|
||||||
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
|
},
|
||||||
},
|
// SUB RBP, 0x6
|
||||||
// MOV CL, [RBP+0x2]
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_CL &&
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
instr.operands[ 1 ].imm.value.u == 0x6;
|
||||||
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP &&
|
},
|
||||||
instr.operands[ 1 ].mem.disp.value == 0x2;
|
// SHR AX, CL
|
||||||
},
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
// SUB RBP, 0x6
|
return instr.mnemonic == ZYDIS_MNEMONIC_SHR &&
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_SUB &&
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_AX &&
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
|
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_CL;
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
|
},
|
||||||
instr.operands[ 1 ].imm.value.u == 0x6;
|
// MOV [RBP+0x8], AX
|
||||||
},
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
// SHR AX, CL
|
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_SHR &&
|
instr.operands[ 0 ].mem.disp.value == 0x8 &&
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_AX &&
|
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_AX;
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
},
|
||||||
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_CL;
|
// PUSHFQ
|
||||||
},
|
[]( const zydis_decoded_instr_t &instr ) -> bool { return instr.mnemonic == ZYDIS_MNEMONIC_PUSHFQ; },
|
||||||
// MOV [RBP+0x8], AX
|
// POP [RBP]
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
return instr.mnemonic == ZYDIS_MNEMONIC_POP && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP;
|
||||||
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP &&
|
} } } };
|
||||||
instr.operands[ 0 ].mem.disp.value == 0x8 &&
|
} // namespace vm::handler::profile
|
||||||
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
|
|
@ -1,115 +1,105 @@
|
|||||||
#include <vmprofiler.hpp>
|
#include <vmprofiler.hpp>
|
||||||
|
|
||||||
namespace vm
|
namespace vm::handler::profile
|
||||||
{
|
{
|
||||||
namespace handler
|
vm::handler::profile_t sregq = {
|
||||||
{
|
// MOV RDX, [RBP]
|
||||||
namespace profile
|
// ADD RBP, 8
|
||||||
{
|
// MOV [RAX+RDI], RDX
|
||||||
vm::handler::profile_t sregq = {
|
"SREGQ",
|
||||||
// MOV RDX, [RBP]
|
SREGQ,
|
||||||
// ADD RBP, 8
|
8,
|
||||||
// MOV [RAX+RDI], RDX
|
{ { // MOV RDX, [RBP]
|
||||||
"SREGQ",
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
SREGQ,
|
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
||||||
8,
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
{ { // MOV RDX, [RBP]
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RDX &&
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
},
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RDX &&
|
// ADD RBP, 8
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
|
return instr.mnemonic == ZYDIS_MNEMONIC_ADD &&
|
||||||
},
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
// ADD RBP, 8
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE && instr.operands[ 1 ].imm.value.u == 8;
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_ADD &&
|
},
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
// MOV [RAX+RDI], RDX or MOV [RDI+RAX], RDX
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
|
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
instr.operands[ 1 ].imm.value.u == 8;
|
( instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RAX ||
|
||||||
},
|
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RDI ) &&
|
||||||
// MOV [RAX+RDI], RDX or MOV [RDI+RAX], RDX
|
( instr.operands[ 0 ].mem.index == ZYDIS_REGISTER_RDI ||
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
instr.operands[ 0 ].mem.index == ZYDIS_REGISTER_RAX ) &&
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RDX;
|
||||||
( 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 = {
|
vm::handler::profile_t sregdw = {
|
||||||
// MOV EDX, [RBP]
|
// MOV EDX, [RBP]
|
||||||
// ADD RBP, 0x4
|
// ADD RBP, 0x4
|
||||||
// MOV [RAX+RDI], EDX
|
// MOV [RAX+RDI], EDX
|
||||||
"SREGDW",
|
"SREGDW",
|
||||||
SREGDW,
|
SREGDW,
|
||||||
8,
|
8,
|
||||||
{ { // MOV EDX, [RBP]
|
{ { // MOV EDX, [RBP]
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_EDX &&
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_EDX &&
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
|
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
|
||||||
},
|
},
|
||||||
// ADD RBP, 0x4
|
// ADD RBP, 0x4
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_ADD &&
|
return instr.mnemonic == ZYDIS_MNEMONIC_ADD &&
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
|
||||||
instr.operands[ 1 ].imm.value.u == 0x4;
|
instr.operands[ 1 ].imm.value.u == 0x4;
|
||||||
},
|
},
|
||||||
// MOV [RAX+RDI], EDX or MOV [RDI+RAX], EDX
|
// MOV [RAX+RDI], EDX or MOV [RDI+RAX], EDX
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
( instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RAX ||
|
||||||
( instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RAX ||
|
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RDI ) &&
|
||||||
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RDI ) &&
|
( instr.operands[ 0 ].mem.index == ZYDIS_REGISTER_RAX ||
|
||||||
( instr.operands[ 0 ].mem.index == ZYDIS_REGISTER_RAX ||
|
instr.operands[ 0 ].mem.index == ZYDIS_REGISTER_RDI ) &&
|
||||||
instr.operands[ 0 ].mem.index == ZYDIS_REGISTER_RDI ) &&
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_EDX;
|
||||||
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_EDX;
|
} } } };
|
||||||
} } } };
|
|
||||||
|
|
||||||
vm::handler::profile_t sregw = {
|
vm::handler::profile_t sregw = {
|
||||||
// MOV DX, [RBP]
|
// MOV DX, [RBP]
|
||||||
// ADD RBP, 0x2
|
// ADD RBP, 0x2
|
||||||
// MOV [RAX+RDI], DX
|
// MOV [RAX+RDI], DX
|
||||||
"SREGW",
|
"SREGW",
|
||||||
SREGW,
|
SREGW,
|
||||||
8,
|
8,
|
||||||
{ { // MOV DX, [RBP]
|
{ { // MOV DX, [RBP]
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_DX &&
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_DX &&
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
|
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
|
||||||
},
|
},
|
||||||
// ADD RBP, 0x2
|
// ADD RBP, 0x2
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_ADD &&
|
return instr.mnemonic == ZYDIS_MNEMONIC_ADD &&
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
|
||||||
instr.operands[ 1 ].imm.value.u == 0x2;
|
instr.operands[ 1 ].imm.value.u == 0x2;
|
||||||
},
|
},
|
||||||
// MOV [RAX+RDI], DX or MOV [RDI+RAX], DX
|
// MOV [RAX+RDI], DX or MOV [RDI+RAX], DX
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
( instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RAX ||
|
||||||
( instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RAX ||
|
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RDI ) &&
|
||||||
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RDI ) &&
|
( instr.operands[ 0 ].mem.index == ZYDIS_REGISTER_RDI ||
|
||||||
( instr.operands[ 0 ].mem.index == ZYDIS_REGISTER_RDI ||
|
instr.operands[ 0 ].mem.index == ZYDIS_REGISTER_RAX ) &&
|
||||||
instr.operands[ 0 ].mem.index == ZYDIS_REGISTER_RAX ) &&
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_DX;
|
||||||
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_DX;
|
} } } };
|
||||||
} } } };
|
} // namespace vm::handler::profile
|
||||||
} // namespace profile
|
|
||||||
} // namespace handler
|
|
||||||
} // namespace vm
|
|
@ -1,29 +1,21 @@
|
|||||||
#include <vmprofiler.hpp>
|
#include <vmprofiler.hpp>
|
||||||
|
|
||||||
namespace vm
|
namespace vm::handler::profile
|
||||||
{
|
{
|
||||||
namespace handler
|
vm::handler::profile_t vmexit = {
|
||||||
{
|
// MOV RSP, RBP
|
||||||
namespace profile
|
// RET
|
||||||
{
|
"VMEXIT",
|
||||||
vm::handler::profile_t vmexit = {
|
VMEXIT,
|
||||||
// MOV RSP, RBP
|
NULL,
|
||||||
// RET
|
{ { // MOV RSP, RBP
|
||||||
"VMEXIT",
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
VMEXIT,
|
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
||||||
NULL,
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
{ { // MOV RSP, RBP
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RSP &&
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RBP;
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
},
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RSP &&
|
// RET
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
[]( const zydis_decoded_instr_t &instr ) -> bool { return instr.mnemonic == ZYDIS_MNEMONIC_RET; } } } };
|
||||||
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RBP;
|
} // namespace vm::handler::profile
|
||||||
},
|
|
||||||
// RET
|
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_RET;
|
|
||||||
} } } };
|
|
||||||
}
|
|
||||||
} // namespace handler
|
|
||||||
} // namespace vm
|
|
@ -1,136 +1,124 @@
|
|||||||
#include <vmprofiler.hpp>
|
#include <vmprofiler.hpp>
|
||||||
|
|
||||||
namespace vm
|
namespace vm::handler::profile
|
||||||
{
|
{
|
||||||
namespace handler
|
vm::handler::profile_t writeq = {
|
||||||
{
|
// MOV RAX, [RBP]
|
||||||
namespace profile
|
// MOV RDX, [RBP+0x8]
|
||||||
{
|
// ADD RBP, 0x10
|
||||||
vm::handler::profile_t writeq = {
|
// MOV [RAX], RDX
|
||||||
// MOV RAX, [RBP]
|
"WRITEQ",
|
||||||
// MOV RDX, [RBP+0x8]
|
WRITEQ,
|
||||||
// ADD RBP, 0x10
|
NULL,
|
||||||
// MOV [RAX], RDX
|
{ { // MOV RAX, [RBP]
|
||||||
"WRITEQ",
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
WRITEQ,
|
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
||||||
NULL,
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
{ { // MOV RAX, [RBP]
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX &&
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
},
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX &&
|
// MOV RDX, [RBP+0x8]
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
|
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
||||||
},
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
// MOV RDX, [RBP+0x8]
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RDX &&
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP && instr.operands[ 1 ].mem.disp.value == 0x8;
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
},
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RDX &&
|
// ADD RBP, 0x10
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP &&
|
return instr.mnemonic == ZYDIS_MNEMONIC_ADD &&
|
||||||
instr.operands[ 1 ].mem.disp.value == 0x8;
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
},
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
|
||||||
// ADD RBP, 0x10
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
instr.operands[ 1 ].imm.value.u == 0x10;
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_ADD &&
|
},
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
// MOV [RAX], RDX
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
|
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
instr.operands[ 1 ].imm.value.u == 0x10;
|
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RAX &&
|
||||||
},
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
// MOV [RAX], RDX
|
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_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 = {
|
vm::handler::profile_t writedw = {
|
||||||
// MOV RAX, [RBP]
|
// MOV RAX, [RBP]
|
||||||
// MOV EDX, [RBP+0x8]
|
// MOV EDX, [RBP+0x8]
|
||||||
// ADD RBP, 0xC
|
// ADD RBP, 0xC
|
||||||
// MOV [RAX], EDX
|
// MOV [RAX], EDX
|
||||||
"WRITEDW",
|
"WRITEDW",
|
||||||
WRITEDW,
|
WRITEDW,
|
||||||
NULL,
|
NULL,
|
||||||
{ { // MOV RAX, [RBP]
|
{ { // MOV RAX, [RBP]
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX &&
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX &&
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
|
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
|
||||||
},
|
},
|
||||||
// MOV EDX, [RBP+0x8]
|
// MOV EDX, [RBP+0x8]
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_EDX &&
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_EDX &&
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP &&
|
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP && instr.operands[ 1 ].mem.disp.value == 0x8;
|
||||||
instr.operands[ 1 ].mem.disp.value == 0x8;
|
},
|
||||||
},
|
// ADD RBP, 0xC
|
||||||
// ADD RBP, 0xC
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
return instr.mnemonic == ZYDIS_MNEMONIC_ADD &&
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_ADD &&
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
|
instr.operands[ 1 ].imm.value.u == 0xC;
|
||||||
instr.operands[ 1 ].imm.value.u == 0xC;
|
},
|
||||||
},
|
// MOV [RAX], EDX
|
||||||
// MOV [RAX], EDX
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RAX &&
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RAX &&
|
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_EDX;
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
} } } };
|
||||||
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_EDX;
|
|
||||||
} } } };
|
|
||||||
|
|
||||||
vm::handler::profile_t writeb = {
|
vm::handler::profile_t writeb = {
|
||||||
// MOV RAX, [RBP]
|
// MOV RAX, [RBP]
|
||||||
// MOV DL, [RBP+0x8]
|
// MOV DL, [RBP+0x8]
|
||||||
// ADD RBP, 0xA
|
// ADD RBP, 0xA
|
||||||
// MOV [RAX], DL
|
// MOV [RAX], DL
|
||||||
"WRITEB",
|
"WRITEB",
|
||||||
WRITEB,
|
WRITEB,
|
||||||
NULL,
|
NULL,
|
||||||
{ { // MOV RAX, [RBP]
|
{ { // MOV RAX, [RBP]
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX &&
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX &&
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
|
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP;
|
||||||
},
|
},
|
||||||
// MOV DL, [RBP+0x8]
|
// MOV DL, [RBP+0x8]
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_DL &&
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_DL &&
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP &&
|
instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP && instr.operands[ 1 ].mem.disp.value == 0x8;
|
||||||
instr.operands[ 1 ].mem.disp.value == 0x8;
|
},
|
||||||
},
|
// ADD RBP, 0xA
|
||||||
// ADD RBP, 0xA
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
return instr.mnemonic == ZYDIS_MNEMONIC_ADD &&
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_ADD &&
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
|
||||||
instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP &&
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
|
instr.operands[ 1 ].imm.value.u == 0xA;
|
||||||
instr.operands[ 1 ].imm.value.u == 0xA;
|
},
|
||||||
},
|
// MOV [RAX], DL
|
||||||
// MOV [RAX], DL
|
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
||||||
[]( const zydis_decoded_instr_t &instr ) -> bool {
|
return instr.mnemonic == ZYDIS_MNEMONIC_MOV && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||||
return instr.mnemonic == ZYDIS_MNEMONIC_MOV &&
|
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RAX &&
|
||||||
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
||||||
instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RAX &&
|
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_DL;
|
||||||
instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
} } } };
|
||||||
instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_DL;
|
} // namespace vm::handler::profile
|
||||||
} } } };
|
|
||||||
} // namespace profile
|
|
||||||
} // namespace handler
|
|
||||||
} // namespace vm
|
|
Loading…
Reference in new issue