ядро — на вилы КРИС КАСПЕРСКИ АКА МЫЩЪХ Спецвыпуск: Хакер, номер #069, стр. 069-032-7 ЛИСТИНГ определение виртуальных адресов системных вызовов на FreeBSD, NetBSD и OpenBSD /* программа, демонстрирующая технику определения адресов системных вызовов, */ /* работающая на всем зоопарке BSD-подобных систем */ /* Based on Stephanie Wehner's checkcall.c,v 1.1.1.1 */ #include <stdio.h> #include <fcntl.h> #include <kvm.h> #include <nlist.h> #include <limits.h> #include <sys/types.h> #include <sys/sysent.h> #include <sys/syscall.h> int main(int argc, char *argv[]) { char errbuf[_POSIX2_LINE_MAX]; kvm_t *kd; u_int32_t addr; int callnum; struct sysent call; struct nlist nl[] = { { NULL }, { NULL }, { NULL }, }; if(argc != 3) { printf("Usage:\n%s <name of syscall> <syscall number>\n\n", argv[0]); printf("See /usr/src/sys/sys/syscall.h for syscall numbers\n");exit(0); } /* Find the syscall */ nl[0].n_name = "sysent"; nl[1].n_name = argv[1]; callnum = atoi(argv[2]); /* Initialize kernel virtual memory access */ kd = kvm_openfiles(NULL, NULL, NULL, O_RDWR, errbuf); /* Find the addresses */ kvm_nlist(kd, nl); if(!nl[0].n_value) return fprintf(stderr,"ERROR: %s not found\n", nl[0].n_name); else printf("%s is 0x%x at 0x%x\n",nl[0].n_name,nl[0].n_type,nl[0].n_value); /* Calculate the address */ addr = nl[0].n_value + callnum * sizeof(struct sysent); /* Print out location */ if(kvm_read(kd, addr, &call, sizeof(struct sysent)) < 0) return fprintf(stderr, "ERROR: %s\n", kvm_geterr(kd)); else printf("sysent[%d] is at 0x%x and will execute function" " located at 0x%x\n", callnum, addr, call.sy_call); kvm_close(kd); } При трансляции листинга компилятору необходимо указать на библиотеку libkvm (при этом «lib», как всегда, опускается), иначе линкер начнет материться на неразрешимые ссылки. ЛИСТИНГ компиляция программы find_syscall.c #gcc find_syscall.c -o find_syscall -lkvm Откомпилировав программу, попробуем определить адрес системного вызова mkdir. На тестируемой машине (FreeBSD 4.5) результат выглядит так: |