четверг, 17 ноября 2011 г.

Перехват системных вызовов

Система: FreeBSD 8.2-RELEASE

/* Файл test.c */

#include <unistd.h>

int
main(void)
{
  write(1, "test1\n", 6);
  return 0;
}

/* Файл newlib.c */

/* Фактически write это еще одна библиотечная функция, которая 
надстроена над настоящим системным вызовом _write, "старая" 
функция будет по-прежнему доступна через вызов _write
(в linux используется glibc, а вызов имеет имя __write) */
extern int _write(int fd, const char *buff, long len);

int
write(int fd, const char *buff, long len)
{
  _write(fd, "test2\n", 6);
  _write(fd, buff, len);
}

Собираем нашу библиотеку
$ gcc newlib.c -fPIC -c
newlib.c:10:2: warning: no newline at end of file
$ gcc newlib.o -shared -o newlib.so
Собираем исполняемый файл
$ gcc test.c
test.c:9:2: warning: no newline at end of file
Запуск файла без подмены функции
$ ./a.out
test1
Запуск файла с подменой функции
$ export LD_PRELOAD=`pwd`/newlib.so
$ ./a.out
test2
test1
Очищаем переменную
$ unset LD_PRELOAD
$ ./a.out
test1

За подробностями: man ld.so

Комментариев нет:

Отправить комментарий