В двоичном формате PIE раздел кода изменяется во время выполнения. Почему так происходит?

Из-за природы двоичного файла PIE все данные в двоичном формате не могут быть доступны по абсолютному адресу.
Итак, есть два способа доступа к данным относительно

ДВА пути

  1. Во время выполнения загрузчик загружает местоположение данных в GOT записи.
    И получает двоичный доступ к этому адресу.

  2. Вычислить адрес данных, используя _GLOBAL_OFFSET_TABLE местоположение, и получить к нему доступ.



Но я увидел относительно другой способ доступа к данным.
В приведенном ниже двоичном файле двоичный код изменил код раздела <.text>.
Это было очень странно.

.global main
main:
 push stderr


Я скомпилировал его в двоичный файл pie.

jiwon@jiwon$ gcc -fPIE -pie -o test test.s
jiwon@jiwon$ objdump -D test_pie | grep "<main>" -A5
000005c0 <main>:
 5c0:   ff 35 00 00 00 00       pushl  0x0
 5c6:   66 90                   xchg   %ax,%ax
 5c8:   66 90                   xchg   %ax,%ax
 5ca:   66 90                   xchg   %ax,%ax


Как вы видите выше, разборка push stderr собрана в pushl 0x0.
И .. Когда я выполняю двоичный файл,

pwndbg> disass /r main
Dump of assembler code for function main:
=> 0x004005c0 <+0>: ff 35 48 18 40 00   push   DWORD PTR ds:0x401848
   0x004005c6 <+6>: 66 90   xchg   ax,ax
   0x004005c8 <+8>: 66 90   xchg   ax,ax
   0x004005ca <+10>:    66 90   xchg   ax,ax

Раздел ‹.text> изменен на stderr!
Я думаю, это очень странно, потому что раздел <.text> имеет -WX разрешение в общем приложении.
Но в этом случае <.text> - это RWX разрешение.


Вопрос:

  1. Почему так происходит? Почему компилятор решил использовать этот странный способ вместо вышеупомянутого TWO Way?
  2. Это обычная ситуация в pie двоичном файле ..?

person Jiwon    schedule 04.10.2018    source источник
comment
Это просто переезд. Это реальный способ доступа к данным, если вы не генерируете PIC, и адрес может вписаться в немедленный.   -  person Margaret Bloom    schedule 04.10.2018
comment
Используйте objdump -drRwC для отображения перемещений, в том числе перемещений разделяемых библиотек, таких как PIE. Но да, 32-битный код не имеет доступной относительной адресации RIP, поэтому ему нужны исправления перемещения при загрузке или очень неудобные методы для создания независимого от позиции кода. Я бы не рекомендовал создавать 32-битные исполняемые файлы PIE, используйте gcc -no-pie -fno-pie -m32.   -  person Peter Cordes    schedule 04.10.2018


Ответы (1)


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

Компоновщик - это не тот, кто создает инструкции относительной загрузки и сохранения, это делает компилятор, а компоновщик следит за тем, чтобы правильные разделы перемещения размещались правильно и тому подобное.

person user2162550    schedule 05.10.2018