diff --git a/include/transform.hpp b/include/transform.hpp index e06f440..d24facb 100644 --- a/include/transform.hpp +++ b/include/transform.hpp @@ -176,12 +176,13 @@ namespace vm transform::inverse[ transforms[ transform::type::update_key ].mnemonic ]; } - inline auto inverse_transform( std::vector< zydis_decoded_instr_t > &instrs ) -> bool + inline auto inverse_transforms( std::vector< zydis_decoded_instr_t > &instrs ) -> bool { - for ( auto idx = 0u; idx < instrs.size() - 1; ++idx ) + for ( auto idx = 0u; idx < instrs.size(); idx++ ) if ( !( instrs[ idx ].mnemonic = inverse[ instrs[ idx ].mnemonic ] ) ) return false; + std::reverse( instrs.begin(), instrs.end() ); return true; } 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..2e9838d 100644 --- a/include/vmprofiler.hpp +++ b/include/vmprofiler.hpp @@ -1,12 +1,16 @@ #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 calc_jmp namespace instrs { @@ -28,9 +32,9 @@ namespace vm { INVALID, PUSHVSP, - SHRQ, MULQ, DIVQ, + CALL, JMP, VMEXIT, @@ -43,10 +47,13 @@ namespace vm LCONSTQ, LCONSTBZXW, + LCONSTBSXQ, LCONSTBSXDW, LCONSTDWSXQ, LCONSTWSXQ, + LCONSTWSXDW, LCONSTDW, + LCONSTW, READQ, READDW, @@ -55,13 +62,18 @@ namespace vm WRITEQ, WRITEDW, WRITEW, + WRITEB, ADDQ, ADDDW, + ADDW, SHLQ, SHLDW, + SHRQ, + SHRW, + NANDQ, NANDDW }; @@ -122,14 +134,19 @@ namespace vm extern vm::handler::profile_t lregdw; extern vm::handler::profile_t lconstq; + extern vm::handler::profile_t lconstdw; + extern vm::handler::profile_t lconstw; + extern vm::handler::profile_t lconstbzxw; extern vm::handler::profile_t lconstbsxdw; + extern vm::handler::profile_t lconstbsxq; extern vm::handler::profile_t lconstdwsxq; extern vm::handler::profile_t lconstwsxq; - extern vm::handler::profile_t lconstdw; + extern vm::handler::profile_t lconstwsxdw; extern vm::handler::profile_t addq; extern vm::handler::profile_t adddw; + extern vm::handler::profile_t addw; extern vm::handler::profile_t shlq; extern vm::handler::profile_t shldw; @@ -139,21 +156,30 @@ namespace vm extern vm::handler::profile_t writeq; extern vm::handler::profile_t writedw; + extern vm::handler::profile_t writeb; + + extern vm::handler::profile_t readq; + extern vm::handler::profile_t readdw; extern vm::handler::profile_t shrq; + extern vm::handler::profile_t shrw; + + extern vm::handler::profile_t call; extern vm::handler::profile_t pushvsp; extern vm::handler::profile_t mulq; extern vm::handler::profile_t divq; extern vm::handler::profile_t jmp; - extern vm::handler::profile_t readq; extern vm::handler::profile_t vmexit; inline std::vector< vm::handler::profile_t * > all = { - &sregq, &sregdw, &sregw, &lregq, &lregdw, &lconstq, &lconstbzxw, - &lconstbsxdw, &lconstdwsxq, &lconstwsxq, &lconstdw, &addq, &adddw, &shlq, - &shldw, &writeq, &writedw, &nandq, &nanddw, + &sregq, &sregdw, &sregw, &lregq, &lregdw, &lconstq, &lconstbzxw, + &lconstbsxdw, &lconstbsxq, &lconstdwsxq, &lconstwsxq, &lconstwsxdw, &lconstdw, &lconstw, + &addq, &adddw, &addw, + + &shlq, &shldw, &writeq, &writedw, &writeb, &nandq, &nanddw, - &shrq, &readq, &mulq, &pushvsp, &divq, &jmp, &vmexit }; + &shrq, &shrw, &readq, &readdw, &mulq, &pushvsp, &divq, + &jmp, &vmexit, &call }; } // namespace profile } // namespace handler } // namespace vm \ No newline at end of file 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..b45f86b 100644 --- a/src/vmprofiler.vcxproj +++ b/src/vmprofiler.vcxproj @@ -104,6 +104,7 @@ + @@ -164,6 +165,7 @@ + diff --git a/src/vmprofiler.vcxproj.filters b/src/vmprofiler.vcxproj.filters index 4de8ca3..ad7842b 100644 --- a/src/vmprofiler.vcxproj.filters +++ b/src/vmprofiler.vcxproj.filters @@ -86,6 +86,9 @@ Source Files + + Source Files\vmprofiles + @@ -226,6 +229,9 @@ Header Files + + Header Files + diff --git a/src/vmprofiles/add.cpp b/src/vmprofiles/add.cpp index 8982d8e..4d92c58 100644 --- a/src/vmprofiles/add.cpp +++ b/src/vmprofiles/add.cpp @@ -59,6 +59,33 @@ namespace vm instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY && instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP; } } } }; + + vm::handler::profile_t addw = { + // ADD [RBP+8], AX + // PUSHFQ + // POP [RBP] + "ADDW", + ADDW, + NULL, + { { // ADD [RBP+8], AX + []( const zydis_decoded_instr_t &instr ) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_ADD && + instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY && + instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP && + instr.operands[ 0 ].mem.disp.value == 0x8 && + instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER && + instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_AX; + }, + // PUSHFQ + []( const zydis_decoded_instr_t &instr ) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_PUSHFQ; + }, + // POP [RBP] + []( const zydis_decoded_instr_t &instr ) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_POP && + instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY && + instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP; + } } } }; } // namespace profile } // namespace handler } // namespace vm \ No newline at end of file diff --git a/src/vmprofiles/call.cpp b/src/vmprofiles/call.cpp new file mode 100644 index 0000000..bb3af63 --- /dev/null +++ b/src/vmprofiles/call.cpp @@ -0,0 +1,40 @@ +#include "../../include/vmprofiler.hpp" + +namespace vm +{ + namespace handler + { + namespace profile + { + vm::handler::profile_t call = { + // MOV RDX, [RBP] + // ADD RBP, 0x8 + // CALL RDX + "CALL", + CALL, + NULL, + { { // MOV RDX, [RBP] + []( const zydis_decoded_instr_t &instr ) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_MOV && + instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER && + instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RDX && + instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY && + instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP; + }, + // ADD RBP, 0x8 + []( const zydis_decoded_instr_t &instr ) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_ADD && + instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER && + instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP && + instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE && + instr.operands[ 1 ].imm.value.u == 0x8; + }, + // CALL RDX + []( const zydis_decoded_instr_t &instr ) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_CALL && + instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER && + instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RDX; + } } } }; + } + } // namespace handler +} // namespace vm \ No newline at end of file diff --git a/src/vmprofiles/lconst.cpp b/src/vmprofiles/lconst.cpp index 863bb5a..9b7bbca 100644 --- a/src/vmprofiles/lconst.cpp +++ b/src/vmprofiles/lconst.cpp @@ -30,6 +30,52 @@ namespace vm instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RAX; } } } }; + vm::handler::profile_t lconstdw = { + // SUB RBP, 4 + // MOV [RBP], EAX + "LCONSTDW", + LCONSTDW, + 32, + { { // SUB RBP, 4 + []( const zydis_decoded_instr_t &instr ) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_SUB && + instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER && + instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP && + instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE && + instr.operands[ 1 ].imm.value.u == 0x4; + }, + // MOV [RBP], EAX + []( const zydis_decoded_instr_t &instr ) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_MOV && + instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY && + instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP && + instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER && + instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_EAX; + } } } }; + + vm::handler::profile_t lconstw = { + // SUB RBP, 2 + // MOV [RBP], AX + "LCONSTW", + LCONSTW, + 16, + { { // SUB RBP, 2 + []( const zydis_decoded_instr_t &instr ) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_SUB && + instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER && + instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP && + instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE && + instr.operands[ 1 ].imm.value.u == 0x2; + }, + // MOV [RBP], AX + []( const zydis_decoded_instr_t &instr ) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_MOV && + instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY && + instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP && + instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER && + instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_AX; + } } } }; + vm::handler::profile_t lconstbzxw = { // MOV AL, [RSI] // SUB RBP, 2 @@ -81,6 +127,33 @@ namespace vm } } }, vm::handler::extention_t::sign_extend }; + vm::handler::profile_t lconstbsxq = { + // CDQE + // SUB RBP, 0x8 + // MOV [RBP], RAX + "LCONSTBSXQ", + LCONSTBSXQ, + 8, + { { // CDQE + []( const zydis_decoded_instr_t &instr ) -> bool { return instr.mnemonic == ZYDIS_MNEMONIC_CDQE; }, + // SUB RBP, 0x8 + []( const zydis_decoded_instr_t &instr ) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_SUB && + instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER && + instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP && + instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE && + instr.operands[ 1 ].imm.value.u == 0x8; + }, + // MOV [RBP], RAX + []( const zydis_decoded_instr_t &instr ) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_MOV && + instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY && + instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP && + instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER && + instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RAX; + } } }, + vm::handler::extention_t::sign_extend }; + vm::handler::profile_t lconstdwsxq = { // CDQE // SUB RBP, 8 @@ -135,13 +208,16 @@ namespace vm } } }, vm::handler::extention_t::sign_extend }; - vm::handler::profile_t lconstdw = { + vm::handler::profile_t lconstwsxdw = { + // CWDE // SUB RBP, 4 // MOV [RBP], EAX - "LCONSTDW", - LCONSTDW, - 32, - { { // SUB RBP, 4 + "LCONSTWSXDW", + LCONSTWSXDW, + 16, + { { // CWDE + []( const zydis_decoded_instr_t &instr ) -> bool { return instr.mnemonic == ZYDIS_MNEMONIC_CWDE; }, + // SUB RBP, 4 []( const zydis_decoded_instr_t &instr ) -> bool { return instr.mnemonic == ZYDIS_MNEMONIC_SUB && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER && @@ -156,7 +232,8 @@ namespace vm instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP && instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER && instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_EAX; - } } } }; + } } }, + vm::handler::extention_t::sign_extend }; } // namespace profile } // namespace handler } // namespace vm \ No newline at end of file diff --git a/src/vmprofiles/read.cpp b/src/vmprofiles/read.cpp index 6a2ee42..31fc822 100644 --- a/src/vmprofiles/read.cpp +++ b/src/vmprofiles/read.cpp @@ -29,6 +29,38 @@ namespace vm instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER && instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RAX; } } } }; + + vm::handler::profile_t readdw = { + // ADD RBP, 0x4 + // MOV EAX, [RAX] + // MOV [RBP], EAX + "READDW", + READDW, + NULL, + { { // ADD RBP, 0x4 + []( const zydis_decoded_instr_t &instr ) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_ADD && + instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER && + instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP && + instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE && + instr.operands[ 1 ].imm.value.u == 0x4; + }, + // MOV EAX, [RAX] + []( const zydis_decoded_instr_t &instr ) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_MOV && + instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER && + instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_EAX && + instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY && + instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RAX; + }, + // MOV [RBP], EAX + []( const zydis_decoded_instr_t &instr ) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_MOV && + instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY && + instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP && + instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER && + instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_EAX; + } } } }; } } // namespace handler } // namespace vm \ No newline at end of file diff --git a/src/vmprofiles/shr.cpp b/src/vmprofiles/shr.cpp index e9ec812..610e2f7 100644 --- a/src/vmprofiles/shr.cpp +++ b/src/vmprofiles/shr.cpp @@ -69,6 +69,70 @@ namespace vm instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY && instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP; } } } }; + + vm::handler::profile_t shrw = { + // MOV AX, [RBP] + // MOV CL, [RBP+0x2] + // SUB RBP, 0x6 + // SHR AX, CL + // MOV [RBP+0x8], AX + // PUSHFQ + // POP [RBP] + "SHRW", + SHRW, + NULL, + { { // MOV AX, [RBP] + []( const zydis_decoded_instr_t &instr ) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_MOV && + instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER && + instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_AX && + instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY && + instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP; + }, + // MOV CL, [RBP+0x2] + []( const zydis_decoded_instr_t &instr ) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_MOV && + instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER && + instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_CL && + instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY && + instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP && + instr.operands[ 1 ].mem.disp.value == 0x2; + }, + // SUB RBP, 0x6 + []( const zydis_decoded_instr_t &instr ) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_SUB && + instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER && + instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP && + instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE && + instr.operands[ 1 ].imm.value.u == 0x6; + }, + // SHR AX, CL + []( const zydis_decoded_instr_t &instr ) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_SHR && + instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER && + instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_AX && + instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER && + instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_CL; + }, + // MOV [RBP+0x8], AX + []( const zydis_decoded_instr_t &instr ) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_MOV && + instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY && + instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP && + instr.operands[ 0 ].mem.disp.value == 0x8 && + instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER && + instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_AX; + }, + // PUSHFQ + []( const zydis_decoded_instr_t &instr ) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_PUSHFQ; + }, + // POP [RBP] + []( const zydis_decoded_instr_t &instr ) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_POP && + instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY && + instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP; + } } } }; } } // namespace handler } // namespace vm \ No newline at end of file diff --git a/src/vmprofiles/write.cpp b/src/vmprofiles/write.cpp index 4c569ed..bf0b7ff 100644 --- a/src/vmprofiles/write.cpp +++ b/src/vmprofiles/write.cpp @@ -89,6 +89,48 @@ namespace vm instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER && instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_EDX; } } } }; + + vm::handler::profile_t writeb = { + // MOV RAX, [RBP] + // MOV DL, [RBP+0x8] + // ADD RBP, 0xA + // MOV [RAX], DL + "WRITEB", + WRITEB, + NULL, + { { // MOV RAX, [RBP] + []( const zydis_decoded_instr_t &instr ) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_MOV && + instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER && + instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX && + instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY && + instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP; + }, + // MOV DL, [RBP+0x8] + []( const zydis_decoded_instr_t &instr ) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_MOV && + instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER && + instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_DL && + instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY && + instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP && + instr.operands[ 1 ].mem.disp.value == 0x8; + }, + // ADD RBP, 0xA + []( const zydis_decoded_instr_t &instr ) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_ADD && + instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER && + instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RBP && + instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE && + instr.operands[ 1 ].imm.value.u == 0xA; + }, + // MOV [RAX], DL + []( const zydis_decoded_instr_t &instr ) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_MOV && + instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY && + instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RAX && + instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER && + instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_DL; + } } } }; } // namespace profile } // namespace handler } // namespace vm \ No newline at end of file