二十,逐步執行與自動執行[Step-by-step execution and animation]
您可以通過按 F7(單步步入)或 F8(單步步過),對程式進行單步調試。這兩個逐步執行操作的主要區別在於:如果當前的命令是一個子函數,按F7,將會進入子函數,並停在子函數的第一條命令上;而按 F8,將會一次運行完這個子函數。如果您單步步過的子函數中含有斷點或其他調試事件,執行將會被暫停,但 OllyDbg 會在子函數的後一條命令上,自動下一個斷點,而這個斷點您遲早會碰到。
如果被偵錯工具停在異常上,您可以跳過它,並轉到被偵錯工具建立的控制代碼處。只需簡單的 Shift 鍵和任何一個單步命令。
如果需要連續按F7、F8鍵上百次,您可以使用自動執行(Ctrl+F7或者Ctrl+F8)功能。在這種情況下,OllyDbg 將自動重複F7或者F8操作,並且即時更新所有的視窗。這個過程會在下面情況停止:
- 按 Esc 鍵或發出任何單步命令
- OllyDbg 遇到斷點
- 被偵錯工具發生異常
使用“+”和“-”按鍵,可以回朔以前的執行曆史[execution history].
注意:當執行停止時 OllyDbg 將會重新整理大部分視窗。如果動態執行過程非常慢,可以嘗試關掉或最小化沒有用的視窗。
另外,更快捷的找到以前執行指令的辦法是Run跟蹤[run trace]。它將建立一個執行協議並告知您指定指令的執行時間和次數
二一,Hit跟蹤[Hit trace]
Hit跟蹤能夠讓您辨別哪一部分代碼執行了,哪一部分沒有。OllyDbg的實現方法相當簡單。它將選中地區的每一條命令處均設定一個INT3斷點。當中斷髮生的時候,OllyDbg便把它去除掉,並把該命令標誌為命中[hit]。因為每個跟蹤斷點只執行一次,所以這種方法速度非常快。
在使用Hit跟蹤的時候,一定要注意不能在資料中設定斷點,否則應用程式極有可能崩潰。因此,您必須開啟相關的菜單選項,以進行程式碼分析[analyze]。我推薦您選擇嚴格或啟發學習法函數識別[strict or heuristical procedure recognition]。如果選擇模糊[Fuzzy]的話,可能會產生很多難以容忍的錯誤,而且經常把本不是函數的程式碼片段識別成函數。
只要您在模組中設定了跟蹤斷點,哪怕只設了一個,OllyDbg都會分配兩倍於程式碼片段大小的緩衝區。
注意:當您退出Hit跟蹤的時候,Run跟蹤也會同時退出。
Run 跟蹤[Run trace]
Run跟蹤是一種反方向跟蹤程式執行的方式,可以瞭解以前發生的事件。您還可以使用Run跟蹤來瞭解啟動並執行簡單統計[profile]。基本上,OllyDbg 是一步一步地執行被偵錯工具的,就像動畫[animation]示範一樣,但不會即時重新整理視窗,最重要的是它能將地址、寄存器的內容、訊息以及已知的運算元記錄到Run跟蹤緩衝區中。如果被調試的代碼是自修改的,您就能夠儲存原始的命令。可以通過按Ctrl+F11(Run跟蹤步入,進入子函數)或者Ctrl+F12(Run跟蹤步過,一次執行完子函數)開始Run跟蹤,並用F12或者Esc鍵停止跟蹤。
您可以指定在Run跟蹤時執行每一步的條件集(快速鍵:Ctrl+T)。如果條件符合,Run跟蹤將暫停。條件包括:
?當EIP在某個位址範圍內時暫停[Pause when EIP is in the address range];
?當EIP在某個位址範圍之外時暫停[Pause when EIP is outside the address range];
?當某個條件為真時暫停[Pause when some condition is true];
?當下一條指令可疑時暫停[Pause when next command is suspicious],比如: 可能為非法指令(根據在分析3[Analysis 3]中設定的規則而定),訪問不存在的記憶體,設定了單步陷阱標誌[single-step trap flag]或者越ESP界訪問棧。注意這個選項會明顯地(大約20%)減慢Run跟蹤的速度;
?當命令執行達到指定的次數(更確切的說,是添加到Run跟蹤的緩衝區裡面的命令數量)時暫停[Pause after specified number of commands is traced]。注意計數器不能自動歸零。也就是說,如果您設定指令次數為10,則在第10次執行到該命令時暫停,並不是該命令每執行10次就暫停一次。
?當下一條命令符合指定的樣式之一時暫停[Pause when next command matches one of the specified patterns]。您可以使用模糊命令和運算元[imprecise commands and operands]及匹配32位寄存器RA和RB,像R32一樣,這兩個寄存器可以替代任何通用32位寄存器,但是在同一條命令中其值是不能變的。而 RA 和 RB
在同一條命令中,則一定是不同的。例如,在程式中含有 XOR EAX,EAX; XOR ESI,EDX 兩條命令,兩條命令均符合樣式 XOR R32,R32;第一條命令符合樣式XOR RA,RA
;而等二條命令 XOR ESI,EDX 符合樣式XOR RA,RB。
毫無疑問,Run跟蹤需要足夠的記憶體,每條命令平均需要佔用16到35位元組,同時速度也非常慢。在500-MHZ處理器、Windows NT環境下,它每秒能跟蹤5000條指令。
Windows95更慢:每秒鐘僅2200條指令。但是在許多情況下,例如當一個程式跳轉到不存在的地址的時候,這是找到原因的唯一方法。您可以在Run跟蹤時將準線性命令序列(即序列尾部只有唯一出口)跳過。當OllyDbg遇到這些需跳過的命令序列時,會設定一個臨時斷點,然後跟進到序列中,並一次運行完。當然了,如果排除命令中返回或跳轉的地址在跟蹤範圍之外,將可能導致跟蹤發生錯誤;因此OllyDbg會檢查您想跳過的代碼塊,如果存在上述情況,會向您詢問。
在大多數情況下,您對跟蹤系統API代碼不感興趣。跟蹤選項總是跟過系統DLL[Always trace over system DLLs]允許您在 跟蹤/自動 模式下跟過API函數。如果模組在系統目錄下,OllyDbg就假設該模組是系統的。您可以在模組[Modules]視窗中標記任意DLL是系統的或者非系統的。
為了使執行速度更快,您可以通過設定Run跟蹤斷點,先將Run跟蹤限制在選定的命令或代碼塊上,然後再運行程式。我把這種做法稱作“強迫Run跟蹤”。一般來說,刪除Run跟蹤斷點不會移除Hit跟蹤斷點。但如果您刪除了hit跟蹤斷點,同時您也移除了Run跟蹤斷點。
跟蹤命令會儲存到跟蹤緩衝區中,這個緩衝區在跟蹤開始時自動建立。您可以在選項中指定它的大小(最高64MB)。這個緩衝區是迴圈隊列,當滿了的時候,會丟棄老的記錄。
您可以通過從OllyDbg主菜單中選擇“調試[Debug]|開啟或者清除Run跟蹤[Open or clear run trace]”,來開啟或者清除Run跟蹤緩衝區。在Run跟蹤緩衝區開啟後,
OllyDbg 會記錄在執行過程中的所有暫停,甚至那些不是由Run跟蹤引起的暫停。例如,您可以通過按 F7 或者 F8 逐步執行程式,然後通過使用+鍵和-鍵來反方向跟蹤程式的執行。注意:如果Run跟蹤緩衝區已經關閉,則用這些鍵瀏覽的是曆史[history]記錄。在您查看Run追蹤記錄時,寄存器和資訊面板會變灰,來強調它們所顯示的寄存器並不是實際的寄存器。跟蹤緩衝區並不儲存棧頂或由寄存器所指向的內容。寄存器、資訊和棧在Run跟蹤的時候使用實際的記憶體狀態來解釋寄存器的變化。
OllyDbg能夠記下每個指令在Run跟蹤緩衝區裡面出現的次數。在反組譯碼視窗捷徑功能表中,選擇是“查看[View]|統計作為注釋[Profile as comments]”。這個命令使用統計取代了注釋欄。或者,如果欄位標題欄可見,則可以單擊它幾次直到它顯示統計資訊。注意顯示出來的數字是動態,而且不計算已經從跟蹤緩衝區中丟棄的指令。您還可以在單獨的統計視窗[Profile window]中,按觸發次數排序,來查看整個模組的統計資料。
在反組譯碼視窗的捷徑功能表中選擇“Run跟蹤[Run trace]|添加到所有函數入口處[Add entries of all procedures]”,這樣能夠檢查每個可識別的函數被調用的次數。另一個命令“Run跟蹤[Run trace]|添加到函數中所有的分支[Add branches in procedure]”會強行跟蹤此函數中所有識別的跳轉目的地址的內容。在這種情況下,統計功能能夠找到最頻繁執行的分支,您可以最佳化這部分的代碼,以提高速度。
在反組譯碼視窗中的某條命令上使用捷徑功能表中選擇“搜尋[Search for]|Run跟蹤的最新記錄[Last record in run trace]”用於尋找該命令是否被執行過,如果執行過,最後一次執行在哪裡。
Run跟蹤視窗顯示跟蹤緩衝區的內容。對每個指令來說包括被指令改變的整數寄存器的內容(更準確的說是給定的記錄變成下一條記錄的變化)。如果您雙擊某條指令,視窗會選擇在跟蹤緩衝區裡全部含有該命令的記錄,而且您可以通過按+和-鍵來快速的瀏覽;如果您在調試選項[Debugging options]中設定了 “跟蹤[Trace]|同步CPU和
Run跟蹤[Synchronize CPU and Run trace]”,雙擊記錄則會跟進到對應的反組譯碼視窗中位置。
注意:當您退出Hit跟蹤時,您同時也強行退出了Run跟蹤。