我一直在尝试从我的程序中获取main的返回地址。这就是我的程序。
#include <stdio.h>
int main(int argc, char **argv)
{
char buffer[64];
printf("[%p]: ", buffer+64+8+4);
printf("%p ", *(buffer+64+8+4));
printf("%p ", *(buffer+64+8+5));
printf("%p ", *(buffer+64+8+6));
printf("%p \n", *(buffer+64+8+7));
}
我加了64个来覆盖缓冲区,8个用于填充(通过gdb计算出来的) 最后4个用于在堆栈中推送ebp。栈中的下一个东西应该是main的返回地址。运行程序后得到。[0xbffff7dc]: 0x76 0xffffffdc 0xffffffea 0xffffffb7
但在gdb中,我得到的是
(gdb) x/x 0xbffff7dc
0xbffff7dc: 0xb7eadc76
我可以看到,在程序的STDOUT中,返回地址的有意义的部分位于LSB处,上面的字节都是0xff(除了0x76,不知道为什么)。
我很快意识到,在C语言中,对指针的去引用完全取决于指针的类型。任何类型的表达式 *(buffer+XXX)
只会返回一个位于该地址的单字节数据,作为 buffer
是一个 char*
(而char是1个字节)。
解决方法是将地址转为一个 int*
(或任何能够容纳地址的数据类型,比如说) char**
) 之前 取消引用。
最后,我想到了这个。
#include <stdio.h>
int main(int argc, char **argv)
{
char buffer[64];
//gets(buffer);
printf("[%p]: ", buffer+64+8+4);
printf("%p \n", *( (char**) (buffer+64+8+4)));
}
它成功地输出了 [0xbffff7dc]: 0xb7eadc76