Из-за природы двоичного файла PIE все данные в двоичном формате не могут быть доступны по абсолютному адресу.
Итак, есть два способа доступа к данным относительно
ДВА пути
Во время выполнения загрузчик загружает местоположение данных в
GOT
записи.
И получает двоичный доступ к этому адресу.Вычислить адрес данных, используя
_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
разрешение.
Вопрос:
- Почему так происходит? Почему компилятор решил использовать этот странный способ вместо вышеупомянутого TWO Way?
- Это обычная ситуация в pie двоичном файле ..?
objdump -drRwC
для отображения перемещений, в том числе перемещений разделяемых библиотек, таких как PIE. Но да, 32-битный код не имеет доступной относительной адресации RIP, поэтому ему нужны исправления перемещения при загрузке или очень неудобные методы для создания независимого от позиции кода. Я бы не рекомендовал создавать 32-битные исполняемые файлы PIE, используйтеgcc -no-pie -fno-pie -m32
. - person Peter Cordes   schedule 04.10.2018