如何解决ELF重定位:存在偏移量,但我看不到偏移量的要求
我正在尝试了解小精灵的重定位,有些事情我并不是很了解:
说我有: relamain.c
#include <stdio.h>
#include <stdlib.h>
#include "relafoo.c"
int main() {
int n;
scanf("%d",&n);
printf("\ngot %d,%d!=%d",n,factorial(n));
return 0;
}
和relafoo.c
int factorial(int n) {
if (n == 0 || n == 1) {
return 1;
}
return factorial(n-1)*n;
}
现在进入relamain.o readelf -r我看到:
000000000027 000900000002 R_X86_64_PC32 0000000000000000 factorial - 4
000000000052 000500000002 R_X86_64_PC32 0000000000000000 .rodata - 4
00000000005c 000c00000004 R_X86_64_plt32 0000000000000000 __isoc99_scanf - 4
000000000066 000900000002 R_X86_64_PC32 0000000000000000 factorial - 4
i objdump -d relamain.o:
0000000000000031 <main>:
31: 55 push rbp
32: 48 89 e5 mov rbp,rsp
35: 48 83 ec 10 sub rsp,0x10
39: 64 48 8b 04 25 28 00 mov rax,QWORD PTR fs:0x28
40: 00 00
42: 48 89 45 f8 mov QWORD PTR [rbp-0x8],rax
46: 31 c0 xor eax,eax
48: 48 8d 45 f4 lea rax,[rbp-0xc]
4c: 48 89 c6 mov rsi,rax
4f: 48 8d 3d 00 00 00 00 lea rdi,[rip+0x0] # 56 <main+0x25>
56: b8 00 00 00 00 mov eax,0x0
5b: e8 00 00 00 00 call 60 <main+0x2f>
60: 8b 45 f4 mov eax,DWORD PTR [rbp-0xc]
63: 89 c7 mov edi,eax
65: e8 00 00 00 00 call 6a <main+0x39>
6a: 89 c1 mov ecx,eax
6c: 8b 55 f4 mov edx,DWORD PTR [rbp-0xc]
6f: 8b 45 f4 mov eax,DWORD PTR [rbp-0xc]
72: 89 c6 mov esi,eax
74: 48 8d 3d 00 00 00 00 lea rdi,[rip+0x0] # 7b <main+0x4a>
7b: b8 00 00 00 00 mov eax,0x0
80: e8 00 00 00 00 call 85 <main+0x54>
85: b8 00 00 00 00 mov eax,0x0
8a: 48 8b 75 f8 mov rsi,QWORD PTR [rbp-0x8]
8e: 64 48 33 34 25 28 00 xor rsi,QWORD PTR fs:0x28
95: 00 00
97: 74 05 je 9e <main+0x6d>
99: e8 00 00 00 00 call 9e <main+0x6d>
9e: c9 leave
9f: c3 ret
-
查看生成的代码,我发现所有调用均未引用我的阶乘函数的偏移量66或27,这是为什么呢?根据Ryan“ elfmaster” O'Neill的“学习linux二进制分析”,我应该期望至少我会看到
call 66
或call 27
,有人可以解释吗?
解决方法
1-对于同一功能,您没有两个偏移量。当必须应用重定位时,您有两个位置的两个偏移量。在您的示例中,您两次调用了函数阶乘。一个位于偏移量0x26,另一个位于偏移量0x66,链接到这些调用的重定位偏移量位于偏移量0x27和0x67。偏移量0x27和0x66处的“ 00000000”将由链接器计算的值替换。您可以肯定地看到可执行文件的转储。
2-创建目标文件时。汇编器不知道factorial
的地址,因此它放置了“ 00000000”并进行了重定位,以告诉链接器将这些0替换为获取factorial
所需的值,因为只有链接器才知道它的确切地址位置。
3-可能是John R. Levine撰写的Linkers&Loaders。但是,我建议您开始阅读http://www.skyfree.org/linux/references/ELF_Format.pdf。也许就足够了,这取决于您寻求的理解水平。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。