You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

118 lines
2.1 KiB

#pragma once
#include <cstdint>
#include <xmmintrin.h>
using u8 = unsigned char;
using u16 = unsigned short;
using u32 = unsigned int;
using u64 = unsigned long long;
using u128 = __m128;
extern "C" void __vtrap(void);
namespace vm
{
typedef struct _registers
{
u128 xmm0;
u128 xmm1;
u128 xmm2;
u128 xmm3;
u128 xmm4;
u128 xmm5;
u128 xmm6;
u128 xmm7;
u128 xmm8;
u128 xmm9;
u128 xmm10;
u128 xmm11;
u128 xmm12;
u128 xmm13;
u128 xmm14;
u128 xmm15;
u64 gap0;
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 vm_handler;
} registers, * pregisters;
using decrypt_handler_t = u64(*)(u64);
using encrypt_handler_t = u64(*)(u64);
namespace handler
{
// these lambdas handle page protections...
using edit_entry_t = void (*)(u64*, u64);
using entry_callback_t = void (*)(vm::registers* regs, u8 handler_idx);
struct entry_t
{
u64 virt;
u64 encrypted;
u64 decrypted;
entry_callback_t callback;
};
class table_t
{
public:
explicit table_t(u64* table_addr, edit_entry_t edit_entry);
u64 get_entry(u8 idx) const;
entry_t get_meta_data(u8 idx) const;
void set_entry(u8 idx, u64 entry);
void set_meta_data(u8 idx, const entry_t& entry);
void set_callback(u8 idx, entry_callback_t callback);
private:
u64* table_addr;
edit_entry_t edit_entry;
entry_t handlers[256];
};
}
class hook_t
{
public:
explicit hook_t(
u64 module_base,
u64 image_base,
decrypt_handler_t decrypt_handler,
encrypt_handler_t encrypt_handler,
vm::handler::table_t* vm_handler_table
);
u64 encrypt(u64 val) const;
u64 decrypt(u64 val) const;
void set_trap(u64 val) const;
void start() const;
void stop() const;
vm::handler::table_t* handler_table;
private:
const u64 module_base, image_base;
u64 vtrap_encrypted;
const decrypt_handler_t decrypt_handler;
const encrypt_handler_t encrypt_handler;
};
inline vm::hook_t* g_vmctx = nullptr;
}
extern "C" void vtrap_wrapper(vm::registers * regs, u8 handler_idx);