PTEditor
A small library to modify all page-table levels of all processes from user space for x86_64 and ARMv8.
Install / Use
/learn @misc0110/PTEditorREADME
PTEditor
A small library to modify all page-table levels of all processes from user space for x86_64 (Linux and Windows 10) and ARMv8 (Linux). It also allows to read and program memory types (i.e., PATs on x86 and MAIRs on ARM).
Installation
The library relies on the pteditor kernel module (Linux) or kernel driver (Windows). The kernel part is provided as source code for compilation (Linux and Windows), PPA (Linux), and as pre-built binary (Windows).
The library can be used by linking it to the application (see example.c) or as a single header (ptedit_header.h) which can be directly included (see the demos).
Install from PPA (Linux, recommended)
First, add the public key of the PPA and the PPA URL to the package manager, and update the package manager
curl -s "https://misc0110.github.io/ppa/KEY.gpg" | sudo tee /etc/apt/trusted.gpg.d/pteditor.asc
sudo curl -s -o /etc/apt/sources.list.d/misc0110.list "https://misc0110.github.io/ppa/file.list"
sudo apt update
Then, simply install the kernel module
sudo apt install pteditor-dkms
Pre-Built Driver (Windows, recommended)
The repository also contains a pre-built driver for Windows 10 in the driver folder.
To load the driver, you have to first disable secure boot and driver signature enforcement.
Temporarily Disable Driver Signature Enforcement
Hold the shift key while clicking on "Restart" in the start menu. This brings up a restart menu, where you can disable driver signature enforcement in "Troubleshoot > Advanced Options > Startup Settings". Press "Restart", and the in the startup settings press "7" or "F7" to disable driver signature enforcement. After the PC is started, the driver can be loaded. Keep in mind that the driver signature enforcement is enabled when the PC is rebooted.
Permanently Disable Driver Signature Enforcement
To permanently disable driver signature enforcement, enable Windows test mode by entering
bcdedit /set testsigning on
in an administrator command prompt. To disable test mode, run
bcdedit /set testsigning off
Loading the Driver
To load and active the driver, the repository contains a loader in driver/PTEditorLoader. Simply run
PTEditorLoader.exe
as an administrator. To unload the driver, run
PTEditorLoader.exe --unload
Alternatively, you can also use any other driver-loading tool, e.g., OSRLoader or NoVirusThanks Kernel-Mode Driver Loader.
Install Kernel Part From Source
Linux
Building the kernel module requires the kernel headers of the kernel. On Ubuntu, they can be installed by running
sudo apt install linux-headers-$(uname -r)
Both the library and the the kernel module can be build by running
make
The resulting kernel module can be loaded using
sudo insmod module/pteditor.ko
Windows
The kernel driver for Windows requires Visual Studio with Visual C++, the Windows SDK, and the Windows Driver Kit (WDK) to build. Using the Visual Studio project, the driver can then simply be built from Visual Studio.
Requirements
The library requires a recent Linux kernel (continuously tested on the current kernel for 20.04 (kernel 5.8), and 22.04 (kernel 5.15 and 6.2)) or Windows 10. It supports both x86_64 and ARMv8.
The library does not rely on any other library. It uses only standard C functionality. On Linux, the library does not require root privileges, whereas on Windows it requires administrator privileges.
Test
To test whether the kernel part and the library works, the repository contains unit tests.
The tests are found in the folder test and can be compiled with make (Linux) or Visual Studio (Windows).
Example
The basic functionality (ptedit_init and ptedit_cleanup) is always required.
After the initialization, all functions provided by the library can be used.
For examples see example.c or the examples in the demo folder.
The demo folder contains multiple examples:
memmap: Starting from the root of paging, the demo iterates through all page tables of all levels and dumps the contents of the entries.map_pt: A Rowhamer exploit simulation, which maps the page table to a user-accessible address for manipulation.uncachable: This demos manipulates the memory type of a mapping to uncachable and back to cachable.nx: After setting a function to non-executable, it uses the page tables to make the function executable again.virt2phys: Converts a virtual to a physical address.performance: Measures how many addresses can be resolved per second.
API
Basic Functionality | Descriptions
--------------------------------|---------------------------------------------
int ptedit_init() | Initializes (and acquires) PTEditor kernel module
void ptedit_cleanup() | Releases PTEditor kernel module
void ptedit_use_implementation(int implementation) | Select the PTEditor implementation to use
Page tables | Descriptions
--------------------------------|---------------------------------------------
ptedit_entry_t ptedit_resolve(void * address,pid_t pid) | Resolves the page-table entries of all levels for a virtual address of a given process.
void ptedit_update(void * address,pid_t pid,ptedit_entry_t * vm) | Updates one or more page-table entries for a virtual address of a given process. The TLB for the given address is flushed after updating the entries.
void ptedit_pte_set_bit(void * address,pid_t pid,int bit) | Sets a bit directly in the PTE of an address.
void ptedit_pte_clear_bit(void * address,pid_t pid,int bit) | Clears a bit directly in the PTE of an address.
unsigned char ptedit_pte_get_bit(void * address,pid_t pid,int bit) | Returns the value of a bit directly from the PTE of an address.
size_t ptedit_pte_get_pfn(void * address,pid_t pid) | Reads the PFN directly from the PTE of an address.
void ptedit_pte_set_pfn(void * address,pid_t pid,size_t pfn) | Sets the PFN directly in the PTE of an address.
TYPE ptedit_cast(size_t entry, TYPE) | Casts a paging structure entry (e.g., page table) to a structure with easy access to its fields
System Info | Descriptions
--------------------------------|---------------------------------------------
int ptedit_get_pagesize() | Returns the default page size of the system
Page frame numbers (PFN) | Descriptions
--------------------------------|---------------------------------------------
size_t ptedit_set_pfn(size_t entry,size_t pfn) | Returns a new page-table entry where the page-frame number (PFN) is replaced by the specified one.
size_t ptedit_get_pfn(size_t entry) | Returns the page-frame number (PFN) of a page-table entry.
Physical pages | Descriptions
--------------------------------|---------------------------------------------
void ptedit_read_physical_page(size_t pfn,char * buffer) | Retrieves the content of a physical page.
void ptedit_write_physical_page(size_t pfn,char * content) | Replaces the content of a physical page.
void * ptedit_pmap(size_t physical,size_t length) | Map a physical address range to the virtual address space.
Paging | Descriptions
--------------------------------|---------------------------------------------
size_t ptedit_get_paging_root(pid_t pid) | Returns the root of the paging structure (i.e., CR3 on x86 and TTBR0 on ARM).
void ptedit_set_paging_root(pid_t pid,size_t root) | Sets the root of the paging structure (i.e., CR3 on x86 and TTBR0 on ARM).
TLB/Barriers | Descriptions
--------------------------------|---------------------------------------------
void ptedit_invalidate_tlb(void * address) | Invalidates the TLB entry of current process for a given address on all CPUs.
void ptedit_invalidate_tlb_pid(pid_t pid, void * address) | Invalidates the TLB for a given PID and address on all CPUs.
void ptedit_full_serializing_barrier() | A full serializing barrier which stops everything.
int ptedit_switch_tlb_invalidation(int implementation) | The implementation to use, either PTEDITOR_TLB_INVALIDATION_KERNEL or PTEDITOR_TLB_INVALIDATION_CUSTOM (unsupported on x86).
Memory types (PATs/MAIRs) | Descriptions
--------------------------------|---------------------------------------------
size_t ptedit_get_mts() | Reads the value
Related Skills
node-connect
354.3kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
112.3kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
354.3kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
354.3kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
