c - 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。
解决方案
为什么64位显示无效内存引用为NULL,不应该是0x41414141吗
它显示 NULL 是因为处理器实际上并未执行CALL
,因为目标地址不是规范形式。
演示这一点的最简单的程序:
int main()
{
int (*fn)(void) = (int(*)()) 0x4141414141414141;
return fn();
}