Значит, большая часть двоичного файла состоит из таблицы перемещения?

Я просто использовал objdump -x ... для проверки разделов PE-файла.

Всего около 90000 строк записей о перемещении:

reloc   92 offset  bc0 [524bc0] HIGHLOW
reloc   93 offset  bc4 [524bc4] HIGHLOW
    ....

Верно ли, что большая часть пространства большинства PE-файлов состоит из записей перемещения, как указано выше?

Для чего эти записи?

ОБНОВЛЕНИЕ

Кто-нибудь может объяснить, как работают записи о перемещении, как указано выше?


person compile-fan    schedule 14.05.2011    source источник
comment
@ Игнасио Васкес-Абрамс, не могли бы вы уточнить?   -  person compile-fan    schedule 14.05.2011
comment
Хотя существуют образцы вредоносных программ, которые полностью состоят из элементов перемещения (т. Е. Без явного кода или данных, вместо этого последовательности перемещений многократно применяются к одному и тому же месту в памяти для формирования окончательных значений), это гораздо больше. вероятно, что код + данные превышают количество перемещений. Идея состоит в том, что любое значение, которое относится к абсолютному адресу в памяти, должно иметь соответствующий элемент перемещения на случай, если изображение не может загрузиться по запрошенному адресу.   -  person peter ferrie    schedule 28.04.2017


Ответы (1)


Перемещения необходимы, когда в памяти есть базовый конфликт. Если библиотека динамической компоновки хочет загрузить свой раздел кода в определенное пространство памяти, но когда он уже занят другим модулем, он должен быть загружен в другое место. Однако, загружая его в другое адресное пространство, он портит всю абсолютную ссылку, на которую ссылалась библиотека. Например, предположим, что исполняемый файл имеет глобальную переменную с именем int dummy;, а переменная находится в 0x602315. Всякий раз, когда к этой переменной обращаются / записываются, программа выполняет следующий код операции (при условии, что код находится в 0x524BBE, как и запись, которую вы упомянули):

0x524BBE: MOV EAX, DWORD PTR DS:[0x602315];//move dummy to eax register to do stuff

Когда библиотека загружается в другое пространство, 0x602315 не будет указывать на переменную, поскольку адресное пространство 0x602315 уже занято каким-то другим модулем. Следовательно, чтобы обойти эту проблему, вы должны указать загрузчику PE добавить / вычесть смещение (|new base address-expected base address|) к этому значению (0x602315). Для этого каждый PE содержит таблицу, называемую таблицей перемещения, и эта таблица содержит все смещения в вашем коде, относящиеся к этой переменной.

Итак, скажем, вместо 0x524000 (ожидаемое базовое смещение) библиотека была загружена по адресу 0x700000. Затем загрузчик PE ищет записи в таблице и добавляет смещение (0x700000-0x524000 = 0x1DC000) к смещению (0x602315), чтобы загруженный код выглядел так:

0x700BBE: MOV EAX, DWORD PTR DS:[0x7DE315];//move dummy to eax register to do stuff

который будет работать нормально, потому что он указывает на правильное расположение переменной dummy.

Возвращаясь к вашему вопросу, вывод objdump показывает каждую запись этой таблицы. 92, вероятно, означает индекс записи, BC0 - относительный адрес кода, в котором вы обращаетесь к переменной, [524BC0] будет результатом относительного адреса + ожидаемого базового смещения. и HIGHLOW - это просто тип перемещения (он по существу зарезервирован для использования в будущем. В настоящее время используется только один тип перемещения (HIGHLOW), поэтому вам не нужно беспокоиться о других типах). Когда загрузчик прочитает эту запись, он изменит значение 0x524BC0, чтобы отразить это изменение.

Что касается вашего вопроса о пространстве большинства PE, состоящем из .reloc таблицы, ответ будет зависит. Если ваша программа часто обращается к глобальным переменным и константам, у нее будет огромная таблица перемещений, потому что существует так много мест, которые загрузчик должен обновлять.

person JosephH    schedule 23.05.2011