在C中打印地址值与在GDB中打印地址值的区别

问题描述 投票:0回答:1

我一直在尝试从我的程序中获取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 gdb reverse-engineering
1个回答
0
投票

我很快意识到,在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

© www.soinside.com 2019 - 2024. All rights reserved.