Перемещение ELF во время загрузки - PullRequest
19 голосов
/ 29 августа 2009

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

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

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

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

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

Ответы [ 2 ]

8 голосов
/ 30 сентября 2009

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

См. Это: Таблица глобальных смещений (зависит от процессора)

Удачи.

4 голосов
/ 06 сентября 2009

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

Рад быть доказанным неправильно. Здесь есть чему поучиться.

...