一步直達法
所謂的一步直達法就是利用殼的特征。殼一般在執行完殼代碼之后需要跳轉到OEP處,而這個跳轉指令一般是call ,jmp ,push retn類型的指令,而且因為殼代碼所在的區段和OEP代碼所在的區段一般屬於不同的區段,所以我們可以通過搜索這些特殊指令的機器碼並查看其跳轉范圍,如果跳轉范圍較大(也就是跨段跳轉)則可以判斷為此指令會跳到OEP處。
下面以UPX殼為例:
我們在OD中通過Crty + B來搜索二進制字串,call的機器碼為E8,jmp的機器碼為E9。這里我們搜索E9,通過Ctry + L來查看下一個機器碼。
通過幾次搜索之后我們找到了一條跳轉到另一個區段的jmp指令,此指令就為對應的OEP跳轉指令。
如果我們通過搜索jmp的機器碼(E9)沒有找到符合條件的跳轉指令我們可以接着搜索call指令的機器碼(E8)。
一步直達法的優點是簡單,缺點是對一些強殼不好判斷,因為一些強殼會采用jmp eax的方式跳轉到oep中,而eax值我們是不能直接判斷的,有的一些強殼還會對跳轉到OEP的指令進行壓縮,在執行此指令前才對其進行解壓縮。這樣我們通過直接搜索這些特定指令的機器碼就很難判斷是否為OEP跳轉指令。
單步跟蹤法
所謂的單步跟蹤法就是從EP處開始F8單步向下跟蹤,遇見向上跳轉的指令不跳。這種方法實際是利用了殼代碼的一般邏輯都是先解壓縮原程序的各個區段和一些簡單處理,然后最后跳轉到OEP處。所以可以忽略前面的那些操作,直接去尋找OEP跳轉的指令。這種方法也是存在一定的偶然性,對一些簡單的殼能起到奇效。
模擬跟蹤法
模擬跟蹤法是利用OD的命令行插件,tc/toc命令是跟蹤步進/步過 直到滿足條件就暫停程序。因為OEP所在區段一般位於第一個區塊處,而殼代碼一般位於后幾個區塊中,因此我們可以利用tc/toc命令當eip小於殼代碼所在的區塊地址時說明程序跳轉到了oep處。
下面我們用例子來演示一遍:
用OD加載程序后我們Alt+M查看內存,我們發現主模塊的殼代碼位於首地址為0x4F1000處。
我們在OD的命令行中輸入 toc eip < 0x4F1000 后運行程序,程序會暫停到OEP處。
模擬跟蹤法優點也是簡單,缺點是耗時特別長,因為其在沒執行完一條指令后都需要判斷條件是否成立,所以程序運行很慢。而且如果殼代碼和OEP在同一個區段中的話此方法就不適用了。(雖然這種情況很少,但不能保證沒有)
SFX法
SFX法和模擬跟蹤法十分相似,只不過SFX是OD本身提供的功能。
SFX法有兩種方式,一種是通過判斷塊的形式看是否到達OEP處,另一種是通過判斷字節的形式。顯而易見塊判斷形式速度快但是准確度低,字節形式速度慢但是准確度高。我們在實際分析時結合具體情況選擇合適的方式進行跟蹤。
內存映像法
內存映像法就是通過對加載到內存中的程序下內存斷點來尋找OEP,因為加殼程序在解壓縮各個區段后會跳轉到OEP執行此處的代碼,所以我們可以通過先對OEP所在的區塊設置內存寫入斷點,待此區段解壓縮完成后我們再在此區塊上設置內存訪問斷點。這樣當程序執行到OEP處時就會暫停。
ESP定律法
ESP定律是利用堆棧平衡,一般殼代碼在執行的時候回保存寄存器環境,在跳轉到OEP處的時候再恢復環境。我們可以利用此特點在執行完push指令保存環境后,對堆棧設置硬件訪問斷點或內存訪問斷點。這樣在跳轉到OEP前其會執行pop指令,程序就會暫停我們就可以單步向下跟蹤尋找OEP跳轉指令。
最后一次異常法
有的加殼程序會在執行殼代碼的時候設置很多異常來干擾脫殼破解者,其會在各個異常的異常處理程序中檢測斷點以及進行反調試。所以我們如果還用esp定律,內存映像等下斷點的方法就會失效。我們需要將這些異常執行完之后在采取以上辦法。最后一次異常法就是尋找到程序最后一次異常發生的指令,當最后一次異常執行后我們在采取常規方法尋找OEP。
利用應用程序調用的第一個API
通過對應用程序調用的第一個API下斷點來到達OEP附近,從而進一步尋找到OEP。
例如GetVersion,GetModuleHandle等。
利用不同編譯器編譯程序入口特征碼定位OEP
如果熟悉各個編譯器編譯程序入口點代碼的特征就可以通過此方法來快速到達OEP處,我們可以在各個區塊解壓縮后通過搜索特定編譯器程序入口點代碼的特征碼來到達OEP處。