2010-05-23 77 views

回答

0

有一種方法被稱爲API掛鉤。來自John Robbins的着名BugslayerUtil.DLL(請參閱他的書「調試應用程序」)戰爭最初被用作自己進程內的API鉤子。我的意思是,所有的內存分配都可以根據少數衆所周知的函數進行分配,如LocalAllocGlobalAlloc,VirtualAlloc等。可以在進程地址空間中覆蓋此函數的起始地址。您可以在流程開始的某個地方執行此操作,也可以使用DLL注入來完成此操作(就像在配置模式下執行Dependency Walker一樣)。因此,您將能夠記錄(跟蹤)每次內存分配嘗試,將調用轉發給原始函數,再次查看結果返回值日誌(跟蹤)並返回結果。在每個調用嘗試的內部,您可以看到調用堆棧中調用此函數的所有函數。因此,調用堆棧的內容以及分配的內存地址和大小可以爲您提供正在查找的完整信息。你會看到所有的動態。

你不應該自己實現所有的東西。只需在互聯網上搜索「API掛鉤」或「DLL注入」,你就可以找到足夠的實例。爲了檢查調用堆棧,您可以使用來自的文檔StackWalk64函數(請參閱http://msdn.microsoft.com/en-us/library/ms680650(VS.85).aspx)imagehlp.dll/dbghelp.dll(例如參見http://www.codeproject.com/KB/threads/StackWalker.aspx)。

所以在我看來,你的問題可以解決。

+0

非常感謝!我已經實現了DLL注入,並且API掛鉤看起來像是一個很好的解決方案。令我困擾的是性能開銷 - 我注入的應用程序分配了超過600MB的內存,但我仍會嘗試。來自烏克蘭的問候:) – Micktu 2010-05-25 10:59:42

+0

歡迎您!我特別高興能幫助一個和我背景相同的人。因爲開銷,你應該嘗試一下。堆上的內存分配不是一個cheep操作,所以如果你不是在每個函數調用時都在日誌文件中寫入一個記錄文件,而是用一些標準過濾掉調用(你應該知道哪一個更好),那麼你的應用程序的總體性能將不會有太大的改變。如果您使用內存映射文件寫入日誌(您只需將字符串複製到映射文件內存),寫入文件將非常快速。最誠摯的問候和更多的成功希望來自德國。 – Oleg 2010-05-25 21:31:57

1

取決於頁面的類型。 dll的代碼頁等的地址在加載時是已知的,並且可以通過查看任何調試器中的「加載的模塊」窗口或等價物來查看。

如果你正在談論一個通用的讀/寫內存頁面,我認爲你是,那麼我不知道一種方法來找出它「屬於」什麼 - 我也不認爲這是這裏擁有嚴格的所有權概念。

+0

謝謝!是的,我正在談論通用讀/寫。當然,知道DLL的基地址沒有問題。我想找到一種方法來告訴內存中已經加載的庫的進程內存 - 迄今爲止沒有成功。 – Micktu 2010-05-23 10:40:43

相關問題