From 6275f70ed8862d8fe4e58ca4524a6994d254be35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ciro=20Santilli=20=E5=85=AD=E5=9B=9B=E4=BA=8B=E4=BB=B6=20?= =?UTF-8?q?=E6=B3=95=E8=BD=AE=E5=8A=9F?= Date: Sat, 9 May 2020 01:00:00 +0000 Subject: [PATCH] pagemap: was missing one bit in lkmc_pagemap_get_entry for pfn Credits to Phidelux: https://stackoverflow.com/questions/6284810/proc-pid-pagemaps-and-proc-pid-maps-linux/45500208?noredirect=1#comment109030479_45500208 --- lkmc/pagemap.h | 6 +++--- userland/linux/pagemap_dump.c | 7 +++++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/lkmc/pagemap.h b/lkmc/pagemap.h index f8891ca..53921be 100644 --- a/lkmc/pagemap.h +++ b/lkmc/pagemap.h @@ -12,7 +12,7 @@ * https://github.com/torvalds/linux/blob/v4.9/Documentation/vm/pagemap.txt */ typedef struct { - uint64_t pfn : 54; + uint64_t pfn : 55; unsigned int soft_dirty : 1; unsigned int file_page : 1; unsigned int swapped : 1; @@ -46,8 +46,8 @@ int lkmc_pagemap_get_entry(LkmcPagemapEntry *entry, int pagemap_fd, uintptr_t va return 1; } } - entry->pfn = data & (((uint64_t)1 << 54) - 1); - entry->soft_dirty = (data >> 54) & 1; + entry->pfn = data & (((uint64_t)1 << 55) - 1); + entry->soft_dirty = (data >> 55) & 1; entry->file_page = (data >> 61) & 1; entry->swapped = (data >> 62) & 1; entry->present = (data >> 63) & 1; diff --git a/userland/linux/pagemap_dump.c b/userland/linux/pagemap_dump.c index 02373fa..2579fb0 100644 --- a/userland/linux/pagemap_dump.c +++ b/userland/linux/pagemap_dump.c @@ -1,6 +1,7 @@ /* https://cirosantilli.com/linux-kernel-module-cheat#pagemap-dump-out */ #define _XOPEN_SOURCE 700 +#include #include #include #include @@ -91,8 +92,10 @@ int main(int argc, char **argv) { { LkmcPagemapEntry entry; for (uintptr_t vaddr = low; vaddr < high; vaddr += sysconf(_SC_PAGE_SIZE)) { - /* TODO always fails for the last page (vsyscall), why? pread returns 0. */ - if (!lkmc_pagemap_get_entry(&entry, pagemap_fd, vaddr)) { + if (lkmc_pagemap_get_entry(&entry, pagemap_fd, vaddr)) { + /* TODO always fails for the last page (vsyscall), why? pread returns 0. */ + /*assert(0);*/ + } else { printf( "%jx %jx %u %u %u %u %s\n", (uintmax_t)vaddr,