source: trunk/src/kern_head.c@ 286

Last change on this file since 286 was 286, checked in by katerina, 15 years ago

Fix for ticket #211 (samhain_kmem compile problems) and ticket #210 (line length, filename quoting in config file).

File size: 23.9 KB
Line 
1/*
2 * need to #define SH_USE_KERN
3 *
4 */
5#define SH_SYSCALL_CODE
6
7#include "config.h"
8
9#if defined(HOST_IS_I86LINUX) || defined(HOST_IS_64LINUX)
10#define SH_IDT_TABLE
11#endif
12
13#include <stdio.h>
14#include <stdlib.h>
15
16#if defined(SH_USE_KERN)
17
18#undef _
19#define _(string) string
20#undef N_
21#define N_(string) string
22
23void usage(int flag)
24{
25 printf("\n");
26 printf("Usage: kern_head [-v | --verbose]\n");
27 printf(" kern_head [-h | --help]\n");
28 printf("\n");
29 /*
30 * printf(" You need superuser privileges to use this program,\n");
31 * printf(" because only the superuser can read from /dev/kmem.\n");
32 * printf("\n");
33 */
34 exit(flag);
35}
36
37#if defined(HOST_IS_LINUX)
38
39
40#include <string.h>
41#include <sys/types.h>
42#include <sys/stat.h>
43#include <fcntl.h>
44#include <unistd.h>
45#include <errno.h>
46#include <limits.h>
47#include <sys/utsname.h>
48#include <sys/mman.h>
49
50/* number of system calls */
51#define SH_MAXCALLS 512
52
53#include "kern_head.h"
54
55static int verbose = 0;
56
57typedef struct _smap_entry {
58#ifdef SH_SYSCALL_CODE
59 unsigned int code[2]; /* 8 bytes */
60#endif
61 unsigned long addr;
62 char name[64];
63} smap_entry;
64
65union {
66 unsigned long addr_sys_call_table;
67 unsigned char str_sys_call_table[sizeof(unsigned long)];
68} sh_sys_call;
69
70#define SYS_CODE_SIZE 1024
71
72static unsigned long addr_system_call;
73static unsigned char system_call_code[SYS_CODE_SIZE];
74
75#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
76
77static int kmem_read (int fd, unsigned long addr, unsigned char * buf, int len)
78{
79 if (lseek(fd, addr, SEEK_SET) == (off_t) (-1))
80 {
81 if (verbose)
82 perror("kmem_read: lseek");
83 return -1;
84 }
85 if (read(fd, buf, len) < 0)
86 {
87 if (verbose)
88 perror("kmem_read: read");
89 return -1;
90 }
91 return 0;
92}
93
94static int kmem_mmap (int fd, unsigned long addr, unsigned char * buf, int len)
95{
96 size_t moff, roff;
97 size_t sz;
98 char * kmap;
99
100 sz = getpagesize(); /* unistd.h */
101
102 moff = ((size_t)(addr/sz)) * sz; /* lower page boundary */
103 roff = addr - moff; /* off relative to lower address of mmapped area */
104 kmap = mmap(0, len+sz, PROT_READ, MAP_PRIVATE, fd, moff);/* sys/mman.h */
105
106 if (kmap == MAP_FAILED)
107 {
108 /* then, try read()
109 */
110 if (verbose)
111 fprintf(stderr, "kmem_mmap: mmap() failed, now trying read()\n");
112
113 if (0 == sh_kern_kmem_read (fd, addr, buf, len))
114 return 0;
115
116 perror("kmem_mmap: mmap");
117 return -1;
118 }
119
120 memcpy (buf, &kmap[roff], len);
121
122 if (munmap(kmap, len+sz) != 0)
123 {
124 perror("kmem_mmap: munmap");
125 return -1;
126 }
127
128 return 0;
129}
130
131int read_kcode (unsigned long addr, unsigned char * buf, int len)
132{
133 int fd;
134
135 if (addr == 0UL)
136 {
137 perror("read_kcode: invalid input");
138 return -1;
139 }
140
141 fd = open ("/dev/kmem", O_RDONLY);
142
143 if (fd < 0)
144 {
145 if (0 != access("/proc/kmem", R_OK))
146 {
147 perror("read_kcode: access /proc/kmem");
148
149 fprintf(stderr, "\n");
150
151 fprintf(stderr, "NOTE: kern_head: apparently you have no /dev/kmem, and the samhain_kmem module is not loaded\n");
152 fprintf(stderr, " If you get this message, then proceed as follows:\n");
153 fprintf(stderr, " $ make samhain_kmem.ko\n");
154 fprintf(stderr, " $ sudo insmod samhain_kmem.ko; sudo ./kern_head > sh_ks.h; sudo rmmod samhain_kmem\n");
155 fprintf(stderr, " $ make\n\n");
156 exit (EXIT_FAILURE);
157 }
158 fd = open ("/proc/kmem", O_RDONLY);
159 }
160
161 if (fd < 0)
162 {
163 perror("read_kcode: open /dev/kmem and /proc/kmem");
164 return -1;
165 }
166
167 if (kmem_mmap(fd, addr, buf, len) < 0)
168 {
169 close (fd);
170 return -1;
171 }
172
173 close (fd);
174
175 return 0;
176}
177
178int get_dispatch (int * qq)
179{
180 int i;
181
182 if (addr_system_call == 0L || sh_sys_call.addr_sys_call_table == 0L)
183 {
184 fprintf(stderr, "get_dispatch: invalid data\n");
185 return -1;
186 }
187
188 if (0 != read_kcode (addr_system_call, system_call_code, SYS_CODE_SIZE))
189 {
190 fprintf(stderr, "get_dispatch: could not read system_call code\n");
191 return -1;
192 }
193
194 for (i = 0; i < (SYS_CODE_SIZE - 4); ++i)
195 {
196 if (system_call_code[i] == sh_sys_call.str_sys_call_table[0] &&
197 system_call_code[i+1] == sh_sys_call.str_sys_call_table[1] &&
198 system_call_code[i+2] == sh_sys_call.str_sys_call_table[2] &&
199 system_call_code[i+3] == sh_sys_call.str_sys_call_table[3])
200 {
201 /*
202 fprintf(stderr, "INFO: get_dispatch: found sys_call_table in "\
203 "system_call code at %d\n", i);
204 */
205 *qq = i;
206 return 0;
207 }
208 }
209 fprintf(stderr,
210 "get_dispatch: did not find sys_call_table in system_call code\n");
211 fprintf(stderr,
212 "** This indicates that either your System.map does not match\n");
213 fprintf(stderr,
214 "** the currently running kernel, or that your System.map does\n");
215 fprintf(stderr,
216 "** not provide the required information, and thus use of\n");
217 fprintf(stderr,
218 "** the --with-kcheck option is not possible\n");
219 return -1;
220}
221
222unsigned long get_symbol_from_systemmap (char * systemmap,
223 char * symbol, char flag)
224{
225 FILE * fp;
226 char buf[512], addr[32], * p;
227 unsigned long retval = 0;
228#if defined(__x86_64__) || defined(__amd64__)
229 int off = 8;
230#else
231 int off = 0;
232#endif
233
234 fp = fopen (systemmap, "r");
235
236 if (!fp)
237 {
238 fprintf(stderr, "error opening <%s>\n", systemmap);
239 perror("get_symbol_from_systemmap: fopen");
240 return -1;
241 }
242 while (fgets(buf, 512, fp) != NULL)
243 {
244 if (buf[9+off] != flag)
245 continue;
246
247 p = strchr(buf, '\n');
248 if (p != NULL)
249 *p = '\0';
250
251 if (0 != strcmp(&buf[11+off], symbol))
252 continue;
253
254 addr[0] = '0'; addr[1] = 'x'; addr[2] = '\0';
255 strncat(&addr[2], buf, 8+off);
256
257 retval = strtoul(addr, NULL, 0);
258 if (retval == ULONG_MAX)
259 {
260 perror("get_symbol_from_systemmap");
261 return -1;
262 }
263 }
264 fclose(fp);
265 return retval;
266}
267
268
269/* returns the number N of entries in syscall table
270 * (0 .. N-1) with valid syscalls
271 */
272int fill_smap(smap_entry * sh_smap, int num)
273{
274 FILE * fp;
275 char buf[512], addr[32], name[128];
276 int i, j, count = 0, maxcall = 0;
277#if defined(__x86_64__) || defined(__amd64__)
278 int off = 8;
279#else
280 int off = 0;
281#endif
282
283 fp = fopen (SYSTEMMAP, "r");
284
285 if (!fp)
286 {
287 perror("fill_smap: fopen");
288 fprintf(stderr, "fill_smap: error opening <%s>\n", SYSTEMMAP);
289 return -1;
290 }
291
292 /* initialize
293 */
294 sh_sys_call.addr_sys_call_table = 0L;
295
296 while (fgets(buf, 512, fp) != NULL)
297 {
298
299 if ( ( (buf[9+off] == 'D') || (buf[9+off] == 'd') ||
300 (buf[9+off] == 'R') || (buf[9+off] == 'r')) &&
301 0 == strncmp("sys_call_table", &buf[11+off], 14))
302 {
303 printf("/* found sys_call_table */\n");
304 /* --- copy symbol address ---
305 */
306 addr[0] = '0'; addr[1] = 'x'; addr[2] = '\0';
307 strncat(&addr[2], buf, 8+off);
308 addr[10+off] = '\0';
309
310 sh_sys_call.addr_sys_call_table = strtoul(addr, NULL, 0);
311 if (sh_sys_call.addr_sys_call_table == ULONG_MAX)
312 {
313 perror("fill_smap");
314 return -1;
315 }
316 else
317 {
318 printf("#define SH_SYS_CALL_TABLE %s\n", addr);
319 }
320 }
321
322 if (buf[9+off] != 'T')
323 continue;
324
325 if (0 == strncmp("system_call", &buf[11+off], 11))
326 {
327 printf("/* found system_call */\n");
328 /* --- copy symbol address ---
329 */
330 addr[0] = '0'; addr[1] = 'x'; addr[2] = '\0';
331 strncat(&addr[2], buf, 8+off);
332 addr[10+off] = '\0';
333 addr_system_call = strtoul(addr, NULL, 0);
334 if (addr_system_call == ULONG_MAX)
335 {
336 perror("fill_smap");
337 return -1;
338 }
339 }
340
341
342 if ( (buf[11+off]!='s' || buf[12+off]!='y' ||
343 buf[13+off]!='s' || buf[14+off]!='_') &&
344 (buf[11+off]!='o' || buf[12+off]!='l' ||
345 buf[13+off]!='d' || buf[14+off]!='_'))
346 continue;
347
348 for (i = 0; i < num; ++i)
349 {
350 for (j = 0; j < 127; ++j)
351 {
352 if (buf[11+off+j] == '\n' || buf[11+off+j] == '\0')
353 {
354 name[j] = '\0';
355 break;
356 }
357 name[j] = buf[11+off+j];
358 }
359
360
361 if (0 == strcmp(name, sh_smap[i].name))
362 {
363
364 /* --- copy symbol address ---
365 */
366 addr[0] = '0'; addr[1] = 'x'; addr[2] = '\0';
367 strncat(&addr[2], buf, 8+off);
368 addr[10+off] = '\0';
369 sh_smap[i].addr = strtoul(addr, NULL, 0);
370 if (sh_smap[i].addr == ULONG_MAX)
371 {
372 perror("fill_smap");
373 return -1;
374 }
375 ++count;
376 if (i > maxcall) maxcall = i;
377 /* printf("maxcall = %d\n", maxcall); */
378 /* break; */
379 }
380 }
381 }
382 fclose(fp);
383
384 if ((count > 0) && (maxcall > 0))
385 return maxcall+1;
386 else
387 return count;
388}
389
390
391int main(int argc, char * argv[])
392{
393 int i, count, maxcall, qq;
394 smap_entry sh_smap[SH_MAXCALLS];
395 struct utsname utbuf;
396 char *p = NULL;
397
398 unsigned long proc_root;
399 unsigned long proc_root_iops;
400 unsigned long proc_root_lookup;
401
402 unsigned long addr_ni_syscall = 0;
403
404 int major, minor, micro, is64 = 0;
405
406 if (argc > 1)
407 {
408 if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0)
409 usage(EXIT_SUCCESS);
410 else if (strcmp(argv[1], "-v") == 0 ||
411 strcmp(argv[1], "--verbose") == 0)
412 verbose = 1;
413 }
414
415 if (0 != uname(&utbuf))
416 {
417 perror("kern_head: uname");
418 exit (EXIT_FAILURE);
419 }
420
421 if (strncmp(utbuf.release, SH_KERNEL_VERSION, 3) != 0)
422 {
423 fprintf(stderr, "kern_head: current kernel version %s does not match\n",
424 utbuf.release);
425 fprintf(stderr, "kern_head: %s from config.h\n", SH_KERNEL_VERSION);
426 fprintf(stderr, "kern_head: continuing with %s\n", SH_KERNEL_VERSION);
427
428 p = SH_KERNEL_VERSION;
429 } else {
430 p = utbuf.release;
431 }
432
433 if (3 != sscanf(p, "%d.%d.%d", &major, &minor, &micro))
434 {
435 perror("kern_head: sscanf");
436 exit (EXIT_FAILURE);
437 }
438
439 if (minor != 4 && minor != 6)
440 {
441 fprintf(stderr, "kern_head: kernel %s not supported\n", p);
442 exit (EXIT_FAILURE);
443 }
444
445
446 if (utbuf.machine[0] != 'i' || utbuf.machine[2] != '8' ||
447 utbuf.machine[3] != '6')
448 {
449 if (0 != strcmp(utbuf.machine, "x86_64"))
450 {
451 fprintf(stderr, "kern_head: machine %s not supported\n", utbuf.machine);
452 exit (EXIT_FAILURE);
453 }
454 else
455 {
456 is64 = 1;
457 }
458 }
459
460 if (0 != getuid())
461 {
462 fprintf(stderr, "\n");
463
464 fprintf(stderr, "NOTE: kern_head: must run as 'root' (need to read from /dev/kmem)\n");
465 fprintf(stderr, " If you get this message, then proceed as follows:\n");
466 fprintf(stderr, " $ sudo ./kern_head > sh_ks.h\n");
467 fprintf(stderr, " $ make\n\n");
468 exit (EXIT_FAILURE);
469 }
470
471 printf("#ifndef SH_KERN_CALLS_H\n");
472 printf("#define SH_KERN_CALLS_H\n\n");
473
474 printf("\n/* Kernel %s, machine %s, %d bit -- use table callz_2p4 */\n\n",
475 p, utbuf.machine,
476 (is64 == 0) ? 32 : 64,
477 (is64 == 0) ? "syscalls_32" : "syscalls_64");
478
479 /* initiate the system call table
480 */
481 if (is64 == 0)
482 {
483 for (i = 0; i < SH_MAXCALLS; ++i)
484 {
485 if (syscalls_32[i] == NULL)
486 break;
487 strcpy(sh_smap[i].name, syscalls_32[i]);
488 sh_smap[i].addr = 0UL;
489 }
490 if (minor == 6) /* fix syscall map for 2.6 */
491 {
492 strcpy(sh_smap[0].name, "sys_restart_syscall");
493 strcpy(sh_smap[180].name, "sys_pread64");
494 strcpy(sh_smap[181].name, "sys_pwrite64");
495 }
496 }
497 else /* x86_64 */
498 {
499 for (i = 0; i < SH_MAXCALLS; ++i)
500 {
501 if (syscalls_64[i] == NULL)
502 break;
503 strcpy(sh_smap[i].name, syscalls_64[i]);
504 sh_smap[i].addr = 0UL;
505 }
506 }
507
508 count = i;
509
510 /* get the actual number of the highest syscall and use no more.
511 * get sys_call_table and system_call
512 */
513 maxcall = fill_smap(sh_smap, count);
514 if ( maxcall < 0)
515 {
516 printf("#endif\n");
517 fprintf(stderr, "kern_head: fill_smap failed\n");
518 exit (EXIT_FAILURE);
519 }
520
521 if (addr_system_call == 0L)
522 {
523 printf("#endif\n");
524 fprintf(stderr,
525 "kern_head: address of system_call not found in System.map\n");
526 fprintf(stderr,
527 "** This indicates that your System.map does not provide\n");
528 fprintf(stderr,
529 "** the required information, and thus use of the\n");
530 fprintf(stderr,
531 "** --with-kcheck option is not possible\n");
532 exit (EXIT_FAILURE);
533 }
534
535 for (i = 0; i < maxcall; ++i)
536 {
537 if (0 == strcmp(sh_smap[i].name, "sys_ni_syscall"))
538 {
539 addr_ni_syscall = sh_smap[i].addr;
540 break;
541 }
542 }
543
544 if (minor < 6)
545 {
546 maxcall = (maxcall > 256) ? 256 : maxcall;
547 }
548
549 for (i = 0; i < maxcall; ++i)
550 {
551 if (sh_smap[i].addr == 0UL)
552 {
553 if (verbose > 0)
554 fprintf(stderr, "** unknown syscall **: [%s]\n", sh_smap[i].name);
555 strcpy(sh_smap[i].name, "sys_ni_syscall");
556 sh_smap[i].addr = addr_ni_syscall;
557 }
558 }
559
560
561 /* get the location of the syscall table address within system_call
562 */
563 if ( get_dispatch (&qq) < 0)
564 {
565 printf("#endif\n");
566 fprintf(stderr, "kern_head: get_dispatch failed\n");
567 exit (EXIT_FAILURE);
568 }
569
570 if (qq <= 252)
571 printf("#define SYS_CALL_LOC %d\n", qq);
572 else
573 {
574 printf("#endif\n");
575 fprintf(stderr, "kern_head: SYS_CALL_LOC (%d) too large\n", qq);
576 exit(EXIT_FAILURE);
577 }
578 printf("#define SH_SYS_CALL_ADDR %#lx\n\n", addr_system_call);
579
580 printf("static unsigned char system_call_code[256] = { 0 };\n");
581
582 printf("#define SH_MAXCALLS %d\n\n", maxcall);
583
584#ifdef SH_IDT_TABLE
585 printf("static unsigned char idt_table[2048] = { 0 };\n");
586#endif
587
588 printf("typedef struct _sh_syscall_t {\n");
589#ifdef SH_SYSCALL_CODE
590 printf(" unsigned int code[2]; /* 8 bytes */\n");
591#endif
592 printf(" unsigned long addr;\n");
593 printf(" char * name;\n");
594 printf("} sh_syscall_t;\n\n");
595
596 printf("static sh_syscall_t sh_syscalls[] = {\n");
597
598 for (i = 0; i < maxcall; ++i)
599 {
600#ifdef SH_SYSCALL_CODE
601 printf(" /* %03d */ { { 0, 0 }, 0, N_(%c%s%c) },\n",
602 i, '"', sh_smap[i].name, '"');
603#else
604 printf(" /* %03d */ { 0, N_(%c%s%c) },\n",
605 i, '"', sh_smap[i].name, '"');
606#endif
607 }
608#ifdef SH_SYSCALL_CODE
609 printf(" /* eof */ { { 0x00000000, 0x00000000 }, 0x00000000, NULL }\n");
610#else
611 printf(" /* eof */ { 0x00000000, NULL }\n");
612#endif
613 printf("};\n\n");
614
615
616 /* get proc addresses
617 */
618 proc_root = get_symbol_from_systemmap (SYSTEMMAP,
619 "proc_root", 'D');
620 if (proc_root == 0)
621 {
622 proc_root = get_symbol_from_systemmap (SYSTEMMAP,
623 "proc_root", 'd');
624 }
625 if (proc_root == 0)
626 {
627 proc_root = get_symbol_from_systemmap (SYSTEMMAP,
628 "proc_root", 'R');
629 }
630 if (proc_root != 0) {
631 printf("#define PROC_ROOT_LOC %#lx\n\n", proc_root);
632 }
633
634 proc_root_lookup = get_symbol_from_systemmap (SYSTEMMAP,
635 "proc_root_lookup", 't');
636 if (proc_root_lookup == 0)
637 {
638 proc_root_lookup = get_symbol_from_systemmap (SYSTEMMAP,
639 "proc_root_lookup", 'T');
640 }
641 if (proc_root_lookup != 0) {
642 printf("#define PROC_ROOT_LOOKUP_LOC %#lx\n\n", proc_root_lookup);
643 }
644
645 proc_root_iops = get_symbol_from_systemmap (SYSTEMMAP,
646 "proc_root_inode_operations",
647 'd');
648 if (proc_root_iops == 0)
649 {
650 proc_root_iops = get_symbol_from_systemmap (SYSTEMMAP,
651 "proc_root_inode_operations",
652 'D');
653 }
654 if (proc_root_iops == 0)
655 {
656 proc_root_iops = get_symbol_from_systemmap (SYSTEMMAP,
657 "proc_root_inode_operations",
658 'R');
659 }
660 if (proc_root_iops != 0) {
661 printf("#define PROC_ROOT_IOPS_LOC %#lx\n\n", proc_root_iops);
662 }
663
664 if (KERNEL_VERSION(major,minor,micro) >= KERNEL_VERSION(2,6,17))
665 {
666 printf("#define TWO_SIX_SEVENTEEN_PLUS 1\n\n");
667 }
668
669 printf("#endif\n");
670
671 exit (EXIT_SUCCESS);
672}
673
674/* if defined(HOST_IS_LINUX) */
675#endif
676
677/************************************************************
678 *
679 *
680 * FreeBSD Implementation
681 *
682 ************************************************************/
683
684#if defined(HOST_IS_FREEBSD) || defined(__OpenBSD__)
685
686#include <stdlib.h>
687#include <unistd.h>
688#include <string.h>
689#include <err.h>
690#include <kvm.h>
691#include <fcntl.h>
692#include <nlist.h>
693#include <limits.h>
694#include <sys/types.h>
695#include <sys/utsname.h>
696
697#ifdef __FreeBSD__
698#include <sys/sysent.h>
699#endif
700
701#include <sys/syscall.h>
702
703#ifndef SYS_MAXSYSCALL
704#define SYS_MAXSYSCALL 512
705#endif
706
707/* number of system calls */
708#define SH_MAXCALLS 512
709#include "kern_head.h"
710static int verbose = 0;
711
712#ifdef __OpenBSD__
713struct proc;
714struct sysent {
715 short sy_narg;
716 short sy_argsize;
717 int (*sy_call)(struct proc *, void *, register_t *);
718};
719#endif
720
721typedef struct _smap_entry {
722 unsigned int code[2]; /* 8 bytes */
723 unsigned long addr;
724 char name[64];
725} smap_entry;
726
727union {
728 unsigned long addr_sys_call_table;
729 unsigned char str_sys_call_table[sizeof(unsigned long)];
730} sh_sys_call;
731
732struct nlist sys_list[SYS_MAXSYSCALL+1];
733
734struct nlist list[2];
735
736
737int main(int argc, char * argv[])
738{
739 int i, count, which;
740 smap_entry sh_smap[SYS_MAXSYSCALL];
741 struct utsname utbuf;
742 char errbuf[_POSIX2_LINE_MAX];
743
744 struct sysent sy;
745 unsigned long offset = 0L;
746 kvm_t *kd;
747
748 list[0].n_name = "_sysent";
749 list[1].n_name = NULL;
750
751 if (argc > 1)
752 {
753 if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0)
754 usage(EXIT_SUCCESS);
755 else if (strcmp(argv[1], "-v") == 0 ||
756 strcmp(argv[1], "--verbose") == 0)
757 verbose = 1;
758 }
759
760 if (0 != uname(&utbuf))
761 {
762 perror("kern_head: uname");
763 exit (EXIT_FAILURE);
764 }
765
766#ifdef __OpenBSD__
767 if (utbuf.release[0] == '3')
768 which = 38;
769 else if (utbuf.release[0] == '4')
770 which = 40;
771#else
772 if (utbuf.release[0] == '4')
773 which = 4;
774 else if (utbuf.release[0] == '5')
775 which = 5;
776 else if (utbuf.release[0] == '6')
777 which = 5;
778#endif
779 else
780 {
781 fprintf(stderr, "kern_head: kernel %s not supported\n", utbuf.release);
782 exit (EXIT_FAILURE);
783 }
784
785 if (utbuf.machine[0] != 'i' || utbuf.machine[2] != '8' ||
786 utbuf.machine[3] != '6')
787 {
788 fprintf(stderr, "kern_head: machine %s not supported\n", utbuf.machine);
789 exit (EXIT_FAILURE);
790 }
791
792 if (0 != getuid())
793 {
794 fprintf(stderr, "\n");
795 fprintf(stderr, "NOTE: kern_head: must run as 'root' ");
796 fprintf(stderr, "(need to read from kernel)\n");
797 fprintf(stderr, " If you get this message, then proceed ");
798 fprintf(stderr, "as follows:\n");
799 fprintf(stderr, " $ su\n");
800 fprintf(stderr, " $ ./kern_head > sh_ks.h\n");
801 fprintf(stderr, " $ exit\n");
802 fprintf(stderr, " $ make\n\n");
803 exit (EXIT_FAILURE);
804 }
805
806 kd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, errbuf);
807 if (!kd)
808 {
809 fprintf(stderr, "check_sysent: kvm_openfiles: %s\n", errbuf);
810 exit(EXIT_FAILURE);
811 }
812
813 i = kvm_nlist(kd, list);
814 if (i == -1)
815 {
816 fprintf(stderr, "check_sysent: kvm_nlist: %s\n", kvm_geterr(kd));
817 exit(EXIT_FAILURE);
818 }
819 else if (i == 1)
820 {
821 fprintf(stderr, "check_sysent: kvm_nlist: _sysent not found\n");
822 exit(EXIT_FAILURE);
823 }
824 else if (list[0].n_value == 0)
825 {
826 fprintf(stderr, "check_sysent: kvm_nlist: zero address for _sysent\n");
827 exit(EXIT_FAILURE);
828 }
829
830 if (which == 4)
831 printf("\n/* Kernel %s, machine %s -- use table %s */\n\n",
832 utbuf.release, utbuf.machine, "callz_fbsd");
833 else if (which == 5 || which == 6)
834 printf("\n/* Kernel %s, machine %s -- use table %s */\n\n",
835 utbuf.release, utbuf.machine, "callz_fbsd5");
836 else if (which == 38 || which == 40)
837 printf("\n/* Kernel %s, machine %s -- use table %s */\n\n",
838 utbuf.release, utbuf.machine, "callz_obsd");
839
840
841 i = 0;
842 if (which == 4) {
843 while ((callz_fbsd[i] != NULL) && (i < SYS_MAXSYSCALL))
844 {
845 sys_list[i].n_name = callz_fbsd[i];
846 /* fprintf(stderr, "sys_list[%d] = %s\n", i, sys_list[i].n_name); */
847 ++i;
848 }
849 if ((utbuf.release[1] == '.') && (utbuf.release[2] == '1') &&
850 (utbuf.release[3] == '0'))
851 {
852 sys_list[336].n_name = callz_fbsd[151]; /* sendfile -> nosys */
853 }
854 } else if (which == 5 || which == 6) {
855 while ((callz_fbsd5[i] != NULL) && (i < SYS_MAXSYSCALL))
856 {
857 sys_list[i].n_name = callz_fbsd5[i];
858 /* fprintf(stderr, "sys_list[%d] = %s\n", i, sys_list[i].n_name); */
859 ++i;
860 }
861 }
862 else if (which == 38 || which == 40) {
863 while ((callz_obsd[i] != NULL) && (i < SYS_MAXSYSCALL))
864 {
865 sys_list[i].n_name = callz_obsd[i];
866 /* fprintf(stderr, "sys_list[%d] = %s\n", i, sys_list[i].n_name); */
867 ++i;
868 }
869 }
870
871 count = i;
872 sys_list[i].n_name = NULL;
873
874 i = kvm_nlist(kd, sys_list);
875 if (i == -1)
876 {
877 fprintf(stderr, "check_sysent: kvm_nlist: %s\n", kvm_geterr(kd));
878 /* exit(EXIT_FAILURE); */
879 }
880 else if (i != 0 && verbose != 0)
881 {
882 fprintf(stderr, "check_sysent: kvm_nlist: %d out of %d invalid.\n",
883 i, count);
884 fprintf(stderr, " Probably the table in kern_head.h\n");
885 fprintf(stderr, " is not for your kernel version.\n");
886 fprintf(stderr, " (No reason to worry, kcheck will "\
887 "work anyway)\n\n");
888 }
889
890 for (i = 0; i < count /* SYS_MAXSYSCALL */; i++)
891 {
892 if (NULL == sys_list[i].n_name)
893 break;
894 if (!sys_list[i].n_value && 0 != strcmp(sys_list[i].n_name, "_nosys")
895 && verbose != 0)
896 {
897 fprintf(stderr,"check_sysent: not found: slot %03d [%s]\n",
898 i, sys_list[i].n_name);
899 /* exit(EXIT_FAILURE); */
900 }
901 offset = list[0].n_value + (i*sizeof(struct sysent));
902 if (kvm_read(kd, offset, &sy, sizeof(struct sysent)) < 0)
903 {
904 fprintf(stderr,"check_sysent: kvm_read: %s\n", kvm_geterr(kd));
905 exit(EXIT_FAILURE);
906 }
907
908 if (verbose > 0)
909 fprintf(stderr, "(kvm_nlist) %#lx %#lx (sysent[%03d]) %03d [%s]\n",
910 (unsigned long) sys_list[i].n_value,
911 (unsigned long) sy.sy_call,
912 i, i, sys_list[i].n_name);
913
914 if((unsigned long)sy.sy_call != sys_list[i].n_value &&
915 sys_list[i].n_value != 0 &&
916 0 != strcmp(sys_list[i].n_name, "_nosys") &&
917 (unsigned long)sy.sy_call != sys_list[151].n_value)
918 {
919 fprintf(stderr,
920 "WARNING: (kvm_nlist) %#lx != %#lx (sysent[%03d]) %03d [%s]\n",
921 (unsigned long) sys_list[i].n_value,
922 (unsigned long) sy.sy_call,
923 i, i, sys_list[i].n_name);
924 }
925 sh_smap[i].addr = (unsigned long) sy.sy_call;
926 strncpy(sh_smap[i].name, sys_list[i].n_name, 64);
927 if(kvm_read(kd, (unsigned int) sy.sy_call, &(sh_smap[i].code[0]),
928 2 * sizeof(unsigned int)) < 0)
929 {
930 fprintf(stderr,"check_sysent: kvm_read: %s\n", kvm_geterr(kd));
931 exit(EXIT_FAILURE);
932 }
933 }
934
935 if(kvm_close(kd) < 0)
936 {
937 fprintf(stderr,"check_sysent: kvm_nlist: %s\n", kvm_geterr(kd));
938 exit(EXIT_FAILURE);
939 }
940
941 printf("#ifndef SH_KERN_CALLS_H\n");
942 printf("#define SH_KERN_CALLS_H\n\n");
943
944 printf("#define SH_MAXCALLS %d\n\n", count);
945
946 printf("typedef struct _sh_syscall_t {\n");
947 printf(" unsigned int code[2]; /* 8 bytes */\n");
948 printf(" unsigned long addr;\n");
949 printf(" char * name;\n");
950 printf("} sh_syscall_t;\n\n");
951
952 printf("static sh_syscall_t sh_syscalls[] = {\n");
953 for (i = 0; i < count; ++i) {
954 printf(" /* %03d */ {{ 0x%-8.8x, 0x%-8.8x }, 0x%-8.8lx, N_(%c%s%c) },\n",
955 i, sh_smap[i].code[0], sh_smap[i].code[1],
956 sh_smap[i].addr, '"', sh_smap[i].name, '"');
957 }
958 printf(" /* eof */ { { 0x00000000, 0x00000000 }, 0x00000000, NULL }\n");
959 printf("};\n\n");
960 printf("#endif\n");
961 return 0;
962}
963/* if defined(HOST_IS_FREEBSD) */
964#endif
965
966/* #if defined(SH_USE_KERN) */
967#else
968
969#include <stdio.h>
970#include <stdlib.h>
971
972int main()
973{
974 printf("#ifndef SH_KERN_CALLS_H\n");
975 printf("#define SH_KERN_CALLS_H\n\n");
976
977 printf("/* Dummy header. */\n\n");
978
979 printf("typedef struct _sh_syscall_t {\n");
980 printf(" unsigned long addr;\n");
981 printf(" char * name;\n");
982 printf("} sh_syscall_t;\n\n");
983
984 printf("#endif\n");
985
986 return (EXIT_SUCCESS);
987}
988
989/* #ifdef SH_USE_KERN */
990#endif
Note: See TracBrowser for help on using the repository browser.