From e237a944cc71dded30228b627d8c8e259512309c Mon Sep 17 00:00:00 2001 From: Aiken Harris Date: Mon, 22 Dec 2025 08:21:43 +0100 Subject: [PATCH] Extend PTE helpers with raw read and write support --- xtoskrnl/includes/mm/amd64/pagemap.hh | 3 ++ xtoskrnl/includes/mm/amd64/paging.hh | 3 ++ xtoskrnl/includes/mm/i686/pagemap.hh | 9 ++++ xtoskrnl/includes/mm/i686/paging.hh | 3 ++ xtoskrnl/mm/amd64/pagemap.cc | 41 +++++++++++++- xtoskrnl/mm/i686/pagemap.cc | 77 +++++++++++++++++++++++++++ xtoskrnl/mm/paging.cc | 39 ++++++++++++++ 7 files changed, 174 insertions(+), 1 deletion(-) diff --git a/xtoskrnl/includes/mm/amd64/pagemap.hh b/xtoskrnl/includes/mm/amd64/pagemap.hh index 57b20e5..9cc6d7e 100644 --- a/xtoskrnl/includes/mm/amd64/pagemap.hh +++ b/xtoskrnl/includes/mm/amd64/pagemap.hh @@ -38,6 +38,7 @@ namespace MM XTAPI PMMPPE GetPpeAddress(IN PVOID Address); XTAPI ULONG GetPpeOffset(IN PVOID Address); VIRTUAL XTAPI PVOID GetPpeVirtualAddress(IN PMMPPE PpePointer) = 0; + XTAPI ULONG_PTR GetPte(IN PMMPTE PtePointer); XTAPI PMMPTE GetPteAddress(IN PVOID Address); XTAPI LONG GetPteDistance(PMMPTE EndPte, PMMPTE StartPte); @@ -57,6 +58,8 @@ namespace MM XTAPI VOID SetPte(IN PMMPTE PtePointer, IN PFN_NUMBER PageFrameNumber, IN ULONG_PTR AttributesMask); + XTAPI VOID SetPte(IN PMMPTE PtePointer, + IN ULONG_PTR Attributes); XTAPI VOID SetPteCaching(IN PMMPTE PtePointer, IN BOOLEAN CacheDisable, IN BOOLEAN WriteThrough); diff --git a/xtoskrnl/includes/mm/amd64/paging.hh b/xtoskrnl/includes/mm/amd64/paging.hh index d2ccda0..efbfe83 100644 --- a/xtoskrnl/includes/mm/amd64/paging.hh +++ b/xtoskrnl/includes/mm/amd64/paging.hh @@ -36,6 +36,7 @@ namespace MM STATIC XTAPI PVOID GetPdeVirtualAddress(IN PMMPDE PdePointer); STATIC XTAPI PMMPPE GetPpeAddress(IN PVOID Address); STATIC XTAPI PVOID GetPpeVirtualAddress(IN PMMPPE PpePointer); + STATIC XTAPI ULONG_PTR GetPte(IN PMMPTE PtePointer); STATIC XTAPI PMMPTE GetPteAddress(IN PVOID Address); STATIC XTAPI LONG GetPteDistance(PMMPTE EndPte, PMMPTE StartPte); @@ -53,6 +54,8 @@ namespace MM STATIC XTAPI VOID SetPte(IN PMMPTE PtePointer, IN PFN_NUMBER PageFrameNumber, IN ULONG_PTR AttributesMask); + STATIC XTAPI VOID SetPte(IN PMMPTE PtePointer, + IN ULONG_PTR Attributes); STATIC XTAPI VOID SetPteCaching(IN PMMPTE PtePointer, IN BOOLEAN CacheDisable, IN BOOLEAN WriteThrough); diff --git a/xtoskrnl/includes/mm/i686/pagemap.hh b/xtoskrnl/includes/mm/i686/pagemap.hh index 64244ce..30de3b6 100644 --- a/xtoskrnl/includes/mm/i686/pagemap.hh +++ b/xtoskrnl/includes/mm/i686/pagemap.hh @@ -35,6 +35,7 @@ namespace MM XTAPI PMMPPE GetPpeAddress(IN PVOID Address); XTAPI ULONG GetPpeOffset(IN PVOID Address); XTAPI PVOID GetPpeVirtualAddress(IN PMMPPE PpePointer); + VIRTUAL XTAPI ULONG_PTR GetPte(IN PMMPTE PtePointer) = 0; XTAPI PMMPTE GetPteAddress(IN PVOID Address); XTAPI ULONG GetPteOffset(IN PVOID Address); VIRTUAL XTAPI LONG GetPteDistance(PMMPTE EndPte, @@ -51,6 +52,8 @@ namespace MM VIRTUAL XTAPI VOID SetPte(IN PMMPTE PtePointer, IN PFN_NUMBER PageFrameNumber, IN ULONG_PTR AttributesMask) = 0; + VIRTUAL XTAPI VOID SetPte(IN PMMPTE PtePointer, + IN ULONG_PTR Attributes) = 0; VIRTUAL XTAPI VOID SetPteCaching(IN PMMPTE PtePointer, IN BOOLEAN CacheDisable, IN BOOLEAN WriteThrough) = 0; @@ -70,6 +73,7 @@ namespace MM XTAPI BOOLEAN GetOneEntry(IN PMMPTE Pte); XTAPI PFN_NUMBER GetPageFrameNumber(IN PMMPTE Pte); XTAPI PVOID GetPdeVirtualAddress(IN PMMPDE PdePointer); + XTAPI ULONG_PTR GetPte(IN PMMPTE PtePointer); XTAPI LONG GetPteDistance(PMMPTE EndPte, PMMPTE StartPte); XTAPI ULONG GetPteSize(VOID); @@ -83,6 +87,8 @@ namespace MM XTAPI VOID SetPte(IN PMMPTE PtePointer, IN PFN_NUMBER PageFrameNumber, IN ULONG_PTR AttributesMask); + XTAPI VOID SetPte(IN PMMPTE PtePointer, + IN ULONG_PTR Attributes); XTAPI VOID SetPteCaching(IN PMMPTE PtePointer, IN BOOLEAN CacheDisable, IN BOOLEAN WriteThrough); @@ -101,6 +107,7 @@ namespace MM XTAPI BOOLEAN GetOneEntry(IN PMMPTE Pte); XTAPI PFN_NUMBER GetPageFrameNumber(IN PMMPTE Pte); XTAPI PVOID GetPdeVirtualAddress(IN PMMPDE PdePointer); + XTAPI ULONG_PTR GetPte(IN PMMPTE PtePointer); XTAPI LONG GetPteDistance(PMMPTE EndPte, PMMPTE StartPte); XTAPI ULONG GetPteSize(VOID); @@ -114,6 +121,8 @@ namespace MM XTAPI VOID SetPte(IN PMMPTE PtePointer, IN PFN_NUMBER PageFrameNumber, IN ULONG_PTR AttributesMask); + XTAPI VOID SetPte(IN PMMPTE PtePointer, + IN ULONG_PTR Attributes); XTAPI VOID SetPteCaching(IN PMMPTE PtePointer, IN BOOLEAN CacheDisable, IN BOOLEAN WriteThrough); diff --git a/xtoskrnl/includes/mm/i686/paging.hh b/xtoskrnl/includes/mm/i686/paging.hh index b6c8209..2c06d3c 100644 --- a/xtoskrnl/includes/mm/i686/paging.hh +++ b/xtoskrnl/includes/mm/i686/paging.hh @@ -34,6 +34,7 @@ namespace MM STATIC XTAPI PVOID GetPdeVirtualAddress(IN PMMPDE PdePointer); STATIC XTAPI PMMPPE GetPpeAddress(IN PVOID Address); STATIC XTAPI PVOID GetPpeVirtualAddress(IN PMMPPE PpePointer); + STATIC XTAPI ULONG_PTR GetPte(IN PMMPTE PtePointer); STATIC XTAPI PMMPTE GetPteAddress(IN PVOID Address); STATIC XTAPI LONG GetPteDistance(PMMPTE EndPte, PMMPTE StartPte); @@ -49,6 +50,8 @@ namespace MM STATIC XTAPI VOID SetPte(IN PMMPTE PtePointer, IN PFN_NUMBER PageFrameNumber, IN ULONG_PTR AttributesMask); + STATIC XTAPI VOID SetPte(IN PMMPTE PtePointer, + IN ULONG_PTR Attributes); STATIC XTAPI VOID SetPteCaching(IN PMMPTE PtePointer, IN BOOLEAN CacheDisable, IN BOOLEAN WriteThrough); diff --git a/xtoskrnl/mm/amd64/pagemap.cc b/xtoskrnl/mm/amd64/pagemap.cc index 06d3e42..e89b05b 100644 --- a/xtoskrnl/mm/amd64/pagemap.cc +++ b/xtoskrnl/mm/amd64/pagemap.cc @@ -269,6 +269,24 @@ MM::PageMap::GetPpeOffset(IN PVOID Address) return ((((ULONGLONG)Address) >> MM_PPI_SHIFT) & 0x1FF); } + /** + * Gets the entire contents of a Page Table Entry (PTE) as a single value. + * + * @param PtePointer + * Pointer to the Page Table Entry (PTE) to read. + * + * @return This routine returns the contents of the PTE as a single value. + * + * @since XT 1.0 + */ +XTAPI +ULONG_PTR +MM::PageMap::GetPte(IN PMMPTE PtePointer) +{ + /* Return PTE value */ + return PtePointer->Long; +} + /** * Gets the address of the PTE (Page Table Entry), that maps given address. * @@ -461,7 +479,7 @@ MM::PageMap::SetOneEntry(IN PMMPTE Pte, } /** - * Sets a PML2 page table entry (PTE) with the specified physical page and access flags. + * Sets a Page Table Entry (PTE) with the specified physical page and access flags. * * @param PtePointer * Pointer to the page table entry (PTE) to set. @@ -488,6 +506,27 @@ MM::PageMap::SetPte(IN PMMPTE PtePointer, PtePointer->Long |= AttributesMask; } +/** + * Sets a Page Table Entry (PTE) with the specified attributes. + * + * @param PtePointer + * Pointer to the page table entry (PTE) to set. + * + * @param Attributes + * Specifies the attributes to apply to the PTE. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +MM::PageMap::SetPte(IN PMMPTE PtePointer, + IN ULONG_PTR Attributes) +{ + PtePointer->Long = Attributes; +} + /** * Sets caching attributes for a PML2 page table entry (PTE). * diff --git a/xtoskrnl/mm/i686/pagemap.cc b/xtoskrnl/mm/i686/pagemap.cc index 7840274..2ca3cd6 100644 --- a/xtoskrnl/mm/i686/pagemap.cc +++ b/xtoskrnl/mm/i686/pagemap.cc @@ -301,6 +301,23 @@ MM::PageMapBasic::GetPdeVirtualAddress(IN PMMPDE PdePointer) return ((PVOID)((ULONG)(PdePointer) << 20)); } + /** + * Gets the entire contents of a PML2 Page Table Entry (PTE) as a single value. + * + * @param PtePointer + * Pointer to the Page Table Entry (PTE) to read. + * + * @return This routine returns the contents of the PTE as a single value. + * + * @since XT 1.0 + */ +XTAPI +ULONG_PTR +MM::PageMapBasic::GetPte(IN PMMPTE PtePointer) +{ + /* Return PTE value */ + return PtePointer->Pml2.Long; +} /** * Calculates the distance between two PTE pointers. * @@ -472,6 +489,27 @@ MM::PageMapBasic::SetPte(IN PMMPTE PtePointer, PtePointer->Pml2.Long |= AttributesMask; } +/** + * Sets a PML2 page table entry (PTE) with the specified attributes. + * + * @param PtePointer + * Pointer to the page table entry (PTE) to set. + * + * @param Attributes + * Specifies the attributes to apply to the PTE. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +MM::PageMapBasic::SetPte(IN PMMPTE PtePointer, + IN ULONG_PTR Attributes) +{ + PtePointer->Pml2.Long = Attributes; +} + /** * Sets caching attributes for a PML2 page table entry (PTE). * @@ -650,6 +688,24 @@ MM::PageMapXpa::GetPdeVirtualAddress(IN PMMPDE PdePointer) return ((PVOID)((ULONG)(PdePointer) << 18)); } + /** + * Gets the entire contents of a PML3 Page Table Entry (PTE) as a single value. + * + * @param PtePointer + * Pointer to the Page Table Entry (PTE) to read. + * + * @return This routine returns the contents of the PTE as a single value. + * + * @since XT 1.0 + */ +XTAPI +ULONG_PTR +MM::PageMapXpa::GetPte(IN PMMPTE PtePointer) +{ + /* Return PTE value */ + return PtePointer->Pml3.Long; +} + /** * Calculates the distance between two PTE pointers. * @@ -820,6 +876,27 @@ MM::PageMapXpa::SetPte(IN PMMPTE PtePointer, PtePointer->Pml3.Long |= AttributesMask; } +/** + * Sets a PML3 page table entry (PTE) with the specified attributes. + * + * @param PtePointer + * Pointer to the page table entry (PTE) to set. + * + * @param Attributes + * Specifies the attributes to apply to the PTE. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +MM::PageMapXpa::SetPte(IN PMMPTE PtePointer, + IN ULONG_PTR Attributes) +{ + PtePointer->Pml3.Long = Attributes; +} + /** * Sets caching attributes for a PML3 page table entry (PTE). * diff --git a/xtoskrnl/mm/paging.cc b/xtoskrnl/mm/paging.cc index 331d9f5..5a9562d 100644 --- a/xtoskrnl/mm/paging.cc +++ b/xtoskrnl/mm/paging.cc @@ -293,6 +293,24 @@ MM::Paging::GetPpeVirtualAddress(IN PMMPPE PpePointer) return PmlRoutines->GetPpeVirtualAddress(PpePointer); } + /** + * Gets the entire contents of a Page Table Entry (PTE) as a single value. + * + * @param PtePointer + * Pointer to the Page Table Entry (PTE) to read. + * + * @return This routine returns the contents of the PTE as a single value. + * + * @since XT 1.0 + */ +XTAPI +ULONG_PTR +MM::Paging::GetPte(IN PMMPTE PtePointer) +{ + /* Return PTE value */ + return PmlRoutines->GetPte(PtePointer); +} + /** * Gets the address of the PTE (Page Table Entry), that maps given address. * @@ -495,6 +513,27 @@ MM::Paging::SetPte(IN PMMPTE PtePointer, PmlRoutines->SetPte(PtePointer, PageFrameNumber, AttributesMask); } +/** + * Sets a Page Table Entry (PTE) with the specified attributes. + * + * @param PtePointer + * Pointer to the page table entry (PTE) to set. + * + * @param Attributes + * Specifies the attributes to apply to the PTE. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +MM::Paging::SetPte(IN PMMPTE PtePointer, + IN ULONG_PTR Attributes) +{ + PmlRoutines->SetPte(PtePointer, Attributes); +} + /** * Sets caching attributes for a PML2 page table entry (PTE). *