【发布时间】:2014-10-08 23:06:28
【问题描述】:
我想知道它是如何精确工作的。 假设我们有以下代码 sn-ps:
0000000000400400 <printf@plt-0x10>:
400400: ff 35 02 0c 20 00 pushq 0x200c02(%rip) # 601008 <_GLOBAL_OFFSET_TABLE_+0x8>
400406: ff 25 04 0c 20 00 jmpq *0x200c04(%rip) # 601010 <_GLOBAL_OFFSET_TABLE_+0x10>
40040c: 0f 1f 40 00 nopl 0x0(%rax)
0000000000400410 <printf@plt>:
400410: ff 25 02 0c 20 00 jmpq *0x200c02(%rip) # 601018 <_GLOBAL_OFFSET_TABLE_+0x18>
400416: 68 00 00 00 00 pushq $0x0
40041b: e9 e0 ff ff ff jmpq 400400 <_init+0x20>
....
40053b: e8 d0 fe ff ff callq 400410 <printf@plt>
首先调用 printf 存根 (printf@plt),然后获取位于 0x601018(在 GOT 内)的地址以便跳转到其中。
假设是第一次调用printf:我们找到的值将是0x400416,也就是说下一条指令,对吧?
按照代码,值 0 被压入堆栈,然后我们跳转到 0x400400。这里推送了一个 GOT 地址(0x601008),然后跳转到下一个地址(0x601010):为什么?里面到底有什么?
此外:动态链接器何时被调用以及如何调用?
【问题讨论】:
标签: linux assembly compilation linker decompiling