用debug函式實現api函式的跟蹤(3)
彭春華 閱讀人次:)條
很明顯,當被除錯程序在函式入口產生中斷除錯資訊時,除錯程式只能得到函式的輸入引數,而不能得到我們希望的輸出引數及返回值!為了實現我們的目標,我們必須在函式呼叫結束時,再次產生中斷,取得函式的輸出引數和返回值。在處理函式入口中斷時,就必須設定好函式的返回位址的斷點。這樣,在函式返回時,就可以得到函式的輸出引數和返回值了。關於這裡的實現說明請參考附錄的源**。
你完全可以參照附錄的源**寫出你自己的簡單的除錯監視程式。當然,有幾個問題因為比較複雜,我沒有在這裡進行說明。乙個就是函式返回斷點的處理,比如try、catch的處理,就必須重新設計好return_fun_stack的結構,考慮一些除錯處理還是可以解決這個問題的。另外乙個問題就是函式的入口斷點和返回斷點沒有任何關係。這個問題更好解決,只需重新設計return_fun,fun_break_map等結構體就可以將它們關聯起來。由於我在這裡只要是分析如何實現中斷除錯處理的過程,這些完善程式的工作就由讀者自行跟蹤改造了。
關於win9x系統
細心的讀者在上面可以發現乙個問題,那就是在setbreakpoint函式中有乙個限制,就是函式的入口位址不能大於0x80000000。確實如此,我們知道0x80000000以上的空間是系統共有的空間,我們一般不能修改這些空間的程式,否則將影響系統的工作。在nt環境下,所有的dll都被載入在0x80000000下,修改0x80000000以下空間的**不會對其它程序產生影響。所以在nt下可以用上面的方案監視所有的dll函式。然而,在win9x下,kernel32.dll,user32.dll,gdi32.dll等系統dll都被載入到0x80000000以上的空間,修改這些空間的**將破壞系統工作。那麼,在9x下就不能監視這些dll模組的函式嗎?
的確,在win9x平台下不能利用在函式入口處設定斷點的方法實現監視。我們必須採用另外的方法實現該功能。在前面討論中知道,通過api hook修改模組匯入表的方法可以實現將api的入口修改為自己監視程式的入口,也可以實現監視功能。如果採用api hook的方法有限制,即必須知道函式原型,對每乙個函式都必須編寫相應的監視**,靈活性受到限制。而我們的目標是不管有多少個dll,不管dll有多少個匯出函式,在不修改我們的程式前提下都可以實現我們的監視功能。所以,api hook是不可以完成我們的目標,但我們可以利用修改匯入表的方案實現目標。首先,修改匯入表,將函式的呼叫位址指向我們的監視**,在監視**中,我們無需對函式程式設計,只是簡單呼叫jmp ***x就可以了。然後,設定斷點時,不是設定在函式的入口點,而是設定在我們的監視**上。這樣,當我們的模組呼叫系統api函式時,就可以實現監視功能了。修改原理如圖:
擴充套件應用
你可以很輕鬆的在此基礎上進行擴充套件你的監視跟蹤功能。只需要修改一下記錄輸入輸出函式結果的程式,就得到乙個新的功能:
1.在記錄輸入輸出引數的地方加入取得當前時刻的功能,就實現了監視函式呼叫效能的功能。(相當於numega的truetime功能)由於採用了debug技術,得到的時間將包括除錯函式導致產生程序的切換時間。等到的時間只是乙個參考價值,但對分析效能而言一般足夠。
2.在記錄輸入輸出引數的地方加入函式呼叫的計數器,就實現了numega的truecoverage功能。
3.監視malloc, free, realloc函式的輸入輸出值,並進行統計,就實現了簡單的記憶體洩漏檢查功能。關鍵的是你可以通過map檔案得到release版本的malloc等函式的位址,實現對release版的跟蹤。
4.在記錄輸入引數處理中加入stackwalk函式可以實現call stack功能,分析是由哪個函式呼叫了自己。在jmp方案中也可以實現這個功能,但是你必須確保stackwalk關聯的函式沒有呼叫被你監視的函式。在hook api(iat)的方案中到是不用保證,但得出的呼叫列表中有可能包含你的監視**。
有一點需要注意的是,我們的目標是監視程式的執行路徑,並不是改變引數和修改結果,所以,在jmp和hook api(iat)中可以實現的修改引數和執行路徑的做法在這裡不能實現。
其他:
本文附錄的**testdebug.zip就是實現了乙個簡單的除錯監視器,自動輸出監視函式的4個輸入引數的位址內容和函式呼叫返回值。該**只是表明通過監視函式可以實現對api的跟蹤,所以沒有實現9x下對系統dll的監視。
debugapi.zip是乙個利用這個方案編寫的應用程式debugapispy.exe,它實現了這個方案中的最基本的跟蹤監視函式的輸入輸出引數功能,也實現了9x下對系統dll的監視支援。該程式支援win9x/nt/w2k/xp上的運用。
用Debug函式實現API函式的跟蹤(3)
用debug函式實現api函式的跟蹤 3 彭春華閱讀人次 條 很明顯,當被除錯程序在函式入口產生中斷除錯資訊時,除錯程式只能得到函式的輸入引數,而不能得到我們希望的輸出引數及返回值!為了實現我們的目標,我們必須在函式呼叫結束時,再次產生中斷,取得函式的輸出引數和返回值。在處理函式入口中斷時,就必須設...
常用 API 函式 選單函式
在指定的選單裡新增乙個選單項 checkmenuitem 複選或撤消複選指定的選單條目 checkmenuradioitem 指定乙個選單條目被複選成 單選 專案 createmenu 建立新選單 createpopupmenu 建立乙個空的彈出式選單 deletemenu 刪除指定的選單條目 de...
用API函式在DELPHI中實現「非典型」窗體
1.異形窗體 窗體只能是方的嗎?不是,還可以有其他形狀。這要用到兩個win32 api函式。首先用createroundrectrgn 函式在窗體內界定乙個橢圓形區域。這裡所指的區域 region 是乙個特殊的api物件,我們可以在區域內部進行填充和剪裁等操作,從而定義窗體的外部特徵。然後呼叫set...