Как readelf переводит точку входа

У меня есть файл elf, и когда я использую readelf -h имя файла, я получаю точку входа. Теперь предположим, что я хочу вычислить этот адрес самостоятельно [используя ассемблер, но язык не важен].

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

Я знаю, что точка входа составляет 4 байта, начиная со смещения 24 в файле, но я не знаю, как преобразовать эти данные в адрес.


person Mickey    schedule 07.06.2014    source источник
comment
Переводить особо нечего, это обычный 4-байтовый адрес в формате с прямым порядком байтов.   -  person Jester    schedule 07.06.2014


Ответы (2)


Я знаю, что точка входа составляет 4 байта, начиная со смещения 24 в файле, но я не знаю, как преобразовать эти данные в адрес.

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

В псевдокоде проверка ошибок опущена:

int fd = open(path, O_RDONLY);
lseek(fd, 24, SEEK_SET);
unsigned long entry_point;
read(fd, &entry_point, sizeof(entry_point));

printf("entry: 0x%lx\n", entry_point);

P.S. 24 является правильным смещением только для Elf32; гораздо лучше записать это переносимо, прочитав целиком Elf32_Ehdr или Elf64_Ehdr (в зависимости от того, байт 5 равен ELFCLASS32 или ELFCLASS64) со смещения 0, а затем используя элемент .e_entry.

person Employed Russian    schedule 08.06.2014

Ваш вопрос не ясен. Если вы спросите, как прочитать это значение из файла ELF, вам следует проанализировать файл ELF (вероятно, используя libelf или другое существующее вспомогательное программное обеспечение). Если вы спросите, как его сформировать, используя некоторую магию на знании содержимого бинарной программы, эта «магия» рассчитывается исключительно из смещения записи, как она компилируется в результирующий бинарник.

Бинарник в Linux (при условии использования стандартного тулчейна, а именно, gcc + GNU binutils) формируется как сумма нескольких входных файлов в качестве основного бинарника, таблицы релокаций для последнего, модулей пролога (crtbegin.o, crti.o), модулей эпилога (crtend.o , crtn.o). Точка входа находится в прологе, но компоновщик может поместить ее после основного бинарного содержимого (я вижу это в /bin/sh на моем OpenSuSE), поэтому на самом деле она находится в конце результирующего бинарного файла. Это право выбора компоновщика, если это явно не регламентировано.

person Netch    schedule 07.06.2014