diff --git a/include/vmp2.hpp b/include/vmp2.hpp index a6469ca..6520d94 100644 --- a/include/vmp2.hpp +++ b/include/vmp2.hpp @@ -1,5 +1,5 @@ #pragma once -#include +#include namespace vmp2 { diff --git a/include/vmprofiler.hpp b/include/vmprofiler.hpp index d0ac42b..63cf5d4 100644 --- a/include/vmprofiler.hpp +++ b/include/vmprofiler.hpp @@ -1,11 +1,15 @@ #pragma once +#include #include +#include namespace vm { namespace calc_jmp { bool get( const zydis_routine_t &vm_entry, zydis_routine_t &calc_jmp ); + + std::optional< vmp2::exec_type_t > get_advancement( const zydis_routine_t &calc_jmp ); } namespace instrs diff --git a/src/calc_jmp.cpp b/src/calc_jmp.cpp index 4cc8eff..0902287 100644 --- a/src/calc_jmp.cpp +++ b/src/calc_jmp.cpp @@ -27,5 +27,71 @@ namespace vm calc_jmp.insert( calc_jmp.end(), result, vm_entry.end() ); return true; } + + std::optional< vmp2::exec_type_t > get_advancement( const zydis_routine_t &calc_jmp ) + { + auto result = + std::find_if( calc_jmp.begin(), calc_jmp.end(), []( const zydis_instr_t &instr_data ) -> bool { + // look for any instruction with RSI being the first operand... + return instr_data.instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER && + instr_data.instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RSI; + } ); + + if ( result == calc_jmp.end() ) + return {}; + + const auto instr = &result->instr; + + switch ( instr->mnemonic ) + { + case ZYDIS_MNEMONIC_LEA: + { + if ( instr->operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY ) + { + if ( instr->operands[ 1 ].mem.disp.value > 0 ) + return vmp2::exec_type_t::forward; + else + return vmp2::exec_type_t::backward; + } + // else we dont know what we are looking at... + return {}; + } + case ZYDIS_MNEMONIC_ADD: + { + // ADD RSI, IMM... + if ( instr->operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE ) + { + // see if IMM is negitive... + if ( instr->operands[ 1 ].imm.value.s > 0 ) + return vmp2::exec_type_t::forward; + else // adding a negitive number is sub... + return vmp2::exec_type_t::backward; + } + // else we dont know what we are looking at... + return {}; + } + case ZYDIS_MNEMONIC_SUB: + { + // SUB RSI, IMM... + if ( instr->operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE ) + { + // see if IMM is negitive... + if ( instr->operands[ 1 ].imm.value.s > 0 ) + return vmp2::exec_type_t::backward; + else // subtracting a negitive number means you are adding... + return vmp2::exec_type_t::forward; + } + // else we dont know what we are looking at... + return {}; + } + case ZYDIS_MNEMONIC_INC: + return vmp2::exec_type_t::forward; + case ZYDIS_MNEMONIC_DEC: + return vmp2::exec_type_t::backward; + default: + break; + } + return {}; + } } // namespace calc_jmp } // namespace vm \ No newline at end of file diff --git a/src/vmprofiler.vcxproj b/src/vmprofiler.vcxproj index 5e9f2de..7e0dd2c 100644 --- a/src/vmprofiler.vcxproj +++ b/src/vmprofiler.vcxproj @@ -164,6 +164,7 @@ + diff --git a/src/vmprofiler.vcxproj.filters b/src/vmprofiler.vcxproj.filters index 4de8ca3..c3db126 100644 --- a/src/vmprofiler.vcxproj.filters +++ b/src/vmprofiler.vcxproj.filters @@ -226,6 +226,9 @@ Header Files + + Header Files +