尋找真正的入口(OEP)--廣義ESP定律

1.前言
在論壇上看到不少朋友,不知道什麼是ESP定律,ESP的適用範圍是什麼,ESP定律的原理是什麼,如何使用ESP定律?看到了我在「」調查結果發現,你們對ESP定律很感興趣,固然由於實在是太好用了,如今我就來告訴你們什麼是ESP定律,它的原理是什麼!
BTW:在看完了手動脫殼入門十八篇了之後,再看這篇文章也許會對你更有幫助!
在下面地址下載:
http://www.jetdown.com/down/down.asp?id=37350&no=1
2.準備知識
在咱們開始討論ESP定律以前,我先給你講解一下一些簡單的彙編知識。
1.call
這個命令是訪問子程序的一個彙編基本指令。也許你說,這個我早就知道了!別急請繼續看完。
call真正的意義是什麼呢?咱們能夠這樣來理解:1.向堆棧中壓入下一行程序的地址;2.JMP到call的子程序地址處。例如:
00401029 . E8 DA240A00 call 004A3508
0040102E . 5A pop edx
在執行了00401029之後,程序會將0040102E壓入堆棧,而後JMP到004A3508地址處!
2.RET
與call對應的就是RET了。對於RET咱們能夠這樣來理解:1.將當前的ESP中指向的地址出棧;2.JMP到這個地址。
這個就完成了一次調用子程序的過程。在這裏關鍵的地方是:若是咱們要返回父程序,則當咱們在堆棧中進行堆棧的操做的時候,必定要保證在RET這條指令以前,ESP指向的是咱們壓入棧中的地址。這也就是著名的「堆棧平衡」原理!
3.狹義ESP定律
ESP定律的原理就是「堆棧平衡」原理。
讓咱們來到程序的入口處看看吧!
1.這個是加了UPX殼的入口時各個寄存器的值!
EAX 00000000
ECX 0012FFB0
EDX 7FFE0304
EBX 7FFDF000
ESP 0012FFC4
EBP 0012FFF0
ESI 77F51778 ntdll.77F51778
EDI 77F517E6 ntdll.77F517E6
EIP 0040EC90 note-upx.<ModuleEntryPoint>
C 0 ES 0023 32bit 0(FFFFFFFF)
P 1 CS 001B 32bit 0(FFFFFFFF)
A 0 SS 0023 32bit 0(FFFFFFFF)
Z 0 DS 0023 32bit 0(FFFFFFFF)
S 1 FS 0038 32bit 7FFDE000(FFF)
T 0 GS 0000 NULL
D 0
O 0 LastErr ERROR_MOD_NOT_FOUND (0000007E)
2.這個是UPX殼JMP到OEP後的寄存器的值!
EAX 00000000
ECX 0012FFB0
EDX 7FFE0304
EBX 7FFDF000
ESP 0012FFC4
EBP 0012FFF0
ESI 77F51778 ntdll.77F51778
EDI 77F517E6 ntdll.77F517E6
EIP 004010CC note-upx.004010CC
C 0 ES 0023 32bit 0(FFFFFFFF)
P 1 CS 001B 32bit 0(FFFFFFFF)
A 0 SS 0023 32bit 0(FFFFFFFF)
Z 1 DS 0023 32bit 0(FFFFFFFF)
S 0 FS 0038 32bit 7FFDE000(FFF)
T 0 GS 0000 NULL
D 0
O 0 LastErr ERROR_MOD_NOT_FOUND (0000007E)
呵呵~是否是除了EIP不一樣之外,其餘都如出一轍啊!
爲何會這樣呢?
咱們來看看UPX的殼的第一行:
0040EC90 n> 60 pushad //****注意這裏*****
0040EC91 BE 15B04000 mov esi,note-upx.0040B015
PUSHAD就是把全部寄存器壓棧!咱們在到殼的最後看看:
0040EE0F 61 popad //****注意這裏*****
0040EE10 - E9 B722FFFF jmp note-upx.004010CC //JMP到OEP
POP就是將全部寄存器出棧!
而當咱們PUSHAD的時候,ESP將寄存器壓入了0012FFC0--0012FFA4的堆棧中!以下:
0012FFA4 77F517E6 返回到 ntdll.77F517E6 來自 ntdll.77F78C4E //EDI
0012FFA8 77F51778 返回到 ntdll.77F51778 來自 ntdll.77F517B5 //ESI
0012FFAC 0012FFF0 //EBP
0012FFB0 0012FFC4 //ESP
0012FFB4 7FFDF000 //EBX
0012FFB8 7FFE0304 //EDX
0012FFBC 0012FFB0 //ECX
0012FFC0 00000000 //EAX
因此這個時候,在教程上面就告訴咱們對ESP的0012FFA4下硬件訪問斷點。也就是說當程序要訪問這些堆棧,從而恢復原來寄存器的值,準備跳向苦苦尋覓的OEP的時候,OD幫助咱們中斷下來。
因而咱們停在0040EE10這一行!
總結:咱們能夠把殼假設爲一個子程序,當殼把代碼解壓前和解壓後,他必需要作的是遵循堆棧平衡的原理,讓ESP執行到OEP的時候,使ESP=0012FFC4。
4.廣義ESP定律
不少人看完了教程就會問:ESP定律是否是就是0012FFA4,ESP定律的適用範圍是否是隻能是壓縮殼!
個人回答是:NO!
看完了上面你就知道你若是用0012FFA8也是能夠的,ESP定律不只用於壓縮殼他也能夠用於加密殼!!!
首先,告訴你一條經驗也是事實---當PE文件運行開始的時候,也就是進入殼的第一行代碼的時候。寄存器的值老是上面的那些值,不信你本身去試試!而當到達OEP後,絕大多的程序都第一句都是壓棧!(除了BC編寫的程序,BC通常是在下面幾句壓棧)
如今,根據上面的ESP原理,咱們知道多數殼在運行到OEP的時候ESP=0012FFC4。這就是說程序的第一句是對0012FFC0進行寫入操做!
最後咱們獲得了廣義的ESP定律,對只要在0012FFC0下,硬件寫入斷點,咱們就能停在OEP的第二句處!!
下面咱們來舉個例子,就脫殼進階第一篇吧!
載入OD後,來到這裏:
0040D042 N> B8 00D04000 mov eax,Notepad.0040D000 //停在這裏
0040D047 68 4C584000 push Notepad.0040584C
0040D04C 64:FF35 00000000 push dword ptr fs:[0] //第一次硬件中斷,F9
0040D053 64:8925 00000000 mov dword ptr fs:[0],esp
0040D05A 66:9C pushfw
0040D05C 60 pushad
0040D05D 50 push eax
直接對0012FFC0下硬件寫入斷點,F9運行。(注意硬件中斷)
在0040D04C第一次硬件中斷,F9繼續!
0040D135 A4 movs byte ptr es:[edi],byte ptr ds:[esi] //訪問異常,無論他 shift+F9繼續
0040D136 33C9 xor ecx,ecx
0040D138 83FB 00 cmp ebx,0
0040D13B ^ 7E A4 jle short Notepad.0040D0E1
第二次硬件中斷。
004058B5 64 db 64 //斷在這裏
004058B6 89 db 89
004058B7 1D db 1D
004058B8 00 db 00
004058B9 00 db 00
這裏也不是,F9繼續!
004010CC /. 55 push ebp
004010CD |. 8BEC mov ebp,esp //斷在這裏,哈哈,到了!(若是發現有花指令,用ctrl+A分析一下就能顯示出來)
004010CF |. 83EC 44 sub esp,44
004010D2 |. 56 push esi
快吧!還不過癮,在來一個例子。
脫殼進階第二篇
若是按上面的方法斷不下來,程序直接運行了!沒什麼,咱們在用另外一種方法!
載入後停在這裏,用插件把OD隱藏!
0040DBD6 N>^\E9 25E4FFFF jmp Note_tEl.0040C000 //停在這裏
0040DBDB 0000 add byte ptr ds:[eax],al
0040DBDD 0038 add byte ptr ds:[eax],bh
0040DBDF A4 movs byte ptr es:[edi],byte ptr ds:[esi]
0040DBE0 54 push esp
F9運行,而後用SHIFT+F9跳過異常來到這裏:
0040D817 ^\73 DC jnb short Note_tEl.0040D7F5 //到這裏
0040D819 CD20 64678F06 vxdcall 68F6764
0040D81F 0000 add byte ptr ds:[eax],al
0040D821 58 pop eax
在這裏對0012FFC0下硬件寫入斷點!(命令行裏鍵入HW 12FFC0)SHIFT+F9跳過異常,就來到OEP的第二行處:(用CTRL+A分析一下)
004010CC /. 55 push ebp
004010CD |. 8BEC mov ebp,esp //斷在這裏
004010CF |. 83EC 44 sub esp,44
004010D2 |. 56 push esi
004010D3 |. FF15 E4634000 call dword ptr ds:[4063E4]
004010D9 |. 8BF0 mov esi,eax
004010DB |. 8A00 mov al,byte ptr ds:[eax]
004010DD |. 3C 22 cmp al,22
就這樣咱們輕鬆搞定了兩個加密殼的找OEP問題!
5.總結
如今咱們能夠輕鬆的回答一些問題了。
1.ESP定律的原理是什麼?
堆棧平衡原理。
2.ESP定律的適用範圍是什麼?
幾乎所有的壓縮殼,部分加密殼。只要是在JMP到OEP後,ESP=0012FFC4的殼,理論上咱們均可以使用。可是在什麼時候下斷點避開校驗,什麼時候下斷OD才能斷下來,這還須要多多總結和多多積累。歡迎你將你的經驗和咱們分享。
3.是否是隻能下斷12FFA4的訪問斷點?
固然不是,那只是ESP定律的一個體現,咱們運用的是ESP定律的原理,而不該該是他的具體數值,不能說12FFA4,或者12FFC0就是ESP定律,他們只是ESP定律的一個應用罷了!
4.對於STOLEN CODE咱們怎麼辦?
哈哈,這正是尋找STOLEN CODE最好的辦法!當咱們斷下時,正好斷在了殼處理STOLEN CODE的地方,在F8一會就到OEP了!
6.後話
以上的方法原理都是我本身總結,本身的經驗,若是有什麼不對的地方,有什麼沒解釋清楚的地方。還請海涵!可是若是以爲我很厲害,那就大可沒必要,由於ESP定律也是別人教個人,不是我第一個提出來的!我只是個比大家早飛一點的菜鳥罷了^-^
看了上面的文字但願能對你在尋找OEP的時候有幫助,可是別忘了一句話:菜鳥認爲找OEP很難,高手認爲修復纔是最難! 好了,下一篇應該寫IAT的修復原理了!讓咱們共同努力吧!加密

相關文章
相關標籤/搜索