2014-12-02 6 views
1

Я знаю, что современные ОС, такие как Linux, не всегда выполняют приложение по тому же адресу, с которого он был первоначально связан. Когда отладчик начинает искать вокруг, он должен знать взаимосвязь между исходным адресом ссылки и конечным исполняемым адресом. Как GDB вычисляет смещение?Как GDB знает, где был переустановлен исполняемый файл?

Пояснения: Я не говорю о виртуальной памяти. То есть у меня (как я считаю) разумное понимание того, как работает виртуальная память, и я полностью работаю в этом адресном пространстве. У меня есть символы, которые находятся в одном месте, когда я сбрасываю таблицу символов из ELF, но в другом месте, когда я получаю их адрес из памяти.

В этом конкретном случае у меня есть строка, которая в связанном исполняемом файле находится по адресу 0x0E984141. В дампе памяти из этого процесса он находится по адресу 0x0E3F2781. Все в разделе .rodata, по крайней мере, сдвинуто на 0x5919C0. Это похоже на рандомизацию компоновки адресного пространства.

ответ

2

Я знаю, что современные операционные системы, такие как Linux не всегда выполнять приложения на тот же адрес был первоначально связан.

Это возможно только для позиционно-независимых исполняемых файлов (связанных с флагом -pie).

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

Исправить.

Как GDB вычисляет смещение?

Точно так же GDB вычисляет смещение для разделяемых библиотек (исполняемый файл PIE действительно является особым случаем общей библиотеки). Существует определенный интерфейс между ld.so и GDB, состоящий из функции _dl_debug_state() (на которой GDB устанавливает внутреннюю точку останова и который ld.so звонит всякий раз, когда он отображает новое изображение ELF в процесс) и struct r_debug. Последнее указывает на связанный список struct link_map s, а l_addr членом этой структуры является смещение между связанными и загруженными адресами.

0

В Linux каждый процесс имеет свой собственный address space в virtual memory.

Исполняемый файл ELF содержит заголовок, описывающий сегменты в памяти (и соответствующие секции в исполняемом файле).