Кодирование кода / символов в двоичный файл ELF с динамической связью - PullRequest
9 голосов
/ 27 октября 2010

Предположим, у меня есть двоичный файл ELF, который динамически связан, и я хочу переопределить / перенаправить определенные вызовы библиотеки.Я знаю, что могу сделать это с LD_PRELOAD, но мне нужно решение, которое является постоянным в двоичном, независимом от среды и работает для двоичных файлов setuid / setgid, ни одно из которых LD_PRELOAD не может достичь.

Что я хотел бы сделать, это добавить код из дополнительных объектных файлов (возможно, в новые разделы, если необходимо) и добавить символы из этих объектных файлов в таблицу символов двоичного файла, чтобы вновь добавленная версия кода использовалась на местеобщего кода библиотеки.Я считаю, что это должно быть возможно без выполнения каких-либо перемещений в существующем коде;даже если они находятся в одном и том же файле, их можно разрешить во время выполнения обычным способом PLT (для чего стоит заботиться только о функциях, а не о данных).

Пожалуйста, не давайтемне отвечает по линии "Вы не хотите делать это!"или "Это не портативно!"То, над чем я работаю, - это способ взаимодействия двоичных файлов со слегка несовместимыми ABI альтернативными реализациями совместно используемых библиотек.Платформа, о которой идет речь, i386-linux (т.е. 32-битная), если это имеет значение.Если я не ошибаюсь в том, что возможно, я мог бы написать некоторые инструменты для анализа файлов ELF и выполнения моих хаков, но я подозреваю, что есть причудливый способ использовать компоновщик GNU и другие инструменты для достижения этой цели без написания нового кода.

Ответы [ 4 ]

5 голосов
/ 27 октября 2010

Я предлагаю elfsh и др. инструменты из проекта ERESI , если вы хотите сами инструментировать файлы ELF. Совместимость с i386-linux не является проблемой, так как я сам использовал ее для той же цели.

Соответствующие инструкции здесь .

2 голосов
/ 27 октября 2010

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

1 голос
/ 20 января 2012

Кажется, я не могу просто добавить комментарий к этому вопросу, поэтому размещаю его как "ответ". Извините, я делаю это только для того, чтобы помочь другим людям, которые ищут ответ.

Итак, у меня, похоже, похожий сценарий использования, но я явно нахожу любые модификации существующих двоичных файлов неприемлемыми (для меня), поэтому я ищу автономный прокси-подход: Общая библиотека прокси (sharedlib, shlib, так) для ELF?

0 голосов
/ 27 октября 2010

Вы можете обрабатывать некоторые динамические ссылки в самой вашей программе.В частности, прочитайте справочную страницу для dlsym (3) и dlopen (3), dlerror (3) и dlclose (3) для остального интерфейса динамического связывания.

Простой пример - скажем, Iхочу переопределить dup2 (2) из ​​libc.Я мог бы использовать следующий код (назовем его «dltest.c»):

#define _GNU_SOURCE

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <dlfcn.h>

int (*prev_dup2)(int oldfd, int newfd);

int dup2(int oldfd, int newfd) {
    printf("DUP2: %d --> %d\n", oldfd, newfd);
    return prev_dup2(oldfd, newfd);
}

int main(void) {
    int i;

    prev_dup2 = dlsym(RTLD_NEXT, "dup2");
    if (!prev_dup2) {
        printf("dlsym failed to find 'dup2' function!\n");
        return 1;
    }
    if (prev_dup2 == dup2) {
        printf("dlsym found our own 'dup2' function!\n");
        return 1;
    }

    i = dup2(1,3);
    if (i == -1) {
        perror("dup2() failed");
    }

    return 0;
}

Компилировать с:

gcc -o dltest dltest.c -ldl

Статически связанная функция dup2 () переопределяет dup2 ()из библиотеки.Это работает, даже если функция находится в другом файле .c (и скомпилирована как отдельный .o).

Если ваши переопределяющие функции сами динамически связаны, вы можете использовать dlopen (), а не доверятькомпоновщик для получения библиотек в правильном порядке.

EDIT : Я подозреваю, что если другая функция в переопределенной библиотеке вызывает переопределенную функцию, то вызывается исходная функция, а не переопределение.Я не знаю, что произойдет, если одна динамическая библиотека вызывает другую.

...