#include #include #include #include #include #include #include #include #include #include "procfs.h" int procfs_open(pid_t pid) { char path[2048]; sprintf(path, "/proc/%d/mem", pid); return open(path, O_RDWR); } ssize_t procfs_maps(pid_t pid, struct procfs_map **maps) { char path[2048]; sprintf(path, "/proc/%d/maps", pid); FILE *f = fopen(path, "r"); if (!f) return -1; int n = 0; int capacity = 2; *maps = calloc(capacity, sizeof(**maps)); if (!*maps) return -1; while (1) { void *base, *max; char prot_str[4]; int matches = fscanf(f, "%p-%p %4c", &base, &max, prot_str); if (matches == EOF) goto eof; if (matches < 3) goto err; int prot = 0; for (int i = 0; i < 4; i++) { switch (prot_str[i]) { case 'r': prot |= PROT_READ; break; case 'w': prot |= PROT_WRITE; break; case 'x': prot |= PROT_EXEC; break; default: break; } } if (prot == 0) prot = PROT_NONE; int c; while ((c = getc(f)) != '\n') if (c == EOF) goto eof; n++; if (n > capacity) { capacity <<= 1; struct procfs_map *r = reallocarray(*maps, capacity, sizeof(*r)); if (!r) goto err; *maps = r; } (*maps)[n - 1] = (struct procfs_map) { (uintptr_t) base, (uintptr_t) max, prot }; } eof: if (ferror(f)) goto err; if (n == 0) free(*maps); return n; err: free(*maps); return -1; } int read_mem(int fd, uintptr_t addr, uint8_t *data, size_t size) { if (lseek(fd, addr, SEEK_SET) == -1) return -1; size_t n = 0; while (n < size) { ssize_t result = read(fd, data + n, size - n); if (result == -1) return -1; n += result; } return 0; } int write_mem(int fd, uintptr_t addr, uint8_t *data, size_t size) { if (lseek(fd, addr, SEEK_SET) == -1) return -1; size_t n = 0; while (n < size) { ssize_t result = write(fd, data + n, size - n); if (result == -1) return -1; n += result; } return 0; } int read_page(int fd, uintptr_t index, uint8_t *data) { return read_mem(fd, index * PAGE_SIZE, data, PAGE_SIZE); }