Предварительная загрузка моей библиотеки для нескольких функций при использовании оригинала другими с помощью LD_PRELOAD - PullRequest
2 голосов
/ 05 марта 2011

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

Ответы [ 2 ]

1 голос
/ 08 марта 2011

Использование функции вставки в следующем примере аналогично этому ответу .

В примере предоставляется функция-обертка write(), которая вызывает исходный write(). Важно отметить, что вы не можете напрямую вызвать оригинал write(), потому что он будет интерпретирован как вызов оболочки. Использование указателей на функции в main() демонстрирует, как можно избежать путаницы в отношении того, какой write() вы вызываете.

Код: test.c

#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
#include <dlfcn.h>

size_t write(int fd, const void *buf, size_t count)
{
    static size_t (*write_func)(int, const void *, size_t) = NULL;

    /* get reference to original (libc provided) write */
    if (!write_func)
    {
        write_func = (size_t(*)(int, const void *, size_t)) dlsym(RTLD_NEXT, "write");
    }

    /* perform wrapper specific actions */
    /* ... */

    /* call original write() */
    return  write_func(fd, buf, count);
}

int main(int argc, char *argv[])
{
    size_t (*wrap_write)(int, const void *, size_t);
    size_t (*orig_write)(int, const void *, size_t);
    char buf1[] = "write() wrapper called\n";
    char buf2[] = "orignial write() called\n";

    /* set pointer to write() wrapper to differentiate */
    wrap_write = write;
    /* get reference to original (libc provided) write() */
    orig_write = (size_t(*)(int, const void *, size_t)) dlsym(RTLD_NEXT, "write");

    /* call write() wrapper */
    wrap_write(1, buf1, strlen(buf1));    
    /* call original write() */
    orig_write(1, buf2, strlen(buf2));

    return 0;
}

Выход:

$ gcc -Wall -Werror -ldl test.c -o test
$ ./test
Оболочка write () с именем
orignial write () называется
$

0 голосов
/ 05 марта 2011

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

...