有人可以請教我一個常見的例子,藉此(!)你在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