|
|
|
@ -186,16 +186,34 @@ namespace vm::locate
|
|
|
|
|
if ( !found_valid_jmp )
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
// second instruction in the flattened stream should be a push...
|
|
|
|
|
// this is also an optimization so we dont have to hit that 0^2 std::find_if every time...
|
|
|
|
|
if ( instr_stream[ 1 ].mnemonic != ZYDIS_MNEMONIC_PUSH )
|
|
|
|
|
// find the first PUSH IMM (encrypted RVA to virtual instructions...)
|
|
|
|
|
auto first_push = std::find_if( instr_stream.begin(), instr_stream.end(),
|
|
|
|
|
[ & ]( const zydis_decoded_instr_t &instr ) -> bool {
|
|
|
|
|
return instr.mnemonic == ZYDIS_MNEMONIC_PUSH &&
|
|
|
|
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE;
|
|
|
|
|
} );
|
|
|
|
|
|
|
|
|
|
if ( first_push == instr_stream.end() )
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
if ( std::find_if( instr_stream.begin() + 1, instr_stream.end(),
|
|
|
|
|
[ & ]( const ZydisDecodedInstruction &instr ) {
|
|
|
|
|
// find the second PUSH IMM...
|
|
|
|
|
auto second_push =
|
|
|
|
|
std::find_if( first_push + 1, instr_stream.end(), [ & ]( const zydis_decoded_instr_t &instr ) -> bool {
|
|
|
|
|
return instr.mnemonic == ZYDIS_MNEMONIC_PUSH &&
|
|
|
|
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE;
|
|
|
|
|
} ) == instr_stream.end() )
|
|
|
|
|
} );
|
|
|
|
|
|
|
|
|
|
if ( second_push == instr_stream.end() )
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
// if there is a third push IMM then we have an invalid instruction stream...
|
|
|
|
|
auto third_push =
|
|
|
|
|
std::find_if( second_push + 1, instr_stream.end(), [ & ]( const zydis_decoded_instr_t &instr ) -> bool {
|
|
|
|
|
return instr.mnemonic == ZYDIS_MNEMONIC_PUSH &&
|
|
|
|
|
instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE;
|
|
|
|
|
} );
|
|
|
|
|
|
|
|
|
|
if ( third_push != instr_stream.end() )
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
// scan over the instruction stream to see if it contains an lea r12, xxxx which is a known vm handler table
|
|
|
|
|