Last active
December 22, 2016 05:22
-
-
Save andreiw/521ba25d3d6c59df3bf4 to your computer and use it in GitHub Desktop.
x64 identity-mapped page table walker - useful for detecting non-identity-mapped bits
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
uint64_t i4; | |
uint64_t *l4pt; | |
__asm__ volatile("mov %%cr3, %0" : "=r" (l4pt)); | |
#define PG_ENTRIES 512 | |
for (i4 = 0; i4 < PG_ENTRIES; i4++) { | |
uint64_t *l3pt; | |
uint64_t i3; | |
#define PG_PRESENT (1ULL << 0) | |
#define PG_PAGE_SIZE (1ULL << 7) | |
#define PG_4K_MASK (0xffffffffff000ULL) | |
#define PG_1G_MASK (0xFFFFFFFFC0000000ULL) | |
#define PG_2M_MASK (0xFFFFFFFFFFE00000ULL) | |
#define PG_ENTRY_TO_PG(entry) ((uint64_t *) (entry & PG_4K_MASK)) | |
uint64_t e4 = l4pt[i]; | |
l3pt = PG_ENTRY_TO_PG(e4); | |
for (i3 = 0; i3 < PG_ENTRIES; i3++) { | |
uint64_t e3 = l3pt[i3]; | |
if ((e3 & PG_PRESENT) == 0) { | |
continue; | |
} | |
if ((e3 & PG_PAGE_SIZE) != 0) { | |
uint64_t va = i * 512*1024*1024*1024ULL + | |
i3 * 1024*1024*1024; | |
uint64_t pa = e3 & PG_1G_MASK; | |
if (va != pa) { | |
warn("0x%lx (1GB) -> 0x%lx", va, pa); | |
} | |
} else { | |
uint64_t i2; | |
uint64_t *l2pt = PG_ENTRY_TO_PG(e3); | |
for (i2 = 0; i2 < PG_ENTRIES; i2++) { | |
uint64_t e2 = l2pt[i2]; | |
if ((e2 & PG_PRESENT) == 0) { | |
continue; | |
} | |
if ((e2 & PG_PAGE_SIZE) != 0) { | |
uint64_t va = i * 512*1024*1024*1024ULL + | |
i3 * 1024*1024*1024ULL + | |
i2 * 2*1024*1024ULL; | |
uint64_t pa = e2 & PG_2M_MASK; | |
if (va != pa) { | |
warn("0x%lx (2MB) -> 0x%lx", va, pa); | |
} | |
} else { | |
uint64_t i1; | |
uint64_t *l1pt = PG_ENTRY_TO_PG(e2); | |
for (i1 = 0; i1 < PG_ENTRIES; i1++) { | |
uint64_t va; | |
uint64_t pa; | |
uint64_t e1 = l1pt[i1]; | |
if ((e1 & PG_PRESENT) == 0) { | |
continue; | |
} | |
va = i * 512*1024*1024*1024ULL + | |
i3 * 1024*1024*1024ULL + | |
i2 * 2*1024*1024ULL + | |
i1 * 4*1024ULL; | |
pa = e1 & PG_4K_MASK | |
if (va != pa) { | |
warn("0x%lx (4KB) -> 0x%lx", va, pa); | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment