Подтвердить что ты не робот

Временное перемещение ELF

Я пишу простой загрузчик ELF для пользовательского пространства под Linux (почему? для 'fun'). Мой загрузчик на данный момент довольно прост и предназначен для загрузки только статически связанных файлов ELF, содержащих позиционно-независимый код.

Обычно, когда программа загружается загрузчиком ядра ELF, она загружается в собственное адресное пространство. Таким образом, сегмент данных и сегмент кода могут быть загружены с правильным виртуальным адресом, указанным в сегментах ELF.

В моем случае, однако, я запрашиваю адреса из ядра через mmap и может или не могу получить адреса, запрошенные в сегментах ELF. Это не проблема для сегмента кода, поскольку он независим от позиции. Однако, если сегмент данных не загружен с ожидаемым адресом, код не сможет правильно ссылаться на что-либо, хранящееся в сегменте данных.

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

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

4b9b3361

Ответ 1

Если вы изменяете абсолютные адреса, доступные в разделе .got(глобальная таблица смещений), ваша программа должна работать. Удостоверьтесь, что вы изменили вычисление абсолютного адреса, чтобы удовлетворить новое расстояние между .text и .data, боюсь, вам нужно выяснить, откуда эта информация появилась для вашей архитектуры.

Смотрите это: Глобальная таблица смещения (зависит от процессора)

Удачи.

Ответ 2

Я не вижу никакого способа сделать это, если вы полностью эмулируете виртуальное адресное пространство, предоставленное ядром, и запустите код внутри этого виртуального пространства. Когда вы mmap раздел данных из файла, вы по существу перекладываете его на неизвестный адрес виртуального адресного пространства вашего ELF-интерпретатора, и ваш код не сможет ссылаться на него каким-либо образом.

Рад оказаться ошибочным. Здесь есть что-то очень классное.