blob: f1fc1e8a5d42123c495a574fd11c1a87b2b30b78 [file] [log] [blame]
#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>
#include <setjmp.h>
#include <signal.h>
#include <err.h>
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;
}