1
0
mirror of https://github.com/momo5502/hypervisor.git synced 2025-07-03 01:31:51 +00:00

Compare commits

..

4 Commits

Author SHA1 Message Date
5e2e3ab36a spoof pc 2024-04-19 20:40:16 +02:00
bfc0b20ba3 Make exceptions copyable 2024-04-15 20:40:50 +02:00
240a6da306 Small fixes 2024-04-06 18:40:55 +02:00
6f653e3032 CPUID interception 2024-04-06 18:40:45 +02:00
13 changed files with 225 additions and 471 deletions

View File

@ -1,12 +1,7 @@
version: 2
updates:
- package-ecosystem: gitsubmodule
directory: "/"
schedule:
interval: monthly
open-pull-requests-limit: 10
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: monthly
- package-ecosystem: gitsubmodule
directory: "/"
schedule:
interval: daily
open-pull-requests-limit: 10

View File

@ -20,7 +20,7 @@ jobs:
- release
steps:
- name: Check out files
uses: actions/checkout@v4
uses: actions/checkout@v3
with:
submodules: true
fetch-depth: 0
@ -38,10 +38,13 @@ jobs:
uses: ammaraskar/msvc-problem-matcher@master
- name: Setup DevCmd
uses: ilammy/msvc-dev-cmd@v1.13.0
uses: ilammy/msvc-dev-cmd@v1.12.0
with:
arch: x64
- name: Setup Ninja
uses: ashutoshvarma/setup-ninja@master
- name: Configure CMake
run: cmake --preset=${{matrix.configuration}}
@ -49,7 +52,7 @@ jobs:
run: cmake --build --preset=${{matrix.configuration}}
- name: Upload ${{matrix.configuration}} binaries
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v3
with:
name: ${{matrix.configuration}} binaries
path: |

View File

@ -7,6 +7,16 @@
#include "memory.hpp"
#include "vmx.hpp"
#define MTRR_PAGE_SIZE 4096
#define MTRR_PAGE_MASK (~(MTRR_PAGE_SIZE-1))
#define ADDRMASK_EPT_PML1_OFFSET(_VAR_) ((_VAR_) & 0xFFFULL)
#define ADDRMASK_EPT_PML1_INDEX(_VAR_) (((_VAR_) & 0x1FF000ULL) >> 12)
#define ADDRMASK_EPT_PML2_INDEX(_VAR_) (((_VAR_) & 0x3FE00000ULL) >> 21)
#define ADDRMASK_EPT_PML3_INDEX(_VAR_) (((_VAR_) & 0x7FC0000000ULL) >> 30)
#define ADDRMASK_EPT_PML4_INDEX(_VAR_) (((_VAR_) & 0xFF8000000000ULL) >> 39)
namespace vmx
{
namespace
@ -291,7 +301,7 @@ namespace vmx
// --------------------------
pml1 temp_epdpte{};
epdpte temp_epdpte;
temp_epdpte.flags = 0;
temp_epdpte.read_access = 1;
temp_epdpte.write_access = 1;
@ -306,7 +316,7 @@ namespace vmx
// --------------------------
pml2 temp_epde{};
epde_2mb temp_epde{};
temp_epde.flags = 0;
temp_epde.read_access = 1;
temp_epde.write_access = 1;
@ -400,18 +410,18 @@ namespace vmx
}
const auto* pml2 = reinterpret_cast<pml2_ptr*>(pml2_entry);
auto* pml1_table = this->find_pml1_table(pml2->page_frame_number * PAGE_SIZE);
if (!pml1_table)
auto* pml1 = this->find_pml1_table(pml2->page_frame_number * PAGE_SIZE);
if (!pml1)
{
pml1_table = static_cast<pml1*>(memory::get_virtual_address(pml2->page_frame_number * PAGE_SIZE));
pml1 = static_cast<epte*>(memory::get_virtual_address(pml2->page_frame_number * PAGE_SIZE));
}
if (!pml1_table)
if (!pml1)
{
return nullptr;
}
return &pml1_table[ADDRMASK_EPT_PML1_INDEX(physical_address)];
return &pml1[ADDRMASK_EPT_PML1_INDEX(physical_address)];
}
pml1* ept::find_pml1_table(const uint64_t physical_address)
@ -551,7 +561,7 @@ namespace vmx
auto& split = this->allocate_ept_split();
pml1 pml1_template{};
epte pml1_template{};
pml1_template.flags = 0;
pml1_template.read_access = 1;
pml1_template.write_access = 1;

