Статическая ELF альтернатива dlsym - PullRequest
0 голосов
/ 23 мая 2018

Можно ли найти местоположение функции с помощью ELF?Похоже на то, что делает

void *f = dlopen(NULL,..);
void *func = dlsym(f, "myfunc");

, но не требует -rdynamic во время компиляции?

Я вижу, используя nm, что именование элементов все еще присутствует в скомпилированном двоичном файле?:

0000000000400716 T lookup
0000000000400759 T main

Могу ли я использовать эту информацию для поиска элементов после загрузки программы в память?

1 Ответ

0 голосов
/ 23 мая 2018

Могу ли я использовать эту информацию, чтобы найти элементы после загрузки программы в память?

Вы можете: перебирать все символы в a.out, пока не найдете соответствующийодин.Пример кода для итерации по символам: здесь .Или используйте libelf .

Если вам нужно выполнить поиск нескольких символов, итерировать один раз (медленно) по всем символам, построить карту от имени символа до его адреса и выполнить поиск, используя эту карту.

Обновление:

Пример, на который вы указываете, кажется неполным?Он использует данные и эльфов, откуда они берутся?

Да, вам нужно немного смазать локтем к этому примеру.

data находится впамять, в которой a.out находится read в, или (лучше) mmap ed.

Вы можете либо mmap a.out самостоятельно, либо найти существующее отображение, например, getauxval(AT_PHDR) округленодо размера страницы.

ehdr равно (ElfW(Ehdr) *)data (то есть data приведено к Elf32_Ehdr или Elf64_Ehdr в зависимости от ситуации.

Если это неясно,тогда вам, вероятно, следует просто использовать libelf, который позаботится о деталях для вас.

Кроме того, ELF позволяет мне только найти имя символа или он может действительно дать мнеуказатель на ячейку в памяти символа?

Он может дать вам оба: str + sym[i].st_name - это имя, sym[i].st_value - указатель (значение, отображаемое nm).

(предположительно, например, 0000000000400716 - это некоторый относительный базовый адрес, а не фактический в ячейке памяти, верно?)

Нет, aфактически (для этого двоичного файла) это абсолютный адрес.

Позиционно-независимые двоичные файлы действительно используют относительные адреса (поэтому вам понадобится что-то вроде getauxval, упомянутое выше, чтобы найти базовое местоположение такого исполняемого файла), но этоконкретный двоичный файл выглядит как ET_EXEC (используйте readelf -h a.out, чтобы проверить это).Адрес 0x400000 - это типичный адрес для загрузки неисполняемых PIE исполняемых файлов в Linux x86_64 (что, вероятно, ваша система).

...