add netbsd nl(1)
[rofl0r-hardcore-utils.git] / kmem_sym_dump.c
blob9d06f554b130f612b5bb6fffbf6e542172a3e314
1 #include <stdio.h>
2 #include <fcntl.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <unistd.h>
6 #include <ctype.h>
7 #include <signal.h>
9 static int open_kmem(int rdwr) {
10 int fd = open("/dev/kmem", rdwr ? O_RDWR : O_RDONLY);
11 return fd;
14 static int seek_kmem(int fd, off_t offset) {
15 if(-1==lseek(fd, offset, SEEK_SET)) {
16 perror("lseek");
17 return 0;
19 return 1;
22 static int find_sym(const char *symname, unsigned long *off, unsigned long *end) {
23 FILE *f = fopen("/proc/kallsyms", "r");
24 if(!f) return 0;
25 char buf[256];
26 size_t l = strlen(symname);
27 int succ = 0;
28 while(fgets(buf, sizeof buf, f)) {
29 char* p = buf;
30 if(succ) {
31 if(1!=sscanf(p, "%lx", end)) succ = 0;
32 goto ret;
34 while(*p && *p != ' ') p++;
35 p+=1;
36 if(*p != 'D' && *p != 'T') continue;
37 p+=2;
38 if(!strncmp(p, symname, l)) {
39 p=buf;
40 while(isspace(*p))p++;
41 if(1!=sscanf(p, "%lx", off)) goto ret;
42 succ=1;
45 ret:
46 fclose(f);
47 return succ;
50 int main(int argc, char **argv){
51 unsigned long off, end;
52 if(argc != 2) return 1;
54 FILE *f = fopen("dump.bin", "w");
55 if(!f) {
56 perror("fopen");
57 return 1;
60 if(!find_sym(argv[1], &off, &end)) {
61 printf("couldnt find offsets\n");
62 return 1;
65 int fd = open_kmem(0);
66 if(!seek_kmem(fd, off)) {
67 printf("kmem seek failed\n");
68 return 1;
70 char buf[4096];
71 size_t left, toread, tot = end - off;
72 while(off<end) {
73 left = end - off;
74 toread = left >= sizeof(buf) ? sizeof(buf) : left;
75 ssize_t n;
76 if(toread != (n = read(fd, buf, toread))) {
77 puts("read error");
78 break;
80 fwrite(buf, toread, 1, f);
81 off+=toread;
83 printf("dumped %zu bytes to dump.bin\n", tot);
84 close(fd);
85 fclose(f);
87 return 0;