__x86.get_pc_thunk
c语言到汇编指令这篇博文中,我一开始通过gcc编译源文件,没有关闭地址随机化这个选项,在编译出的程序的反汇编中,发现了很奇怪的call指令
源程序
long x = 1; |
反汇编
0x11ad <main> endbr32 |
在main+10的位置处调用了一个__x86.get_pc_thunk.ax,很好奇这个是什么东西,gdb动态调试跟进去看看
发现了只有两条汇编指令
mov eax,[esp] |
esp存的就是main函数的地址(因为在main函数中call了当前这个函数)
简单说这个指令就相当于mov eax,eip
这个函数的作用就是get到main函数的地址
很好奇,为什么要获得main函数的地址呢?
我们继续往下走
发现eax这里通过add一个数字后变成了GOT表的地址,这样就不难理解了(关于什么是GOT表和PLT表,我会后面再展开文章进行学习记录),这个函数在x86上的PIC(position independent code)中使用,用来实现对模块的内部数据进行访问,比如全局变量。我们在main函数中访问一下全局变量x,用gdb查看汇编代码,果然可以看到程序访问x是通过GOT进行的。
事实上类似的函数还有:
__x86.get_pc_thunk.bx
,__x86.get_pc_thunk.cx
,__x86.get_pc_thunk.dx
。功能是类似的,只不过传入的寄存器分别为%ebx
,%ecx
,%edx
。早期版本的编译器中,这个函数叫__i686.get_pc_thunk.ax
。
关闭pie
使用gcc编译命令
gcc -fno-pie
关闭pie,调试程序发现已经不需要再通过该函数进行寻址了
Reference
c - How do i get rid of call __x86.get_pc_thunk.ax - Stack Overflow