通过未初始化的全局指针访问。
#include <stdio.h>
char * str = "Hello World";
int main(void){
puts(str);
return 0;
}
反汇编代码:
0x000011e0 <+19>: call 0x120d <__x86.get_pc_thunk.ax>
0x000011e5 <+24>: add eax,0x2df3
0x000011ea <+29>: mov edx,DWORD PTR [eax+0x30]
0x000011f0 <+35>: sub esp,0xc
0x000011f3 <+38>: push edx
0x000011f4 <+39>: mov ebx,eax
0x000011f6 <+41>: call 0x1070 <puts@plt>
再看重定位表。
p@ubuntu:~/Templates$ readelf -r Hello
Relocation section '.rel.dyn' at offset 0x3a4 contains 9 entries:
Offset Info Type Sym.Value Sym. Name
00003ed8 00000008 R_386_RELATIVE # init_array
00003edc 00000008 R_386_RELATIVE # fini_array
00003ff8 00000008 R_386_RELATIVE
00004004 00000008 R_386_RELATIVE
00004008 00000008 R_386_RELATIVE # 这里就是我们str全局变量。该地址在data段
00003fec 00000106 R_386_GLOB_DAT 00000000 _ITM_deregisterTMClone
00003ff0 00000206 R_386_GLOB_DAT 00000000 __cxa_finalize@GLIBC_2.1.3
00003ff4 00000406 R_386_GLOB_DAT 00000000 __gmon_start__
00003ffc 00000606 R_386_GLOB_DAT 00000000 _ITM_registerTMCloneTa
Relocation section '.rel.plt' at offset 0x3ec contains 2 entries:
Offset Info Type Sym.Value Sym. Name
00003fe4 00000307 R_386_JUMP_SLOT 00000000 puts@GLIBC_2.0
00003fe8 00000507 R_386_JUMP_SLOT 00000000 __libc_start_main@GLIBC_2.0
确实通过ip relative 来定位的全局变量,并不应该需要重定位,但只能定位到指向”helloWorld”字符串全局指针。但是这个全局指针需要重定位,将指向相对文件偏移的地址转化为指向内存偏移的地
通过未初始化的全局指针访问。
#include <stdio.h>
char * str2;
int main(void){
str2 = "Hello World" ;
puts(str2);
return 0;
}
反汇编代码
0x000011e0 <+19>: call 0x1219 <__x86.get_pc_thunk.ax>
0x000011e5 <+24>: add eax,0x2df3
0x000011ea <+29>: lea edx,[eax-0x1fd0]
0x000011f0 <+35>: mov DWORD PTR [eax+0x34],edx
0x000011f6 <+41>: mov edx,DWORD PTR [eax+0x34]
0x000011fc <+47>: sub esp,0xc
0x000011ff <+50>: push edx
0x00001200 <+51>: mov ebx,eax
0x00001202 <+53>: call 0x1070 <puts@plt>
没有重定位,懂得都懂。
局部变量使用访问模块内部全局变量指针。
char * str = "Hello World";
int main(void){
char * str2 = str ;
puts(str2);
return 0;
}
反汇编代码
0x000011e0 <+19>: sub esp,0x10
0x000011e3 <+22>: call 0x1215 <__x86.get_pc_thunk.ax>
0x000011e8 <+27>: add eax,0x2df0
0x000011ed <+32>: mov edx,DWORD PTR [eax+0x30]
0x000011f3 <+38>: mov DWORD PTR [ebp-0xc],edx
0x000011f6 <+41>: sub esp,0xc
0x000011f9 <+44>: push DWORD PTR [ebp-0xc]
0x000011fc <+47>: mov ebx,eax
0x000011fe <+49>: call 0x1070 <puts@plt>
通过ip relative 指令定位到0x4008,该地址的值指向”Hello World”字符串,
查看重定位表
p@ubuntu:~/Templates$ readelf -r Hello
Relocation section '.rel.dyn' at offset 0x3a4 contains 9 entries:
Offset Info Type Sym.Value Sym. Name
00003ed8 00000008 R_386_RELATIVE
00003edc 00000008 R_386_RELATIVE
00003ff8 00000008 R_386_RELATIVE
00004004 00000008 R_386_RELATIVE
00004008 00000008 R_386_RELATIVE # 这次将存储字符串的指针存放在该处
00003fec 00000106 R_386_GLOB_DAT 00000000 _ITM_deregisterTMClone
00003ff0 00000206 R_386_GLOB_DAT 00000000 __cxa_finalize@GLIBC_2.1.3
00003ff4 00000406 R_386_GLOB_DAT 00000000 __gmon_start__
00003ffc 00000606 R_386_GLOB_DAT 00000000 _ITM_registerTMCloneTa
Relocation section '.rel.plt' at offset 0x3ec contains 2 entries:
Offset Info Type Sym.Value Sym. Name
00003fe4 00000307 R_386_JUMP_SLOT 00000000 puts@GLIBC_2.0
00003fe8 00000507 R_386_JUMP_SLOT 00000000 __libc_start_main@GLIBC_2.0
该处为data段。
且该地址的值为0x2008 , 刚好为“hello world” 字符串的文件偏移。
直接访问
#include <stdio.h>
int main(void){
puts("Hello World");
return 0;
}
同未初始化的全局指针访问。那必然不需要重定位。
结论
模块内部变量指针 | 类型 | 重定位地址 | |||
---|---|---|---|---|---|
直接访问 | 无 | ||||
全局函数指针调用 | R_386_RELATIVE | data段 | |||
未初始化全局指针访问 | 无 | ||||
局部指针访问 | R_386_RELATIVE | data段 |
到这里,有个体会,重定位的对象都是指针。
0 条评论