#pragma once #include #include namespace vm::handler { /// /// handler_t contains all the information for a vm handler such as its immidate value size (zero if there is no /// imm), the transformations applied to the imm to decrypt it (if any), a pointer to the profile (nullptr if /// there is none), and other meta data... /// struct handler_t { /// /// imm size in bits, zero if no imm... /// u8 imm_size; /// /// transformations to decrypt imm... /// vm::transform::map_t transforms; /// /// pointer to the profile, nullptr if none... /// vm::handler::profile_t *profile; /// /// native instructions of the vm handler... (calc_jmp/check_vsp is removed from this)... /// zydis_routine_t instrs; /// /// linear virtual address to the vm handler... /// std::uintptr_t address; }; /// /// given a vm handler returns true if the vm handler decrypts an operand... /// /// const reference to a vm handler... /// returns true if the vm handler decrypts an operand, else false... bool has_imm( const zydis_routine_t &vm_handler ); /// /// gets the imm size of a vm handler... /// /// const reference to a vm handler... /// returns the imm size, otherwise returns an empty optional value... std::optional< std::uint8_t > imm_size( const zydis_routine_t &vm_handler ); /// /// gets a vm handler, puts all of the native instructions inside of the vm_handler param... /// /// reference to a zydis_routine_t that will get filled with the /// native instructions of the vm handler... linear virtual address to the /// first instruction of the vm handler... returns true if the native instructions of the vm /// handler was extracted... bool get( zydis_routine_t &vm_handler, std::uintptr_t handler_addr ); /// /// get all 256 vm handlers... /// /// linear virtual address of the module base... /// image base from optional nt header... IMAGE_OPTIONAL_HEADER64... /// zydis_routine_t containing the deobfuscated and flattened vm entry native /// instructions... linear virtual address to the vm handler /// table... vector of handler_t's that will be filled with the vm /// handlers... returns true if all vm handlers were extracted, else false... 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 ); /// /// get operand decryption instructions given a vm handler... /// /// reference to a zydis_routine_t containing the deobfuscated and flattened vm handler /// native instructions... reference to a transform::map_t that will get filled /// up with the transforms needed to decrypt operands... returns true if the transformations /// were extracted successfully bool get_operand_transforms( zydis_routine_t &vm_handler, transform::map_t &transforms ); /// /// get a vm handler profile given a handler_t... /// /// reference to a handler_t structure that contains all the information of a given vm /// handler... returns a pointer to the vm profile, else a nullptr... vm::handler::profile_t *get_profile( handler_t &vm_handler ); /// /// get a vm handler profile given the mnemonic of the vm handler... /// /// mnemonic of the vm handler... /// returns a pointer to the profile if the given menmonic is implimented, else a nullptr... vm::handler::profile_t *get_profile( vm::handler::mnemonic_t mnemonic ); namespace table { /// /// get the linear virtual address of the vm handler table give a deobfuscated, flattened, vm entry... /// /// deobfuscated, flattened, vm entry... /// returns the linear virtual address of the vm handler table... std::uintptr_t *get( const zydis_routine_t &vm_entry ); /// /// get the single native instruction used to decrypt vm handler entries... /// /// reference to the deobfuscated, flattened, vm entry... /// /// bool get_transform( const zydis_routine_t &vm_entry, zydis_decoded_instr_t *transform_instr ); /// /// encrypt a linear virtual address given the transformation that is used to decrypt the vm handler table /// entry... this function will apply the inverse of the transformation so you dont need to get the inverse /// yourself... /// /// reference to the transformation native instruction... /// value to be encrypted (linear virtual address) /// returns the encrypted value... std::uint64_t encrypt( zydis_decoded_instr_t &transform_instr, std::uint64_t val ); /// /// decrypts a vm handler table entry... /// /// transformation extracted from vm_entry that decrypts vm handler table /// entries... encrypted value to be decrypted... returns the /// decrypted value... std::uint64_t decrypt( zydis_decoded_instr_t &transform_instr, std::uint64_t val ); } // namespace table } // namespace vm::handler