DICHook/DICHook_OpenSource/MyMemoryIo64.cpp

132 lines
3.0 KiB
C++

#include "MyMemoryIo64.h"
DWORD64 g_PteBase = NULL;
DWORD64 g_PdeBase = NULL;
DWORD64 g_PpeBase = NULL;
DWORD64 g_PxeBase = NULL;
union VirtualAddress {
ULONG64 all;
struct {
ULONG64 offset : 12;
ULONG64 pte_index : 9;
ULONG64 pde_index : 9;
ULONG64 ppe_index : 9;
ULONG64 pxe_index : 9;
ULONG64 head : 16;
};
};
DWORD64 MmiGetPteAddress(PVOID64 Address) {
return ((((((DWORD64)Address) & 0x0000FFFFFFFFF000) >> 12) << 3) + g_PteBase);
}
DWORD64 MmiGetPdeAddress(PVOID64 Address) {
return ((((((DWORD64)Address) & 0x0000FFFFFFFFF000) >> 21) << 3) + g_PdeBase);
}
DWORD64 MmiGetPpeAddress(PVOID64 Address) {
return ((((((DWORD64)Address) & 0x0000FFFFFFFFF000) >> 30) << 3) + g_PpeBase);
}
DWORD64 MmiGetPxeAddress(PVOID64 Address) {
return ((((((DWORD64)Address) & 0x0000FFFFFFFFF000) >> 39) << 3) + g_PxeBase);
}
bool g_invpcid_enable = 0;
bool g_clfsh_enable = 0;
BOOLEAN Mmi_Init() {
if (g_PteBase)
return TRUE;
g_PteBase = (DWORD64)KGetPteBase();
if (g_PteBase == 0) {
KeBugCheck(0x8787878);
return FALSE;
}
g_PdeBase = MmiGetPteAddress((PVOID)g_PteBase);
g_PpeBase = MmiGetPteAddress((PVOID)g_PdeBase);
g_PxeBase = MmiGetPteAddress((PVOID)g_PpeBase);
CpuidRet cpuid_ret;
memset(&cpuid_ret, 0, sizeof(cpuid_ret));
AsmCpuid(7, 0, &cpuid_ret);
g_invpcid_enable = cpuid_ret.EBX & 0x400;
AsmCpuid(1, 0, &cpuid_ret);
g_clfsh_enable = cpuid_ret.EDX & 0x80000;
return TRUE;
}
VOID MmiClearPteBase() {
g_PteBase = 0;
g_PdeBase = 0;
g_PpeBase = 0;
g_PxeBase = 0;
}
VOID MmiFlushTLB(PVOID LinearAddress) {
/*if (g_invpcid_enable) {
BOOL i_enable = AsmGetRFlags() & 0x200;
if (i_enable)
_disable();
CR4 cr4;
cr4.all = __readcr4();
if (cr4.PCIDE) {
INVPCID_CTX ctx;
ctx.LinearAddress = (ULONG64)LinearAddress;
ctx.PCID = __readcr3() & 0xFFF;
if (ctx.PCID != 0) {
AsmInvpcid(0, &ctx);
return;
}
}
if (i_enable)
_enable();
}*/
/*if (g_clfsh_enable) {
_mm_mfence();
_mm_clflush(LinearAddress);
}
else*/
__invlpg(LinearAddress);
}
ULONG64 MmiGetPhysicalAddress(PVOID va) {
HardwarePteX64 PageEntry[3] = { 0 };
HardwarePteX64 page;
PULONG64 p_pxe = (PULONG64)MmiGetPxeAddress(va);
page.all = *p_pxe;
if (page.valid == 0)
return 0;
if (page.large_page) {
ULONG64 off = (ULONG64)va & 0x7FFFFFFFFF;
ULONG64 PhyAdd = page.page_frame_number << 12;
PhyAdd += off;
return PhyAdd;
}
PULONG64 p_ppe = (PULONG64)MmiGetPpeAddress(va);
page.all = *p_ppe;
if (page.valid == 0)
return 0;
if (page.large_page) {
ULONG64 off = (ULONG64)va & 0x3FFFFFFF;
ULONG64 PhyAdd = page.page_frame_number << 12;
PhyAdd += off;
return PhyAdd;
}
PULONG64 p_pde = (PULONG64)MmiGetPdeAddress(va);
page.all = *p_pde;
if (page.valid == 0)
return 0;
if (page.large_page) {
ULONG64 off = (ULONG64)va & 0x1FFFFF;
ULONG64 PhyAdd = page.page_frame_number << 12;
PhyAdd += off;
return PhyAdd;
}
PULONG64 p_pte = (PULONG64)MmiGetPteAddress(va);
page.all = *p_pte;
if (page.valid == 0)
return 0;
ULONG64 off = (ULONG64)va & 0xFFF;
ULONG64 PhyAdd = page.page_frame_number << 12;
PhyAdd += off;
return PhyAdd;
}