我想知道是否有一種方法可以在Linux 進程的地址空間(從進程本身內部,通過 mprotect()
)寫保護每一頁。通過「每一頁」,我的意思是每個頁面的進程的地址空間可能會被一個普通的 程序在用戶模式下運行 - 所以程序文本,常量,全局變量和堆 - - 但我會很滿意常量,全局變量和堆。我不想寫保護堆棧 - 似乎是一個壞主意。我可以在Linux進程的地址空間中寫保護每個頁面嗎?
一個問題是,我不知道從哪裏開始寫保護 內存。查看/proc/pid/maps
,其中顯示了用於給定pid的內存 的各個部分,但他們似乎始於具有程序文本的地址 0x08048000
。 (在Linux中,據我所知, 一個進程的內存是用底部的 底部的程序文本進行佈局的,然後是常量,然後是全局變量,然後是堆,然後是 一個大小不同的空白空間堆的大小或者堆棧的大小,然後堆棧從內存頂部向下增長,在 虛擬地址0xffffffff
。)有一種方法可以告訴堆的頂端是哪個堆(是通過調用sbrk(0)
,它只是返回一個指向 當前「中斷」的指針,即堆頂部),但不是真正的方法來告訴堆的開始位置。
如果我試圖保護從0x08048000
到中斷的所有頁面,我最終會得到mprotect: Cannot allocate memory
錯誤。我不知道爲什麼mprotect
會是 無論如何分配內存 - 谷歌是不是很有幫助。有任何想法嗎?
順便說一句,我想這樣做的原因是因爲我希望創建一個在程序的運行過程中寫入的所有頁面的 列表, ,我能想到的這樣做的方法是對所有頁面進行寫保護,讓任何嘗試寫入導致寫入錯誤,然後執行寫入 錯誤處理程序,該頁面將頁面添加到列表中,然後刪除寫入 保護。我想我知道如何實現處理程序,如果只有我能 找出哪些頁面要保護以及如何去做。
謝謝!
我其實已經有了代碼,完全符合你想要做的事情。你的想法會起作用,但是你無法保護你的「這些頁面被寫入」列表所在的頁面,或者你的SEGV處理程序將導致SEGV! – Borealid 2010-08-10 00:36:08
@Borealid,謝謝,現在我正試圖解決這個問題(我已經有了segfault處理程序,並且/ proc/self/maps解析現在可以工作)。如何避免保護包含該列表的頁面?在堆棧上分配列表可行,但我沒有看到任何方式將它傳遞給處理程序。另外,我可以將它作爲全局分配,但我想使用比定長數組(比如STL容器)更出色的數據結構,並且我可能並不總是知道我寫入的列表位於何處在記憶中。 – 2010-08-11 00:13:45
@borealid:你說你有這樣做的代碼 - 你介意分享你的代碼嗎?我是新來的,而且我找不到直接與您聯繫的方式(反向頻道)。我正在努力完成Linsey正在做的事情,所以任何代碼示例都會非常有幫助。 – 2010-11-21 17:37:41