WIN10 页表操作常用函数和宏

发布于 2017-05-30  1.25k 次阅读


#define MM_ZERO_ACCESS 0
#define MM_READONLY 1
#define MM_EXECUTE 2
#define MM_EXECUTE_READ 3
#define MM_READWRITE 4
#define MM_WRITECOPY 5
#define MM_EXECUTE_READWRITE 6
#define MM_EXECUTE_WRITECOPY 7

#define MM_PTE_VALID_MASK 0x1
#define MM_PTE_WRITE_MASK 0x800
#define MM_PTE_OWNER_MASK 0x4
#define MM_PTE_WRITE_THROUGH_MASK 0x8
#define MM_PTE_CACHE_DISABLE_MASK 0x10
#define MM_PTE_ACCESS_MASK 0x20
#define MM_PTE_DIRTY_MASK 0x42
#define MM_PTE_LARGE_PAGE_MASK 0x80
#define MM_PTE_GLOBAL_MASK 0x100
#define MM_PTE_COPY_ON_WRITE_MASK 0x200
#define MM_PTE_PROTOTYPE_MASK 0x400
#define MM_PTE_TRANSITION_MASK 0x800

#define VIRTUAL_ADDRESS_BITS 48
#define VIRTUAL_ADDRESS_MASK ((((ULONG_PTR)1) << VIRTUAL_ADDRESS_BITS) - 1)

#define THREAD_CREATE_FLAGS_CREATE_SUSPENDED 0x00000001
#define THREAD_CREATE_FLAGS_SKIP_THREAD_ATTACH 0x00000002
#define THREAD_CREATE_FLAGS_HIDE_FROM_DEBUGGER 0x00000004

#define EX_ADDITIONAL_INFO_SIGNATURE (ULONG_PTR)(-2)

#define KI_USER_SHARED_DATA 0xFFFFF78000000000UI64

#define SharedUserData ((KUSER_SHARED_DATA * const)KI_USER_SHARED_DATA)
#ifndef PGD_SHIFT_P
#define PGD_SHIFT_P 39
#endif

#ifndef PUD_SHIFT_P
#define PUD_SHIFT_P 30
#endif

#ifndef PMD_SHIFT_P
#define PMD_SHIFT_P 21
#endif

#ifndef PTE_SHIFT_P
#define PTE_SHIFT_P 12
#endif

#define VA_BITS 48
#define VA_MASK ((1ULL << VA_BITS) - 1)
#define VA_SHIFT 16
#ifndef PTX_MASK
#define PTX_MASK 0x1FF
#endif
#ifndef PUD_MASK_P
#define PUD_MASK_P 0x3FFFF
#endif
#ifndef PMD_MASK_P
#define PMD_MASK_P 0x7FFFFFF
#endif
#ifndef PTE_MASK_P
#define PTE_MASK_P 0xFFFFFFFFF
#endif #ifndef PTE_SHIFT
#define PTE_SHIFT 3
#endif #ifndef PTI_SHIFT
#define PTI_SHIFT 12
#endif
#ifndef PDI_SHIFT
#define PDI_SHIFT 21
#endif #ifndef PPI_SHIFT
#define PPI_SHIFT 30
#endif
#ifndef PXI_SHIFT
#define PXI_SHIFT 39
#endif
#define PTE_PER_PAGE 512
#define PDE_PER_PAGE 512
#define PPE_PER_PAGE 512
#define PXE_PER_PAGE 512
#define PPI_MASK (PPE_PER_PAGE - 1)
#define PXI_MASK (PXE_PER_PAGE - 1) uintptr_t pxe_base = 0xfffff6fb7dbed000ull;
uintptr_t ppe_base = 0xfffff6fb7da00000ull; uintptr_t pde_base = 0xfffff6fb40000000ull;
uintptr_t pte_base = 0xfffff68000000000ull; uintptr_t pxe_selfmap = 0xFFFFF6FB7DBEDF68ull;
typedef unsigned short WORD; ULONG MiGetPxeOffset(ULONG_PTR va) {
return ((ULONG)(((ULONG_PTR)(va) >> PXI_SHIFT) & PXI_MASK));
}

PMMPTE MiGetPxeAddress(ULONG_PTR va) {
return ((PMMPTE)pxe_base + MiGetPxeOffset(va));
}

