2013-09-25 153 views
1

正如我們所知道的,使虛擬內存的堆棧和堆區不可執行可以阻止內存中執行惡意代碼(如shellcode)(該技術被稱爲Data Execution Prevention) 。而且,將惡意代碼注入內存的最簡單方法是通過溢出緩衝區。因此,使這些內存區域不可執行可以幫助減少溢出攻擊的嚴重性。需要可執行堆棧和堆內存

但是,還有許多其他技術,如地址空間隨機化,指針保護,使用金絲雀等,這些技術用於防止這種攻擊。我認爲大部分系統使用這些其他方法而不是使堆棧/堆內存不可執行(請糾正我,如果我在這裏錯了)

現在,我的問題是,是否有一些特定的操作或內存堆棧/堆部分需要執行的特殊情況?

+3

如果堆可執行,則JIT很容易實現。不過,不知道一般情況如何。 – 2013-09-25 05:34:26

+1

[GCC的嵌套函數]的蹦牀代碼(http://gcc.gnu.org/onlinedocs/gcc/Nested-Functions.html)需要一個可執行堆棧AFAIK。 – tangrs

回答

1

JIT映射內存的可寫區域和可執行區域,或者簡單地將以前分配的內存映射爲可執行區域。

GCC用於需要依賴於系統的方法來標記堆棧可執行文件的部分蹦牀代碼。儘管這是12年前的事,但我不知道今天是如何完成的。

許多系統上的動態鏈接還需要爲運行時解析的函數調用寫入跳轉表的功能。如果您希望跳轉表在該表的更新之間不可寫,而這些更新可能非常昂貴。

通常,可以通過嘗試強制執行內存爲可寫或可執行的策略來安全地解決這些問題,但從未同時解決這兩個問題。當寫入需要完成時,內存可以重新映射爲可寫,然後再次保護以使其可執行。它爲了更好的安全性和稍微複雜的代碼而取消了一些性能(並不那麼重要)。