|
|
@ -19,14 +19,14 @@ namespace vm
|
|
|
|
return false;
|
|
|
|
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 {
|
|
|
|
auto result = std::find_if( vm_handler.begin(), vm_handler.end(), []( const zydis_instr_t &instr ) -> bool {
|
|
|
|
if ( instr.instr.mnemonic == ZYDIS_MNEMONIC_LEA &&
|
|
|
|
return instr.instr.mnemonic == ZYDIS_MNEMONIC_LEA &&
|
|
|
|
instr.instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX &&
|
|
|
|
instr.instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX &&
|
|
|
|
instr.instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RDI &&
|
|
|
|
instr.instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RDI &&
|
|
|
|
instr.instr.operands[ 1 ].mem.disp.value == 0xE0 )
|
|
|
|
instr.instr.operands[ 1 ].mem.disp.value == 0xE0
|
|
|
|
return true;
|
|
|
|
? true
|
|
|
|
|
|
|
|
: calc_jmp_check( instr.addr );
|
|
|
|
return calc_jmp_check( instr.addr );
|
|
|
|
|
|
|
|
} );
|
|
|
|
} );
|
|
|
|
|
|
|
|
|
|
|
|
// remove calc_jmp from the vm handler vector...
|
|
|
|
// remove calc_jmp from the vm handler vector...
|
|
|
@ -42,16 +42,14 @@ namespace vm
|
|
|
|
{
|
|
|
|
{
|
|
|
|
result = std::find_if( ++result, vm_handler.end(), []( const zydis_instr_t &instr_data ) -> bool {
|
|
|
|
result = std::find_if( ++result, vm_handler.end(), []( const zydis_instr_t &instr_data ) -> bool {
|
|
|
|
// mov/movsx/movzx rax/eax/ax/al, [rsi]
|
|
|
|
// mov/movsx/movzx rax/eax/ax/al, [rsi]
|
|
|
|
if ( instr_data.instr.operand_count > 1 &&
|
|
|
|
return instr_data.instr.operand_count > 1 &&
|
|
|
|
( instr_data.instr.mnemonic == ZYDIS_MNEMONIC_MOV ||
|
|
|
|
( instr_data.instr.mnemonic == ZYDIS_MNEMONIC_MOV ||
|
|
|
|
instr_data.instr.mnemonic == ZYDIS_MNEMONIC_MOVSX ||
|
|
|
|
instr_data.instr.mnemonic == ZYDIS_MNEMONIC_MOVSX ||
|
|
|
|
instr_data.instr.mnemonic == ZYDIS_MNEMONIC_MOVZX ) &&
|
|
|
|
instr_data.instr.mnemonic == ZYDIS_MNEMONIC_MOVZX ) &&
|
|
|
|
instr_data.instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
|
|
|
instr_data.instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
|
|
|
util::reg::to64( instr_data.instr.operands[ 0 ].reg.value ) == ZYDIS_REGISTER_RAX &&
|
|
|
|
util::reg::to64( instr_data.instr.operands[ 0 ].reg.value ) == ZYDIS_REGISTER_RAX &&
|
|
|
|
instr_data.instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
|
|
|
instr_data.instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
|
|
|
instr_data.instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RSI )
|
|
|
|
instr_data.instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RSI;
|
|
|
|
return true;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
} );
|
|
|
|
} );
|
|
|
|
|
|
|
|
|
|
|
|
if ( result != vm_handler.end() )
|
|
|
|
if ( result != vm_handler.end() )
|
|
|
@ -77,17 +75,15 @@ namespace vm
|
|
|
|
|
|
|
|
|
|
|
|
for ( auto idx = 0u; idx < 256; ++idx )
|
|
|
|
for ( auto idx = 0u; idx < 256; ++idx )
|
|
|
|
{
|
|
|
|
{
|
|
|
|
const auto decrypt_val = vm::handler::table::decrypt( instr, vm_handler_table[ idx ] );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
handler_t vm_handler;
|
|
|
|
handler_t vm_handler;
|
|
|
|
vm::transform::map_t transforms;
|
|
|
|
vm::transform::map_t transforms;
|
|
|
|
zydis_routine_t vm_handler_instrs;
|
|
|
|
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 ) )
|
|
|
|
if ( !vm::handler::get( calc_jmp, vm_handler_instrs, ( decrypt_val - image_base ) + module_base ) )
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
|
|
const auto has_imm = vm::handler::has_imm( vm_handler_instrs );
|
|
|
|
const auto has_imm = vm::handler::has_imm( vm_handler_instrs );
|
|
|
|
|
|
|
|
|
|
|
|
const auto imm_size = vm::handler::imm_size( vm_handler_instrs );
|
|
|
|
const auto imm_size = vm::handler::imm_size( vm_handler_instrs );
|
|
|
|
|
|
|
|
|
|
|
|
if ( has_imm && !vm::handler::get_operand_transforms( vm_handler_instrs, transforms ) )
|
|
|
|
if ( has_imm && !vm::handler::get_operand_transforms( vm_handler_instrs, transforms ) )
|
|
|
@ -109,16 +105,14 @@ namespace vm
|
|
|
|
const auto result =
|
|
|
|
const auto result =
|
|
|
|
std::find_if( vm_handler.begin(), vm_handler.end(), []( const zydis_instr_t &instr_data ) -> bool {
|
|
|
|
std::find_if( vm_handler.begin(), vm_handler.end(), []( const zydis_instr_t &instr_data ) -> bool {
|
|
|
|
// mov/movsx/movzx rax/eax/ax/al, [rsi]
|
|
|
|
// mov/movsx/movzx rax/eax/ax/al, [rsi]
|
|
|
|
if ( instr_data.instr.operand_count > 1 &&
|
|
|
|
return instr_data.instr.operand_count > 1 &&
|
|
|
|
( instr_data.instr.mnemonic == ZYDIS_MNEMONIC_MOV ||
|
|
|
|
( instr_data.instr.mnemonic == ZYDIS_MNEMONIC_MOV ||
|
|
|
|
instr_data.instr.mnemonic == ZYDIS_MNEMONIC_MOVSX ||
|
|
|
|
instr_data.instr.mnemonic == ZYDIS_MNEMONIC_MOVSX ||
|
|
|
|
instr_data.instr.mnemonic == ZYDIS_MNEMONIC_MOVZX ) &&
|
|
|
|
instr_data.instr.mnemonic == ZYDIS_MNEMONIC_MOVZX ) &&
|
|
|
|
instr_data.instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
|
|
|
instr_data.instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
|
|
|
util::reg::to64( instr_data.instr.operands[ 0 ].reg.value ) == ZYDIS_REGISTER_RAX &&
|
|
|
|
util::reg::to64( instr_data.instr.operands[ 0 ].reg.value ) == ZYDIS_REGISTER_RAX &&
|
|
|
|
instr_data.instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
|
|
|
instr_data.instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
|
|
|
instr_data.instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RSI )
|
|
|
|
instr_data.instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RSI;
|
|
|
|
return true;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
} );
|
|
|
|
} );
|
|
|
|
|
|
|
|
|
|
|
|
return result != vm_handler.end();
|
|
|
|
return result != vm_handler.end();
|
|
|
@ -129,16 +123,14 @@ namespace vm
|
|
|
|
const auto result =
|
|
|
|
const auto result =
|
|
|
|
std::find_if( vm_handler.begin(), vm_handler.end(), []( const zydis_instr_t &instr_data ) -> bool {
|
|
|
|
std::find_if( vm_handler.begin(), vm_handler.end(), []( const zydis_instr_t &instr_data ) -> bool {
|
|
|
|
// mov/movsx/movzx rax/eax/ax/al, [rsi]
|
|
|
|
// mov/movsx/movzx rax/eax/ax/al, [rsi]
|
|
|
|
if ( instr_data.instr.operand_count > 1 &&
|
|
|
|
return instr_data.instr.operand_count > 1 &&
|
|
|
|
( instr_data.instr.mnemonic == ZYDIS_MNEMONIC_MOV ||
|
|
|
|
( instr_data.instr.mnemonic == ZYDIS_MNEMONIC_MOV ||
|
|
|
|
instr_data.instr.mnemonic == ZYDIS_MNEMONIC_MOVSX ||
|
|
|
|
instr_data.instr.mnemonic == ZYDIS_MNEMONIC_MOVSX ||
|
|
|
|
instr_data.instr.mnemonic == ZYDIS_MNEMONIC_MOVZX ) &&
|
|
|
|
instr_data.instr.mnemonic == ZYDIS_MNEMONIC_MOVZX ) &&
|
|
|
|
instr_data.instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
|
|
|
instr_data.instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER &&
|
|
|
|
util::reg::to64( instr_data.instr.operands[ 0 ].reg.value ) == ZYDIS_REGISTER_RAX &&
|
|
|
|
util::reg::to64( instr_data.instr.operands[ 0 ].reg.value ) == ZYDIS_REGISTER_RAX &&
|
|
|
|
instr_data.instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
|
|
|
instr_data.instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
|
|
|
instr_data.instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RSI )
|
|
|
|
instr_data.instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RSI;
|
|
|
|
return true;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
} );
|
|
|
|
} );
|
|
|
|
|
|
|
|
|
|
|
|
if ( result == vm_handler.end() )
|
|
|
|
if ( result == vm_handler.end() )
|
|
|
|