Загрузка не перемещаемого, статического двоичного файла ELF в пользовательском пространстве

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

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

Но я попытался изменить его, чтобы загрузить программу с ожидаемым виртуальным смещением (используя phdr.p_vaddr), но натолкнулся на сложность: мой загрузчик уже использует этот диапазон виртуальной памяти! Я не могу отобразить это, тем более написать что-нибудь в это. Как мне продолжить, чтобы я мог загрузить свой неперемещаемый двоичный файл в адресное пространство моего загрузчика, не перезаписывая собственный код загрузчика до его завершения? Нужно ли заставлять мой загрузчик работать из совершенно другого диапазона виртуальной памяти, возможно, с помощью компоновщика, который связывает его выше обычного диапазона виртуальной памяти для не перемещаемого двоичного файла (который в моем случае начинается с 0x400000) или есть ли какая-то хитрость?

Я прочитал документацию по ELF (кстати, я здесь работаю с ELF64, но я думаю, что ELF32 и ELF64 очень похожи) и много документов в Интернете, но я до сих пор не понимаю.

Может кто-нибудь объяснить, как загрузчик ELF справляется с этим конкретным осложнением? Спасибо!

1 ответ

Решение

Архимед назвал "эврика", когда обнаружил, что в локации может находиться только один объект. Если ваш бинарный файл ELF должен находиться в одном месте, потому что вы не можете перестроить его в другое место, вам нужно переместить сам загрузчик.

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

Перепишите загрузчик, если вы не можете получить исходный код вашего ELF-файла или перемещаемой версии.

КСТАТИ: Архимед Эврика был смертельным для обманщика ювелира. Я надеюсь, что это не так дорого в вашем случае.

Другие вопросы по тегам