#define _GNU_SOURCE #include #include #include #include #include #include #include static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *), int flags) { struct sigaction sa; memset(&sa, 0, sizeof(sa)); sa.sa_sigaction = handler; sa.sa_flags = SA_SIGINFO | flags; sigemptyset(&sa.sa_mask); if (sigaction(sig, &sa, 0)) err(1, "sigaction"); } static jmp_buf fail_jmp; static void handler(int sig, siginfo_t *si, void *ctx_void) { siglongjmp(fail_jmp, 1); } static void dump_page(int n, const void *base) { unsigned char data[4096]; sethandler(SIGBUS, handler, 0); if (sigsetjmp(fail_jmp, 1)) { fprintf(stderr, "Cannot read vvar page %d\n", n); memset(data, 0xff, sizeof(data)); } else { memcpy(data, base, sizeof(data)); } write(1, data, 4096); } int main() { FILE *maps; void *vvar_begin, *vvar_end; int found_vvar = 0; int npages; maps = fopen("/proc/self/maps", "r"); char buf[1024]; while (fgets(buf, 1024, maps)) { if (strstr(buf, "[vvar]")) { found_vvar = 1; break; } } fclose(maps); if (!found_vvar) { fprintf(stderr, "Could not find vvar mapping\n"); return 1; } sscanf(buf, "%p-%p", &vvar_begin, &vvar_end); npages = ((char *)vvar_end - (char *)vvar_begin) / 4096;; fprintf(stderr, "vvar mapping is %d pages (0x%lx - 0x%lx)\n", npages, (unsigned long)vvar_begin, (unsigned long)vvar_end); for (int i = 0; i < npages; i++) dump_page(i, (char *)vvar_begin + i * 4096); mprotect(vvar_begin, vvar_end - vvar_begin, PROT_READ | PROT_WRITE); return 0; }