Каковы возможные способы перехвата системных вызовов в среде Unix? - PullRequest
6 голосов
/ 21 мая 2009

Каковы возможные способы перехвата системных вызовов в среде Unix? Я ищу делать в AIX.

Спасибо

Ответы [ 3 ]

3 голосов
/ 21 мая 2009

Не знаком с AIX, но следующее работает в Linux и Solaris. Вы можете использовать переменную среды LD_PRELOAD, которая сообщает ld.so, чтобы загрузить разделяемую библиотеку перед libc, а затем написать собственную версию системного вызова и при необходимости вызвать оригинал. man ld.so для получения дополнительной информации. Что-то вроде

#include <dlfcn.h>

typedef int (*ioctl_fn)(int, int, void*);

static 
int
my_ioctl(int      fildes,
         int      request,
         void*    argp,
         ioctl_fn fn_ptr)

{
    int result = 0;

    /* call original or do my stuff */
    if (request == INTERESTED)
    {
        result = 0;
    }
    else
    {
        result = (*fn_ptr)(fildes, request, argp);
    }

    return result;
}

/*
 * override ioctl() - on first call get a pointer to the "real" one
 * and then pass it onto our version of the function
 */
int
ioctl(int fildes,
      int request,
      void* argp)
{
    static ioctl_fn S_fn_ptr = 0;

    if (S_fn_ptr == 0)
    {
        S_fn_ptr = (ioctl_fn)dlsym(RTLD_NEXT, "ioctl");
    }

    return my_ioctl(fildes, request, argp, S_fn_ptr);
}

Вырезал это из некоторого кода, который у меня лежал, извиняюсь, если я сделал это неправильно.

1 голос
/ 22 мая 2009

Ну, всегда есть systrace .

0 голосов
/ 29 июня 2017

Я не уверен насчет AIX, но я сделал это на Linux. В Linux таблица системных вызовов содержится в массиве sys_call_table. Нам нужно сначала узнать адрес этой таблицы. Теперь это сложная вещь, и есть несколько способов сделать это.

Мы можем найти его адрес, посмотрев файл sysmap:

punb200m2labs08vm1:/ # cat /boot/System.map-4.4.21-69-default | grep sys_call_table
ffffffff81600180 R sys_call_table

Следовательно, ffffffff81600180 - это адрес sys_call_table на моей машине. В вашем модуле ядра вы можете просто изменить функцию по умолчанию, соответствующую определенному номеру системного вызова (который вы меняете), и назначить ее для своей собственной функции.

например. Предположим, вы хотите перехватить «открытый» системный вызов с номером __NR_open в Linux. После того, как вы получите адрес sys_call_table сверху, просто назначьте свою функцию на index __NR_open из sys_call_table:

sys_call_table[__NR_open] = your_function;

где your_function реализован вами для перехвата «открытого» системного вызова. С этого момента каждый открытый системный вызов будет проходить через эту функцию.

Детали в AIX могут отличаться, но общая идея, похоже, будет аналогичной. Вам просто нужно узнать конкретную процедуру AIX для достижения этой цели.

...