Run trace 在OllyDbg
1.04中被引進。 這種debug技術的基礎非常簡單。程式碼一步步的執行,偵錯程式把各種命令,暫存器和標誌放在一個大的迴圈緩衝區。當異常發生,就可以回溯到前面幾步甚至幾百上千步,從而分析導致錯誤的原因。
OllyDbg 1.06極大的提高了run trace的可能性. Run trace顯示被修改的暫存器值和保留重要的訊息和已知函式的運算元。你可以設定條件中斷run
trace,概括被跟蹤程式碼,把run trace寫入磁碟避免超過記憶體上限或者比較兩次執行,除錯self-modified程式,找出上次什麼時候命令在某個位置被執行等等。
請記住run trace是非常慢的.。在一個500-MHz的處理器上,OllyDbg沒妙能夠跟蹤最多
2500 (Windows 95)或者5000 (NT)命令. 為了加速run trace,你可以把準線性的程式碼塊(就是不包括調轉指令的)標記為一次執行。另一個侷限是:OllyDbg不儲存可存取記憶體的內容。
為了讓你熟悉run trace,讓我們嘗試除錯一個簡單的控制檯應用程式(己編譯好的rtrace.exe下載):
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
函式f1,
f2 and f3列印出a, b and c。主程式call每個函式33次,然後回車結束...至少理論上是這樣。(你已經發現錯誤了?很好,但這裡我們學習如何透過run
trace得到一樣的結果)。試執行
rtrace.exe,幾秒後他崩潰了:
哦不!(編者:好惡:)非常明顯的錯誤!如果OllyDbg是你的實時偵錯程式,你按"Debug",但是Disassembler視窗是空的!地址00620061不指向任何地方,而且你沒有模糊的概念哪一條指令跳到這個位置。讓我們從頭開始按Ctrl+F2
(Restart),然後Ctrl+F11 (Trace into) 等一到兩分鐘。控制檯仍然是空的。可能夠某些程式碼花費太長時間執行,中斷run trace用F12
(Pause)或者Esc。在可執行模組點選RTRACE並選擇"View run trace profile":
一條命令或者說一系列命令在地址00401191被執行超過24000次。從這裡進入Disassembler:
這個3條命令的短迴圈執行了F4240 (十進位制1000000)次。按沒秒5000條命令,OllyDbg將需要10分鐘透過這個迴圈。注意到這個命令序列是準線性的,例如沒有跳轉到外部。從pop-up右鍵選單,選擇"Run
trace|Skip selection when tracing"。紅線在第四欄包括那幾條命令被排除在run trace之外。當OllyDbg遇到被排出的命令序列,他在被排除命令塊的下一條指令設定一個臨時斷點(在這個例子裡是00401199)然後執行一次命令塊。當然,任何返回或者向外部得跳轉將導致正確的跟蹤失效,因此OllyDbg檢測你需要排除的程式碼塊並要求你的確認。
繼續執行run trace。現在數值顯示很迅速,20秒內OllyDbg報告錯誤:
檢查這個錯誤,開啟Run trace(在標題欄前端有'...'的)並把捲軸拉到底部:
現在我們看到跳轉到00620061的命令是CALL
EAX在004011AF,並且無效的地址由call前的指令計算得到。雙擊這行在Disassembler裡可以看到暫存器和資訊都變灰色以強調他們不是實際上的值而是跟蹤後的值(編者:也就是說它記錄下了當時暫存器的情況):
地址常量0040A128指向3個固定容量的函式地址f1,
f2 and f3。當這條命令最後一次執行EAX的值是3,超過陣列邊界。前面兩條指令應該是執行邊界檢查的,但EAX大於3時條件是無效的,跳轉依然執行。正確的條件應該是“大於等於“,雙擊無效的指令修正它。
當你彙編了一條指令後,這條指令變紅,意味著它是被更改的。再次選擇它在右鍵選單裡選擇強大的工具"Copy
to executable file"。這樣你的更改就會直接應用到程式裡(編者:天!以前我居然不知道,汗!):
現在你唯一要做的就是存檔(用不同的名字,of
course(為什麼?我喜歡覆蓋不行呀?!))然後檢查。現在程式執行的亂爽,是不是很簡單!