Подтвердить что ты не робот

Как переопределить (или обернуть) функцию syscall в Linux?

Предположим, я хочу полностью взять на себя системный вызов open(), возможно, чтобы обернуть фактический системный вызов и выполнить некоторые протоколирования. Один из способов сделать это - использовать LD_PRELOAD для загрузки (пользовательской) общей библиотеки объектов, которая принимает точку входа open().

Пользовательская процедура open() затем получает указатель на функцию glibc open() на dlsym() и вызывает ее.

Решение, предложенное выше, является динамическим решением. Предположим, я хочу связать свою собственную упаковку open() статически. Как мне это сделать? Я предполагаю, что механизм тот же, но я также предполагаю, что будет конфликт символов между пользовательскими open() и libc open().

Пожалуйста, поделитесь любыми другими методами для достижения той же цели.

4b9b3361

Ответ 1

Вы можете использовать функцию обертки, предоставляемую ld. От man ld:

--wrap symbol Используйте функцию обертки для символа. Любые undefined ссылки на symbol будет разрешено до __wrap_symbol.

Любые undefined ссылки на __real_symbol будут разрешены на symbol.

Поэтому вам просто нужно использовать префикс __wrap_ для вашей функции-обертки и __real_, когда вы хотите вызвать реальную функцию. Простой пример:

malloc_wrapper.c:

#include <stdio.h>
void *__real_malloc (size_t);

/* This function wraps the real malloc */
void * __wrap_malloc (size_t size)
{
    void *lptr = __real_malloc(size);
    printf("Malloc: %lu bytes @%p\n", size, lptr);
    return lptr;
}

Тестирование testapp.c:

#include <stdio.h>
#include <stdlib.h>
int main()
{
    free(malloc(1024)); // malloc will resolve to __wrap_malloc
    return 0;
}

Затем скомпилируйте приложение:

gcc -c malloc_wrapper.c
gcc -c testapp.c
gcc -Wl,-wrap,malloc testapp.o malloc_wrapper.o -o testapp

Результат результирующего приложения будет:

$ ./testapp
Malloc: 1024 bytes @0x20d8010

Ответ 2

Символы разрешаются компоновщиком в том порядке, в котором вы указываете их в командной строке, поэтому, если вы указали свою библиотеку перед стандартной библиотекой, у вас возникли бы сомнения. Для gcc вам нужно указать

gcc <BLAH> -nodefaultlibs <BLAH BLAH> -lYOUR_LIB <OTHER_LIBS>

Таким образом, ваши библиотеки будут найдены и найдены в первую очередь.