VMProfiler
v1.8
vmprofiler is a c++ library which is used to statically analyze VMProtect 2 polymorphic virtual machines. This project is inherited in vmprofiler-qt, vmprofiler-cli, and vmemu.
|
contains all functions related to virtual instructions... More...
Classes | |
struct | virt_instr_t |
struct | jcc_data |
struct | code_block_t |
Enumerations | |
enum class | jcc_type { none , branching , absolute } |
Functions | |
bool | get_rva_decrypt (const zydis_routine_t &vm_entry, std::vector< zydis_decoded_instr_t > &transform_instrs) |
gets the native instructions that are used to decrypt the relative virtual address to virtual instructions located on the stack at RSP+0xA0... you can learn about this https://back.engineering/17/05/2021/#vm_entry More... | |
std::pair< std::uint64_t, std::uint64_t > | decrypt_operand (transform::map_t &transforms, std::uint64_t operand, std::uint64_t rolling_key) |
decrypt virtual instruction operand given the decryption transformations... you can read about these transformations https://back.engineering/17/05/2021/#operand-decryption More... | |
std::pair< std::uint64_t, std::uint64_t > | encrypt_operand (transform::map_t &transforms, std::uint64_t operand, std::uint64_t rolling_key) |
encrypt a virtual instructions operand given the transformations to decrypt the operand... the transformations are inversed by this functions so you dont need to worry about doing that. More... | |
std::optional< virt_instr_t > | get (vm::ctx_t &ctx, vmp2::v2::entry_t &entry) |
get virt_instr_t filled in with data given a vmp2 trace entry and vm context... More... | |
std::optional< std::uint64_t > | get_imm (vm::ctx_t &ctx, std::uint8_t imm_size, std::uintptr_t vip) |
gets the encrypted second operand (imm) given vip and vm::ctx_t... More... | |
std::optional< jcc_data > | get_jcc_data (vm::ctx_t &ctx, code_block_t &code_block) |
get jcc data out of a code block... this function will loop over the code block and look for the last LCONSTDW in the virtual instructions. More... | |
std::uintptr_t | code_block_addr (const vm::ctx_t &ctx, const vmp2::v2::entry_t &entry) |
the top of the stack will contain the lower 32bits of the RVA to the virtual instructions that will be jumping too... the RVA is image based (not module based, but optional header image based)... this means the value ontop of the stack could be "40007fd8" with image base being 0x140000000... as you can see the 0x100000000 is missing... the below statement deals with this... More... | |
std::uintptr_t | code_block_addr (const vm::ctx_t &ctx, const std::uint32_t lower_32bits) |
same routine as above except lower_32bits is passed directly and not extracted from the stack... More... | |
contains all functions related to virtual instructions...
|
strong |
std::uintptr_t vm::instrs::code_block_addr | ( | const vm::ctx_t & | ctx, |
const std::uint32_t | lower_32bits | ||
) |
same routine as above except lower_32bits is passed directly and not extracted from the stack...
ctx | vm context |
lower_32bits | lower 32bits of the relative virtual address... |
std::uintptr_t vm::instrs::code_block_addr | ( | const vm::ctx_t & | ctx, |
const vmp2::v2::entry_t & | entry | ||
) |
the top of the stack will contain the lower 32bits of the RVA to the virtual instructions that will be jumping too... the RVA is image based (not module based, but optional header image based)... this means the value ontop of the stack could be "40007fd8" with image base being 0x140000000... as you can see the 0x100000000 is missing... the below statement deals with this...
ctx | vm context |
entry | current trace entry for virtual JMP instruction |
std::pair< std::uint64_t, std::uint64_t > vm::instrs::decrypt_operand | ( | transform::map_t & | transforms, |
std::uint64_t | operand, | ||
std::uint64_t | rolling_key | ||
) |
decrypt virtual instruction operand given the decryption transformations... you can read about these transformations https://back.engineering/17/05/2021/#operand-decryption
transforms | decryption transformations... |
operand | encrypted virtual instruction operand... |
rolling_key | the decryption key (RBX)... |
std::pair< std::uint64_t, std::uint64_t > vm::instrs::encrypt_operand | ( | transform::map_t & | transforms, |
std::uint64_t | operand, | ||
std::uint64_t | rolling_key | ||
) |
encrypt a virtual instructions operand given the transformations to decrypt the operand... the transformations are inversed by this functions so you dont need to worry about doing that.
you can learn about transformations https://back.engineering/17/05/2021/#operand-decryption
transforms | transformations to decrypt operand, these transformations are inversed by the function... |
operand | operand to be encrypted... |
rolling_key | encryption key... (RBX)... |
std::optional< virt_instr_t > vm::instrs::get | ( | vm::ctx_t & | ctx, |
vmp2::v2::entry_t & | entry | ||
) |
get virt_instr_t filled in with data given a vmp2 trace entry and vm context...
ctx | current vm context |
entry | vmp2 trace entry containing all of the native/virtual register/stack values... |
std::optional< std::uint64_t > vm::instrs::get_imm | ( | vm::ctx_t & | ctx, |
std::uint8_t | imm_size, | ||
std::uintptr_t | vip | ||
) |
gets the encrypted second operand (imm) given vip and vm::ctx_t...
ctx | vm context |
imm_size | immediate value size in bits... |
vip | virtual instruction pointer, linear virtual address... |
std::optional< jcc_data > vm::instrs::get_jcc_data | ( | vm::ctx_t & | ctx, |
code_block_t & | code_block | ||
) |
get jcc data out of a code block... this function will loop over the code block and look for the last LCONSTDW in the virtual instructions.
it will then loop and look for all PUSHVSP's, checking each to see if the stack contains two encrypted rva's to each branch.. if there is not two encrypted rva's then the virtual jmp instruction only has one dest...
ctx | vm context |
code_block | code block that does not have its jcc_data yet |
bool vm::instrs::get_rva_decrypt | ( | const zydis_routine_t & | vm_entry, |
std::vector< zydis_decoded_instr_t > & | transform_instrs | ||
) |
gets the native instructions that are used to decrypt the relative virtual address to virtual instructions located on the stack at RSP+0xA0... you can learn about this https://back.engineering/17/05/2021/#vm_entry
vm_entry | pass by reference of the specific vm entry you want to get the decryption instructions from... |
transform_instrs | pass by reference vector that will be filled with the decryption instructions... |