由于 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
许可。
问题:
- 为什么会发生这种情况?为什么编译器选择使用这种奇怪的方式,而不是上面的两种方式?
- 这是馅饼二进制中的常见情况..?