C 此代码如何损坏我的堆栈跟踪?
这个简单的测试程序,C 此代码如何损坏我的堆栈跟踪?,c,gdb,C,Gdb,这个简单的测试程序, $ cat crash.c int main() { int x = 0; *(&x + 5) = 10; return 0; } 使用GCC 7.4.0编译 $ gcc -O0 -g crash.c 具有意外的堆栈跟踪 $ ./a.out Segmentation fault (core dumped) $ gdb ./a.out /tmp/wk_cores/core-pid_19675.dump Reading symbols f
$ cat crash.c
int main() {
int x = 0;
*(&x + 5) = 10;
return 0;
}
使用GCC 7.4.0编译
$ gcc -O0 -g crash.c
具有意外的堆栈跟踪
$ ./a.out
Segmentation fault (core dumped)
$ gdb ./a.out /tmp/wk_cores/core-pid_19675.dump
Reading symbols from ./a.out...done.
[New LWP 19675]
Core was generated by `./a.out'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x00007f450000000a in ?? ()
(gdb) bt
#0 0x00007f450000000a in ?? ()
#1 0x0000000000000001 in ?? ()
#2 0x00007fffd6f97598 in ?? ()
#3 0x0000000100008000 in ?? ()
#4 0x00005632be83d66a in frame_dummy ()
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
我不明白为什么堆栈没有向特权内存显示无效存储?有人能帮我理解吗
我不明白为什么堆栈没有向特权内存显示无效存储
因为你没有将任何东西存储到特权内存中
要做到这一点,您需要以堆栈之外的方式编写,例如:
*(&x + 0x10000) = 5;
实际上,您的程序确实表现出未定义的行为,但它不会写入“特权”内存,只写入可写但不应写入的内存。x是堆栈中的最新变量。因此,如果在x+5处写入,无论走多远,都会在当前分配堆栈的区域之后写入堆栈内存。因此,它总是失败。哪个无效存储到特权内存?
*(&x+5)=10代码>会导致未定义的行为,因此可能会损坏堆栈指针。它需要那些堆栈指针来正确执行堆栈跟踪。实际操作系统会启动一些堆栈保护策略,这些策略可以在某种程度上保护它不受小型越界访问的影响。假设您的地址是64位,但整数只需要32位,0x00007F45000000A
的下半部分可能是由无效的赋值引起的。这个答案毫无意义。我正要评论类似“在声明x之后添加缓冲区”的内容。我想解释一下,如果你写的东西超过了堆栈上分配的最后一个地址,那么(bruh)你总是在堆栈外写,这总是给你segfulf,因为读取未分配的内存。然而,这个技巧不起作用,因为现代编译器可以检测到gcc所称的“堆栈破坏”。