首页 > 解决方案 > 32 位应用程序与 64 位应用程序引发的 SIGSEGV

问题描述

我一直在学习缓冲区溢出并注意到一些奇怪的事情。

void vuln()
{
    char buf[180];

    gets(buf);
    puts(buf);

    return;
}

int main()
{
    __gid_t egid;

    setvbuf(stdout, 0x0, 2, 0);
    egid = getegid();
    setresgid(effective_gid, effective_gid, effective_gid);

    puts("You know who are 0xDiablos: ");
    vuln();
    return 0;
}

我将代码编译为 64 位和 32 位。

gcc test.c -fno-stack-protector -o 64bit.o
gcc test.c -fno-stack-protector -o 32bit.o -m32 

我在 strace 下的 32 位应用程序上传递了 180 多个 A 作为输入。

--- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=0x41414141} ---
+++ killed by SIGSEGV (core dumped) +++

然后我在 strace 下对 64 位应用程序进行了相同的测试。

--- SIGSEGV {si_signo=SIGSEGV, si_code=SI_KERNEL, si_addr=NULL} ---
+++ killed by SIGSEGV (core dumped) +++

为什么64位显示无效内存引用为NULL,不应该像32位SIGSEGV一样是0x41414141吗?

不确定这是否重要,但我的内核是 5.5.8。

标签: cgccsegmentation-faultkernel

解决方案


为什么64位显示无效内存引用为NULL,不应该是0x41414141吗

它显示 NULL 是因为处理器实际上并未执行CALL,因为目标地址不是规范形式

演示这一点的最简单的程序:

int main()
{
  int (*fn)(void) = (int(*)()) 0x4141414141414141;
  return fn();
}

推荐阅读