2012-02-16 138 views
2

有沒有辦法讓我檢測/啓動 - 創傷 - 寫入字符串而不使用mprotect(我不能使用)?檢測寫入字符串

目前我只能在下面的讀取中檢測到寫入,但這太遲了(以下讀取可能來自完全不同的lib)。

注意:將gdb與觀察點一起使用失敗,原因是優化程序在進程內存中移動字符串。

編輯:有問題的變量是一個類成員(char *),它包含一些元數據作爲字符串的前綴。字符串是需要不可變的部分,並且前綴必須是可寫的。我在靜態哈希類中有幾百萬個這樣的對象,並且可以從我們的代碼中的任何地方訪問它們。

+1

如何在未優化的代碼上使用gdb觀察點? – 2012-02-16 09:09:04

+0

因爲我不能在另一臺機器上重現錯誤,並且將所有libs \ execs替換爲未優化的將需要重新安裝操作系統(這是非常低級的代碼) – Neowizard 2012-02-16 09:12:55

+0

不是'watch myString'獨立於優化器放置了你的字符串'myString'?找出內存中的'myString'是不是調試器的頭痛? – 2012-02-16 10:18:34

回答

1

你可以試着將所有寫入內存的代碼封裝在預處理器宏中,這些代碼檢查你正在使用的地址,但由於大多數人喜歡使用裸骨指針(而不是封裝事物的庫調用),它會可能是很多努力。

唯一的其他選項是mprotect(2)或GDB,它們都使用CPU的特殊部件來觀察地址總線以訪問有問題的存儲器。

既然你不能使用它,最後的選擇是打印在紙上的代碼,並坐在一個安靜的角落幾天來閱讀它。這通常會起作用,但大多數人會避免這種努力(並且因爲它看起來不像「真正的」工作;-)。

+0

我希望能夠看看所有相關的代碼,但它遠遠超過數百萬潛在的代碼行。目前我正試圖挑選有罪的圖書館來縮小搜索範圍。 – Neowizard 2012-02-16 10:23:50

+0

如果它總是出現亂碼的字符串,那麼有問題的代碼必須以某種方式得到它的地址。這意味着它不能與創建/使用字符串的代碼完全無關。 – 2012-02-16 13:38:58

+1

的確,這是一個過程,但這是一個巨大的過程。無論如何,我確實已經設法將其縮小到相關的流程流程,從那裏開始,它只是一個非常注意閱讀代碼的問題......太過於我看起來像「真正」(並且最終非常有效)的工作:)。 – Neowizard 2012-02-17 08:09:27

0

我不確定在gdb中是否有類似於dbx中的「trace」的命令,但是在dbx中我記得使用了一個名爲「trace」的命令,它可以用於跟蹤代碼中的各個變量,並向您顯示當變量值在執行過程中發生變化時。

+0

'痕跡'不會做你在這裏說的。根據DBX文檔「跟蹤 - 在程序執行時跟蹤打印的信息」。事實上,'停止'這樣做!參考DBX docs -'stop-當達到給定行時停止執行,輸入過程或函數,變量更改,模塊加載或卸載,或條件爲真' 而'watch'是GDB中最接近的'stop' – 2012-02-16 10:16:19

+0

是的,跟蹤信息意味着當程序執行時特定變量中的值發生變化時它會打印。如果希望程序一旦變量中的值發生變化就停止,則可以使用Stop。每次變量值更改時跟蹤都會繼續執行打印。 – 2012-02-16 10:20:56