Skip to content

Instantly share code, notes, and snippets.

@ephemient
Last active June 9, 2016 04:50
Show Gist options
  • Save ephemient/16da99af04ac93d29baa339c15e934d7 to your computer and use it in GitHub Desktop.
Save ephemient/16da99af04ac93d29baa339c15e934d7 to your computer and use it in GitHub Desktop.
#define _GNU_SOURCE
#include <ctype.h>
#include <inttypes.h>
#include <setjmp.h>
#include <signal.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <sysexits.h>
#include <unistd.h>
static sigjmp_buf env;
static void skip(int signo) {
siglongjmp(env, signo);
}
int main(int argc, const char *const *argv) {
const struct sigaction sa_skip = { .sa_handler = skip };
struct sigaction old_sigbus, old_sigsegv;
FILE *fp;
uintptr_t addr0, addr1;
char readable;
fp = fopen("/proc/self/maps", "r");
if (!fp) {
perror("Failed to open /proc/self/maps");
exit(EX_OSFILE);
}
sigaction(SIGBUS, &sa_skip, &old_sigbus);
sigaction(SIGSEGV, &sa_skip, &old_sigsegv);
while (fscanf(fp, "%"SCNxPTR"-%"SCNxPTR" %c%*[^\n]\n", &addr0, &addr1, &readable) > 2) {
for (ptrdiff_t off0 = 0, off1; off0 < addr1 - addr0; off0 += 16) {
printf("%08"PRIxPTR":", addr0 + off0);
for (off1 = off0; off1 < addr1 - addr0 && off1 < off0 + 16; off1++) {
if (~(off0 ^ off1) & 1) {
printf(" ");
}
if (!sigsetjmp(env, 1) && readable == 'r') {
printf("%02x", *(unsigned char *) (addr0 + off1));
} else {
printf("??");
}
}
printf("%*s", (int) (off0 + 16 - off1) * 5 / 2 + 2, "");
for (off1 = off0; off1 < addr1 - addr0 && off1 < off0 + 16; off1++) {
char c = !sigsetjmp(env, 1) && readable == 'r' ? *(char *) (addr0 + off1) : 0;
printf("%c", isprint(c) ? c : '.');
}
printf("\n");
}
}
sigaction(SIGSEGV, &old_sigsegv, NULL);
sigaction(SIGBUS, &old_sigbus, NULL);
fclose(fp);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment