From 4832530dfb2ef7522ed960d3393d44906c42eb74 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Mon, 31 May 2021 23:09:43 -0700 Subject: [PATCH] added clang format, its 90% ok --- .clang-format | 18 + include/transform.hpp | 437 +++++++++---------- include/vmp2.hpp | 120 +++--- include/vmprofiler.hpp | 293 +++++++------ include/vmutils.h | 42 +- src/calc_jmp.cpp | 52 ++- src/vmhandler.cpp | 741 +++++++++++++++------------------ src/vminstrs.cpp | 349 +++++++--------- src/vmprofiler.vcxproj | 3 + src/vmprofiler.vcxproj.filters | 8 + src/vmprofiles/add.cpp | 128 +++--- src/vmprofiles/div.cpp | 151 ++++--- src/vmprofiles/jmp.cpp | 102 +++-- src/vmprofiles/lconst.cpp | 349 +++++++--------- src/vmprofiles/lreg.cpp | 166 ++++---- src/vmprofiles/mul.cpp | 149 +++---- src/vmprofiles/nand.cpp | 273 ++++++------ src/vmprofiles/pushvsp.cpp | 81 ++-- src/vmprofiles/read.cpp | 83 ++-- src/vmprofiles/shl.cpp | 288 ++++++------- src/vmprofiles/shr.cpp | 151 ++++--- src/vmprofiles/sreg.cpp | 239 +++++------ src/vmprofiles/vmexit.cpp | 61 ++- src/vmprofiles/write.cpp | 194 ++++----- src/vmutils.cpp | 151 ++++--- 25 files changed, 2160 insertions(+), 2469 deletions(-) create mode 100644 .clang-format diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..8063c5e --- /dev/null +++ b/.clang-format @@ -0,0 +1,18 @@ +--- +BasedOnStyle: Microsoft +AlignAfterOpenBracket: Align +AllowAllArgumentsOnNextLine: 'true' +AllowAllParametersOfDeclarationOnNextLine: 'true' +AllowShortIfStatementsOnASingleLine: Never +BreakBeforeBraces: Allman +IndentWidth: '4' +Language: Cpp +NamespaceIndentation: All +SpacesInAngles: 'true' +SpacesInCStyleCastParentheses: 'true' +SpacesInContainerLiterals: 'true' +SpacesInParentheses: 'true' +SpacesInSquareBrackets: 'true' +UseTab: Never + +... diff --git a/include/transform.hpp b/include/transform.hpp index a9fb80c..e06f440 100644 --- a/include/transform.hpp +++ b/include/transform.hpp @@ -1,238 +1,213 @@ #pragma once -#include #include -#include #include +#include +#include #include namespace vm { - namespace transform - { - // taken from ida... - template inline T __ROL__(T value, int count) - { - const unsigned int nbits = sizeof(T) * 8; - - if (count > 0) - { - count %= nbits; - T high = value >> (nbits - count); - if (T(-1) < 0) // signed value - high &= ~((T(-1) << count)); - value <<= count; - value |= high; - } - else - { - count = -count % nbits; - T low = value << (nbits - count); - value >>= count; - value |= low; - } - return value; - } - - // taken from ida... - inline u8 __ROL1__(u8 value, int count) { return __ROL__((u8)value, count); } - inline u16 __ROL2__(u16 value, int count) { return __ROL__((u16)value, count); } - inline u32 __ROL4__(u32 value, int count) { return __ROL__((u32)value, count); } - inline u64 __ROL8__(u64 value, int count) { return __ROL__((u64)value, count); } - inline u8 __ROR1__(u8 value, int count) { return __ROL__((u8)value, -count); } - inline u16 __ROR2__(u16 value, int count) { return __ROL__((u16)value, -count); } - inline u32 __ROR4__(u32 value, int count) { return __ROL__((u32)value, -count); } - inline u64 __ROR8__(u64 value, int count) { return __ROL__((u64)value, -count); } - - template - using transform_t = std::function; - - enum class type - { - generic0, - rolling_key, - generic1, - generic2, - generic3, - update_key - }; - - using map_t = std::map; - - template - inline const auto _bswap = [](T a, T b) -> T - { - if constexpr (std::is_same_v) - return _byteswap_uint64(a); - if constexpr (std::is_same_v) - return _byteswap_ulong(a); - if constexpr (std::is_same_v) - return _byteswap_ushort(a); - - throw std::invalid_argument("invalid type size..."); - }; - - template - inline const auto _add = [](T a, T b) -> T - { - return a + b; - }; - - template - inline const auto _xor = [](T a, T b) -> T - { - return a ^ b; - }; - - template - inline const auto _sub = [](T a, T b) -> T - { - return a - b; - }; - - template - inline const auto _neg = [](T a, T b) -> T - { - return a * -1; - }; - - template - inline const auto _not = [](T a, T b) -> T - { - return ~a; - }; - - template - inline const auto _ror = [](T a, T b) -> T - { - if constexpr (std::is_same_v) - return __ROR8__(a, b); - if constexpr (std::is_same_v) - return __ROR4__(a, b); - if constexpr (std::is_same_v) - return __ROR2__(a, b); - if constexpr (std::is_same_v ) - return __ROR1__(a, b); - - throw std::invalid_argument("invalid type size..."); - }; - - template - inline const auto _rol = [](T a, T b) -> T - { - if constexpr (std::is_same_v) - return __ROL8__(a, b); - if constexpr (std::is_same_v) - return __ROL4__(a, b); - if constexpr (std::is_same_v) - return __ROL2__(a, b); - if constexpr (std::is_same_v ) - return __ROL1__(a, b); - - throw std::invalid_argument("invalid type size..."); - }; - - template - inline const auto _inc = [](T a, T b) -> T - { - return a + 1; - }; - - template - inline const auto _dec = [](T a, T b) -> T - { - return a - 1; - }; - - template - inline std::map> transforms = - { - { ZYDIS_MNEMONIC_ADD, _add }, - { ZYDIS_MNEMONIC_XOR, _xor }, - { ZYDIS_MNEMONIC_BSWAP, _bswap }, - { ZYDIS_MNEMONIC_SUB, _sub}, - { ZYDIS_MNEMONIC_NEG, _neg}, - { ZYDIS_MNEMONIC_NOT, _not}, - { ZYDIS_MNEMONIC_ROR, _ror}, - { ZYDIS_MNEMONIC_ROL, _rol}, - { ZYDIS_MNEMONIC_INC, _inc}, - { ZYDIS_MNEMONIC_DEC, _dec} - }; - - inline std::map inverse = - { - {ZYDIS_MNEMONIC_ADD, ZYDIS_MNEMONIC_SUB}, - {ZYDIS_MNEMONIC_XOR, ZYDIS_MNEMONIC_XOR}, - {ZYDIS_MNEMONIC_BSWAP, ZYDIS_MNEMONIC_BSWAP}, - {ZYDIS_MNEMONIC_SUB, ZYDIS_MNEMONIC_ADD}, - {ZYDIS_MNEMONIC_NEG, ZYDIS_MNEMONIC_NEG}, - {ZYDIS_MNEMONIC_NOT, ZYDIS_MNEMONIC_NOT}, - {ZYDIS_MNEMONIC_ROR, ZYDIS_MNEMONIC_ROL}, - {ZYDIS_MNEMONIC_ROL, ZYDIS_MNEMONIC_ROR}, - {ZYDIS_MNEMONIC_INC, ZYDIS_MNEMONIC_DEC}, - {ZYDIS_MNEMONIC_DEC, ZYDIS_MNEMONIC_INC} - }; - - inline void inverse_transforms(transform::map_t& transforms, transform::map_t& inverse) - { - inverse[transform::type::generic0] = transforms[transform::type::generic0]; - inverse[transform::type::generic0].mnemonic = - transform::inverse[transforms[transform::type::generic0].mnemonic]; - - inverse[transform::type::rolling_key] = transforms[transform::type::rolling_key]; - inverse[transform::type::rolling_key].mnemonic = - transform::inverse[transforms[transform::type::rolling_key].mnemonic]; - - inverse[transform::type::generic1] = transforms[transform::type::generic1]; - inverse[transform::type::generic1].mnemonic = - transform::inverse[transforms[transform::type::generic1].mnemonic]; - - inverse[transform::type::generic2] = transforms[transform::type::generic2]; - inverse[transform::type::generic2].mnemonic = - transform::inverse[transforms[transform::type::generic2].mnemonic]; - - inverse[transform::type::generic3] = transforms[transform::type::generic3]; - inverse[transform::type::generic3].mnemonic = - transform::inverse[transforms[transform::type::generic3].mnemonic]; - - inverse[transform::type::update_key] = transforms[transform::type::update_key]; - inverse[transform::type::update_key].mnemonic = - transform::inverse[transforms[transform::type::update_key].mnemonic]; - } - - inline auto inverse_transform(std::vector& instrs) -> bool - { - for (auto idx = 0u; idx < instrs.size() - 1; ++idx) - if (!(instrs[idx].mnemonic = inverse[instrs[idx].mnemonic])) - return false; - - return true; - } - - // max size of a and b is 64 bits, a and b is then converted to - // the number of bits in bitsize, the transformation is applied, - // finally the result is converted back to 64bits... zero extended... - inline auto apply(std::uint8_t bitsize, ZydisMnemonic op, - std::uint64_t a, std::uint64_t b) -> std::uint64_t - { - switch (bitsize) - { - case 8: - return transforms[op](a, b); - case 16: - return transforms[op](a, b); - case 32: - return transforms[op](a, b); - case 64: - return transforms[op](a, b); - default: - throw std::invalid_argument("invalid bit size..."); - } - } - - inline bool has_imm(zydis_decoded_instr_t* instr) - { - return instr->operand_count > 1 && - (instr->operands[1].type & ZYDIS_OPERAND_TYPE_IMMEDIATE); - } - } -} \ No newline at end of file + namespace transform + { + // taken from ida... + template < class T > inline T __ROL__( T value, int count ) + { + const unsigned int nbits = sizeof( T ) * 8; + + if ( count > 0 ) + { + count %= nbits; + T high = value >> ( nbits - count ); + if ( T( -1 ) < 0 ) // signed value + high &= ~( ( T( -1 ) << count ) ); + value <<= count; + value |= high; + } + else + { + count = -count % nbits; + T low = value << ( nbits - count ); + value >>= count; + value |= low; + } + return value; + } + + // taken from ida... + inline u8 __ROL1__( u8 value, int count ) + { + return __ROL__( ( u8 )value, count ); + } + inline u16 __ROL2__( u16 value, int count ) + { + return __ROL__( ( u16 )value, count ); + } + inline u32 __ROL4__( u32 value, int count ) + { + return __ROL__( ( u32 )value, count ); + } + inline u64 __ROL8__( u64 value, int count ) + { + return __ROL__( ( u64 )value, count ); + } + inline u8 __ROR1__( u8 value, int count ) + { + return __ROL__( ( u8 )value, -count ); + } + inline u16 __ROR2__( u16 value, int count ) + { + return __ROL__( ( u16 )value, -count ); + } + inline u32 __ROR4__( u32 value, int count ) + { + return __ROL__( ( u32 )value, -count ); + } + inline u64 __ROR8__( u64 value, int count ) + { + return __ROL__( ( u64 )value, -count ); + } + + template < typename T > using transform_t = std::function< T( T, T ) >; + + enum class type + { + generic0, + rolling_key, + generic1, + generic2, + generic3, + update_key + }; + + using map_t = std::map< transform::type, zydis_decoded_instr_t >; + + template < class T > + inline const auto _bswap = []( T a, T b ) -> T { + if constexpr ( std::is_same_v< T, std::uint64_t > ) + return _byteswap_uint64( a ); + if constexpr ( std::is_same_v< T, std::uint32_t > ) + return _byteswap_ulong( a ); + if constexpr ( std::is_same_v< T, std::uint16_t > ) + return _byteswap_ushort( a ); + + throw std::invalid_argument( "invalid type size..." ); + }; + + template < class T > inline const auto _add = []( T a, T b ) -> T { return a + b; }; + + template < class T > inline const auto _xor = []( T a, T b ) -> T { return a ^ b; }; + + template < class T > inline const auto _sub = []( T a, T b ) -> T { return a - b; }; + + template < class T > inline const auto _neg = []( T a, T b ) -> T { return a * -1; }; + + template < class T > inline const auto _not = []( T a, T b ) -> T { return ~a; }; + + template < class T > + inline const auto _ror = []( T a, T b ) -> T { + if constexpr ( std::is_same_v< T, std::uint64_t > ) + return __ROR8__( a, b ); + if constexpr ( std::is_same_v< T, std::uint32_t > ) + return __ROR4__( a, b ); + if constexpr ( std::is_same_v< T, std::uint16_t > ) + return __ROR2__( a, b ); + if constexpr ( std::is_same_v< T, std::uint8_t > ) + return __ROR1__( a, b ); + + throw std::invalid_argument( "invalid type size..." ); + }; + + template < class T > + inline const auto _rol = []( T a, T b ) -> T { + if constexpr ( std::is_same_v< T, std::uint64_t > ) + return __ROL8__( a, b ); + if constexpr ( std::is_same_v< T, std::uint32_t > ) + return __ROL4__( a, b ); + if constexpr ( std::is_same_v< T, std::uint16_t > ) + return __ROL2__( a, b ); + if constexpr ( std::is_same_v< T, std::uint8_t > ) + return __ROL1__( a, b ); + + throw std::invalid_argument( "invalid type size..." ); + }; + + template < class T > inline const auto _inc = []( T a, T b ) -> T { return a + 1; }; + + template < class T > inline const auto _dec = []( T a, T b ) -> T { return a - 1; }; + + template < class T > + inline std::map< ZydisMnemonic, transform_t< T > > transforms = { + { ZYDIS_MNEMONIC_ADD, _add< T > }, { ZYDIS_MNEMONIC_XOR, _xor< T > }, { ZYDIS_MNEMONIC_BSWAP, _bswap< T > }, + { ZYDIS_MNEMONIC_SUB, _sub< T > }, { ZYDIS_MNEMONIC_NEG, _neg< T > }, { ZYDIS_MNEMONIC_NOT, _not< T > }, + { ZYDIS_MNEMONIC_ROR, _ror< T > }, { ZYDIS_MNEMONIC_ROL, _rol< T > }, { ZYDIS_MNEMONIC_INC, _inc< T > }, + { ZYDIS_MNEMONIC_DEC, _dec< T > } }; + + inline std::map< ZydisMnemonic, ZydisMnemonic > inverse = { + { ZYDIS_MNEMONIC_ADD, ZYDIS_MNEMONIC_SUB }, { ZYDIS_MNEMONIC_XOR, ZYDIS_MNEMONIC_XOR }, + { ZYDIS_MNEMONIC_BSWAP, ZYDIS_MNEMONIC_BSWAP }, { ZYDIS_MNEMONIC_SUB, ZYDIS_MNEMONIC_ADD }, + { ZYDIS_MNEMONIC_NEG, ZYDIS_MNEMONIC_NEG }, { ZYDIS_MNEMONIC_NOT, ZYDIS_MNEMONIC_NOT }, + { ZYDIS_MNEMONIC_ROR, ZYDIS_MNEMONIC_ROL }, { ZYDIS_MNEMONIC_ROL, ZYDIS_MNEMONIC_ROR }, + { ZYDIS_MNEMONIC_INC, ZYDIS_MNEMONIC_DEC }, { ZYDIS_MNEMONIC_DEC, ZYDIS_MNEMONIC_INC } }; + + inline void inverse_transforms( transform::map_t &transforms, transform::map_t &inverse ) + { + inverse[ transform::type::generic0 ] = transforms[ transform::type::generic0 ]; + inverse[ transform::type::generic0 ].mnemonic = + transform::inverse[ transforms[ transform::type::generic0 ].mnemonic ]; + + inverse[ transform::type::rolling_key ] = transforms[ transform::type::rolling_key ]; + inverse[ transform::type::rolling_key ].mnemonic = + transform::inverse[ transforms[ transform::type::rolling_key ].mnemonic ]; + + inverse[ transform::type::generic1 ] = transforms[ transform::type::generic1 ]; + inverse[ transform::type::generic1 ].mnemonic = + transform::inverse[ transforms[ transform::type::generic1 ].mnemonic ]; + + inverse[ transform::type::generic2 ] = transforms[ transform::type::generic2 ]; + inverse[ transform::type::generic2 ].mnemonic = + transform::inverse[ transforms[ transform::type::generic2 ].mnemonic ]; + + inverse[ transform::type::generic3 ] = transforms[ transform::type::generic3 ]; + inverse[ transform::type::generic3 ].mnemonic = + transform::inverse[ transforms[ transform::type::generic3 ].mnemonic ]; + + inverse[ transform::type::update_key ] = transforms[ transform::type::update_key ]; + inverse[ transform::type::update_key ].mnemonic = + transform::inverse[ transforms[ transform::type::update_key ].mnemonic ]; + } + + inline auto inverse_transform( std::vector< zydis_decoded_instr_t > &instrs ) -> bool + { + for ( auto idx = 0u; idx < instrs.size() - 1; ++idx ) + if ( !( instrs[ idx ].mnemonic = inverse[ instrs[ idx ].mnemonic ] ) ) + return false; + + return true; + } + + // max size of a and b is 64 bits, a and b is then converted to + // the number of bits in bitsize, the transformation is applied, + // finally the result is converted back to 64bits... zero extended... + inline auto apply( std::uint8_t bitsize, ZydisMnemonic op, std::uint64_t a, std::uint64_t b ) -> std::uint64_t + { + switch ( bitsize ) + { + case 8: + return transforms< std::uint8_t >[ op ]( a, b ); + case 16: + return transforms< std::uint16_t >[ op ]( a, b ); + case 32: + return transforms< std::uint32_t >[ op ]( a, b ); + case 64: + return transforms< std::uint64_t >[ op ]( a, b ); + default: + throw std::invalid_argument( "invalid bit size..." ); + } + } + + inline bool has_imm( zydis_decoded_instr_t *instr ) + { + return instr->operand_count > 1 && ( instr->operands[ 1 ].type & ZYDIS_OPERAND_TYPE_IMMEDIATE ); + } + } // namespace transform +} // namespace vm \ No newline at end of file diff --git a/include/vmp2.hpp b/include/vmp2.hpp index d94d7a6..a6469ca 100644 --- a/include/vmp2.hpp +++ b/include/vmp2.hpp @@ -3,70 +3,70 @@ namespace vmp2 { - enum class exec_type_t - { - forward, - backward - }; + enum class exec_type_t + { + forward, + backward + }; - enum class version_t - { - invalid, - v1 = 0x101 - }; + enum class version_t + { + invalid, + v1 = 0x101 + }; - struct file_header - { - u32 magic; // VMP2 - u64 epoch_time; - u64 module_base; - exec_type_t advancement; - version_t version; + struct file_header + { + u32 magic; // VMP2 + u64 epoch_time; + u64 module_base; + exec_type_t advancement; + version_t version; - u32 entry_count; - u32 entry_offset; - }; + u32 entry_count; + u32 entry_offset; + }; - struct entry_t - { - u8 handler_idx; - u64 decrypt_key; - u64 vip; + struct entry_t + { + u8 handler_idx; + u64 decrypt_key; + u64 vip; - union - { - struct - { - u64 r15; - u64 r14; - u64 r13; - u64 r12; - u64 r11; - u64 r10; - u64 r9; - u64 r8; - u64 rbp; - u64 rdi; - u64 rsi; - u64 rdx; - u64 rcx; - u64 rbx; - u64 rax; - u64 rflags; - }; - u64 raw[16]; - } regs; + union + { + struct + { + u64 r15; + u64 r14; + u64 r13; + u64 r12; + u64 r11; + u64 r10; + u64 r9; + u64 r8; + u64 rbp; + u64 rdi; + u64 rsi; + u64 rdx; + u64 rcx; + u64 rbx; + u64 rax; + u64 rflags; + }; + u64 raw[ 16 ]; + } regs; - union - { - u64 qword[0x28]; - u8 raw[0x140]; - } vregs; + union + { + u64 qword[ 0x28 ]; + u8 raw[ 0x140 ]; + } vregs; - union - { - u64 qword[0x20]; - u8 raw[0x100]; - } vsp; - }; -} \ No newline at end of file + union + { + u64 qword[ 0x20 ]; + u8 raw[ 0x100 ]; + } vsp; + }; +} // namespace vmp2 \ No newline at end of file diff --git a/include/vmprofiler.hpp b/include/vmprofiler.hpp index ad089e6..d0ac42b 100644 --- a/include/vmprofiler.hpp +++ b/include/vmprofiler.hpp @@ -3,69 +3,68 @@ namespace vm { - namespace calc_jmp - { - bool get(const zydis_routine_t& vm_entry, zydis_routine_t& calc_jmp); - } - - namespace instrs - { - // decrypt transformations for encrypted virtual instruction rva... - bool get_rva_decrypt(const zydis_routine_t& vm_entry, - std::vector& transform_instrs); - - std::pair decrypt_operand(transform::map_t& transforms, - std::uint64_t operand, std::uint64_t rolling_key); - - std::pair encrypt_operand(transform::map_t& transforms, - std::uint64_t operand, std::uint64_t rolling_key); - } - - namespace handler - { - using instr_callback_t = bool(*)(const zydis_decoded_instr_t& instr); - - enum mnemonic_t - { - INVALID, - PUSHVSP, - SHRQ, - MULQ, - DIVQ, - JMP, - VMEXIT, - - SREGQ, - SREGDW, - SREGW, - - LREGQ, - LREGDW, - - LCONSTQ, - LCONSTBZXW, - LCONSTBSXDW, - LCONSTDWSXQ, - LCONSTWSXQ, - LCONSTDW, - - READQ, - READDW, - READW, - - WRITEQ, - WRITEDW, - WRITEW, - - ADDQ, - ADDDW, - - SHLQ, - SHLDW, - - NANDQ, - NANDDW - }; + namespace calc_jmp + { + bool get( const zydis_routine_t &vm_entry, zydis_routine_t &calc_jmp ); + } + + namespace instrs + { + // decrypt transformations for encrypted virtual instruction rva... + bool get_rva_decrypt( const zydis_routine_t &vm_entry, std::vector< zydis_decoded_instr_t > &transform_instrs ); + + std::pair< std::uint64_t, std::uint64_t > decrypt_operand( transform::map_t &transforms, std::uint64_t operand, + std::uint64_t rolling_key ); + + std::pair< std::uint64_t, std::uint64_t > encrypt_operand( transform::map_t &transforms, std::uint64_t operand, + std::uint64_t rolling_key ); + } // namespace instrs + + namespace handler + { + using instr_callback_t = bool ( * )( const zydis_decoded_instr_t &instr ); + + enum mnemonic_t + { + INVALID, + PUSHVSP, + SHRQ, + MULQ, + DIVQ, + JMP, + VMEXIT, + + SREGQ, + SREGDW, + SREGW, + + LREGQ, + LREGDW, + + LCONSTQ, + LCONSTBZXW, + LCONSTBSXDW, + LCONSTDWSXQ, + LCONSTWSXQ, + LCONSTDW, + + READQ, + READDW, + READW, + + WRITEQ, + WRITEDW, + WRITEW, + + ADDQ, + ADDDW, + + SHLQ, + SHLDW, + + NANDQ, + NANDDW + }; enum extention_t { @@ -76,97 +75,85 @@ namespace vm struct profile_t { - const char* name; - mnemonic_t mnemonic; + const char *name; + mnemonic_t mnemonic; u8 imm_size; - std::vector signature; + std::vector< instr_callback_t > signature; extention_t extention; }; - struct handler_t - { - u8 imm_size; // size in bits... - vm::transform::map_t transforms; - vm::handler::profile_t* profile; - zydis_routine_t instrs; - std::uintptr_t address; - }; - - bool has_imm(const zydis_routine_t& vm_handler); - std::uint8_t imm_size(const zydis_routine_t& vm_handler); - bool get(zydis_routine_t& vm_entry, zydis_routine_t& vm_handler, std::uintptr_t handler_addr); - - // may throw an exception... - 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_handlers); - - // can be used on calc_jmp... - bool get_operand_transforms(const zydis_routine_t& vm_handler, transform::map_t& transforms); - vm::handler::profile_t* get_profile(handler_t& vm_handler); - - namespace table - { - std::uintptr_t* get(const zydis_routine_t& vm_entry); - bool get_transform(const zydis_routine_t& vm_entry, zydis_decoded_instr_t* transform_instr); - - std::uint64_t encrypt(zydis_decoded_instr_t& transform_instr, std::uint64_t val); - std::uint64_t decrypt(zydis_decoded_instr_t& transform_instr, std::uint64_t val); - } - - namespace profile - { - extern vm::handler::profile_t sregq; - extern vm::handler::profile_t sregdw; - extern vm::handler::profile_t sregw; - - extern vm::handler::profile_t lregq; - extern vm::handler::profile_t lregdw; - - extern vm::handler::profile_t lconstq; - extern vm::handler::profile_t lconstbzxw; - extern vm::handler::profile_t lconstbsxdw; - extern vm::handler::profile_t lconstdwsxq; - extern vm::handler::profile_t lconstwsxq; - extern vm::handler::profile_t lconstdw; - - extern vm::handler::profile_t addq; - extern vm::handler::profile_t adddw; - - extern vm::handler::profile_t shlq; - extern vm::handler::profile_t shldw; - - extern vm::handler::profile_t nandq; - extern vm::handler::profile_t nanddw; - - extern vm::handler::profile_t writeq; - extern vm::handler::profile_t writedw; - - extern vm::handler::profile_t shrq; - 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 all = - { - &sregq, &sregdw, &sregw, - &lregq, &lregdw, - &lconstq, &lconstbzxw, &lconstbsxdw, &lconstdwsxq, &lconstwsxq, &lconstdw, - &addq, &adddw, - &shlq, &shldw, - &writeq, &writedw, - &nandq, &nanddw, - - &shrq, - &readq, - &mulq, - &pushvsp, - &divq, - &jmp, - &vmexit - }; - } - } -} \ No newline at end of file + struct handler_t + { + u8 imm_size; // size in bits... + vm::transform::map_t transforms; + vm::handler::profile_t *profile; + zydis_routine_t instrs; + std::uintptr_t address; + }; + + bool has_imm( const zydis_routine_t &vm_handler ); + std::uint8_t imm_size( const zydis_routine_t &vm_handler ); + bool get( zydis_routine_t &vm_entry, zydis_routine_t &vm_handler, std::uintptr_t handler_addr ); + + // may throw an exception... + 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< handler_t > &vm_handlers ); + + // can be used on calc_jmp... + bool get_operand_transforms( const zydis_routine_t &vm_handler, transform::map_t &transforms ); + vm::handler::profile_t *get_profile( handler_t &vm_handler ); + + namespace table + { + std::uintptr_t *get( const zydis_routine_t &vm_entry ); + bool get_transform( const zydis_routine_t &vm_entry, zydis_decoded_instr_t *transform_instr ); + + std::uint64_t encrypt( zydis_decoded_instr_t &transform_instr, std::uint64_t val ); + std::uint64_t decrypt( zydis_decoded_instr_t &transform_instr, std::uint64_t val ); + } // namespace table + + namespace profile + { + extern vm::handler::profile_t sregq; + extern vm::handler::profile_t sregdw; + extern vm::handler::profile_t sregw; + + extern vm::handler::profile_t lregq; + extern vm::handler::profile_t lregdw; + + extern vm::handler::profile_t lconstq; + extern vm::handler::profile_t lconstbzxw; + extern vm::handler::profile_t lconstbsxdw; + extern vm::handler::profile_t lconstdwsxq; + extern vm::handler::profile_t lconstwsxq; + extern vm::handler::profile_t lconstdw; + + extern vm::handler::profile_t addq; + extern vm::handler::profile_t adddw; + + extern vm::handler::profile_t shlq; + extern vm::handler::profile_t shldw; + + extern vm::handler::profile_t nandq; + extern vm::handler::profile_t nanddw; + + extern vm::handler::profile_t writeq; + extern vm::handler::profile_t writedw; + + extern vm::handler::profile_t shrq; + 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, + + &shrq, &readq, &mulq, &pushvsp, &divq, &jmp, &vmexit }; + } // namespace profile + } // namespace handler +} // namespace vm \ No newline at end of file diff --git a/include/vmutils.h b/include/vmutils.h index e900a8b..aa1811b 100644 --- a/include/vmutils.h +++ b/include/vmutils.h @@ -1,7 +1,7 @@ #pragma once -#include -#include #include +#include +#include #include using u8 = unsigned char; @@ -15,29 +15,29 @@ using zydis_register_t = ZydisRegister; struct zydis_instr_t { - zydis_decoded_instr_t instr; - std::vector raw; - std::uintptr_t addr; + zydis_decoded_instr_t instr; + std::vector< u8 > raw; + std::uintptr_t addr; }; -using zydis_routine_t = std::vector; +using zydis_routine_t = std::vector< zydis_instr_t >; namespace vm { - namespace util - { - namespace reg - { - // converts say... AL to RAX... - zydis_register_t to64(zydis_register_t reg); - bool compare(zydis_register_t a, zydis_register_t b); - } + namespace util + { + namespace reg + { + // converts say... AL to RAX... + zydis_register_t to64( zydis_register_t reg ); + bool compare( zydis_register_t a, zydis_register_t b ); + } // namespace reg - void print(zydis_routine_t& routine); - void print(const zydis_decoded_instr_t& instr); - bool is_jmp(const zydis_decoded_instr_t& instr); + void print( zydis_routine_t &routine ); + void print( const zydis_decoded_instr_t &instr ); + bool is_jmp( const zydis_decoded_instr_t &instr ); - bool flatten(zydis_routine_t& routine, std::uintptr_t routine_addr, bool keep_jmps = false); - void deobfuscate(zydis_routine_t& routine); - } -} \ No newline at end of file + bool flatten( zydis_routine_t &routine, std::uintptr_t routine_addr, bool keep_jmps = false ); + void deobfuscate( zydis_routine_t &routine ); + } // namespace util +} // namespace vm \ No newline at end of file diff --git a/src/calc_jmp.cpp b/src/calc_jmp.cpp index 8d47395..4cc8eff 100644 --- a/src/calc_jmp.cpp +++ b/src/calc_jmp.cpp @@ -2,32 +2,30 @@ namespace vm { - namespace calc_jmp - { - bool get(const zydis_routine_t& vm_entry, zydis_routine_t& calc_jmp) - { - auto result = std::find_if(vm_entry.begin(), vm_entry.end(), - [](const zydis_instr_t& instr_data) -> bool - { - // mov/movsx/movzx rax/eax/ax/al, [rsi] - if (instr_data.instr.operand_count > 1 && - (instr_data.instr.mnemonic == ZYDIS_MNEMONIC_MOV || - instr_data.instr.mnemonic == ZYDIS_MNEMONIC_MOVSX || - 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 && - instr_data.instr.operands[1].type == ZYDIS_OPERAND_TYPE_MEMORY && - instr_data.instr.operands[1].mem.base == ZYDIS_REGISTER_RSI) - return true; - return false; - } - ); + namespace calc_jmp + { + bool get( const zydis_routine_t &vm_entry, zydis_routine_t &calc_jmp ) + { + auto result = + std::find_if( vm_entry.begin(), vm_entry.end(), []( const zydis_instr_t &instr_data ) -> bool { + // mov/movsx/movzx rax/eax/ax/al, [rsi] + if ( instr_data.instr.operand_count > 1 && + ( instr_data.instr.mnemonic == ZYDIS_MNEMONIC_MOV || + instr_data.instr.mnemonic == ZYDIS_MNEMONIC_MOVSX || + 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 && + instr_data.instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY && + instr_data.instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RSI ) + return true; + return false; + } ); - if (result == vm_entry.end()) - return false; + if ( result == vm_entry.end() ) + return false; - calc_jmp.insert(calc_jmp.end(), result, vm_entry.end()); - return true; - } - } -} \ No newline at end of file + calc_jmp.insert( calc_jmp.end(), result, vm_entry.end() ); + return true; + } + } // namespace calc_jmp +} // namespace vm \ No newline at end of file diff --git a/src/vmhandler.cpp b/src/vmhandler.cpp index 17c8584..3b8a926 100644 --- a/src/vmhandler.cpp +++ b/src/vmhandler.cpp @@ -2,398 +2,349 @@ namespace vm { - namespace handler - { - 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; - }; - - auto result = std::find_if( - vm_handler.begin(), vm_handler.end(), - [](const zydis_instr_t& instr) -> bool - { - if (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) - return true; - - return 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... - { - zydis_routine_t::iterator last = vm_handler.end(); - result = vm_handler.begin(); - - while (result != vm_handler.end()) - { - result = std::find_if( - ++result, vm_handler.end(), - [](const zydis_instr_t& instr_data) -> bool - { - // mov/movsx/movzx rax/eax/ax/al, [rsi] - if (instr_data.instr.operand_count > 1 && - (instr_data.instr.mnemonic == ZYDIS_MNEMONIC_MOV || - instr_data.instr.mnemonic == ZYDIS_MNEMONIC_MOVSX || - 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 && - instr_data.instr.operands[1].type == ZYDIS_OPERAND_TYPE_MEMORY && - instr_data.instr.operands[1].mem.base == ZYDIS_REGISTER_RSI) - return true; - return false; - } - ); - - if (result != vm_handler.end()) - last = result; - } - - 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_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; - - for (auto idx = 0u; idx < 256; ++idx) - { - const auto decrypt_val = - vm::handler::table::decrypt( - instr, vm_handler_table[idx]); - - handler_t vm_handler; - vm::transform::map_t transforms; - zydis_routine_t vm_handler_instrs; - - 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); - - const auto imm_size = - vm::handler::imm_size(vm_handler_instrs); - - if (has_imm && !vm::handler::get_operand_transforms(vm_handler_instrs, transforms)) - return false; - - vm_handler.address = (decrypt_val - image_base) + module_base; - vm_handler.instrs = vm_handler_instrs; - vm_handler.imm_size = imm_size; - vm_handler.transforms = transforms; - vm_handler.profile = vm::handler::get_profile(vm_handler); - vm_handlers.push_back(vm_handler); - } - - return true; - } - - bool has_imm(const zydis_routine_t& vm_handler) - { - const auto result = std::find_if( - vm_handler.begin(), vm_handler.end(), - [](const zydis_instr_t& instr_data) -> bool - { - // mov/movsx/movzx rax/eax/ax/al, [rsi] - if (instr_data.instr.operand_count > 1 && - (instr_data.instr.mnemonic == ZYDIS_MNEMONIC_MOV || - instr_data.instr.mnemonic == ZYDIS_MNEMONIC_MOVSX || - 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 && - instr_data.instr.operands[1].type == ZYDIS_OPERAND_TYPE_MEMORY && - instr_data.instr.operands[1].mem.base == ZYDIS_REGISTER_RSI) - return true; - return false; - } - ); - - return result != vm_handler.end(); - } - - std::uint8_t imm_size(const zydis_routine_t& vm_handler) - { - const auto result = std::find_if( - vm_handler.begin(), vm_handler.end(), - [](const zydis_instr_t& instr_data) -> bool - { - // mov/movsx/movzx rax/eax/ax/al, [rsi] - if (instr_data.instr.operand_count > 1 && - (instr_data.instr.mnemonic == ZYDIS_MNEMONIC_MOV || - instr_data.instr.mnemonic == ZYDIS_MNEMONIC_MOVSX || - 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 && - instr_data.instr.operands[1].type == ZYDIS_OPERAND_TYPE_MEMORY && - instr_data.instr.operands[1].mem.base == ZYDIS_REGISTER_RSI) - return true; - return false; - } - ); - - if (result == vm_handler.end()) - return 0u; - - return result->instr.operands[1].size; - } - - bool get_operand_transforms(const zydis_routine_t& vm_handler, transform::map_t& transforms) - { - auto imm_fetch = std::find_if( - vm_handler.begin(), vm_handler.end(), - [](const zydis_instr_t& instr_data) -> bool - { - // mov/movsx/movzx rax/eax/ax/al, [rsi] - if (instr_data.instr.operand_count > 1 && - (instr_data.instr.mnemonic == ZYDIS_MNEMONIC_MOV || - instr_data.instr.mnemonic == ZYDIS_MNEMONIC_MOVSX || - 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 && - instr_data.instr.operands[1].type == ZYDIS_OPERAND_TYPE_MEMORY && - instr_data.instr.operands[1].mem.base == ZYDIS_REGISTER_RSI) - return true; - return false; - } - ); - - if (imm_fetch == vm_handler.end()) - return false; - - // this finds the first transformation which looks like: - // transform rax, rbx <--- note these registers can be smaller so we to64 them... - auto key_transform = std::find_if(imm_fetch, vm_handler.end(), - [](const zydis_instr_t& instr_data) -> bool - { - if (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 true; - return false; - } - ); - - if (key_transform == vm_handler.end()) - return false; - - // look for a primer/instruction that alters RAX prior to the 5 transformations... - auto generic0 = std::find_if(imm_fetch + 1, key_transform, - [](const zydis_instr_t& instr_data) -> bool - { - return 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; - nogeneric0.mnemonic = ZYDIS_MNEMONIC_INVALID; - - transforms[transform::type::generic0] = - generic0 != key_transform ? generic0->instr : nogeneric0; - - // last transformation is the same as the first except src and dest are swwapped... - transforms[transform::type::rolling_key] = key_transform->instr; - auto instr_copy = key_transform->instr; - instr_copy.operands[0].reg.value = key_transform->instr.operands[1].reg.value; - instr_copy.operands[1].reg.value = key_transform->instr.operands[0].reg.value; - transforms[transform::type::update_key] = instr_copy; - - // three generic transformations... - auto generic_transform = key_transform; - - for (auto idx = 2u; idx < 5; ++idx) - { - generic_transform = std::find_if(++generic_transform, vm_handler.end(), - [](const zydis_instr_t& instr_data) -> bool - { - if (util::reg::compare(instr_data.instr.operands[0].reg.value, ZYDIS_REGISTER_RAX)) - return true; - - return false; - } - ); - - if (generic_transform == vm_handler.end()) - return false; - - transforms[(transform::type)(idx)] = generic_transform->instr; - } - - return true; - } - - vm::handler::profile_t* get_profile(handler_t& vm_handler) - { - static const auto vcontains = - [](vm::handler::profile_t* vprofile, handler_t* vm_handler) -> bool - { - if (vprofile->imm_size != vm_handler->imm_size) - return false; - - for (auto& instr : vprofile->signature) - { - const auto contains = std::find_if - ( - vm_handler->instrs.begin(), - vm_handler->instrs.end(), - - [&](zydis_instr_t& instr_data) -> bool - { return instr(instr_data.instr); } - ); - - if (contains == vm_handler->instrs.end()) - return false; - } - - return true; - }; - - for (auto profile : vm::handler::profile::all) - if (vcontains(profile, &vm_handler)) - return profile; - - return nullptr; - } - - namespace table - { - 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)... - if (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 true; - - return false; - } - ); - - if (result == vm_entry.end()) - return nullptr; - - std::uintptr_t ptr = 0u; - ZydisCalcAbsoluteAddress(&result->instr, - &result->instr.operands[1], result->addr, &ptr); - - return reinterpret_cast(ptr); - } - - bool get_transform(const zydis_routine_t& vm_entry, zydis_decoded_instr_t* transform_instr) - { - zydis_register_t rcx_or_rdx = ZYDIS_REGISTER_NONE; - - auto handler_fetch = std::find_if( - vm_entry.begin(), vm_entry.end(), - [&](const zydis_instr_t& instr_data) -> bool - { - const auto instr = &instr_data.instr; - if (instr->mnemonic == ZYDIS_MNEMONIC_MOV && - instr->operand_count == 2 && - instr->operands[1].type == ZYDIS_OPERAND_TYPE_MEMORY && - 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)) - { - rcx_or_rdx = instr->operands[0].reg.value; - return true; - } - - return false; - } - ); - - // 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() || ++handler_fetch == vm_entry.end() || - // must be RCX or RDX... else something went wrong... - (rcx_or_rdx != ZYDIS_REGISTER_RCX && rcx_or_rdx != ZYDIS_REGISTER_RDX)) - return false; - - // find the next instruction that writes to RCX or RDX... - // the register is determined by the vm handler fetch above... - auto handler_transform = std::find_if( - handler_fetch, vm_entry.end(), - [&](const zydis_instr_t& instr_data) -> bool - { - if (instr_data.instr.operands[0].reg.value == rcx_or_rdx && - instr_data.instr.operands[0].actions & ZYDIS_OPERAND_ACTION_WRITE) - return true; - return false; - } - ); - - if (handler_transform == vm_entry.end()) - return false; - - *transform_instr = handler_transform->instr; - return true; - } - - std::uint64_t encrypt(zydis_decoded_instr_t& transform_instr, std::uint64_t val) - { - assert(transform_instr.operands[0].size == 64, - "invalid transformation for vm handler table entries..."); - - 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; - - return vm::transform::apply(bitsize, operation, val, imm); - } - - std::uint64_t decrypt(zydis_decoded_instr_t& transform_instr, std::uint64_t val) - { - assert(transform_instr.operands[0].size == 64, - "invalid transformation for vm handler table entries..."); - - const auto operation = 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; - - return vm::transform::apply(bitsize, operation, val, imm); - } - } - } -} \ No newline at end of file + namespace handler + { + 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; + }; + + auto result = std::find_if( vm_handler.begin(), vm_handler.end(), []( const zydis_instr_t &instr ) -> bool { + if ( 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 ) + return true; + + return 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... + { + zydis_routine_t::iterator last = vm_handler.end(); + result = vm_handler.begin(); + + while ( result != vm_handler.end() ) + { + result = std::find_if( ++result, vm_handler.end(), []( const zydis_instr_t &instr_data ) -> bool { + // mov/movsx/movzx rax/eax/ax/al, [rsi] + if ( instr_data.instr.operand_count > 1 && + ( instr_data.instr.mnemonic == ZYDIS_MNEMONIC_MOV || + instr_data.instr.mnemonic == ZYDIS_MNEMONIC_MOVSX || + 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 && + instr_data.instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY && + instr_data.instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RSI ) + return true; + return false; + } ); + + if ( result != vm_handler.end() ) + last = result; + } + + 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; + + for ( auto idx = 0u; idx < 256; ++idx ) + { + const auto decrypt_val = vm::handler::table::decrypt( instr, vm_handler_table[ idx ] ); + + handler_t vm_handler; + vm::transform::map_t transforms; + zydis_routine_t vm_handler_instrs; + + 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 ); + + const auto imm_size = vm::handler::imm_size( vm_handler_instrs ); + + if ( has_imm && !vm::handler::get_operand_transforms( vm_handler_instrs, transforms ) ) + return false; + + vm_handler.address = ( decrypt_val - image_base ) + module_base; + vm_handler.instrs = vm_handler_instrs; + vm_handler.imm_size = imm_size; + vm_handler.transforms = transforms; + vm_handler.profile = vm::handler::get_profile( vm_handler ); + vm_handlers.push_back( vm_handler ); + } + + return true; + } + + bool has_imm( const zydis_routine_t &vm_handler ) + { + const auto result = + std::find_if( vm_handler.begin(), vm_handler.end(), []( const zydis_instr_t &instr_data ) -> bool { + // mov/movsx/movzx rax/eax/ax/al, [rsi] + if ( instr_data.instr.operand_count > 1 && + ( instr_data.instr.mnemonic == ZYDIS_MNEMONIC_MOV || + instr_data.instr.mnemonic == ZYDIS_MNEMONIC_MOVSX || + 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 && + instr_data.instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY && + instr_data.instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RSI ) + return true; + return false; + } ); + + return result != vm_handler.end(); + } + + std::uint8_t imm_size( const zydis_routine_t &vm_handler ) + { + const auto result = + std::find_if( vm_handler.begin(), vm_handler.end(), []( const zydis_instr_t &instr_data ) -> bool { + // mov/movsx/movzx rax/eax/ax/al, [rsi] + if ( instr_data.instr.operand_count > 1 && + ( instr_data.instr.mnemonic == ZYDIS_MNEMONIC_MOV || + instr_data.instr.mnemonic == ZYDIS_MNEMONIC_MOVSX || + 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 && + instr_data.instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY && + instr_data.instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RSI ) + return true; + return false; + } ); + + if ( result == vm_handler.end() ) + return 0u; + + return result->instr.operands[ 1 ].size; + } + + bool get_operand_transforms( const zydis_routine_t &vm_handler, transform::map_t &transforms ) + { + auto imm_fetch = + std::find_if( vm_handler.begin(), vm_handler.end(), []( const zydis_instr_t &instr_data ) -> bool { + // mov/movsx/movzx rax/eax/ax/al, [rsi] + if ( instr_data.instr.operand_count > 1 && + ( instr_data.instr.mnemonic == ZYDIS_MNEMONIC_MOV || + instr_data.instr.mnemonic == ZYDIS_MNEMONIC_MOVSX || + 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 && + instr_data.instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY && + instr_data.instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RSI ) + return true; + return false; + } ); + + if ( imm_fetch == vm_handler.end() ) + return false; + + // this finds the first transformation which looks like: + // transform rax, rbx <--- note these registers can be smaller so we to64 them... + auto key_transform = + std::find_if( imm_fetch, vm_handler.end(), []( const zydis_instr_t &instr_data ) -> bool { + if ( 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 true; + return false; + } ); + + if ( key_transform == vm_handler.end() ) + return false; + + // look for a primer/instruction that alters RAX prior to the 5 transformations... + auto generic0 = std::find_if( imm_fetch + 1, key_transform, []( const zydis_instr_t &instr_data ) -> bool { + return 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; + nogeneric0.mnemonic = ZYDIS_MNEMONIC_INVALID; + + transforms[ transform::type::generic0 ] = generic0 != key_transform ? generic0->instr : nogeneric0; + + // last transformation is the same as the first except src and dest are swwapped... + transforms[ transform::type::rolling_key ] = key_transform->instr; + auto instr_copy = key_transform->instr; + instr_copy.operands[ 0 ].reg.value = key_transform->instr.operands[ 1 ].reg.value; + instr_copy.operands[ 1 ].reg.value = key_transform->instr.operands[ 0 ].reg.value; + transforms[ transform::type::update_key ] = instr_copy; + + // three generic transformations... + auto generic_transform = key_transform; + + for ( auto idx = 2u; idx < 5; ++idx ) + { + generic_transform = + std::find_if( ++generic_transform, vm_handler.end(), []( const zydis_instr_t &instr_data ) -> bool { + if ( util::reg::compare( instr_data.instr.operands[ 0 ].reg.value, ZYDIS_REGISTER_RAX ) ) + return true; + + return false; + } ); + + if ( generic_transform == vm_handler.end() ) + return false; + + transforms[ ( transform::type )( idx ) ] = generic_transform->instr; + } + + return true; + } + + vm::handler::profile_t *get_profile( handler_t &vm_handler ) + { + static const auto vcontains = []( vm::handler::profile_t *vprofile, handler_t *vm_handler ) -> bool { + if ( vprofile->imm_size != vm_handler->imm_size ) + return false; + + for ( auto &instr : vprofile->signature ) + { + const auto contains = std::find_if( + vm_handler->instrs.begin(), vm_handler->instrs.end(), + + [ & ]( zydis_instr_t &instr_data ) -> bool { return instr( instr_data.instr ); } ); + + if ( contains == vm_handler->instrs.end() ) + return false; + } + + return true; + }; + + for ( auto profile : vm::handler::profile::all ) + if ( vcontains( profile, &vm_handler ) ) + return profile; + + return nullptr; + } + + namespace table + { + 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)... + if ( 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 true; + + return false; + } ); + + if ( result == vm_entry.end() ) + return nullptr; + + std::uintptr_t ptr = 0u; + 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 ) + { + zydis_register_t rcx_or_rdx = ZYDIS_REGISTER_NONE; + + auto handler_fetch = + std::find_if( vm_entry.begin(), vm_entry.end(), [ & ]( const zydis_instr_t &instr_data ) -> bool { + const auto instr = &instr_data.instr; + if ( instr->mnemonic == ZYDIS_MNEMONIC_MOV && instr->operand_count == 2 && + instr->operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY && + 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 ) ) + { + rcx_or_rdx = instr->operands[ 0 ].reg.value; + return true; + } + + return false; + } ); + + // 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() || ++handler_fetch == vm_entry.end() || + // must be RCX or RDX... else something went wrong... + ( rcx_or_rdx != ZYDIS_REGISTER_RCX && rcx_or_rdx != ZYDIS_REGISTER_RDX ) ) + return false; + + // find the next instruction that writes to RCX or RDX... + // the register is determined by the vm handler fetch above... + auto handler_transform = + std::find_if( handler_fetch, vm_entry.end(), [ & ]( const zydis_instr_t &instr_data ) -> bool { + if ( instr_data.instr.operands[ 0 ].reg.value == rcx_or_rdx && + instr_data.instr.operands[ 0 ].actions & ZYDIS_OPERAND_ACTION_WRITE ) + return true; + return false; + } ); + + if ( handler_transform == vm_entry.end() ) + return false; + + *transform_instr = handler_transform->instr; + return true; + } + + std::uint64_t encrypt( zydis_decoded_instr_t &transform_instr, std::uint64_t val ) + { + assert( transform_instr.operands[ 0 ].size == 64, + "invalid transformation for vm handler table entries..." ); + + 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; + + return vm::transform::apply( bitsize, operation, val, imm ); + } + + std::uint64_t decrypt( zydis_decoded_instr_t &transform_instr, std::uint64_t val ) + { + assert( transform_instr.operands[ 0 ].size == 64, + "invalid transformation for vm handler table entries..." ); + + const auto operation = 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; + + return vm::transform::apply( bitsize, operation, val, imm ); + } + } // namespace table + } // namespace handler +} // namespace vm \ No newline at end of file diff --git a/src/vminstrs.cpp b/src/vminstrs.cpp index 3589a84..99ebf3f 100644 --- a/src/vminstrs.cpp +++ b/src/vminstrs.cpp @@ -2,190 +2,165 @@ namespace vm { - namespace instrs - { - std::pair decrypt_operand(transform::map_t& transforms, - std::uint64_t operand, std::uint64_t rolling_key) - { - const auto generic_decrypt_0 = &transforms[transform::type::generic0]; - const auto key_decrypt = &transforms[transform::type::rolling_key]; - const auto generic_decrypt_1 = &transforms[transform::type::generic1]; - const auto generic_decrypt_2 = &transforms[transform::type::generic2]; - const auto generic_decrypt_3 = &transforms[transform::type::generic3]; - const auto update_key = &transforms[transform::type::update_key]; - - if (generic_decrypt_0->mnemonic != ZYDIS_MNEMONIC_INVALID) - { - operand = transform::apply( - generic_decrypt_0->operands[0].size, - generic_decrypt_0->mnemonic, operand, - // check to see if this instruction has an IMM... - transform::has_imm(generic_decrypt_0) ? - generic_decrypt_0->operands[1].imm.value.u : 0); - } - - // apply transformation with rolling decrypt key... - operand = transform::apply(key_decrypt->operands[0].size, - key_decrypt->mnemonic, operand, rolling_key); - - // apply three generic transformations... - { - operand = transform::apply( - generic_decrypt_1->operands[0].size, - generic_decrypt_1->mnemonic, operand, - // check to see if this instruction has an IMM... - transform::has_imm(generic_decrypt_1) ? - generic_decrypt_1->operands[1].imm.value.u : 0); - - operand = transform::apply( - generic_decrypt_2->operands[0].size, - generic_decrypt_2->mnemonic, operand, - // check to see if this instruction has an IMM... - transform::has_imm(generic_decrypt_2) ? - generic_decrypt_2->operands[1].imm.value.u : 0); - - operand = transform::apply( - generic_decrypt_3->operands[0].size, - generic_decrypt_3->mnemonic, operand, - // check to see if this instruction has an IMM... - transform::has_imm(generic_decrypt_3) ? - generic_decrypt_3->operands[1].imm.value.u : 0); - } - - // update rolling key... - auto result = transform::apply(update_key->operands[0].size, - update_key->mnemonic, rolling_key, operand); - - // update decryption key correctly... - switch (update_key->operands[0].size) - { - case 8: - rolling_key = (rolling_key & ~0xFFull) + result; - break; - case 16: - rolling_key = (rolling_key & ~0xFFFFull) + result; - break; - default: - rolling_key = result; - break; - } - - return { operand, rolling_key }; - } - - std::pair encrypt_operand(transform::map_t& transforms, - std::uint64_t operand, std::uint64_t rolling_key) - { - transform::map_t inverse; - inverse_transforms(transforms, inverse); - - const auto generic_decrypt_0 = &inverse[transform::type::generic0]; - const auto key_decrypt = &inverse[transform::type::rolling_key]; - const auto generic_decrypt_1 = &inverse[transform::type::generic1]; - const auto generic_decrypt_2 = &inverse[transform::type::generic2]; - const auto generic_decrypt_3 = &inverse[transform::type::generic3]; - const auto update_key = &inverse[transform::type::update_key]; - - auto result = transform::apply(update_key->operands[0].size, - update_key->mnemonic, rolling_key, operand); - - // make sure we update the rolling decryption key correctly... - switch (update_key->operands[0].size) - { - case 8: - rolling_key = (rolling_key & ~0xFFull) + result; - break; - case 16: - rolling_key = (rolling_key & ~0xFFFFull) + result; - break; - default: - rolling_key = result; - break; - } - - { - operand = transform::apply( - generic_decrypt_3->operands[0].size, - generic_decrypt_3->mnemonic, operand, - // check to see if this instruction has an IMM... - transform::has_imm(generic_decrypt_3) ? - generic_decrypt_3->operands[1].imm.value.u : 0); - - operand = transform::apply( - generic_decrypt_2->operands[0].size, - generic_decrypt_2->mnemonic, operand, - // check to see if this instruction has an IMM... - transform::has_imm(generic_decrypt_2) ? - generic_decrypt_2->operands[1].imm.value.u : 0); - - operand = transform::apply( - generic_decrypt_1->operands[0].size, - generic_decrypt_1->mnemonic, operand, - // check to see if this instruction has an IMM... - transform::has_imm(generic_decrypt_1) ? - generic_decrypt_1->operands[1].imm.value.u : 0); - } - - operand = transform::apply(key_decrypt->operands[0].size, - key_decrypt->mnemonic, operand, rolling_key); - - if (generic_decrypt_0->mnemonic != ZYDIS_MNEMONIC_INVALID) - { - operand = transform::apply( - generic_decrypt_0->operands[0].size, - generic_decrypt_0->mnemonic, operand, - // check to see if this instruction has an IMM... - transform::has_imm(generic_decrypt_0) ? - generic_decrypt_0->operands[1].imm.value.u : 0); - } - - return { operand, rolling_key }; - } - - bool get_rva_decrypt( - const zydis_routine_t& vm_entry, std::vector& transform_instrs) - { - // - // find mov esi, [rsp+0xA0] - // - - auto result = std::find_if(vm_entry.begin(), vm_entry.end(), - [](const zydis_instr_t& instr_data) -> bool - { - if (instr_data.instr.mnemonic == ZYDIS_MNEMONIC_MOV && - instr_data.instr.operand_count == 2 && - instr_data.instr.operands[0].reg.value == ZYDIS_REGISTER_ESI && - instr_data.instr.operands[1].mem.base == ZYDIS_REGISTER_RSP && - instr_data.instr.operands[1].mem.disp.has_displacement && - instr_data.instr.operands[1].mem.disp.value == 0xA0) - return true; - return false; - } - ); - - if (result == vm_entry.end()) - return false; - - // - // find the next three instruction with ESI as the dest... - // - - for (auto idx = 0u; idx < 3; ++idx) - { - result = std::find_if(++result, vm_entry.end(), - [](const zydis_instr_t& instr_data) -> bool - { - return instr_data.instr.operands[0].reg.value == ZYDIS_REGISTER_ESI; - } - ); - - if (result == vm_entry.end()) - return false; - - transform_instrs.push_back(result->instr); - } - - return true; - } - } -} \ No newline at end of file + namespace instrs + { + std::pair< std::uint64_t, std::uint64_t > decrypt_operand( transform::map_t &transforms, std::uint64_t operand, + std::uint64_t rolling_key ) + { + const auto generic_decrypt_0 = &transforms[ transform::type::generic0 ]; + const auto key_decrypt = &transforms[ transform::type::rolling_key ]; + const auto generic_decrypt_1 = &transforms[ transform::type::generic1 ]; + const auto generic_decrypt_2 = &transforms[ transform::type::generic2 ]; + const auto generic_decrypt_3 = &transforms[ transform::type::generic3 ]; + const auto update_key = &transforms[ transform::type::update_key ]; + + if ( generic_decrypt_0->mnemonic != ZYDIS_MNEMONIC_INVALID ) + { + operand = transform::apply( + generic_decrypt_0->operands[ 0 ].size, generic_decrypt_0->mnemonic, operand, + // check to see if this instruction has an IMM... + transform::has_imm( generic_decrypt_0 ) ? generic_decrypt_0->operands[ 1 ].imm.value.u : 0 ); + } + + // apply transformation with rolling decrypt key... + operand = transform::apply( key_decrypt->operands[ 0 ].size, key_decrypt->mnemonic, operand, rolling_key ); + + // apply three generic transformations... + { + operand = transform::apply( + generic_decrypt_1->operands[ 0 ].size, generic_decrypt_1->mnemonic, operand, + // check to see if this instruction has an IMM... + transform::has_imm( generic_decrypt_1 ) ? generic_decrypt_1->operands[ 1 ].imm.value.u : 0 ); + + operand = transform::apply( + generic_decrypt_2->operands[ 0 ].size, generic_decrypt_2->mnemonic, operand, + // check to see if this instruction has an IMM... + transform::has_imm( generic_decrypt_2 ) ? generic_decrypt_2->operands[ 1 ].imm.value.u : 0 ); + + operand = transform::apply( + generic_decrypt_3->operands[ 0 ].size, generic_decrypt_3->mnemonic, operand, + // check to see if this instruction has an IMM... + transform::has_imm( generic_decrypt_3 ) ? generic_decrypt_3->operands[ 1 ].imm.value.u : 0 ); + } + + // update rolling key... + auto result = + transform::apply( update_key->operands[ 0 ].size, update_key->mnemonic, rolling_key, operand ); + + // update decryption key correctly... + switch ( update_key->operands[ 0 ].size ) + { + case 8: + rolling_key = ( rolling_key & ~0xFFull ) + result; + break; + case 16: + rolling_key = ( rolling_key & ~0xFFFFull ) + result; + break; + default: + rolling_key = result; + break; + } + + return { operand, rolling_key }; + } + + std::pair< std::uint64_t, std::uint64_t > encrypt_operand( transform::map_t &transforms, std::uint64_t operand, + std::uint64_t rolling_key ) + { + transform::map_t inverse; + inverse_transforms( transforms, inverse ); + + const auto generic_decrypt_0 = &inverse[ transform::type::generic0 ]; + const auto key_decrypt = &inverse[ transform::type::rolling_key ]; + const auto generic_decrypt_1 = &inverse[ transform::type::generic1 ]; + const auto generic_decrypt_2 = &inverse[ transform::type::generic2 ]; + const auto generic_decrypt_3 = &inverse[ transform::type::generic3 ]; + const auto update_key = &inverse[ transform::type::update_key ]; + + auto result = + transform::apply( update_key->operands[ 0 ].size, update_key->mnemonic, rolling_key, operand ); + + // make sure we update the rolling decryption key correctly... + switch ( update_key->operands[ 0 ].size ) + { + case 8: + rolling_key = ( rolling_key & ~0xFFull ) + result; + break; + case 16: + rolling_key = ( rolling_key & ~0xFFFFull ) + result; + break; + default: + rolling_key = result; + break; + } + + { + operand = transform::apply( + generic_decrypt_3->operands[ 0 ].size, generic_decrypt_3->mnemonic, operand, + // check to see if this instruction has an IMM... + transform::has_imm( generic_decrypt_3 ) ? generic_decrypt_3->operands[ 1 ].imm.value.u : 0 ); + + operand = transform::apply( + generic_decrypt_2->operands[ 0 ].size, generic_decrypt_2->mnemonic, operand, + // check to see if this instruction has an IMM... + transform::has_imm( generic_decrypt_2 ) ? generic_decrypt_2->operands[ 1 ].imm.value.u : 0 ); + + operand = transform::apply( + generic_decrypt_1->operands[ 0 ].size, generic_decrypt_1->mnemonic, operand, + // check to see if this instruction has an IMM... + transform::has_imm( generic_decrypt_1 ) ? generic_decrypt_1->operands[ 1 ].imm.value.u : 0 ); + } + + operand = transform::apply( key_decrypt->operands[ 0 ].size, key_decrypt->mnemonic, operand, rolling_key ); + + if ( generic_decrypt_0->mnemonic != ZYDIS_MNEMONIC_INVALID ) + { + operand = transform::apply( + generic_decrypt_0->operands[ 0 ].size, generic_decrypt_0->mnemonic, operand, + // check to see if this instruction has an IMM... + transform::has_imm( generic_decrypt_0 ) ? generic_decrypt_0->operands[ 1 ].imm.value.u : 0 ); + } + + return { operand, rolling_key }; + } + + bool get_rva_decrypt( const zydis_routine_t &vm_entry, std::vector< zydis_decoded_instr_t > &transform_instrs ) + { + // + // find mov esi, [rsp+0xA0] + // + + auto result = + std::find_if( vm_entry.begin(), vm_entry.end(), []( const zydis_instr_t &instr_data ) -> bool { + if ( instr_data.instr.mnemonic == ZYDIS_MNEMONIC_MOV && instr_data.instr.operand_count == 2 && + instr_data.instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_ESI && + instr_data.instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RSP && + instr_data.instr.operands[ 1 ].mem.disp.has_displacement && + instr_data.instr.operands[ 1 ].mem.disp.value == 0xA0 ) + return true; + return false; + } ); + + if ( result == vm_entry.end() ) + return false; + + // + // find the next three instruction with ESI as the dest... + // + + for ( auto idx = 0u; idx < 3; ++idx ) + { + result = std::find_if( ++result, vm_entry.end(), []( const zydis_instr_t &instr_data ) -> bool { + return instr_data.instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_ESI; + } ); + + if ( result == vm_entry.end() ) + return false; + + transform_instrs.push_back( result->instr ); + } + + return true; + } + } // namespace instrs +} // namespace vm \ No newline at end of file diff --git a/src/vmprofiler.vcxproj b/src/vmprofiler.vcxproj index 6d3efbe..b5c3895 100644 --- a/src/vmprofiler.vcxproj +++ b/src/vmprofiler.vcxproj @@ -172,6 +172,9 @@ {88a23124-5640-35a0-b890-311d7a67a7d2} + + + diff --git a/src/vmprofiler.vcxproj.filters b/src/vmprofiler.vcxproj.filters index e8d15e1..4de8ca3 100644 --- a/src/vmprofiler.vcxproj.filters +++ b/src/vmprofiler.vcxproj.filters @@ -27,6 +27,9 @@ {388154c1-cb08-493f-88fb-7e16cfffa010} + + {5bb0ecc9-da37-4a13-8958-3c8eef2ceab5} + @@ -224,4 +227,9 @@ Header Files + + + Resources + + \ No newline at end of file diff --git a/src/vmprofiles/add.cpp b/src/vmprofiles/add.cpp index 9b848e2..8292dde 100644 --- a/src/vmprofiles/add.cpp +++ b/src/vmprofiles/add.cpp @@ -2,75 +2,61 @@ namespace vm { - namespace handler - { - namespace profile - { - vm::handler::profile_t addq = - { - // ADD [RBP+8], RAX - // PUSHFQ - // POP [RBP] - "ADDQ", ADDQ, NULL, - { - { - // ADD [RBP+8], RAX - [](const zydis_decoded_instr_t& instr) -> bool - { - return instr.mnemonic == ZYDIS_MNEMONIC_ADD && - instr.operands[0].type == ZYDIS_OPERAND_TYPE_MEMORY && - instr.operands[1].mem.base == ZYDIS_REGISTER_RBP && - 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 profile + { + vm::handler::profile_t addq = { + // ADD [RBP+8], RAX + // PUSHFQ + // POP [RBP] + "ADDQ", + ADDQ, + NULL, + { { // ADD [RBP+8], RAX + []( const zydis_decoded_instr_t &instr ) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_ADD && + instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY && + instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP && + 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; + } } } }; - vm::handler::profile_t adddw = - { - // ADD [RBP+8], EAX - // PUSHFQ - // POP [RBP] - "ADDDW", ADDDW, NULL, - { - { - // ADD [RBP+8], EAX - [](const zydis_decoded_instr_t& instr) -> bool - { - return instr.mnemonic == ZYDIS_MNEMONIC_ADD && - instr.operands[0].type == ZYDIS_OPERAND_TYPE_MEMORY && - instr.operands[1].mem.base == ZYDIS_REGISTER_RBP && - 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; - }, - // 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; - } - } - } - }; - } - } -} \ No newline at end of file + vm::handler::profile_t adddw = { + // ADD [RBP+8], EAX + // PUSHFQ + // POP [RBP] + "ADDDW", + ADDDW, + NULL, + { { // ADD [RBP+8], EAX + []( const zydis_decoded_instr_t &instr ) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_ADD && + instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY && + instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP && + 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; + }, + // 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/div.cpp b/src/vmprofiles/div.cpp index 1e53563..e69c211 100644 --- a/src/vmprofiles/div.cpp +++ b/src/vmprofiles/div.cpp @@ -2,84 +2,73 @@ namespace vm { - namespace handler - { - namespace profile - { - vm::handler::profile_t divq = - { - // MOV RDX, [RBP] - // MOV RAX, [RBP+0x8] - // DIV [RBP+0x10] - // MOV [RBP+0x8], RDX - // MOV [RBP+0x10], RAX - // PUSHFQ - // POP [RBP] - "DIVQ", DIVQ, 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; - }, - // MOV RAX, [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_RAX && - instr.operands[1].type == ZYDIS_OPERAND_TYPE_MEMORY && - instr.operands[1].mem.base == ZYDIS_REGISTER_RBP && - instr.operands[1].mem.index == 0x8; - }, - // DIV [RBP+0x10] - [](const zydis_decoded_instr_t& instr) -> bool - { - return instr.mnemonic == ZYDIS_MNEMONIC_DIV && - instr.operands[0].type == ZYDIS_OPERAND_TYPE_MEMORY && - instr.operands[0].mem.base == ZYDIS_REGISTER_RBP && - instr.operands[0].mem.index == 0x10; - }, - // MOV [RBP+0x8], 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_RBP && - instr.operands[0].mem.index == 0x8 && - instr.operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER && - instr.operands[1].reg.value == ZYDIS_REGISTER_RDX; - }, - // MOV [RBP+0x10], 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[0].mem.index == 0x10 && - 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; - } - } - } - }; - } - } -} \ No newline at end of file + namespace handler + { + namespace profile + { + vm::handler::profile_t divq = { + // MOV RDX, [RBP] + // MOV RAX, [RBP+0x8] + // DIV [RBP+0x10] + // MOV [RBP+0x8], RDX + // MOV [RBP+0x10], RAX + // PUSHFQ + // POP [RBP] + "DIVQ", + DIVQ, + 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; + }, + // MOV RAX, [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_RAX && + instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY && + instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP && + instr.operands[ 1 ].mem.index == 0x8; + }, + // DIV [RBP+0x10] + []( const zydis_decoded_instr_t &instr ) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_DIV && + instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY && + instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP && + instr.operands[ 0 ].mem.index == 0x10; + }, + // MOV [RBP+0x8], 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_RBP && + instr.operands[ 0 ].mem.index == 0x8 && + instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER && + instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RDX; + }, + // MOV [RBP+0x10], 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[ 0 ].mem.index == 0x10 && + 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 \ No newline at end of file diff --git a/src/vmprofiles/jmp.cpp b/src/vmprofiles/jmp.cpp index 9aca0db..dc2a94e 100644 --- a/src/vmprofiles/jmp.cpp +++ b/src/vmprofiles/jmp.cpp @@ -2,58 +2,50 @@ namespace vm { - namespace handler - { - namespace profile - { - vm::handler::profile_t jmp = - { - // MOV ESI, [RBP] - // ADD RSI, RAX - // MOV RBX, RSI - // ADD RSI, [RBP] - "JMP", JMP, NULL, - { - { - // MOV ESI, [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_ESI && - instr.operands[1].type == ZYDIS_OPERAND_TYPE_MEMORY && - instr.operands[1].mem.base == ZYDIS_REGISTER_RBP; - }, - // ADD RSI, RAX - [](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_RSI && - instr.operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER && - instr.operands[1].reg.value == ZYDIS_REGISTER_RAX; - }, - // MOV RBX, RSI - [](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_RBX && - instr.operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER && - instr.operands[1].reg.value == ZYDIS_REGISTER_RSI; - }, - // ADD RSI, [RBP] - [](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_RSI && - instr.operands[1].type == ZYDIS_OPERAND_TYPE_MEMORY && - instr.operands[1].mem.base == ZYDIS_REGISTER_RBP; - } - } - } - }; - } - } -} \ No newline at end of file + namespace handler + { + namespace profile + { + vm::handler::profile_t jmp = { + // MOV ESI, [RBP] + // ADD RSI, RAX + // MOV RBX, RSI + // ADD RSI, [RBP] + "JMP", + JMP, + NULL, + { { // MOV ESI, [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_ESI && + instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY && + instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP; + }, + // ADD RSI, RAX + []( 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_RSI && + instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER && + instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RAX; + }, + // MOV RBX, RSI + []( 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_RBX && + instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER && + instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RSI; + }, + // ADD RSI, [RBP] + []( 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_RSI && + instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY && + instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP; + } } } }; + } + } // namespace handler +} // namespace vm \ No newline at end of file diff --git a/src/vmprofiles/lconst.cpp b/src/vmprofiles/lconst.cpp index 83991f2..863bb5a 100644 --- a/src/vmprofiles/lconst.cpp +++ b/src/vmprofiles/lconst.cpp @@ -2,204 +2,161 @@ namespace vm { - namespace handler - { - namespace profile - { - vm::handler::profile_t lconstq = - { - // MOV RAX, [RSI] - // SUB RBP, 8 - // MOV [RBP], RAX - "LCONSTQ", LCONSTQ, 64, - { - { - // SUB RBP, 8 - [](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; - } - } - } - }; + namespace handler + { + namespace profile + { + vm::handler::profile_t lconstq = { + // MOV RAX, [RSI] + // SUB RBP, 8 + // MOV [RBP], RAX + "LCONSTQ", + LCONSTQ, + 64, + { { // SUB RBP, 8 + []( 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::profile_t lconstbzxw = - { - // MOV AL, [RSI] - // SUB RBP, 2 - // MOV [RBP], AX - "LCONSTBZXW", LCONSTBZXW, 8, - { - { - // 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 + // MOV [RBP], AX + "LCONSTBZXW", + LCONSTBZXW, + 8, + { { // 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 lconstbsxdw = - { - // CWDE - // SUB RBP, 4 - // MOV [RBP], EAX - "LCONSTBSXDW", LCONSTBSXDW, 8, - { - { - // 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 && - 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::extention_t::sign_extend - }; + vm::handler::profile_t lconstbsxdw = { + // CWDE + // SUB RBP, 4 + // MOV [RBP], EAX + "LCONSTBSXDW", + LCONSTBSXDW, + 8, + { { // 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 && + 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::extention_t::sign_extend }; - vm::handler::profile_t lconstdwsxq = - { - // CDQE - // SUB RBP, 8 - // MOV [RBP], RAX - "LCONSTDWSXQ", LCONSTDWSXQ, 32, - { - // CDQE - [](const zydis_decoded_instr_t& instr) -> bool - { - return instr.mnemonic == ZYDIS_MNEMONIC_CDQE; - }, - // SUB RBP, 8 - [](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 + // MOV [RBP], RAX + "LCONSTDWSXQ", + LCONSTDWSXQ, + 32, + { // CDQE + []( const zydis_decoded_instr_t &instr ) -> bool { return instr.mnemonic == ZYDIS_MNEMONIC_CDQE; }, + // SUB RBP, 8 + []( 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 lconstwsxq = - { - // CDQE - // SUB RBP, 8 - // MOV [RBP], RAX - "LCONSTWSXQ", LCONSTWSXQ, 16, - { - { - // CDQE - [](const zydis_decoded_instr_t& instr) -> bool - { - return instr.mnemonic == ZYDIS_MNEMONIC_CDQE; - }, - // SUB RBP, 8 - [](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 lconstwsxq = { + // CDQE + // SUB RBP, 8 + // MOV [RBP], RAX + "LCONSTWSXQ", + LCONSTWSXQ, + 16, + { { // CDQE + []( const zydis_decoded_instr_t &instr ) -> bool { return instr.mnemonic == ZYDIS_MNEMONIC_CDQE; }, + // SUB RBP, 8 + []( 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 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; - } - } - } - }; - } - } -} \ No newline at end of file + 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; + } } } }; + } // namespace profile + } // namespace handler +} // namespace vm \ No newline at end of file diff --git a/src/vmprofiles/lreg.cpp b/src/vmprofiles/lreg.cpp index 847e598..265311d 100644 --- a/src/vmprofiles/lreg.cpp +++ b/src/vmprofiles/lreg.cpp @@ -2,94 +2,80 @@ namespace vm { - namespace handler - { - namespace profile - { - vm::handler::profile_t lregq = - { - // MOV RDX, [RAX+RDI] - // SUB RBP, 8 - // MOV [RBP], RDX - "LREGQ", LREGQ, 8, - { - { - // MOV RDX, [RAX+RDI] or MOV RDX, [RDI+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_RDX && - instr.operands[1].type == ZYDIS_OPERAND_TYPE_MEMORY && - (instr.operands[1].mem.base == ZYDIS_REGISTER_RAX || - instr.operands[1].mem.base == ZYDIS_REGISTER_RDI) && - (instr.operands[1].mem.index == ZYDIS_REGISTER_RDI || - instr.operands[1].mem.index == ZYDIS_REGISTER_RAX); - }, - // SUB RBP, 8 - [](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], 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_RBP && - instr.operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER && - instr.operands[1].reg.value == ZYDIS_REGISTER_RDX; - } - } - } - }; + namespace handler + { + namespace profile + { + vm::handler::profile_t lregq = { + // MOV RDX, [RAX+RDI] + // SUB RBP, 8 + // MOV [RBP], RDX + "LREGQ", + LREGQ, + 8, + { { // MOV RDX, [RAX+RDI] or MOV RDX, [RDI+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_RDX && + instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY && + ( instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RAX || + instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RDI ) && + ( instr.operands[ 1 ].mem.index == ZYDIS_REGISTER_RDI || + instr.operands[ 1 ].mem.index == ZYDIS_REGISTER_RAX ); + }, + // SUB RBP, 8 + []( 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], 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_RBP && + instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER && + instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RDX; + } } } }; - vm::handler::profile_t lregdw = - { - // MOVZX AL, [RSI] - // MOV RDX, [RAX + RDI] - // SUB RBP, 0x4 - // MOV [RBP], EDX - "LREGDW", LREGDW, 8, - { - { - // MOV RDX, [RAX + RDI] or MOV RDX, [RDI + 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_EDX && - instr.operands[1].type == ZYDIS_OPERAND_TYPE_MEMORY && - (instr.operands[1].mem.base == ZYDIS_REGISTER_RAX || - instr.operands[1].mem.base == ZYDIS_REGISTER_RDI) && - (instr.operands[1].mem.index == ZYDIS_REGISTER_RAX || - instr.operands[1].mem.index == ZYDIS_REGISTER_RDI); - }, - // SUB RBP, 0x4 - [](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], EDX - [](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_EDX; - } - } - } - }; - } - } -} \ No newline at end of file + vm::handler::profile_t lregdw = { + // MOVZX AL, [RSI] + // MOV RDX, [RAX + RDI] + // SUB RBP, 0x4 + // MOV [RBP], EDX + "LREGDW", + LREGDW, + 8, + { { // MOV RDX, [RAX + RDI] or MOV RDX, [RDI + 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_EDX && + instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY && + ( instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RAX || + instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RDI ) && + ( instr.operands[ 1 ].mem.index == ZYDIS_REGISTER_RAX || + instr.operands[ 1 ].mem.index == ZYDIS_REGISTER_RDI ); + }, + // SUB RBP, 0x4 + []( 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], EDX + []( 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_EDX; + } } } }; + } // namespace profile + } // namespace handler +} // namespace vm \ No newline at end of file diff --git a/src/vmprofiles/mul.cpp b/src/vmprofiles/mul.cpp index 6b73a40..d8b85e1 100644 --- a/src/vmprofiles/mul.cpp +++ b/src/vmprofiles/mul.cpp @@ -2,83 +2,72 @@ namespace vm { - namespace handler - { - namespace profile - { - vm::handler::profile_t mulq = - { - // MOV RAX, [RBP+0x8] - // SUB RBP, 0x8 - // MUL RDX - // MOV [RBP+0x8], RDX - // MOV [RBP+0x10], RAX - // PUSHFQ - // POP [RBP] - "MULQ", MULQ, NULL, - { - { - // MOV RAX, [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_RAX && - instr.operands[1].type == ZYDIS_OPERAND_TYPE_MEMORY && - instr.operands[1].mem.base == ZYDIS_REGISTER_RBP && - instr.operands[1].mem.index == 0x8; - }, - // 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; - }, - // MUL RDX - [](const zydis_decoded_instr_t& instr) -> bool - { - return instr.mnemonic == ZYDIS_MNEMONIC_MUL && - instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && - instr.operands[0].reg.value == ZYDIS_REGISTER_RDX; - }, - // MOV [RBP+0x8], 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_RBP && - instr.operands[0].mem.index == 0x8 && - instr.operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER && - instr.operands[1].reg.value == ZYDIS_REGISTER_RDX; - }, - // MOV [RBP+0x10], 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[0].mem.index == 0x10 && - 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; - } - } - } - }; - } - } -} \ No newline at end of file + namespace handler + { + namespace profile + { + vm::handler::profile_t mulq = { + // MOV RAX, [RBP+0x8] + // SUB RBP, 0x8 + // MUL RDX + // MOV [RBP+0x8], RDX + // MOV [RBP+0x10], RAX + // PUSHFQ + // POP [RBP] + "MULQ", + MULQ, + NULL, + { { // MOV RAX, [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_RAX && + instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY && + instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP && + instr.operands[ 1 ].mem.index == 0x8; + }, + // 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; + }, + // MUL RDX + []( const zydis_decoded_instr_t &instr ) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_MUL && + instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER && + instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RDX; + }, + // MOV [RBP+0x8], 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_RBP && + instr.operands[ 0 ].mem.index == 0x8 && + instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER && + instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RDX; + }, + // MOV [RBP+0x10], 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[ 0 ].mem.index == 0x10 && + 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 \ No newline at end of file diff --git a/src/vmprofiles/nand.cpp b/src/vmprofiles/nand.cpp index 0934e20..f4bceca 100644 --- a/src/vmprofiles/nand.cpp +++ b/src/vmprofiles/nand.cpp @@ -2,152 +2,129 @@ namespace vm { - namespace handler - { - namespace profile - { - vm::handler::profile_t nandq = - { - // MOV RAX, [RBP] - // MOV RDX, [RBP+8] - // NOT RAX - // NOT RDX - // AND RAX, RDX - // MOV [RBP], RAX - // PUSHFQ - // POP [RBP] - "NANDQ", NANDQ, 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 RDX, [RBP+8] - [](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 && - instr.operands[1].mem.index == 0x8; - }, - // NOT RAX - [](const zydis_decoded_instr_t& instr) -> bool - { - return instr.mnemonic == ZYDIS_MNEMONIC_NOT && - instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && - instr.operands[0].reg.value == ZYDIS_REGISTER_RAX; - }, - // NOT RDX - [](const zydis_decoded_instr_t& instr) -> bool - { - return instr.mnemonic == ZYDIS_MNEMONIC_NOT && - instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && - instr.operands[0].reg.value == ZYDIS_REGISTER_RDX; - }, - // AND RAX, RDX - [](const zydis_decoded_instr_t& instr) -> bool - { - return instr.mnemonic == ZYDIS_MNEMONIC_AND && - instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && - instr.operands[0].reg.value == ZYDIS_REGISTER_RAX && - instr.operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER && - instr.operands[1].reg.value == ZYDIS_REGISTER_RDX; - }, - // 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; - }, - // 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 profile + { + vm::handler::profile_t nandq = { + // MOV RAX, [RBP] + // MOV RDX, [RBP+8] + // NOT RAX + // NOT RDX + // AND RAX, RDX + // MOV [RBP], RAX + // PUSHFQ + // POP [RBP] + "NANDQ", + NANDQ, + 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 RDX, [RBP+8] + []( 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 && + instr.operands[ 1 ].mem.index == 0x8; + }, + // NOT RAX + []( const zydis_decoded_instr_t &instr ) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_NOT && + instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER && + instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX; + }, + // NOT RDX + []( const zydis_decoded_instr_t &instr ) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_NOT && + instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER && + instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RDX; + }, + // AND RAX, RDX + []( const zydis_decoded_instr_t &instr ) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_AND && + instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER && + instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX && + instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER && + instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RDX; + }, + // 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; + }, + // 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 = - { - // NOT DWORD PTR [RBP] - // MOV AX, [RBP] - // SUB RBP, 0x6 - // AND [RBP+0x8], AX - // PUSHFQ - // POP [RBP] - "NANDDW", NANDDW, NULL, - { - { - // NOT DWORD PTR [RBP] - [](const zydis_decoded_instr_t& instr) -> bool - { - return instr.mnemonic == ZYDIS_MNEMONIC_NOT && - instr.operands[0].type == ZYDIS_OPERAND_TYPE_MEMORY && - instr.operands[0].size == 32 && - instr.operands[0].mem.base == ZYDIS_REGISTER_RBP; - }, - // 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; - }, - // 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; - }, - // AND [RBP+0x8], AX - [](const zydis_decoded_instr_t& instr) -> bool - { - return instr.mnemonic == ZYDIS_MNEMONIC_AND && - instr.operands[0].type == ZYDIS_OPERAND_TYPE_MEMORY && - instr.operands[0].mem.base == ZYDIS_REGISTER_RBP && - instr.operands[0].mem.index == 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; - } - } - } - }; - } - } -} \ No newline at end of file + vm::handler::profile_t nanddw = { + // NOT DWORD PTR [RBP] + // MOV AX, [RBP] + // SUB RBP, 0x6 + // AND [RBP+0x8], AX + // PUSHFQ + // POP [RBP] + "NANDDW", + NANDDW, + NULL, + { { // NOT DWORD PTR [RBP] + []( const zydis_decoded_instr_t &instr ) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_NOT && + instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY && + instr.operands[ 0 ].size == 32 && instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP; + }, + // 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; + }, + // 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; + }, + // AND [RBP+0x8], AX + []( const zydis_decoded_instr_t &instr ) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_AND && + instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY && + instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP && + instr.operands[ 0 ].mem.index == 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/pushvsp.cpp b/src/vmprofiles/pushvsp.cpp index 56e2d08..2995c7f 100644 --- a/src/vmprofiles/pushvsp.cpp +++ b/src/vmprofiles/pushvsp.cpp @@ -2,47 +2,40 @@ namespace vm { - namespace handler - { - namespace profile - { - vm::handler::profile_t pushvsp = - { - // MOV RAX, RBP - // SUB RBP, 8 - "PUSHVSP", PUSHVSP, 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_REGISTER && - instr.operands[1].reg.value == ZYDIS_REGISTER_RBP; - }, - // SUB RBP, 8 - [](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; - } - } - } - }; - } - } -} \ No newline at end of file + namespace handler + { + namespace profile + { + vm::handler::profile_t pushvsp = { + // MOV RAX, RBP + // SUB RBP, 8 + "PUSHVSP", + PUSHVSP, + 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_REGISTER && + instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RBP; + }, + // SUB RBP, 8 + []( 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; + } } } }; + } + } // namespace handler +} // namespace vm \ No newline at end of file diff --git a/src/vmprofiles/read.cpp b/src/vmprofiles/read.cpp index 0d8570e..a05a92b 100644 --- a/src/vmprofiles/read.cpp +++ b/src/vmprofiles/read.cpp @@ -2,48 +2,41 @@ namespace vm { - namespace handler - { - namespace profile - { - vm::handler::profile_t readq = - { - // MOV RAX, [RBP] - // MOV RAX, [RAX] - // MOV [RBP], RAX - "READQ", READQ, 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 RAX, [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_RAX && - instr.operands[1].type == ZYDIS_OPERAND_TYPE_MEMORY && - instr.operands[1].mem.base == ZYDIS_REGISTER_RAX; - }, - // 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; - } - } - } - }; - } - } -} \ No newline at end of file + namespace handler + { + namespace profile + { + vm::handler::profile_t readq = { + // MOV RAX, [RBP] + // MOV RAX, [RAX] + // MOV [RBP], RAX + "READQ", + READQ, + 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 RAX, [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_RAX && + instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY && + instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RAX; + }, + // 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; + } } } }; + } + } // namespace handler +} // namespace vm \ No newline at end of file diff --git a/src/vmprofiles/shl.cpp b/src/vmprofiles/shl.cpp index a8b9aa7..a0355b8 100644 --- a/src/vmprofiles/shl.cpp +++ b/src/vmprofiles/shl.cpp @@ -2,159 +2,137 @@ namespace vm { - namespace handler - { - namespace profile - { - vm::handler::profile_t shlq = - { - // MOV RAX, [RBP] - // MOV CL, [RBP+0x8] - // SUB RBP, 0x6 - // SHL RAX, CL - // MOV [RBP+0x8], RAX - // PUSHFQ - // POP [RBP] - "SHLQ", SHLQ, 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 CL, [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_CL && - instr.operands[1].type == ZYDIS_OPERAND_TYPE_MEMORY && - instr.operands[1].mem.base == ZYDIS_REGISTER_RBP && - instr.operands[1].mem.index == 0x8; - }, - // 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; - }, - // SHL RAX, CL - [](const zydis_decoded_instr_t& instr) -> bool - { - return instr.mnemonic == ZYDIS_MNEMONIC_SHL && - instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && - instr.operands[0].reg.value == ZYDIS_REGISTER_RAX && - instr.operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER && - instr.operands[1].reg.value == ZYDIS_REGISTER_CL; - }, - // MOV [RBP+0x8], 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[0].mem.index == 0x8 && - 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 profile + { + vm::handler::profile_t shlq = { + // MOV RAX, [RBP] + // MOV CL, [RBP+0x8] + // SUB RBP, 0x6 + // SHL RAX, CL + // MOV [RBP+0x8], RAX + // PUSHFQ + // POP [RBP] + "SHLQ", + SHLQ, + 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 CL, [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_CL && + instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY && + instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP && + instr.operands[ 1 ].mem.index == 0x8; + }, + // 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; + }, + // SHL RAX, CL + []( const zydis_decoded_instr_t &instr ) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_SHL && + instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER && + instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX && + instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER && + instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_CL; + }, + // MOV [RBP+0x8], 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[ 0 ].mem.index == 0x8 && + 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; + } } } }; - vm::handler::profile_t shldw = - { - // MOV EAX, [RBP] - // MOV CL, [RBP+0x4] - // SUB RBP, 0x6 - // SHL EAX, CL - // MOV [RBP+0x8], EAX - // PUSHFQ - // POP [RBP] - "SHLQ", SHLQ, NULL, - { - { - // MOV EAX, [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_EAX && - instr.operands[1].type == ZYDIS_OPERAND_TYPE_MEMORY && - instr.operands[1].mem.base == ZYDIS_REGISTER_RBP; - }, - // MOV CL, [RBP+0x4] - [](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.index == 0x4; - }, - // 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; - }, - // SHL EAX, CL - [](const zydis_decoded_instr_t& instr) -> bool - { - return instr.mnemonic == ZYDIS_MNEMONIC_SHL && - instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && - instr.operands[0].reg.value == ZYDIS_REGISTER_EAX && - instr.operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER && - instr.operands[1].reg.value == ZYDIS_REGISTER_CL; - }, - // MOV [RBP+0x8], 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[0].mem.index == 0x8 && - 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; - }, - // 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; - } - } - } - }; - } - } -} \ No newline at end of file + vm::handler::profile_t shldw = { + // MOV EAX, [RBP] + // MOV CL, [RBP+0x4] + // SUB RBP, 0x6 + // SHL EAX, CL + // MOV [RBP+0x8], EAX + // PUSHFQ + // POP [RBP] + "SHLQ", + SHLQ, + NULL, + { { // MOV EAX, [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_EAX && + instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY && + instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP; + }, + // MOV CL, [RBP+0x4] + []( 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.index == 0x4; + }, + // 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; + }, + // SHL EAX, CL + []( const zydis_decoded_instr_t &instr ) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_SHL && + instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER && + instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_EAX && + instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER && + instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_CL; + }, + // MOV [RBP+0x8], 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[ 0 ].mem.index == 0x8 && + 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; + }, + // 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/shr.cpp b/src/vmprofiles/shr.cpp index 5ac355f..eadbf0c 100644 --- a/src/vmprofiles/shr.cpp +++ b/src/vmprofiles/shr.cpp @@ -2,84 +2,73 @@ namespace vm { - namespace handler - { - namespace profile - { - vm::handler::profile_t shrq = - { - // MOV RAX, [RBP] - // MOV CL, [RBP+0x8] - // SUB RBP, 0x6 - // SHR RAX, CL - // MOV [RBP+0x8], RAX - // PUSHFQ - // POP [RBP] - "SHRQ", SHRQ, 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 CL, [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_CL && - instr.operands[1].type == ZYDIS_OPERAND_TYPE_MEMORY && - instr.operands[1].mem.base == ZYDIS_REGISTER_RBP && - instr.operands[1].mem.index == 0x8; - }, - // 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 RAX, 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_RAX && - instr.operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER && - instr.operands[1].reg.value == ZYDIS_REGISTER_CL; - }, - // MOV [RBP+0x8], 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[0].mem.index == 0x8 && - 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; - } - } - } - }; - } - } -} \ No newline at end of file + namespace handler + { + namespace profile + { + vm::handler::profile_t shrq = { + // MOV RAX, [RBP] + // MOV CL, [RBP+0x8] + // SUB RBP, 0x6 + // SHR RAX, CL + // MOV [RBP+0x8], RAX + // PUSHFQ + // POP [RBP] + "SHRQ", + SHRQ, + 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 CL, [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_CL && + instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY && + instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP && + instr.operands[ 1 ].mem.index == 0x8; + }, + // 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 RAX, 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_RAX && + instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER && + instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_CL; + }, + // MOV [RBP+0x8], 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[ 0 ].mem.index == 0x8 && + 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 \ No newline at end of file diff --git a/src/vmprofiles/sreg.cpp b/src/vmprofiles/sreg.cpp index 4ff111c..294f736 100644 --- a/src/vmprofiles/sreg.cpp +++ b/src/vmprofiles/sreg.cpp @@ -2,135 +2,114 @@ namespace vm { - namespace handler - { - namespace profile - { - vm::handler::profile_t sregq = - { - // MOV RDX, [RBP] - // ADD RBP, 8 - // MOV [RAX+RDI], RDX - "SREGQ", SREGQ, 8, - { - { - // 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, 8 - [](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 == 8; - }, - // MOV [RAX+RDI], RDX or MOV [RDI+RAX], 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[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; - } - } - } - }; + namespace handler + { + namespace profile + { + vm::handler::profile_t sregq = { + // MOV RDX, [RBP] + // ADD RBP, 8 + // MOV [RAX+RDI], RDX + "SREGQ", + SREGQ, + 8, + { { // 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, 8 + []( 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 == 8; + }, + // MOV [RAX+RDI], RDX or MOV [RDI+RAX], 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[ 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 = - { - // MOV EDX, [RBP] - // ADD RBP, 0x4 - // MOV [RAX+RDI], EDX - "SREGDW", SREGDW, 8, - { - { - // MOV EDX, [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_EDX && - instr.operands[1].type == ZYDIS_OPERAND_TYPE_MEMORY && - instr.operands[1].mem.base == ZYDIS_REGISTER_RBP; - }, - // 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 [RAX+RDI], EDX or MOV [RDI+RAX], EDX - [](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[0].mem.base == ZYDIS_REGISTER_RDI) && - (instr.operands[0].mem.index == ZYDIS_REGISTER_RAX || - instr.operands[0].mem.index == ZYDIS_REGISTER_RDI) && - instr.operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER && - instr.operands[1].reg.value == ZYDIS_REGISTER_EDX; - } - } - } - }; + vm::handler::profile_t sregdw = { + // MOV EDX, [RBP] + // ADD RBP, 0x4 + // MOV [RAX+RDI], EDX + "SREGDW", + SREGDW, + 8, + { { // MOV EDX, [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_EDX && + instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY && + instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP; + }, + // 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 [RAX+RDI], EDX or MOV [RDI+RAX], EDX + []( 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[ 0 ].mem.base == ZYDIS_REGISTER_RDI ) && + ( instr.operands[ 0 ].mem.index == ZYDIS_REGISTER_RAX || + instr.operands[ 0 ].mem.index == ZYDIS_REGISTER_RDI ) && + instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER && + instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_EDX; + } } } }; - vm::handler::profile_t sregw = - { - // MOV DX, [RBP] - // ADD RBP, 0x2 - // MOV [RAX+RDI], DX - "SREGW", SREGW, 8, - { - { - // MOV DX, [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_DX && - instr.operands[1].type == ZYDIS_OPERAND_TYPE_MEMORY && - instr.operands[1].mem.base == ZYDIS_REGISTER_RBP; - }, - // ADD RBP, 0x2 - [](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 == 0x2; - }, - // MOV [RAX+RDI], DX or MOV [RDI+RAX], DX - [](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[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_DX; - } - } - } - }; - } - } -} \ No newline at end of file + vm::handler::profile_t sregw = { + // MOV DX, [RBP] + // ADD RBP, 0x2 + // MOV [RAX+RDI], DX + "SREGW", + SREGW, + 8, + { { // MOV DX, [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_DX && + instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY && + instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP; + }, + // ADD RBP, 0x2 + []( 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 == 0x2; + }, + // MOV [RAX+RDI], DX or MOV [RDI+RAX], DX + []( 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[ 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_DX; + } } } }; + } // namespace profile + } // namespace handler +} // namespace vm \ No newline at end of file diff --git a/src/vmprofiles/vmexit.cpp b/src/vmprofiles/vmexit.cpp index f7d9825..94d7467 100644 --- a/src/vmprofiles/vmexit.cpp +++ b/src/vmprofiles/vmexit.cpp @@ -2,36 +2,31 @@ namespace vm { - namespace handler - { - namespace profile - { - vm::handler::profile_t vmexit = - { - // MOV RAX, RBP - // POPFQ - // RET - "VMEXIT", VMEXIT, 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_REGISTER && - instr.operands[1].reg.value == ZYDIS_REGISTER_RBP; - }, - // POPFQ - [](const zydis_decoded_instr_t& instr) -> bool - { return instr.mnemonic == ZYDIS_MNEMONIC_POPFQ; }, - // RET - [](const zydis_decoded_instr_t& instr) -> bool - { return instr.mnemonic == ZYDIS_MNEMONIC_RET; } - } - } - }; - } - } -} \ No newline at end of file + namespace handler + { + namespace profile + { + vm::handler::profile_t vmexit = { + // MOV RAX, RBP + // POPFQ + // RET + "VMEXIT", + VMEXIT, + 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_REGISTER && + instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RBP; + }, + // POPFQ + []( const zydis_decoded_instr_t &instr ) -> bool { return instr.mnemonic == ZYDIS_MNEMONIC_POPFQ; }, + // RET + []( const zydis_decoded_instr_t &instr ) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_RET; + } } } }; + } + } // namespace handler +} // namespace vm \ No newline at end of file diff --git a/src/vmprofiles/write.cpp b/src/vmprofiles/write.cpp index cf4044d..14e4662 100644 --- a/src/vmprofiles/write.cpp +++ b/src/vmprofiles/write.cpp @@ -2,109 +2,93 @@ namespace vm { - namespace handler - { - namespace profile - { - vm::handler::profile_t writeq = - { - // MOV RAX, [RBP] - // MOV RDX, [RBP+0x8] - // ADD RBP, 0x10 - // MOV [RAX], RDX - "WRITEQ", WRITEQ, 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 RDX, [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_RDX && - instr.operands[1].type == ZYDIS_OPERAND_TYPE_MEMORY && - instr.operands[1].mem.base == ZYDIS_REGISTER_RBP && - instr.operands[1].mem.index == 0x8; - }, - // ADD RBP, 0x10 - [](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 == 0x10; - }, - // MOV [RAX], 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; - } - } - } - }; + namespace handler + { + namespace profile + { + vm::handler::profile_t writeq = { + // MOV RAX, [RBP] + // MOV RDX, [RBP+0x8] + // ADD RBP, 0x10 + // MOV [RAX], RDX + "WRITEQ", + WRITEQ, + 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 RDX, [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_RDX && + instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY && + instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP && + instr.operands[ 1 ].mem.index == 0x8; + }, + // ADD RBP, 0x10 + []( 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 == 0x10; + }, + // MOV [RAX], 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 = - { - // MOV RAX, [RBP] - // MOV EDX, [RBP+0x8] - // ADD RBP, 0xC - // MOV [RAX], EDX - "WRITEDW", WRITEDW, 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 EDX, [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_EDX && - instr.operands[1].type == ZYDIS_OPERAND_TYPE_MEMORY && - instr.operands[1].mem.base == ZYDIS_REGISTER_RBP && - instr.operands[1].mem.index == 0x8; - }, - // ADD RBP, 0xC - [](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 == 0xC; - }, - // MOV [RAX], EDX - [](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_EDX; - } - } - } - }; - } - } -} \ No newline at end of file + vm::handler::profile_t writedw = { + // MOV RAX, [RBP] + // MOV EDX, [RBP+0x8] + // ADD RBP, 0xC + // MOV [RAX], EDX + "WRITEDW", + WRITEDW, + 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 EDX, [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_EDX && + instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_MEMORY && + instr.operands[ 1 ].mem.base == ZYDIS_REGISTER_RBP && + instr.operands[ 1 ].mem.index == 0x8; + }, + // ADD RBP, 0xC + []( 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 == 0xC; + }, + // MOV [RAX], EDX + []( 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_EDX; + } } } }; + } // namespace profile + } // namespace handler +} // namespace vm \ No newline at end of file diff --git a/src/vmutils.cpp b/src/vmutils.cpp index 1890a01..cb8d53f 100644 --- a/src/vmutils.cpp +++ b/src/vmutils.cpp @@ -7,48 +7,45 @@ namespace vm { namespace reg { - zydis_register_t to64(zydis_register_t reg) + zydis_register_t to64( zydis_register_t reg ) { - return ZydisRegisterGetLargestEnclosing( - ZYDIS_MACHINE_MODE_LONG_64, reg); + return ZydisRegisterGetLargestEnclosing( ZYDIS_MACHINE_MODE_LONG_64, reg ); } - bool compare(zydis_register_t a, zydis_register_t b) + bool compare( zydis_register_t a, zydis_register_t b ) { - return to64(a) == to64(b); + return to64( a ) == to64( b ); } - } + } // namespace reg - void print(const zydis_decoded_instr_t& instr) + void print( const zydis_decoded_instr_t &instr ) { - char buffer[256]; + char buffer[ 256 ]; ZydisFormatter formatter; - ZydisFormatterInit(&formatter, ZYDIS_FORMATTER_STYLE_INTEL); - ZydisFormatterFormatInstruction(&formatter, &instr, - buffer, sizeof(buffer), 0u); + ZydisFormatterInit( &formatter, ZYDIS_FORMATTER_STYLE_INTEL ); + ZydisFormatterFormatInstruction( &formatter, &instr, buffer, sizeof( buffer ), 0u ); - puts(buffer); + puts( buffer ); } - void print(zydis_routine_t& routine) + void print( zydis_routine_t &routine ) { - char buffer[256]; + char buffer[ 256 ]; ZydisFormatter formatter; - ZydisFormatterInit(&formatter, ZYDIS_FORMATTER_STYLE_INTEL); + ZydisFormatterInit( &formatter, ZYDIS_FORMATTER_STYLE_INTEL ); - for (auto [instr, raw, addr] : routine) + for ( auto [ instr, raw, addr ] : routine ) { - std::printf("> 0x%p ", addr); - ZydisFormatterFormatInstruction(&formatter, &instr, - buffer, sizeof(buffer), addr); + std::printf( "> 0x%p ", addr ); + ZydisFormatterFormatInstruction( &formatter, &instr, buffer, sizeof( buffer ), addr ); - puts(buffer); + puts( buffer ); } } - bool is_jmp(const zydis_decoded_instr_t& instr) + bool is_jmp( const zydis_decoded_instr_t &instr ) { - switch (instr.mnemonic) + switch ( instr.mnemonic ) { case ZYDIS_MNEMONIC_JB: case ZYDIS_MNEMONIC_JBE: @@ -79,150 +76,142 @@ namespace vm return false; } - bool flatten(zydis_routine_t& routine, std::uintptr_t routine_addr, bool keep_jmps) + bool flatten( zydis_routine_t &routine, std::uintptr_t routine_addr, bool keep_jmps ) { ZydisDecoder decoder; zydis_decoded_instr_t instr; - ZydisDecoderInit(&decoder, ZYDIS_MACHINE_MODE_LONG_64, ZYDIS_ADDRESS_WIDTH_64); + ZydisDecoderInit( &decoder, ZYDIS_MACHINE_MODE_LONG_64, ZYDIS_ADDRESS_WIDTH_64 ); - while (ZYAN_SUCCESS(ZydisDecoderDecodeBuffer(&decoder, reinterpret_cast( - routine_addr), 0x1000, &instr))) + while ( ZYAN_SUCCESS( + ZydisDecoderDecodeBuffer( &decoder, reinterpret_cast< void * >( routine_addr ), 0x1000, &instr ) ) ) { - std::vector raw_instr; - raw_instr.insert(raw_instr.begin(), - (u8*)routine_addr, - (u8*)routine_addr + instr.length); + std::vector< u8 > raw_instr; + raw_instr.insert( raw_instr.begin(), ( u8 * )routine_addr, ( u8 * )routine_addr + instr.length ); - if (is_jmp(instr)) + if ( is_jmp( instr ) ) { - if (instr.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER) + if ( instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER ) { - routine.push_back({ instr, raw_instr, routine_addr }); + routine.push_back( { instr, raw_instr, routine_addr } ); return true; } - if (keep_jmps) - routine.push_back({ instr, raw_instr, routine_addr }); + if ( keep_jmps ) + routine.push_back( { instr, raw_instr, routine_addr } ); - ZydisCalcAbsoluteAddress(&instr, &instr.operands[0], routine_addr, &routine_addr); + ZydisCalcAbsoluteAddress( &instr, &instr.operands[ 0 ], routine_addr, &routine_addr ); } - else if (instr.mnemonic == ZYDIS_MNEMONIC_RET) + else if ( instr.mnemonic == ZYDIS_MNEMONIC_RET ) { - routine.push_back({ instr, raw_instr, routine_addr }); + routine.push_back( { instr, raw_instr, routine_addr } ); return true; } else { - routine.push_back({ instr, raw_instr, routine_addr }); + routine.push_back( { instr, raw_instr, routine_addr } ); routine_addr += instr.length; } } return false; } - void deobfuscate(zydis_routine_t& routine) + void deobfuscate( zydis_routine_t &routine ) { - static const auto _uses = - [](ZydisDecodedOperand& op, zydis_register_t reg) -> bool - { - switch (op.type) + static const auto _uses = []( ZydisDecodedOperand &op, zydis_register_t reg ) -> bool { + switch ( op.type ) { case ZYDIS_OPERAND_TYPE_MEMORY: { - return reg::compare(op.mem.base, reg) || reg::compare(op.mem.index, reg); + return reg::compare( op.mem.base, reg ) || reg::compare( op.mem.index, reg ); } case ZYDIS_OPERAND_TYPE_REGISTER: { - return reg::compare(op.reg.value, reg); + return reg::compare( op.reg.value, reg ); } } return false; }; - static const auto _writes = - [](zydis_decoded_instr_t& inst) -> bool - { - for (auto idx = 0; idx < inst.operand_count; ++idx) - if (inst.operands[idx].actions & ZYDIS_OPERAND_ACTION_MASK_WRITE) + static const auto _writes = []( zydis_decoded_instr_t &inst ) -> bool { + for ( auto idx = 0; idx < inst.operand_count; ++idx ) + if ( inst.operands[ idx ].actions & ZYDIS_OPERAND_ACTION_MASK_WRITE ) return true; return false; }; - static const auto _remove = - [](zydis_routine_t& routine, zydis_routine_t::iterator itr, - zydis_register_t reg, u32 opcode_size) -> void - { - for (; itr >= routine.begin(); --itr) + static const auto _remove = []( zydis_routine_t &routine, zydis_routine_t::iterator itr, + zydis_register_t reg, u32 opcode_size ) -> void { + for ( ; itr >= routine.begin(); --itr ) { const auto instruction = &itr->instr; bool stop = false; - if (instruction->mnemonic == ZYDIS_MNEMONIC_JMP) + if ( instruction->mnemonic == ZYDIS_MNEMONIC_JMP ) continue; - for (auto op_idx = 0u; op_idx < instruction->operand_count; ++op_idx) + for ( auto op_idx = 0u; op_idx < instruction->operand_count; ++op_idx ) { - const auto op = &instruction->operands[op_idx]; + const auto op = &instruction->operands[ op_idx ]; - if (!_uses(*op, reg)) + if ( !_uses( *op, reg ) ) continue; - if (op->type == ZYDIS_OPERAND_TYPE_MEMORY) + if ( op->type == ZYDIS_OPERAND_TYPE_MEMORY ) { stop = true; continue; } - if (opcode_size < 32 && op->size > opcode_size) + if ( opcode_size < 32 && op->size > opcode_size ) continue; - if (op->actions & ZYDIS_OPERAND_ACTION_MASK_WRITE) + if ( op->actions & ZYDIS_OPERAND_ACTION_MASK_WRITE ) op->actions &= ~ZYDIS_OPERAND_ACTION_MASK_WRITE; - else stop = true; + else + stop = true; } - if (!_writes(*instruction)) - routine.erase(itr); + if ( !_writes( *instruction ) ) + routine.erase( itr ); - else if (stop) break; + else if ( stop ) + break; } }; - for (const auto& instr_data : routine) + for ( const auto &instr_data : routine ) { - if (routine.empty() || routine.size() == 1 || - instr_data.instr.mnemonic == ZYDIS_MNEMONIC_JMP) + if ( routine.empty() || routine.size() == 1 || instr_data.instr.mnemonic == ZYDIS_MNEMONIC_JMP ) continue; - for (auto itr = routine.begin() + 1; itr != routine.end(); itr++) + for ( auto itr = routine.begin() + 1; itr != routine.end(); itr++ ) { - if (itr->instr.mnemonic == ZYDIS_MNEMONIC_JMP || - itr->instr.mnemonic == ZYDIS_MNEMONIC_RET) + if ( itr->instr.mnemonic == ZYDIS_MNEMONIC_JMP || itr->instr.mnemonic == ZYDIS_MNEMONIC_RET ) break; // find the write operations that happen... - for (auto idx = 0u; idx < itr->instr.operand_count; ++idx) + for ( auto idx = 0u; idx < itr->instr.operand_count; ++idx ) { - const auto op = &itr->instr.operands[idx]; + const auto op = &itr->instr.operands[ idx ]; // if its a read, continue to next opcode... - if (op->actions & ZYDIS_OPERAND_ACTION_MASK_READ) + if ( op->actions & ZYDIS_OPERAND_ACTION_MASK_READ ) continue; // if its not a write then continue to next opcode... - if (!(op->actions & ZYDIS_OPERAND_ACTION_MASK_WRITE)) + if ( !( op->actions & ZYDIS_OPERAND_ACTION_MASK_WRITE ) ) continue; // if this operand is not a register then we continue... - if (op->type != ZYDIS_OPERAND_TYPE_REGISTER) + if ( op->type != ZYDIS_OPERAND_TYPE_REGISTER ) continue; // else we see if we can remove dead writes to this register... - _remove(routine, itr - 1, op->reg.value, op->size); + _remove( routine, itr - 1, op->reg.value, op->size ); } } } } - } -} \ No newline at end of file + } // namespace util +} // namespace vm \ No newline at end of file