View File

@ -3,30 +3,13 @@
#define DECLSPEC_PAGE_ALIGN DECLSPEC_ALIGN(PAGE_SIZE)
#include "list.hpp"
#define MTRR_PAGE_SIZE 4096
#define MTRR_PAGE_MASK (~(MTRR_PAGE_SIZE-1))
#define ADDRMASK_EPT_PML1_OFFSET(_VAR_) ((_VAR_) & 0xFFFULL)
#define ADDRMASK_EPT_PML1_INDEX(_VAR_) (((_VAR_) & 0x1FF000ULL) >> 12)
#define ADDRMASK_EPT_PML2_INDEX(_VAR_) (((_VAR_) & 0x3FE00000ULL) >> 21)
#define ADDRMASK_EPT_PML3_INDEX(_VAR_) (((_VAR_) & 0x7FC0000000ULL) >> 30)
#define ADDRMASK_EPT_PML4_INDEX(_VAR_) (((_VAR_) & 0xFF8000000000ULL) >> 39)
namespace vmx
{
using pml4 = ept_pml4e;
using pml3 = ept_pdpte;
using pml2 = ept_pde_2mb;
using pml2_ptr = ept_pde;
using pml1 = ept_pte;
using pml4_entry = pml4e_64;
using pml3_entry = pdpte_64;
using pml2_entry = pde_64;
using pml1_entry = pte_64;
using pml4 = ept_pml4;
using pml3 = epdpte;
using pml2 = epde_2mb;
using pml2_ptr = epde;
using pml1 = epte;
struct ept_split
{

View File

@ -13,14 +13,6 @@
#define DPL_USER 3
#define DPL_SYSTEM 0
typedef struct _EPROCESS
{
DISPATCHER_HEADER Header;
LIST_ENTRY ProfileListHead;
ULONG_PTR DirectoryTableBase;
UCHAR Data[1];
} EPROCESS, *PEPROCESS;
namespace
{
hypervisor* instance{nullptr};
@ -53,12 +45,6 @@ namespace
return cpuid_data[0] == 'momo';
}
void enable_syscall_hooking()
{
int32_t cpu_info[4]{0};
__cpuidex(cpu_info, 0x41414141, 0x42424243);
}
void cpature_special_registers(vmx::special_registers& special_registers)
{
special_registers.cr0 = __readcr0();
@ -77,7 +63,7 @@ namespace
// See: https://github.com/ionescu007/SimpleVisor/issues/48
#define capture_cpu_context(launch_context) \
cpature_special_registers((launch_context).special_registers);\
RtlCaptureContext(&(launch_context).context_frame);
RtlCaptureContext(&(launch_context).context_frame)
void restore_descriptor_tables(vmx::launch_context& launch_context)
{
@ -469,378 +455,78 @@ void vmx_handle_invd()
__wbinvd();
}
void inject_interuption(const interruption_type type, const exception_vector vector, const bool deliver_code,
const uint32_t error_code)
bool log_other_call(uintptr_t guest_rip, bool rdtsc)
{
vmentry_interrupt_information interrupt{};
interrupt.valid = true;
interrupt.interruption_type = type;
interrupt.vector = vector;
interrupt.deliver_error_code = deliver_code;
__vmx_vmwrite(VMCS_CTRL_VMENTRY_INTERRUPTION_INFORMATION_FIELD, interrupt.flags);
if (deliver_code)
if (guest_rip < 0x140000000 || guest_rip > 0x15BC27000)
{
__vmx_vmwrite(VMCS_CTRL_VMENTRY_INTERRUPTION_INFORMATION_FIELD, error_code);
return false;
}
}
void inject_invalid_opcode()
{
inject_interuption(hardware_exception, invalid_opcode, false, 0);
}
void inject_page_fault(const uint64_t page_fault_address)
{
__writecr2(page_fault_address);
page_fault_exception error_code{};
error_code.flags = 0;
inject_interuption(hardware_exception, page_fault, true, error_code.flags);
}
void inject_page_fault(const void* page_fault_address)
{
inject_page_fault(reinterpret_cast<uint64_t>(page_fault_address));
}
cr3 get_current_process_cr3()
{
cr3 guest_cr3{};
guest_cr3.flags = PsGetCurrentProcess()->DirectoryTableBase;
return guest_cr3;
}
template <size_t Length>
bool is_mem_equal(const uint8_t* ptr, const uint8_t (&array)[Length])
{
for (size_t i = 0; i < Length; ++i)
const auto is_privileged = (read_vmx(VMCS_GUEST_CS_SELECTOR) &
SEGMENT_ACCESS_RIGHTS_DESCRIPTOR_PRIVILEGE_LEVEL_MASK) == DPL_SYSTEM;
if(is_privileged)
{
if (ptr[i] != array[i])
{
return false;
}
return false;
}
const auto proc = process::get_current_process();
const auto filename = proc.get_image_filename();
if (!string::equal(filename, "HogwartsLegacy"))
{
return false;
}
debug_log("%s (%s): %llX\n", rdtsc ? "RDTSC" : "RDTSCP",
filename,
guest_rip);
return true;
}
void set_exception_bit(const exception_vector bit, const bool value)
bool log_cpuid_call(uintptr_t guest_rip, uintptr_t rax, uintptr_t rcx, const INT32* cpu_info)
{
auto exception_bitmap = read_vmx(VMCS_CTRL_EXCEPTION_BITMAP);
if (value)
if (guest_rip < 0x140000000 || guest_rip > 0x15BC27000)
{
exception_bitmap |= 1ULL << bit;
}
else
{
exception_bitmap &= ~(1ULL << bit);
return false;
}
__vmx_vmwrite(VMCS_CTRL_EXCEPTION_BITMAP, exception_bitmap);
}
void vmx_enable_syscall_hooks(const bool enable)
{
ULARGE_INTEGER msr{};
ia32_efer_register efer_register{};
ia32_vmx_basic_register vmx_basic_register{};
ia32_vmx_exit_ctls_register exit_ctls_register{};
ia32_vmx_entry_ctls_register entry_ctls_register{};
vmx_basic_register.flags = __readmsr(IA32_VMX_BASIC);
exit_ctls_register.flags = read_vmx(VMCS_CTRL_PRIMARY_VMEXIT_CONTROLS);
entry_ctls_register.flags = read_vmx(VMCS_CTRL_VMENTRY_CONTROLS);
efer_register.flags = __readmsr(IA32_EFER);
// ---------------------------------------
efer_register.syscall_enable = !enable;
exit_ctls_register.save_ia32_efer = enable;
entry_ctls_register.load_ia32_efer = enable;
// ---------------------------------------
if (enable)
const auto is_privileged = (read_vmx(VMCS_GUEST_CS_SELECTOR) &
SEGMENT_ACCESS_RIGHTS_DESCRIPTOR_PRIVILEGE_LEVEL_MASK) == DPL_SYSTEM;
if (is_privileged)
{
msr.QuadPart = __readmsr(vmx_basic_register.vmx_controls ? IA32_VMX_TRUE_ENTRY_CTLS : IA32_VMX_ENTRY_CTLS);
__vmx_vmwrite(VMCS_CTRL_VMENTRY_CONTROLS, adjust_msr(msr, entry_ctls_register.flags));
msr.QuadPart = __readmsr(vmx_basic_register.vmx_controls ? IA32_VMX_TRUE_EXIT_CTLS : IA32_VMX_EXIT_CTLS);
__vmx_vmwrite(VMCS_CTRL_PRIMARY_VMEXIT_CONTROLS, adjust_msr(msr, exit_ctls_register.flags));
return false;
}
__vmx_vmwrite(VMCS_GUEST_EFER, efer_register.flags);
const auto proc = process::get_current_process();
set_exception_bit(invalid_opcode, enable);
}
enum class syscall_state
{
is_sysret,
is_syscall,
page_fault,
none,
};
class scoped_cr3_switch
{
public:
scoped_cr3_switch()
const auto filename = proc.get_image_filename();
if (!string::equal(filename, "HogwartsLegacy"))
{
original_cr3_.flags = __readcr3();
return false;
}
scoped_cr3_switch(const cr3 new_cr3)
: scoped_cr3_switch()
{
this->set_cr3(new_cr3);
}
scoped_cr3_switch(const scoped_cr3_switch&) = delete;
scoped_cr3_switch& operator=(const scoped_cr3_switch&) = delete;
debug_log("CPUID call (%s): %llX - (EAX: %08X - ECX: %08X) - (EAX: %08X - EBX: %08X - ECX: %08X - EDX: %08X)\n",
filename,
guest_rip, rax, rcx, cpu_info[0], cpu_info[1], cpu_info[2], cpu_info[3]);
scoped_cr3_switch(scoped_cr3_switch&&) = delete;
scoped_cr3_switch& operator=(scoped_cr3_switch&&) = delete;
~scoped_cr3_switch()
{
__writecr3(original_cr3_.flags);
}
void set_cr3(const cr3 new_cr3)
{
this->must_restore_ = true;
__writecr3(new_cr3.flags);
}
private:
bool must_restore_{false};
cr3 original_cr3_{};
};
template <size_t Length>
bool read_data_or_page_fault(uint8_t (&array)[Length], const uint8_t* base)
{
for (size_t offset = 0; offset < Length;)
{
auto* current_base = base + offset;
auto* current_destination = array + offset;
auto read_length = Length - offset;
const auto* page_start = static_cast<uint8_t*>(PAGE_ALIGN(current_base));
const auto* next_page = page_start + PAGE_SIZE;
if (current_base + read_length > next_page)
{
read_length = next_page - current_base;
}
offset += read_length;
const auto physical_base = memory::get_physical_address(const_cast<uint8_t*>(current_base));
if (!physical_base)
{
inject_page_fault(current_base);
return false;
}
if (!memory::read_physical_memory(current_destination, physical_base, read_length))
{
// Not sure if we can recover from that :(
return false;
}
}
//debug_log("OVERHEAD\n");
return true;
}
syscall_state get_syscall_state(const vmx::guest_context& guest_context)
{
scoped_cr3_switch cr3_switch{};
constexpr auto PCID_NONE = 0x000;
constexpr auto PCID_MASK = 0x003;
cr3 guest_cr3{};
guest_cr3.flags = read_vmx(VMCS_GUEST_CR3);
if ((guest_cr3.flags & PCID_MASK) != PCID_NONE)
{
cr3_switch.set_cr3(get_current_process_cr3());
}
const auto* rip = reinterpret_cast<uint8_t*>(guest_context.guest_rip);
constexpr uint8_t syscall_bytes[] = {0x0F, 0x05};
constexpr uint8_t sysret_bytes[] = {0x48, 0x0F, 0x07};
constexpr auto max_byte_length = max(sizeof(sysret_bytes), sizeof(syscall_bytes));
uint8_t data[max_byte_length];
if (!read_data_or_page_fault(data, rip))
{
return syscall_state::page_fault;
}
if (is_mem_equal(data, syscall_bytes))
{
return syscall_state::is_syscall;
}
if (is_mem_equal(data, sysret_bytes))
{
return syscall_state::is_sysret;
}
return syscall_state::none;
}
void vmx_handle_exception(vmx::guest_context& guest_context)
{
vmexit_interrupt_information interrupt{};
interrupt.flags = static_cast<uint32_t>(read_vmx(VMCS_VMEXIT_INTERRUPTION_INFORMATION));
if (interrupt.interruption_type == non_maskable_interrupt
&& interrupt.vector == nmi)
{
// TODO ?
return;
}
if (interrupt.vector == invalid_opcode)
{
guest_context.increment_rip = false;
const auto state = get_syscall_state(guest_context);
if (state == syscall_state::page_fault)
{
return;
}
const auto proc = process::get_current_process();
const auto filename = proc.get_image_filename();
if (string::equal(filename, "explorer.exe"))
{
debug_log("Explorer SYSCALL: %d\n", static_cast<uint32_t>(guest_context.vp_regs->Rax));
}
if (state == syscall_state::is_syscall)
{
const auto instruction_length = read_vmx(VMCS_VMEXIT_INSTRUCTION_LENGTH);
const auto star = __readmsr(IA32_STAR);
const auto lstar = __readmsr(IA32_LSTAR);
const auto fmask = __readmsr(IA32_FMASK);
guest_context.vp_regs->Rcx = guest_context.guest_rip + instruction_length;
guest_context.guest_rip = lstar;
__vmx_vmwrite(VMCS_GUEST_RIP, guest_context.guest_rip);
guest_context.vp_regs->R11 = guest_context.guest_e_flags;
guest_context.guest_e_flags &= ~(fmask | RFLAGS_RESUME_FLAG_FLAG);
__vmx_vmwrite(VMCS_GUEST_RFLAGS, guest_context.guest_e_flags);
vmx::gdt_entry gdt_entry{};
gdt_entry.selector.flags = static_cast<uint16_t>((star >> 32) & ~3);
gdt_entry.base = 0;
gdt_entry.limit = 0xFFFFF;
gdt_entry.access_rights.flags = 0xA09B;
__vmx_vmwrite(VMCS_GUEST_CS_SELECTOR, gdt_entry.selector.flags);
__vmx_vmwrite(VMCS_GUEST_CS_LIMIT, gdt_entry.limit);
__vmx_vmwrite(VMCS_GUEST_CS_ACCESS_RIGHTS, gdt_entry.access_rights.flags);
__vmx_vmwrite(VMCS_GUEST_CS_BASE, gdt_entry.base);
gdt_entry = {};
gdt_entry.selector.flags = static_cast<uint16_t>(((star >> 32) & ~3) + 8);
gdt_entry.base = 0;
gdt_entry.limit = 0xFFFFF;
gdt_entry.access_rights.flags = 0xC093;
__vmx_vmwrite(VMCS_GUEST_SS_SELECTOR, gdt_entry.selector.flags);
__vmx_vmwrite(VMCS_GUEST_SS_LIMIT, gdt_entry.limit);
__vmx_vmwrite(VMCS_GUEST_SS_ACCESS_RIGHTS, gdt_entry.access_rights.flags);
__vmx_vmwrite(VMCS_GUEST_SS_BASE, gdt_entry.base);
}
else if (state == syscall_state::is_sysret)
{
const auto star = __readmsr(IA32_STAR);
guest_context.vp_regs->Rip = guest_context.vp_regs->Rcx;
__vmx_vmwrite(VMCS_GUEST_RIP, guest_context.vp_regs->Rip);
guest_context.guest_e_flags = (guest_context.vp_regs->R11 & 0x3C7FD7) | 2;
__vmx_vmwrite(VMCS_GUEST_RFLAGS, guest_context.guest_e_flags);
vmx::gdt_entry gdt_entry{};
gdt_entry.selector.flags = static_cast<uint16_t>(((star >> 48) + 16) | 3);
gdt_entry.base = 0;
gdt_entry.limit = 0xFFFFF;
gdt_entry.access_rights.flags = 0xA0FB;
__vmx_vmwrite(VMCS_GUEST_CS_SELECTOR, gdt_entry.selector.flags);
__vmx_vmwrite(VMCS_GUEST_CS_LIMIT, gdt_entry.limit);
__vmx_vmwrite(VMCS_GUEST_CS_ACCESS_RIGHTS, gdt_entry.access_rights.flags);
__vmx_vmwrite(VMCS_GUEST_CS_BASE, gdt_entry.base);
gdt_entry = {};
gdt_entry.selector.flags = static_cast<uint16_t>(((star >> 48) + 8) | 3);
gdt_entry.base = 0;
gdt_entry.limit = 0xFFFFF;
gdt_entry.access_rights.flags = 0xC0F3;
__vmx_vmwrite(VMCS_GUEST_SS_SELECTOR, gdt_entry.selector.flags);
__vmx_vmwrite(VMCS_GUEST_SS_LIMIT, gdt_entry.limit);
__vmx_vmwrite(VMCS_GUEST_SS_ACCESS_RIGHTS, gdt_entry.access_rights.flags);
__vmx_vmwrite(VMCS_GUEST_SS_BASE, gdt_entry.base);
}
else
{
inject_invalid_opcode();
}
}
else
{
__vmx_vmwrite(VMCS_CTRL_VMENTRY_INTERRUPTION_INFORMATION_FIELD, interrupt.flags);
if (interrupt.error_code_valid)
{
__vmx_vmwrite(VMCS_CTRL_VMENTRY_EXCEPTION_ERROR_CODE, read_vmx(VMCS_VMEXIT_INTERRUPTION_ERROR_CODE));
}
}
}
bool is_system()
{
return (read_vmx(VMCS_GUEST_CS_SELECTOR) & SEGMENT_ACCESS_RIGHTS_DESCRIPTOR_PRIVILEGE_LEVEL_MASK) == DPL_SYSTEM;
}
void vmx_handle_cpuid(vmx::guest_context& guest_context)
{
if (guest_context.vp_regs->Rax == 0x41414141 &&
guest_context.vp_regs->Rcx == 0x42424243 &&
is_system())
{
vmx_enable_syscall_hooks(true);
return;
}
INT32 cpu_info[4]{0, 0, 0, 0};
INT32 cpu_info[4];
const auto is_privileged = (read_vmx(VMCS_GUEST_CS_SELECTOR) &
SEGMENT_ACCESS_RIGHTS_DESCRIPTOR_PRIVILEGE_LEVEL_MASK) == DPL_SYSTEM;
if (guest_context.vp_regs->Rax == 0x41414141 &&
guest_context.vp_regs->Rcx == 0x42424242 &&
is_system())
is_privileged)
{
guest_context.exit_vm = true;
return;
@ -849,6 +535,15 @@ void vmx_handle_cpuid(vmx::guest_context& guest_context)
__cpuidex(cpu_info, static_cast<int32_t>(guest_context.vp_regs->Rax),
static_cast<int32_t>(guest_context.vp_regs->Rcx));
bool should_zero = false;
if (!is_privileged)
{
should_zero = log_cpuid_call(guest_context.guest_rip, guest_context.vp_regs->Rax, guest_context.vp_regs->Rcx,
cpu_info);
}
const auto _rax = guest_context.vp_regs->Rax;
if (guest_context.vp_regs->Rax == 1)
{
cpu_info[2] |= HYPERV_HYPERVISOR_PRESENT_BIT;
@ -858,6 +553,107 @@ void vmx_handle_cpuid(vmx::guest_context& guest_context)
cpu_info[0] = 'momo';
}
if (should_zero)
{
// [MOMO] CPUID call(HogwartsLegacy) : 140D2451B - (EAX : 80000006 - ECX : 00000000) - (EAX : 00000000 - EBX : 00000000 - ECX : 01006040 - EDX : 00000000)
// [MOMO] CPUID call (HogwartsLegacy): 1405F4817 - (EAX: 00000004 - ECX: 00000000) - (EAX: 1C004121 - EBX: 01C0003F - ECX: 0000003F - EDX: 00000000)
bool allow_all = true;
// not sure if necessary
/*if (_rax == 0 && allow_all)
{
cpu_info[0] = 0x00000016;
cpu_info[1] = 0x756E6547;
cpu_info[2] = 0x6C65746E;
cpu_info[3] = 0x49656E69;
}
else if (_rax == 4 && allow_all)
{
cpu_info[0] = 0x00000000;
cpu_info[1] = 0x01C0003F;
cpu_info[2] = 0x0000003F;
cpu_info[3] = 0x00000000;
}
else if (_rax == 7 && allow_all)
{
cpu_info[0] = 0x1C004121;
cpu_info[1] = 0x029C6FBF;
cpu_info[2] = 0x40000000;
cpu_info[3] = (INT32)0xBC002E00;
}
else if (_rax == 0x80000000 && allow_all)
{
cpu_info[0] = (INT32)0x80000008;
cpu_info[1] = 0x00000000;
cpu_info[2] = 0x00000000;
cpu_info[3] = 0x00000000;
}
else if (_rax == 0x80000006 && allow_all)
{
cpu_info[0] = 0x00000000;
cpu_info[1] = 0x00000000;
cpu_info[2] = 0x01006040;
cpu_info[3] = 0x00000000;
}
// absolutely necessary v
else*/ if (_rax == 1 && allow_all)
{
cpu_info[0] = 0x000306A9;
cpu_info[1] = 0x02100800;
cpu_info[2] = 0x7FBAE3FF & (~0xC000000);
//cpu_info[0] = 0x000906EA;
//cpu_info[1] = 0x04100800;
//cpu_info[2] = 0x7FFAFBFF & (~0xC000000);
cpu_info[3] = (INT32)0xBFEBFBFF ;
}
else if (_rax == 0x80000002)
{
cpu_info[0] = 0x65746E49;
cpu_info[1] = 0x2952286C;
cpu_info[2] = 0x726F4320;
cpu_info[3] = 0x4D542865;
}
else if (_rax == 0x80000003)
{
cpu_info[0] = 0x37692029;
cpu_info[1] = 0x3538382D;
cpu_info[2] = 0x43204830;
cpu_info[3] = 0x40205550;
}
else if (_rax == 0x80000004)
{
cpu_info[0] = 0x362E3220;
cpu_info[1] = 0x7A484730;
cpu_info[2] = 0x00000000;
cpu_info[3] = 0x00000000;
}
else if(false)
{
cpu_info[0] = 0;
cpu_info[1] = 0;
cpu_info[2] = 0;
cpu_info[3] = 0;
debug_log("Not zeroing!\n");
}
/* should_zero &= _rax == 1
|| _rax == 0x80000002
|| _rax == 0x80000003
|| _rax == 0x80000004;
*
if (should_zero)
{
cpu_info[0] = 0;
cpu_info[1] = 0;
cpu_info[2] = 0;
cpu_info[3] = 0;
}*/
}
guest_context.vp_regs->Rax = cpu_info[0];
guest_context.vp_regs->Rbx = cpu_info[1];
guest_context.vp_regs->Rcx = cpu_info[2];
@ -907,12 +703,37 @@ void vmx_dispatch_vm_exit(vmx::guest_context& guest_context, const vmx::state& v
case VMX_EXIT_REASON_EPT_MISCONFIGURATION:
vm_state.ept->handle_misconfiguration(guest_context);
break;
case VMX_EXIT_REASON_EXCEPTION_OR_NMI:
vmx_handle_exception(guest_context);
case VMX_EXIT_REASON_EXECUTE_RDTSC:
{
//debug_log("VM exit: VMX_EXIT_REASON_EXECUTE_RDTSC\n");
ULARGE_INTEGER tsc{};
tsc.QuadPart = __rdtsc();
guest_context.vp_regs->Rax = tsc.LowPart;
guest_context.vp_regs->Rdx = tsc.HighPart;
log_other_call(guest_context.guest_rip, true);
break;
//case VMX_EXIT_REASON_EXECUTE_RDTSC:
// break;
}
case VMX_EXIT_REASON_EXECUTE_RDTSCP:
{
//debug_log("VM exit: VMX_EXIT_REASON_EXECUTE_RDTSCP\n");
uint32_t _rcx{};
ULARGE_INTEGER tsc{};
tsc.QuadPart = __rdtscp(&_rcx);
guest_context.vp_regs->Rax = tsc.LowPart;
guest_context.vp_regs->Rdx = tsc.HighPart;
guest_context.vp_regs->Rcx = _rcx;
log_other_call(guest_context.guest_rip, false);
break;
}
default:
//debug_log("Unknown VM exit: %X\n",(uint32_t) guest_context.exit_reason);
break;
}
@ -989,6 +810,7 @@ void setup_vmcs_for_cpu(vmx::state& vm_state)
ia32_vmx_procbased_ctls_register procbased_ctls_register{};
procbased_ctls_register.activate_secondary_controls = 1;
procbased_ctls_register.use_msr_bitmaps = 1;
procbased_ctls_register.rdtsc_exiting = 0;
__vmx_vmwrite(VMCS_CTRL_PROCESSOR_BASED_VM_EXECUTION_CONTROLS,
adjust_msr(launch_context->msr_data[14],
@ -996,7 +818,7 @@ void setup_vmcs_for_cpu(vmx::state& vm_state)
ia32_vmx_exit_ctls_register exit_ctls_register{};
exit_ctls_register.host_address_space_size = 1;
__vmx_vmwrite(VMCS_CTRL_PRIMARY_VMEXIT_CONTROLS,
__vmx_vmwrite(VMCS_CTRL_VMEXIT_CONTROLS,
adjust_msr(launch_context->msr_data[15],
exit_ctls_register.flags));
@ -1087,8 +909,7 @@ void setup_vmcs_for_cpu(vmx::state& vm_state)
__vmx_vmwrite(VMCS_GUEST_DEBUGCTL, state->debug_control);
__vmx_vmwrite(VMCS_GUEST_DR7, state->kernel_dr7);
const auto stack_pointer = reinterpret_cast<uintptr_t>(vm_state.stack_buffer) + KERNEL_STACK_SIZE - sizeof(
CONTEXT);
const auto stack_pointer = reinterpret_cast<uintptr_t>(vm_state.stack_buffer) + KERNEL_STACK_SIZE - sizeof(CONTEXT);
__vmx_vmwrite(VMCS_GUEST_RSP, stack_pointer);
__vmx_vmwrite(VMCS_GUEST_RIP, reinterpret_cast<uintptr_t>(vm_launch));
@ -1151,8 +972,6 @@ void hypervisor::enable_core(const uint64_t system_directory_table_base)
{
throw std::runtime_error("Hypervisor is not present");
}
enable_syscall_hooking();
}
void hypervisor::disable_core()

View File

@ -68,18 +68,6 @@ namespace memory
return memory;
}
_IRQL_requires_max_(APC_LEVEL)
bool read_physical_memory(void* destination, uint64_t physical_address, const size_t size)
{
size_t bytes_read{};
MM_COPY_ADDRESS source{};
source.PhysicalAddress.QuadPart = static_cast<int64_t>(physical_address);
return MmCopyMemory(destination, source, size, MM_COPY_MEMORY_PHYSICAL, &bytes_read) == STATUS_SUCCESS &&
bytes_read == size;
}
uint64_t get_physical_address(void* address)
{
return static_cast<uint64_t>(MmGetPhysicalAddress(address).QuadPart);

View File

@ -10,9 +10,6 @@ namespace memory
_IRQL_requires_max_(DISPATCH_LEVEL)
void* allocate_aligned_memory(size_t size);
_IRQL_requires_max_(APC_LEVEL)
bool read_physical_memory(void* destination, uint64_t physical_address, size_t size);
uint64_t get_physical_address(void* address);
void* get_virtual_address(uint64_t address);

View File

@ -56,29 +56,6 @@ MmAllocateContiguousNodeMemory(
// ----------------------------------------
typedef struct _MM_COPY_ADDRESS {
union {
PVOID VirtualAddress;
PHYSICAL_ADDRESS PhysicalAddress;
};
} MM_COPY_ADDRESS, * PMMCOPY_ADDRESS;
#define MM_COPY_MEMORY_PHYSICAL 0x1
#define MM_COPY_MEMORY_VIRTUAL 0x2
_IRQL_requires_max_(APC_LEVEL)
NTKERNELAPI
NTSTATUS
MmCopyMemory(
_In_ PVOID TargetAddress,
_In_ MM_COPY_ADDRESS SourceAddress,
_In_ SIZE_T NumberOfBytes,
_In_ ULONG Flags,
_Out_ PSIZE_T NumberOfBytesTransferred
);
// ----------------------------------------
NTSYSAPI
VOID
NTAPI

View File

@ -10,7 +10,7 @@ namespace string
char* get_va_buffer();
template <typename ...Args>
template <typename... Args>
const char* va(const char* message, Args&&... args)
{
auto* buffer = get_va_buffer();
@ -25,9 +25,9 @@ namespace string
return !s2;
}
while (*s1)
while(*s1)
{
if (*(s1++) != *(s2++))
if(*(s1++) != *(s2++))
{
return false;
}

View File

@ -45,25 +45,12 @@ namespace
static driver hypervisor{};
static driver_device device{};
if (!device)
if (!hypervisor)
{
try
{
device = create_driver_device();
}
catch (...)
{
}
}
if (device)
{
return device;
}
if (!hypervisor)
{
hypervisor = create_driver();
hypervisor = create_driver();
}catch(...){}
}
if (!device)

View File

@ -87,12 +87,7 @@ void patch_t6(const uint32_t pid)
void try_patch_t6()
{
auto pid = get_process_id_from_window(nullptr, "Call of Duty" "\xAE" ": Black Ops II - Multiplayer");
if (!pid)
{
pid = get_process_id_from_window("CoDBlackOps", nullptr);
}
const auto pid = get_process_id_from_window(nullptr, "Call of Duty" "\xAE" ": Black Ops II - Multiplayer");
if (pid)
{
printf("Patching T6...\n");