有人可以请教我一个常见的例子,借此(!)你在C程序中销毁堆栈?我在Ubuntu中使用GCC。 谢谢。在C程序中堆栈破坏的典型例子
回答
这取决于你所说的“破坏栈”是什么,但是这是一个常见的错误一般会导致重要堆栈数据的损坏:
void dumb()
{
char small[2];
strcpy(small, "too long to fit"); // Writes past the end of "small", overwriting vital information
}
这是安全漏洞的常见来源。它可能被用来劫持指令指针,从而使恶意代码执行。见buffer overflow。
可能被描述为“破坏栈”的另一个错误是infinite recursion的情况下(向下滚动该网页上):
int add(int n)
{
return n + add(n + 1);
}
其中,因为它缺乏一个退出条件,将推动这么多帧到最后得到“满”的堆栈上。 (除非编译器可以应用tail-call optimization;请参阅下面的内容)
这两个例子都没有像使用GCC 4.4.3的警告那样编译。
注:作为比利奥尼尔下面指出的那样,这些实施例的行为是特定于86,而不是C作为一种语言,并且可以变化从一个编译器到另一个。这并不是说他们不演示了如何突破堆在一个特定的(而且非常普遍的)实现C.
注意:所有这些特定于x86。这里没有什么是由C标准规定的。 (C不知道SIGSEGV/EXCEPTION_ACCESS_VIOLATION,也不知道任何类型的虚拟内存模型) – 2010-10-06 19:09:06
是的,只是意识到自己。我会相应地更新我的帖子。感谢您指出了这一点。 – 2010-10-06 19:11:21
@Martin:编辑+1。另一件值得注意的事情是:如果编译器tailcall优化了'add'函数,它甚至可以在x86上永远循环而不会崩溃。 – 2010-10-06 19:17:47
你不能,至少不符合C标准。你也许可以使用GCC的内联汇编器功能来处理堆栈指针。
编辑:我想打电话exit
,abort
,或(终止在C++只)会导致栈破坏:Pterminate
我真的希望有人会对他们为什么低估这个答案给予评论.... – 2010-10-07 02:18:36
我不知道他们为什么低估了你的答案,但它肯定对我没有帮助。我认为你不了解这个问题。 – 2010-10-07 16:46:22
我不知道你的意思到底是什么,但每当你退出一个函数,该函数的“堆栈”被销毁。例如:
void foo(void) {
// a, b and c are "allocated" on the stack here
int a, b, c;
} // a, b and c are destroyed here
实际上,堆栈永远不会以您想象的方式被破坏。有一个指向堆栈顶部的指针,并且相对于当前堆栈顶部函数引用位置。当函数退出时,TOS指针减少一定量,但不会发生实际的破坏。所以理论上你仍然可以在函数退出后访问函数中的值,尽管这是一个坏主意。
你可能想看看这些:
“TOS”指针?我不知道有这样的事情的架构。至少在x86上,您要寻找的寄存器是“ESP”。在讨论标准中指定的C语言时,这是回答某个特定架构行为时的问题。 – 2010-10-06 19:14:27
@Billy ONeal:TOS ==堆栈顶部,可能是ESP上的ESP,正如你指出的那样。 – 2010-10-06 19:21:16
这里有几个例子,其中堆栈可以得到丢弃。
char* foo()
{
char str[256];
return str;
}
void bar()
{
char* str = foo();
strcpy(str, "Holy sweet Moses! I blew my stack!!");
}
或者,
void foo()
{
char* str; // uninitialized; has garbage value
strcpy(str, "Holy sweet Moses! I blew my stack!!");
// well, could be anything you are trashing
}
void foo()
{
int* ptr; // uninitialized; has garbage value
*ptr = "0xDEADBEEF";
// well, could be anything you are trashing
}
好的,第一个例子工作。但第二个例子与堆栈无关。仅仅因为它是一个堆栈分配指针,并不意味着它与堆栈有任何关系。 – 2010-10-07 02:19:40
- 1. 堆栈框架破坏
- 2. 是否有在C++堆栈变量的顺序被破坏
- 3. c中的堆栈损坏
- 4. 在堆栈上处理对象破坏
- 5. C/C++程序中的损坏堆栈问题
- 6. 破坏内核堆栈的函数
- 7. 破坏调用堆栈的C/C++代码
- 8. 堆栈变量''在C++中损坏
- 9. C++堆栈中分配变量不破坏(/销毁?)
- 10. c堆栈变量损坏
- 11. C中的损坏堆栈变量
- 12. c#程序破坏文件
- 13. 堆栈损坏
- 14. C程序的堆栈和堆内存
- 15. 损坏的堆栈
- 16. 大Monad堆栈的例子
- 17. 为什么在循环中调用ReadConsole会破坏堆栈?
- 18. 订单破坏堆栈/堆分配数组
- 19. 使用C/C++/Java程序理解堆栈和堆栈
- 20. 用指针损坏的C++堆栈
- 21. 堆栈被损坏
- 22. GetCPUDescriptorHandleForHeapStart堆栈损坏
- 23. Python堆栈损坏?
- 24. LinkedList堆栈损坏
- 25. 堆栈被损坏
- 26. Libspotify破坏程序
- 27. C++映射迭代和堆栈损坏
- 28. 围绕p堆栈被损坏C++
- 29. 在C++中实现泛型堆栈
- 30. 如何打破Cocoa Touch应用程序中的“导航堆栈”?
你是什么意思摧毁堆栈? – 2010-10-06 19:04:49
您使用的是哪种CPU架构? Ubuntu有几个架构端口IIRC。 – 2010-10-06 19:09:58