Как вызвать и скомпилировать функцию из elf в мой бинарный файл? - PullRequest
1 голос
/ 08 мая 2019

У меня есть двоичный файл (ELF), который я не пишу, но я хочу использовать 1 функцию из этого двоичного файла (я знаю адрес / смещение функции), эта функция не экспортируется из двоичного файла.

Моя цель - вызвать эту функцию из моего кода C, который я пишу, и статически скомпилировать эту функцию в моем двоичном файле (я компилирую с помощью gcc).

Как я могу это сделать, пожалуйста?

1 Ответ

2 голосов
/ 09 мая 2019

Я собираюсь ответить на

вызов этой функции из моего кода c, который я пишу

часть.

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

$ cat lib.c
int data = 42;
static int foo () { return data; }

gcc -fpic -shared lib.c -o lib.so

$ nm lib.so  | grep foo
00000000000010e9 t foo

Выше приведено воспроизведение с адресом, который вы знаете. Адрес, который мы знаем сейчас, 0x10e9. Это виртуальный адрес foo до переезда. Мы смоделируем перемещение, которое динамический загрузчик делает вручную, просто добавив базовый адрес, по которому загружается lib.so.

$ cat 1.c
#define _GNU_SOURCE
#include <stdio.h>
#include <link.h>
#include <string.h>
#include <elf.h>

#define FOO_VADDR 0x10e9

typedef int(*func_t)();

int callback(struct dl_phdr_info *info, size_t size, void *data)
{
    if (!(strstr(info->dlpi_name, "lib.so")))
        return 0;
    Elf64_Addr addr = info->dlpi_addr + FOO_VADDR;
    func_t f = (func_t)addr;
    int res = f();
    printf("res = %d\n", res);
    return 0;
}

int main()
{
    void *handle = dlopen("./lib.so", RTLD_LAZY);
    if (!handle) {
        puts("failed to load");
        return 1;
    }
    dl_iterate_phdr(&callback, NULL);
    dlclose(handle);
    return 0;
}

А теперь ...

$ gcc 1.c -ldl  && ./a.out
res = 42

Вуаля - это сработало! Это было весело.

Кредит: Это было полезно.

Если у вас есть вопросы, не стесняйтесь читать человека и спрашивать в комментариях.

Что касается

статически скомпилировать эту функцию в моем двоичном файле

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

...