Издательский дом ООО "Гейм Лэнд"СПЕЦВЫПУСК ЖУРНАЛА ХАКЕР #69, АВГУСТ 2006 г.

ядро — на вилы

КРИС КАСПЕРСКИ АКА МЫЩЪХ

Спецвыпуск: Хакер, номер #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) результат выглядит так:

Назад на стр. 069-032-6  Содержание  Вперед на стр. 069-032-8