Могу ли я использовать эту информацию для поиска элементов после загрузки программы в память?
Вы, конечно, можете: перебирать все символы в 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 - это какой-то относительный базовый адрес, а не фактическое расположение в памяти, верно?)
Нет, на самом деле (для этого бинарника) это абсолютный адрес.
Позиционно-независимые двоичные файлы используют относительные адреса (поэтому вам понадобится что-то вроде getauxval
, упомянутого выше, чтобы найти базовое местоположение такого исполняемого файла), но этот конкретный двоичный файл выглядит как ET_EXEC
(используйте readelf -h a.out
, чтобы убедиться в этом). Адрес 0x400000
является типичным адресом для загрузки исполняемых файлов, отличных от PIE, в Linux x86_64 (вероятно, это ваша система).
person
Employed Russian
schedule
23.05.2018