⬢ DragonFlyBSD Kernel Audit
DF-2361 / kmemv.c
← back to finding ↓ download raw
/* kmemv.c -- read/write kernel memory via /dev/kmem (rig configuration tool).
 * usage: kmemv <hexaddr> [r|w] [hexbytes...]   (addr negative ok)
 */
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <inttypes.h>
#include <string.h>

int main(int argc, char **argv) {
    long long addr = strtoll(argv[1], NULL, 0);
    int fd = open("/dev/kmem", O_RDWR);
    if (fd < 0) { perror("open /dev/kmem"); return 1; }
    if (argc >= 3 && strcmp(argv[2], "w") == 0) {
        unsigned char buf[512];
        int n = 0;
        for (int i = 3; i < argc && n < 512; i++, n++) {
            buf[n] = (unsigned char)strtoul(argv[i], NULL, 16);
        }
        if (n == 0) { fprintf(stderr, "no bytes\n"); return 1; }
        ssize_t w = pwrite(fd, buf, n, (off_t)addr);
        if (w != n) { perror("pwrite"); return 1; }
        printf("wrote %zd bytes at %llx\n", w, addr);
    } else {
        int n = (argc >= 3) ? atoi(argv[2]) : 8;
        unsigned char buf[512];
        ssize_t r = pread(fd, buf, n, (off_t)addr);
        if (r != n) { perror("pread"); return 1; }
        for (int i = 0; i < n; i++) printf("%02x", buf[i]);
        printf("\n");
        if (n == 8) printf("as u64: 0x%016" PRIx64 "\n", *(uint64_t *)buf);
    }
    return 0;
}