單步跟蹤法¶
單步跟蹤法的原理就是通過Ollydbg的步過(F8), 步入(F7)和運行到(F4)功能, 完整走過程序的自脫殼過程, 跳過一些循環恢復代碼的片段, 並用單步進入確保程序不會略過OEP. 這樣可以在軟件自動脫殼模塊運行完畢後, 到達OEP, 並dump程序.
要點¶
- 打開程序按F8單步向下, 儘量實現向下的jmp跳轉
- 會經常遇到大的循環, 這時要多用 F4 來跳過循環
- 如果函數載入時不遠處就是一個call(近call), 那麼我們儘量不要直接跳過, 而是進入這個call
- 一般跳轉幅度大的jmp指令, 都極有可能是跳轉到了原程序入口點(OEP)
示例¶
示例程序可以點擊此處下載: 1_trace.zip
單步跟蹤法其實就是一步一步儘量從程序入口點往下走, 在單步的過程中注意EIP不要跑偏了, 但是對於一些比較複雜的殼而言, 單步的過程會顯得異常枯燥而且容易把自己繞暈. 所以單步跟蹤也常用於分析一些關鍵代碼部分(跟靜態分析相結合), 而不是完全地從頭分析到尾, 這有違逆向工程的理念.
用Ollydbg打開壓縮包內的Notepad.exe, 停在了下圖位置. 入口點是一個pushad
保存所有寄存器狀態到棧中, 隨後便是一個call
調用位於0040D00A
處的函數. 調用後便無條件跳轉到459DD4F7
處, 之後的push ebp
和retn
顯然沒有任何意義. 像這種入口點附近就是一個call
的我們稱爲近call
, 對於近call我們選擇步進, 按下F7(當然你也只能選擇步進, 不然EIP就跑偏程序停止了).
步進後又是一個call
, 我們繼續步進, 按F7, 跟進後發現沒有近call了, 我們可以看到程序在調GetModuleHandleA
, GetProcAddress
等API, 繼續向下分析.
之後會遇到多個跳轉,我們儘量滿足向下的跳轉,對於向上的跳轉不予實現並利用F4跳出循環,直到0040D3AF
處, 我們看以下的代碼
0040D3AF 61 popad
0040D3B0 75 08 jnz short NotePad.0040D3BA
0040D3B2 B8 01000000 mov eax,0x1
0040D3B7 C2 0C00 retn 0xC
0040D3BA 68 CC104000 push NotePad.004010CC
0040D3BF C3 retn
這裏popad
可以恢復在程序入口點處保存的寄存器狀態, 然後jnz
跳轉到0040D3BA
處, 這裏是利用push
和retn
來將EIP
改變爲004010CC
, 也就是說在殼解壓完代碼等資源完畢後, 將通過jnz
跳轉到push
處, 然後通過push
和ret
將EIP
設置爲程序原來的入口點(OEP)並返回到OEP處, 然後繼續執行原程序的代碼. 我們執行到retn
返回後, 可以看到如下:
顯然, 我們到了一堆被Ollydbg
誤認爲是數據的地方繼續執行, 顯然Ollydbg
分析錯誤了, 我們需要讓Ollydbg
重新分析, 我們可以右鍵選擇分析->從模塊中刪除分析
, 或是按下ctrl+a
, 這時正確地顯示出OEP處的彙編指令.