我很好奇readelf
,objdump
和gdb
这样的程序如何知道callq
指令旁边显示的内容。由于该计划还没有运行,他们如何知道.plt
“落后”的距离?他们根据传递给它的论据猜测吗?或者他们是否真的对程序进行模拟运行以找出答案?
例如:
400ca4: e8 e7 fb ff ff callq 400890 <printf@plt>
400ca9: 48 8b 85 28 ff ff ff mov -0xd8(%rbp),%rax
以上代码知道要转到printf()
的{{1}},地址为0x400890:
.plt
这只是0000000000400890 <printf@plt>:
400890: ff 25 ba 17 20 00 jmpq *0x2017ba(%rip) # 602050 <_GLOBAL_OFFSET_TA$
400896: 68 07 00 00 00 pushq $0x7
40089b: e9 70 ff ff ff jmpq 400810 <_init+0x20>
的输出,所以我不确定该程序是如何知道它需要objdump -d
。我能看到的唯一关联是重定位索引(printf
)和pushq $0x7
部分,虽然它是一个值,因为它从0开始:
.dynsym
让我感到困惑的另一件事是在8: 0000000000000000 0 FUNC GLOBAL DEFAULT UND printf@GLIBC_2.2.5 (2)
条目中引用GOT(#602050)。我从.plt
看到它是基于地址范围的readelf
的一部分,但这些程序在程序运行之前如何确定值?
.got.plt
**编辑**
[23] .got.plt PROGBITS 0000000000602000 00002000
00000000000000b8 0000000000000008 WA 0 0 8
答案 0 :(得分:0)
其中一小部分内存不足,但让我们看看能不能帮助你...
关于你的第一个问题,有一系列链接在一起的东西。我无法保证这些工具是如何做的,只是为了表明有办法。
正如您所看到的,您可以按照PLT到rel(a).plt,到符号表,到字符串表,在那里找到&#34; printf。&#34;
要回答第二个问题,请查看程序标题(readelf -Wl <program>
),然后您将看到不同部分的虚拟地址。那个地址范围来自哪里。