PMMPTE MiGetPpeAddress(ULONG_PTR va) {

return ((PMMPTE)(((((ULONG_PTR)(va)& VIRTUAL_ADDRESS_MASK) >> PPI_SHIFT) << PTE_SHIFT) + ppe_base)); } PMMPTE MiGetPdeAddress(ULONG_PTR va) { return ((PMMPTE)(((((ULONG_PTR)(va)& VIRTUAL_ADDRESS_MASK) >> PDI_SHIFT) << PTE_SHIFT) + pde_base)); } PMMPTE MiGetPteAddress(ULONG_PTR va) { return ((PMMPTE)(((((ULONG_PTR)(va)& VIRTUAL_ADDRESS_MASK) >> PTI_SHIFT) << PTE_SHIFT) + pte_base));
}

#define VA_SHIFT (63 - 47) // address sign extend shift count

PVOID MiGetVirtualAddressMappedByPte(LONG_PTR PTE) {
return ((PVOID)((LONG_PTR)(((LONG_PTR)(PTE)-pte_base) << (PAGE_SHIFT + VA_SHIFT - PTE_SHIFT)) >> VA_SHIFT));
}

BOOLEAN MI_IS_PHYSICAL_ADDRESS(Va) {
return ((MiGetPxeAddress(Va)->u.Hard.Valid == 1) && (MiGetPpeAddress(Va)->u.Hard.Valid == 1) && ((MiGetPdeAddress(Va)->u.Long & 0x81) == 0x81) || (MiGetPteAddress(Va)->u.Hard.Valid == 1));
}

PVOID MiGetPxeSelfMapAddress(){
ULONG64 PXE_SELFMAP;
PXE_SELFMAP = ((pxe_base & 0x0000FFFFFFFFF000) >> 12) * 8 + pte_base;
return PXE_SELFMAP;
}

ULONG64 MiGetPxeSelfMapSpace(){

return (*(ULONG64*)MiGetPxeSelfMapAddress())& 0x0000FFFFFFFFF000;
}
ULONG64 MiGetPageSpaceByProcess(PEPROCESS process) {

if(MmIsAddressValid(process)){

return *(ULONG64*)((ULONG64)process + 0x28);

}

return 0ull;

}
VOID MiSetProcessSpace(PEPROCESS process ,ULONG64 space){

if (MmIsAddressValid(process)) {
*(ULONG64*)((ULONG64)process + 0x28) = space;
return TRUE;

}

return FALSE;

}
static inline NTSTATUS check_dynamic_pgtables(void)
{
/* On Windows 10 build 14316+ Page table base addresses are not static. */
RTL_OSVERSIONINFOW osv;
osv.dwOSVersionInfoSize = sizeof(osv);

NTSTATUS status = RtlGetVersion(&osv);
if (!NT_SUCCESS(status))
return status;

if (osv.dwMajorVersion >= 10 && osv.dwBuildNumber >= 14316) { //这个版本后的WIN10 页表虚拟地址不再是映射到固定位置了
static const UCHAR pattern[] = {
0x48, 0x8b, 0x04, 0xd0, // mov rax, [rax+rdx*8] 0x48, 0xc1, 0xe0, 0x19, // shl rax, 19h
0x48, 0xba, // mov rdx, ????????`???????? ; PTE_BASE
};

UCHAR *base = (UCHAR *)MmGetVirtualForPhysical;
BOOLEAN found = FALSE;
for (size_t i = 0; i <= 0x50 - sizeof(pattern); ++i) { if (RtlCompareMemory(pattern, &base[i], sizeof(pattern)) == sizeof(pattern)) { pte_base = *(uintptr_t *)(base + i + sizeof(pattern)); uintptr_t idx = (pte_base >> PGD_SHIFT_P) & PTX_MASK;
pde_base = pte_base | (idx << PUD_SHIFT_P);
ppe_base = pde_base | (idx << PMD_SHIFT_P);
pxe_base = ppe_base | (idx << PTE_SHIFT_P);
found = TRUE;
break;
}
}

if (!found)
return STATUS_NOT_FOUND;

uintptr_t tmp = (uintptr_t)MmGetVirtualForPhysical;

}

return STATUS_SUCCESS;
}

忆观园 - enderdz--:-- / 01:46
(*+﹏+*)


博客管理员