步驟如下
1.查殼
由圖可見莱找,顯然有殼
2.找oep(ESP定律)
程序加載進(jìn)OD赦颇,F(xiàn)8單步運(yùn)行,右邊寄存器窗口發(fā)現(xiàn)只有esp的值在變曙搬,符合ESP定律摔吏。
在寄存器位置右鍵,點(diǎn)擊HW-break下硬件斷點(diǎn)纵装。然后F9運(yùn)行到斷點(diǎn)處征讲,到達(dá)跳轉(zhuǎn)到oep 的前一步,單步運(yùn)行搂擦,遇到如下圖:右鍵分析點(diǎn)擊在模塊中刪除分析稳诚,即得到OEP.在oep處右鍵用ollydump脫殼當(dāng)前進(jìn)程。復(fù)制當(dāng)前oep.
3.脫殼(LordPE)
在lordPE中打開樣本程序瀑踢,選中右鍵糾正鏡像大小扳还,再右鍵完全脫殼才避。
4.修復(fù)導(dǎo)入表(ImportREC)
在ImportREC中打開目標(biāo)進(jìn)程即樣本進(jìn)程,然后右邊選項(xiàng)中輸入之前在OD中選中的OEP氨距,點(diǎn)擊IAT自動(dòng)搜索桑逝,然后點(diǎn)擊獲取導(dǎo)入表。
5.文件大小自檢
脫殼以后雙擊沒得反應(yīng)俏让,可能是有文件大小自檢校驗(yàn)楞遏,脫殼后的程序載入OD,在GetFileSize函數(shù)下斷點(diǎn)首昔,在插件中選API斷點(diǎn)設(shè)置工具->常用API斷點(diǎn)寡喝。選中文件類的GetFileSize.然后F9運(yùn)行程序,到斷點(diǎn)處停下勒奇,在堆棧中右鍵反匯編跟隨预鬓,找到調(diào)用這個(gè)函數(shù)的位置,然后下斷點(diǎn)赊颠,把剛剛的那個(gè)斷點(diǎn)刪除格二。在斷點(diǎn)后發(fā)現(xiàn)是幾個(gè)cmp ,很明顯是比較文件大小,故而把這兩個(gè)cmp右鍵二進(jìn)制->用nop填充竣蹦。然后復(fù)制到可執(zhí)行文件顶猜,保存文件。再次點(diǎn)擊程序痘括,發(fā)現(xiàn)正常運(yùn)行长窄。
**
注:esp 定律**
ESP定律算是我們?cè)诿摎ぎ?dāng)中最常使用的方法之一,也特別適合像我一樣的新手远寸!而今天文章說的是ESP脫殼的原理和分析抄淑!只有知道原理了,我們的技術(shù)才能走得列遠(yuǎn)驰后!
一.準(zhǔn)備知識(shí)
在我們開始討論ESP定律之前,說些簡(jiǎn)單的匯編知識(shí)矗愧。
1.call
這個(gè)命令是訪問子程序的一個(gè)匯編基本指令灶芝。也許你說,這個(gè)我早就知道了唉韭!別急請(qǐng)繼續(xù)看完夜涕。call真正的意義是什么呢?我們可以這樣來理解:
1.向堆棧中壓入下一行程序的地址属愤;
2.JMP到call的子程序地址處女器。
例如:
代碼:
00401029.E8 DA240A00 call 004A3508
0040102E.5A pop edx
在執(zhí)行了00401029以后,程序會(huì)將0040102E壓入堆棧住诸,然后JMP到004A3508地址處驾胆!
2.RETN
與call對(duì)應(yīng)的就是RETN了涣澡。對(duì)于RETN我們可以這樣來理解:
1.將當(dāng)前的ESP中指向的地址出棧;
2.JMP到這個(gè)地址丧诺。
這個(gè)就完成了一次調(diào)用子程序的過程入桂。在這里關(guān)鍵的地方是:如果我們要返回父程序,則當(dāng)我們?cè)诙褩V羞M(jìn)行堆棧的操作的時(shí)候驳阎,一定要保證在RETN這條指令之前抗愁,ESP指向的是我們壓入棧中的地址。這也就是著名的“堆棧平衡”原理呵晚!
3.狹義ESP定律
ESP定律的原理就是“堆棧平衡”原理蜘腌。
讓我們來到程序的入口處看看吧!
1.這個(gè)是加了ASPACK殼的入口時(shí)各個(gè)寄存器的值饵隙!
代碼:
EAX 00000000
ECX 0012FFB0
EDX 7FFE0304 //堆棧值
EBX 7FFDF000 //堆棧值
ESP 0012FFC4
EBP 0012FFF0
ESI 77F57D70 ntdll.77F57D70
EDI 77F944A8 ntdll.77F944A8
EIP 0040D000 ASPACK.<ModuleEntryPoint>
2.這個(gè)是ASPACK殼JMP到OEP后的寄存器的值撮珠!
代碼:
EAX 004010CC ASPACK.004010CC
ECX 0012FFB0
EDX 7FFE0304 //堆棧值
EBX 7FFDF000 //堆棧值
ESP 0012FFC4
EBP 0012FFF0
ESI 77F57D70 ntdll.77F57D70
EDI 77F944A8 ntdll.77F944A8
EIP 004010CC ASPACK.004010CC
呵呵~是不是除了EIP不同以外,eax保存當(dāng)前OEP值癞季,其他都一模一樣敖偻!
為什么會(huì)這樣呢绷柒?我們來看看
0040D000 A> 60 pushad //注意這里ESP=0012FFC4
0040D001 E8 00000000 call ASPACK.0040D006 //ESP=0012FFA4
PUSHAD就是把所有寄存器壓棧志于!我們?cè)诘綒さ淖詈罂纯矗?/p>
代碼:
0040D558 61 popad //ESP=0012FFA4
0040D559 75 08 jnz short ASPACK.0040D563 //注意這里ESP=0012FFC4
也就是說當(dāng)我們對(duì)ESP的0012FFA4下硬件訪問斷點(diǎn)之后。當(dāng)程序要通過堆棧訪問這些值废睦,從而恢復(fù)原來寄存器的值伺绽,準(zhǔn)備跳向苦苦尋覓的OEP的時(shí)候,OD幫助我們中斷下來嗜湃。
小結(jié):我們可以把殼假設(shè)為一個(gè)子程序奈应,當(dāng)殼把代碼解壓前和解壓后,他必須要做的是遵循堆棧平衡的原理购披。
因?yàn)榇蠹覍?duì)ESP理解各有異同杖挣,但是,大同小異刚陡!一般理解可以為:
1惩妇、在命令行下斷hr esp-4(此時(shí)的ESP就是OD載入后當(dāng)前顯示的值)
2、hr ESP(關(guān)鍵標(biāo)志下一行代碼所指示的ESP值(單步通過))