diff --git a/include/vmprofiler.hpp b/include/vmprofiler.hpp index e9cd7ee..15bc224 100644 --- a/include/vmprofiler.hpp +++ b/include/vmprofiler.hpp @@ -218,7 +218,7 @@ namespace vm { bool has_jcc; jcc_type type; - std::uint32_t block_rva[ 2 ]; + std::uintptr_t block_rva[ 2 ]; }; struct code_block_t @@ -237,6 +237,12 @@ namespace vm std::pair< std::uint64_t, std::uint64_t > encrypt_operand( transform::map_t &transforms, std::uint64_t operand, std::uint64_t rolling_key ); + /// + /// get virt_instr_t filled in with data given a vmp2 trace entry and vm context... + /// + /// current vm context + /// vmp2 trace entry containing all of the native/virtual register/stack values... + /// returns a filled in virt_instr_t on success... std::optional< virt_instr_t > get( vm::ctx_t &ctx, vmp2::v2::entry_t &entry ); /// diff --git a/src/vminstrs.cpp b/src/vminstrs.cpp index 09e0ac5..3677db0 100644 --- a/src/vminstrs.cpp +++ b/src/vminstrs.cpp @@ -166,30 +166,36 @@ namespace vm if ( !imm_size ) return {}; - return ctx.exec_type == vmp2::exec_type_t::forward - ? *reinterpret_cast< std::uintptr_t * >( vip + ( imm_size / 8 ) ) - : *reinterpret_cast< std::uintptr_t * >( vip - ( imm_size / 8 ) ); + std::uint64_t result = 0u; + if ( ctx.exec_type == vmp2::exec_type_t::forward ) + std::memcpy( &result, reinterpret_cast< void * >( vip ), imm_size / 8 ); + else // else the second operand is below vip... + std::memcpy( &result, reinterpret_cast< void * >( vip - ( imm_size / 8 ) ), imm_size / 8 ); + + return result; } std::optional< virt_instr_t > get( vm::ctx_t &ctx, vmp2::v2::entry_t &entry ) { virt_instr_t result; - const auto &vm_handler = ctx.vm_handlers[ entry.handler_idx ]; + auto &vm_handler = ctx.vm_handlers[ entry.handler_idx ]; const auto profile = vm_handler.profile; - result.mnemonic_t = profile ? profile->mnemonic : vm::handler::mnemonic_t::INVALID; + result.mnemonic_t = profile ? profile->mnemonic : vm::handler::INVALID; result.opcode = entry.handler_idx; result.trace_data = entry; if ( vm_handler.imm_size ) { result.operand.has_imm = true; + result.operand.imm.imm_size = vm_handler.imm_size; const auto imm_val = get_imm( ctx, vm_handler.imm_size, entry.vip ); if ( !imm_val.has_value() ) return {}; - result.operand.imm.u = imm_val.value(); + result.operand.imm.u = + vm::instrs::decrypt_operand( vm_handler.transforms, imm_val.value(), entry.decrypt_key ).first; } else result.operand.has_imm = false; @@ -266,12 +272,13 @@ namespace vm std::uintptr_t code_block_addr( const vm::ctx_t &ctx, const vmp2::v2::entry_t &entry ) { - return ( ( entry.vsp.qword[ 0 ] + ctx.image_base & ~0xFFFFFFFFull ) - ctx.image_base ) + ctx.module_base; + return ( ( entry.vsp.qword[ 0 ] + ( ctx.image_base & ~0xFFFFFFFFull ) ) - ctx.image_base ) + + ctx.module_base; } std::uintptr_t code_block_addr( const vm::ctx_t &ctx, const std::uint32_t lower_32bits ) { - return ( ( lower_32bits + ctx.image_base & ~0xFFFFFFFFull ) - ctx.image_base ) + ctx.module_base; + return ( ( lower_32bits + ( ctx.image_base & ~0xFFFFFFFFull ) ) - ctx.image_base ) + ctx.module_base; } } // namespace instrs } // namespace vm \ No newline at end of file