在無(wú)法使用ESP定律時(shí)—EBP的妙用
互聯(lián)網(wǎng) 發(fā)布時(shí)間:2008-10-08 19:03:28 作者:佚名
我要評(píng)論

在寄存器里面有很多寄存器雖然他們的功能和使用沒(méi)有任何的區(qū)別,但是在長(zhǎng)期的編程和使用中,在程序員習(xí)慣中已經(jīng)默認(rèn)的給每個(gè)寄存器賦上了特殊的含義,比如:EAX一般用來(lái)做返回值,ECX用于記數(shù)等等。在win32的環(huán)境下EBP寄存器用與存放在進(jìn)入call以后的ESP的值,便于退出的
在寄存器里面有很多寄存器雖然他們的功能和使用沒(méi)有任何的區(qū)別,但是在長(zhǎng)期的編程和使用中,在程序員習(xí)慣中已經(jīng)默認(rèn)的給每個(gè)寄存器賦上了特殊的含義,比如:EAX一般用來(lái)做返回值,ECX用于記數(shù)等等。在win32的環(huán)境下EBP寄存器用與存放在進(jìn)入call以后的ESP的值,便于退出的時(shí)候回復(fù)ESP的值,達(dá)到堆棧平衡的目的。
應(yīng)用以前說(shuō)過(guò)的一段話:
原程序的OEP,通常是一開(kāi)始以 Push EBP 和MOV Ebp,Esp這兩句開(kāi)始的,不用我多說(shuō)大家也知道這兩句的意思是以EBP代替ESP,作為訪問(wèn)堆棧的指針。
為什么要這樣呢?為什么幾乎每個(gè)程序都是的開(kāi)頭能?因?yàn)槿绻覀儗?xiě)過(guò)C等函數(shù)的時(shí)候就應(yīng)該清楚,程序的開(kāi)始是以一個(gè)主函數(shù)main()為開(kāi)始的,而函數(shù)在訪問(wèn)的過(guò)程中最重要的事情就是要確保堆棧的平衡,而在win32的環(huán)境下保持平衡的辦法是這樣的:
1.讓EBP保存ESP的值;
2.在結(jié)束的時(shí)候調(diào)用
mov esp,ebp
pop ebp
retn
或者是
leave
retn
兩個(gè)形式是一個(gè)意思。
這樣做的好處是不用考慮ESP等于多少,PUSH了多少次,要POP多少次了,因?yàn)槲覀冎繣BP里面放的是開(kāi)始時(shí)候的ESP值。
2.推廣的ESP定律
在尋找OEP的時(shí)候,往往下斷HW ESP-4不成功,除了殼代碼將硬件斷點(diǎn)刪除了以外,很可能的情況就是因?yàn)闅ごa在運(yùn)行到OEP的時(shí)候他的ESP已經(jīng)不再是在EP時(shí)候的ESP(12FFC4)了,這樣我們下斷當(dāng)然是不成功的。
那么如何找到在殼到達(dá)OEP的時(shí)候的堆棧的值將是關(guān)鍵。
在這里我們應(yīng)用的關(guān)鍵是
Push EBP
MOV Ebp,Esp----》關(guān)鍵是這句
我來(lái)解釋一下,當(dāng)程序到達(dá)OEP的時(shí)候Push EBP這句對(duì)于ESP的值來(lái)說(shuō)就是ESP-4,然后是ESP-4賦給了EBP,而做為保存ESP值作用的EBP寄存器在這個(gè)“最上層的程序”中的值將始終不會(huì)改變。雖然他可能在進(jìn)入子call里面以后會(huì)暫時(shí)的改變(用于子程序的堆棧平衡)但是在退出了以后依*pop ebp這一句將還原原來(lái)的EBP的值。
以這句做為突破口,就是說(shuō)只要我們能斷在“最上層的程序”中,就能通過(guò)觀察EBP的值得到殼在JMP到OEP的時(shí)候的ESP的值了。
3.實(shí)戰(zhàn)
來(lái)看看pespin1.1的殼,在pespin1.0的殼中,我們使用HW 12FFC0能很容易的找到stolen code的地方,但是到pespin1.1的時(shí)候,我們就不行了。用HW 12FFC0根本斷不下來(lái)。
現(xiàn)在我們就使用這個(gè)推廣的ESP定律,載入程序后來(lái)到最后的一個(gè)異常
0040ED85 2BDB sub ebx,ebx //停在這里
0040ED87 64:8F03 pop dword ptr fs:[ebx]
0040ED8A 58 pop eax
0040ED8B 5D pop ebp
0040ED8C 2BFF sub edi,edi
0040ED8E EB 01 jmp short pespin1_.0040ED91
0040ED90 C466 81 les esp,fword ptr ds:[esi-7F]
我用使用內(nèi)存斷點(diǎn)辦法來(lái)到FOEP處
004010D3 0000 add byte ptr ds:[eax],al
004010D5 0000 add byte ptr ds:[eax],al
004010D7 0000 add byte ptr ds:[eax],al
004010D9 0000 add byte ptr ds:[eax],al
004010DB 0000 add byte ptr ds:[eax],al
004010DD 0000 add byte ptr ds:[eax],al
004010DF 75 1B jnz short pespin1_.004010FC //這里是FOEP
004010E1 56 push esi
004010E2 FF15 99F44000 call dword ptr ds:[40F499]
004010E8 8BF0 mov esi,eax
004010EA 8A00 mov al,byte ptr ds:[eax]
好了,這里就是“最上層的程序”的地方了,看看寄存器
EAX 00141E22
ECX 0040C708 pespin1_.0040C708
EDX 0040C708 pespin1_.0040C708
EBX 0040C708 pespin1_.0040C708
ESP 0012F978
EBP 0012F9C0 //注意這里
ESI 00141EE0
EDI 0040E5CD pespin1_.0040E5CD
EIP 004010DF pespin1_.004010DF
看到了吧,EBP=0012F9C0,我們來(lái)想象一下這個(gè)值是怎么得到的。
首先肯定是通過(guò)MOV ESP,EBP這一句,也就是說(shuō)ESP這時(shí)是0012F9C0的,然而上面還有一句PUSH EBP也就是說(shuō)ESP在到達(dá)OEP的時(shí)候應(yīng)該是0012F9C4的。好了得到這個(gè)結(jié)論我們就能很快的找到stolen code的所在了。
重來(lái)停在最后的異常
0040ED85 2BDB sub ebx,ebx //停在這里
0040ED87 64:8F03 pop dword ptr fs:[ebx]
0040ED8A 58 pop eax
0040ED8B 5D pop ebp
0040ED8C 2BFF sub edi,edi
0040ED8E EB 01 jmp short pespin1_.0040ED91
0040ED90 C466 81 les esp,fword ptr ds:[esi-7F]
然后下斷HW 0012F9C0 ,F(xiàn)9運(yùn)行,來(lái)到這里
0040D8FB 61 popad
0040D8FC 55 push ebp
0040D8FD EB 01 jmp short pespin1_.0040D900 //停在這里
0040D8FF 318B ECEB01AC xor dword ptr ds:[ebx AC01EBEC],ecx
0040D905 83EC 44 sub esp,44
0040D908 EB 01 jmp short pespin1_.0040D90B
0040D90A 72 56 jb short pespin1_.0040D962
0040D90C EB 01 jmp short pespin1_.0040D90F
0040D90E 95 xchg eax,ebp
0040D90F FF15 6CF34000 call dword ptr ds:[40F36C]
0040D915 EB 01 jmp short pespin1_.0040D918
于是就很快的找到了stolen code的所在了。
4.總結(jié)
上面的這個(gè)辦法大概可以總結(jié)以下的步驟:
(1).直接或間接的斷在“最上層的程序”的地方。
(2).得到“最上層的程序”的EBP的值。
(3).利用程序初始化的兩個(gè)固定語(yǔ)句找到殼JMP到OEP的堆棧值。這個(gè)辦法有很大的局限性,因?yàn)橹挥蠽C和delphi程序使用這個(gè)初始化的開(kāi)頭。
但是找到“最上層的程序”的辦法除了內(nèi)存斷點(diǎn)還有很多辦法,例如對(duì)于VC來(lái)說(shuō)使用 bp ExitProcess也是一個(gè)很好的斷點(diǎn),可以直接得到EBP的數(shù)值。
5.后話
原來(lái)這個(gè)辦法有很強(qiáng)的前提條件,不是一個(gè)很具普遍性的辦法,我原來(lái)也不想單獨(dú)的提出來(lái),但是對(duì)于jney2兄弟的anti-ESP定律來(lái)說(shuō)這個(gè)辦法卻是一個(gè)解決之道。
當(dāng)然還有更多的辦法,在這里我只想說(shuō)很多事情有矛就有盾,沒(méi)有什么辦法是一定沒(méi)有漏洞的,只是希望這篇文章給大家闊寬思路,起到拋磚引玉的作用。
應(yīng)用以前說(shuō)過(guò)的一段話:
原程序的OEP,通常是一開(kāi)始以 Push EBP 和MOV Ebp,Esp這兩句開(kāi)始的,不用我多說(shuō)大家也知道這兩句的意思是以EBP代替ESP,作為訪問(wèn)堆棧的指針。
為什么要這樣呢?為什么幾乎每個(gè)程序都是的開(kāi)頭能?因?yàn)槿绻覀儗?xiě)過(guò)C等函數(shù)的時(shí)候就應(yīng)該清楚,程序的開(kāi)始是以一個(gè)主函數(shù)main()為開(kāi)始的,而函數(shù)在訪問(wèn)的過(guò)程中最重要的事情就是要確保堆棧的平衡,而在win32的環(huán)境下保持平衡的辦法是這樣的:
1.讓EBP保存ESP的值;
2.在結(jié)束的時(shí)候調(diào)用
mov esp,ebp
pop ebp
retn
或者是
leave
retn
兩個(gè)形式是一個(gè)意思。
這樣做的好處是不用考慮ESP等于多少,PUSH了多少次,要POP多少次了,因?yàn)槲覀冎繣BP里面放的是開(kāi)始時(shí)候的ESP值。
2.推廣的ESP定律
在尋找OEP的時(shí)候,往往下斷HW ESP-4不成功,除了殼代碼將硬件斷點(diǎn)刪除了以外,很可能的情況就是因?yàn)闅ごa在運(yùn)行到OEP的時(shí)候他的ESP已經(jīng)不再是在EP時(shí)候的ESP(12FFC4)了,這樣我們下斷當(dāng)然是不成功的。
那么如何找到在殼到達(dá)OEP的時(shí)候的堆棧的值將是關(guān)鍵。
在這里我們應(yīng)用的關(guān)鍵是
Push EBP
MOV Ebp,Esp----》關(guān)鍵是這句
我來(lái)解釋一下,當(dāng)程序到達(dá)OEP的時(shí)候Push EBP這句對(duì)于ESP的值來(lái)說(shuō)就是ESP-4,然后是ESP-4賦給了EBP,而做為保存ESP值作用的EBP寄存器在這個(gè)“最上層的程序”中的值將始終不會(huì)改變。雖然他可能在進(jìn)入子call里面以后會(huì)暫時(shí)的改變(用于子程序的堆棧平衡)但是在退出了以后依*pop ebp這一句將還原原來(lái)的EBP的值。
以這句做為突破口,就是說(shuō)只要我們能斷在“最上層的程序”中,就能通過(guò)觀察EBP的值得到殼在JMP到OEP的時(shí)候的ESP的值了。
3.實(shí)戰(zhàn)
來(lái)看看pespin1.1的殼,在pespin1.0的殼中,我們使用HW 12FFC0能很容易的找到stolen code的地方,但是到pespin1.1的時(shí)候,我們就不行了。用HW 12FFC0根本斷不下來(lái)。
現(xiàn)在我們就使用這個(gè)推廣的ESP定律,載入程序后來(lái)到最后的一個(gè)異常
0040ED85 2BDB sub ebx,ebx //停在這里
0040ED87 64:8F03 pop dword ptr fs:[ebx]
0040ED8A 58 pop eax
0040ED8B 5D pop ebp
0040ED8C 2BFF sub edi,edi
0040ED8E EB 01 jmp short pespin1_.0040ED91
0040ED90 C466 81 les esp,fword ptr ds:[esi-7F]
我用使用內(nèi)存斷點(diǎn)辦法來(lái)到FOEP處
004010D3 0000 add byte ptr ds:[eax],al
004010D5 0000 add byte ptr ds:[eax],al
004010D7 0000 add byte ptr ds:[eax],al
004010D9 0000 add byte ptr ds:[eax],al
004010DB 0000 add byte ptr ds:[eax],al
004010DD 0000 add byte ptr ds:[eax],al
004010DF 75 1B jnz short pespin1_.004010FC //這里是FOEP
004010E1 56 push esi
004010E2 FF15 99F44000 call dword ptr ds:[40F499]
004010E8 8BF0 mov esi,eax
004010EA 8A00 mov al,byte ptr ds:[eax]
好了,這里就是“最上層的程序”的地方了,看看寄存器
EAX 00141E22
ECX 0040C708 pespin1_.0040C708
EDX 0040C708 pespin1_.0040C708
EBX 0040C708 pespin1_.0040C708
ESP 0012F978
EBP 0012F9C0 //注意這里
ESI 00141EE0
EDI 0040E5CD pespin1_.0040E5CD
EIP 004010DF pespin1_.004010DF
看到了吧,EBP=0012F9C0,我們來(lái)想象一下這個(gè)值是怎么得到的。
首先肯定是通過(guò)MOV ESP,EBP這一句,也就是說(shuō)ESP這時(shí)是0012F9C0的,然而上面還有一句PUSH EBP也就是說(shuō)ESP在到達(dá)OEP的時(shí)候應(yīng)該是0012F9C4的。好了得到這個(gè)結(jié)論我們就能很快的找到stolen code的所在了。
重來(lái)停在最后的異常
0040ED85 2BDB sub ebx,ebx //停在這里
0040ED87 64:8F03 pop dword ptr fs:[ebx]
0040ED8A 58 pop eax
0040ED8B 5D pop ebp
0040ED8C 2BFF sub edi,edi
0040ED8E EB 01 jmp short pespin1_.0040ED91
0040ED90 C466 81 les esp,fword ptr ds:[esi-7F]
然后下斷HW 0012F9C0 ,F(xiàn)9運(yùn)行,來(lái)到這里
0040D8FB 61 popad
0040D8FC 55 push ebp
0040D8FD EB 01 jmp short pespin1_.0040D900 //停在這里
0040D8FF 318B ECEB01AC xor dword ptr ds:[ebx AC01EBEC],ecx
0040D905 83EC 44 sub esp,44
0040D908 EB 01 jmp short pespin1_.0040D90B
0040D90A 72 56 jb short pespin1_.0040D962
0040D90C EB 01 jmp short pespin1_.0040D90F
0040D90E 95 xchg eax,ebp
0040D90F FF15 6CF34000 call dword ptr ds:[40F36C]
0040D915 EB 01 jmp short pespin1_.0040D918
于是就很快的找到了stolen code的所在了。
4.總結(jié)
上面的這個(gè)辦法大概可以總結(jié)以下的步驟:
(1).直接或間接的斷在“最上層的程序”的地方。
(2).得到“最上層的程序”的EBP的值。
(3).利用程序初始化的兩個(gè)固定語(yǔ)句找到殼JMP到OEP的堆棧值。這個(gè)辦法有很大的局限性,因?yàn)橹挥蠽C和delphi程序使用這個(gè)初始化的開(kāi)頭。
但是找到“最上層的程序”的辦法除了內(nèi)存斷點(diǎn)還有很多辦法,例如對(duì)于VC來(lái)說(shuō)使用 bp ExitProcess也是一個(gè)很好的斷點(diǎn),可以直接得到EBP的數(shù)值。
5.后話
原來(lái)這個(gè)辦法有很強(qiáng)的前提條件,不是一個(gè)很具普遍性的辦法,我原來(lái)也不想單獨(dú)的提出來(lái),但是對(duì)于jney2兄弟的anti-ESP定律來(lái)說(shuō)這個(gè)辦法卻是一個(gè)解決之道。
當(dāng)然還有更多的辦法,在這里我只想說(shuō)很多事情有矛就有盾,沒(méi)有什么辦法是一定沒(méi)有漏洞的,只是希望這篇文章給大家闊寬思路,起到拋磚引玉的作用。
相關(guān)文章
- “CMOS密碼”就是通常所說(shuō)的“開(kāi)機(jī)密碼”,主要是為了防止別人使用自已的計(jì)算機(jī),設(shè)置的一個(gè)屏障2023-08-01
QQScreenShot之逆向并提取QQ截圖--OCR和其他功能
上一篇文章逆向并提取QQ截圖沒(méi)有提取OCR功能, 再次逆向我發(fā)現(xiàn)是可以本地調(diào)用QQ的OCR的,但翻譯按鈕確實(shí)沒(méi)啥用, 于是Patch了翻譯按鈕事件, 改為了將截圖用百度以圖搜圖搜索.2023-02-04- QQ截圖是我用過(guò)的最好用的截圖工具, 由于基本不在電腦上登QQ了, 于是就想將其提取出獨(dú)立版目前除了屏幕錄制功能其他都逆出來(lái)了, 在此分享一下2023-02-04
非系統(tǒng)分區(qū)使用BitLocker加密導(dǎo)致軟件無(wú)法安裝的解決方法
很多電腦用戶在考慮自己電腦磁盤(pán)分區(qū)安全時(shí)會(huì)采用 Windows 自帶的 BitLocker 加密工具對(duì)電腦磁盤(pán)分區(qū)進(jìn)行加密。但有些人加密后就會(huì)忘記自己設(shè)置的密碼從而導(dǎo)致在安裝其它軟2020-11-25防止離職員工帶走客戶、防止內(nèi)部員工泄密、避免華為員工泄密事件的發(fā)生
這篇文章為大家詳細(xì)介紹了如何才能防止離職員工帶走客戶、防止內(nèi)部員工泄密、避免華為員工泄密事件的發(fā)生,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-06-27徹底防止計(jì)算機(jī)泄密、重要涉密人員離職泄密、涉密人員離崗離職前防范舉
近些年企業(yè)商業(yè)機(jī)密泄漏的事件屢有發(fā)生,這篇文章主要教大家如何徹底防止計(jì)算機(jī)泄密、重要涉密人員離職泄密、告訴大家涉密人員離崗離職前的防范舉措,具有一定的參考價(jià)值,2017-06-27量子計(jì)算機(jī)輕松破解加密算法 如何破解加密算法?
最近有電腦用戶反應(yīng)量子計(jì)算機(jī)可以破解下載的所有的加密算法嗎?其實(shí)也不是不可以,下面虛擬就為大家講解買(mǎi)臺(tái)量子計(jì)算機(jī),如何分分鐘破解加密算法2016-09-26怎么破解Webshell密碼 Burpsuite破解Webshell密碼圖文教程
webshell是以asp、php、jsp或者cgi等網(wǎng)頁(yè)文件形式存在的一種命令執(zhí)行環(huán)境,一種網(wǎng)頁(yè)后門(mén)。黑客通常會(huì)通過(guò)它控制別人網(wǎng)絡(luò)服務(wù)器,那么怎么破解webshell密碼呢?一起來(lái)看看吧2016-09-19針對(duì)Linux系統(tǒng)全盤(pán)加密的啟動(dòng)攻擊
本文討論了針對(duì)Linux系統(tǒng)全盤(pán)加密的冷啟動(dòng)攻擊,大家都認(rèn)為這種攻擊是可行的,但執(zhí)行這么一次攻擊有多難?攻擊的可行性有多少呢?需要的朋友可以參考下2015-12-28防止泄露公司機(jī)密、企業(yè)數(shù)據(jù)防泄密軟件排名、電腦文件加密軟件排行
面對(duì)日漸嚴(yán)重的內(nèi)部泄密事件,我們?nèi)绾问刈o(hù)企業(yè)的核心信息,如何防止內(nèi)部泄密也就成了擺在各個(gè)企業(yè)領(lǐng)導(dǎo)面前的一大問(wèn)題。其實(shí),針對(duì)內(nèi)網(wǎng)安全,防止內(nèi)部信息泄漏早已有了比較2015-12-17