#pragma once #include #include #include #include #include #ifdef _MSC_VER #include #define bswap_32(x) _byteswap_ulong(x) #define bswap_64(x) _byteswap_uint64(x) #define bswap_16(x) _byteswap_ushort(x) #elif defined(__APPLE__) // Mac OS X / Darwin features #include #define bswap_32(x) OSSwapInt32(x) #define bswap_64(x) OSSwapInt64(x) #elif defined(__sun) || defined(sun) #include #define bswap_32(x) BSWAP_32(x) #define bswap_64(x) BSWAP_64(x) #elif defined(__FreeBSD__) #include #define bswap_32(x) bswap32(x) #define bswap_64(x) bswap64(x) #elif defined(__OpenBSD__) #include #define bswap_32(x) swap32(x) #define bswap_64(x) swap64(x) #elif defined(__NetBSD__) #include #include #if defined(__BSWAP_RENAME) && !defined(__bswap_32) #define bswap_32(x) bswap32(x) #define bswap_64(x) bswap64(x) #endif #else #include #endif using u8 = unsigned char; using u16 = unsigned short; using u32 = unsigned int; using u64 = unsigned long long; using u128 = __m128; using zydis_decoded_instr_t = ZydisDecodedInstruction; using zydis_register_t = ZydisRegister; using zydis_mnemonic_t = ZydisMnemonic; using zydis_decoded_operand_t = ZydisDecodedOperand; struct zydis_instr_t { zydis_decoded_instr_t instr; std::vector< u8 > raw; std::uintptr_t addr; }; using zydis_routine_t = std::vector< zydis_instr_t >; /// /// utils used by the other cpp files... misc things that get used a lot... /// namespace vm::util { /// /// utils pertaining to native registers... /// namespace reg { /// /// converts say... AL to RAX... /// /// a zydis decoded register value... /// returns the largest width register of the given register... AL gives RAX... zydis_register_t to64( zydis_register_t reg ); /// /// compares to registers with each other... calls to64 and compares... /// /// register a... /// register b... /// returns true if register to64(a) == to64(b)... bool compare( zydis_register_t a, zydis_register_t b ); } // namespace reg /// /// get the instruction that fetches an operand out of VIP... /// /// this is a deobfuscated, flattened, view of any set of native instructions that read an operand out of VIP... can be calc_jmp, vm_entry, or vm handlers... /// /// returns true of the fetch operand native instruction is found... bool get_fetch_operand( const zydis_routine_t &routine, zydis_instr_t &fetch_instr ); /// /// gets the instruction that fetches an operand out of VIP and returns an iterator to it... /// /// this is a deobfuscated, flattened, view of any set of native instructions that read an operand out of VIP... can be calc_jmp, vm_entry, or vm handlers... /// returns the iterator of the native instruction, else an empty std::optional... std::optional< zydis_routine_t::iterator > get_fetch_operand( zydis_routine_t &routine ); /// /// prints a disassembly view of a routine... /// /// reference to a zydis_routine_t to be printed... void print( zydis_routine_t &routine ); /// /// prints a single disassembly view of an instruction... /// /// instruction to print... void print( const zydis_decoded_instr_t &instr ); /// /// determines if a given decoded native instruction is a JCC... /// /// /// bool is_jmp( const zydis_decoded_instr_t &instr ); /// /// flatten native instruction stream, takes every JCC (follows the branch)... /// /// filled with decoded instructions... /// linear virtual address to start flattening from... /// keep JCC's in the flattened instruction stream... /// returns true if flattened was successful... bool flatten( zydis_routine_t &routine, std::uintptr_t routine_addr, bool keep_jmps = false ); /// /// deadstore deobfuscation of a flattened routine... /// /// reference to a flattened instruction vector... void deobfuscate( zydis_routine_t &routine ); } // namespace vm::util