我有一个x86-64
可执行文件,我正在尝试使用静态方法对其进行分析。从_start
开始,我看到跳转到0x400648
- PLT
中的地址 - 其中包含指令jmp *0x20065a(%rip)
。此跳转会导致*0x600ca8
,实际上是0x40064e
。这会将我们带回PLT
并执行pushq $0x2
。
这就是我被困的地方:我知道存在pushq $0x2
指令,告诉动态链接器解析.dynsym
表中的第3个条目。问题是该条目中的st_value
字段为0x0
。这个值实际上应该是main
与_start
的偏移量,对吗?如果是这样,st_value
字段如何初始化?
答案 0 :(得分:1)
这个值实际上应该是_start的偏移量,对吧?
错误。您不能只从_start
跳到main
- 后者需要argc
和argv[]
个参数,但是还没有人设置它们。 libc
初始化代码的作用是:
FILE
句柄(stdout
等),设置环境等等。main
,main
返回时,使用正确的退出代码安排程序exit(2)
。您所看到的实际上是对PLT
__libc_start_main
的{{1}}来电,它将执行上述所有操作,然后调用main
。您可以使用objdump -dr a.out
看到这一点,它看起来与此类似:
00000000004003d0 <_start>:
4003d0: 31 ed xor %ebp,%ebp
4003d2: 49 89 d1 mov %rdx,%r9
4003d5: 5e pop %rsi
4003d6: 48 89 e2 mov %rsp,%rdx
4003d9: 48 83 e4 f0 and $0xfffffffffffffff0,%rsp
4003dd: 50 push %rax
4003de: 54 push %rsp
4003df: 49 c7 c0 50 05 40 00 mov $0x400550,%r8
4003e6: 48 c7 c1 c0 04 40 00 mov $0x4004c0,%rcx
4003ed: 48 c7 c7 b4 04 40 00 mov $0x4004b4,%rdi
4003f4: e8 c7 ff ff ff callq 4003c0 <__libc_start_main@plt>
4003f9: f4 hlt
4003fa: 90 nop
4003fb: 90 nop
如何初始化st_value字段?
您可以阅读有关动态符号解析如何工作的实际细节here(搜索“程序链接表”;请注意:很少有人真正了解其工作原理)。