破解脫殼黃金定律 ESP定律(堆棧平衡原理應用)

ESP定律算是我們在脫殼當中最常使用的方法之一,也特別適合像我一樣的新手!而今天文章說的是ESP脫殼的原理和分析!只有知道原理了,我們的技術才能走得列遠!


一.準備知識
在我們開始討論ESP定律之前,我先給你講解一下一些簡單的彙編知識。


1.call
這個命令是訪問子程序的一個彙編基本指令。也許你說,這個我早就知道了!別急請繼續看完。call真正的意義是什麼呢?我們可以這樣來理解:

1.向堆棧中壓入下一行程序的地址;
2.JMP到call的子程序地址處。
例如:
代碼:
00401029.E8 DA240A00 call 004A3508

0040102E.5A pop edx


在執行了00401029以後,程序會將0040102E壓入堆棧,然後JMP到004A3508地址處!



2.RETN
與call對應的就是RETN了。對於RETN我們可以這樣來理解:
1.將當前的ESP中指向的地址出棧;
2.JMP到這個地址。
這個就完成了一次調用子程序的過程。在這裏關鍵的地方是:如果我們要返回父程序,則當我們在堆棧中進行堆棧的操作的時候,一定要保證在RETN這條指令之前,ESP指向的是我們壓入棧中的地址。這也就是著名的“堆棧平衡”原理!



3.狹義ESP定律
ESP定律的原理就是“堆棧平衡”原理。
讓我們來到程序的入口處看看吧!
1.這個是加了ASPACK殼的入口時各個寄存器的值!
代碼:
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.這個是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保存當前OEP值,其他都一模一樣啊!
爲什麼會這樣呢?我們來看看

0040D000 A> 60 pushad //注意這裏ESP=0012FFC4
0040D001 E8 00000000 call ASPACK.0040D006 //ESP=0012FFA4

PUSHAD就是把所有寄存器壓棧!我們在到殼的最後看看:

代碼:
0040D558 61 popad //ESP=0012FFA4
0040D559 75 08 jnz short ASPACK.0040D563 //注意這裏ESP=0012FFC4

也就是說當我們對ESP的0012FFA4下硬件訪問斷點之後。當程序要通過堆棧訪問這些值,從而恢復原來寄存器的值,準備跳向苦苦尋覓的OEP的時候,OD幫助我們中斷下來。



小結:我們可以把殼假設爲一個子程序,當殼把代碼解壓前和解壓後,他必須要做的是遵循堆棧平衡的原理。

因爲大家對ESP理解各有異同,但是,大同小異!一般理解可以爲:
1、在命令行下斷hr esp-4(此時的ESP就是OD載入後當前顯示的值)
2、hr ESP(關鍵標誌下一行代碼所指示的ESP值(單步通過)) 
發佈了27 篇原創文章 · 獲贊 13 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章