1. 程式人生 > >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值(單步通過))

5.總結

現在我們可以輕鬆的回答一些問題了。

1.ESP定律的原理是什麼?
堆疊平衡原理。

2.ESP定律的適用範圍是什麼?
幾乎全部的壓縮殼,部分加密殼。只要是在JMP到OEP後,ESP=0012FFC4的殼,理論上我們都可以使用。但是在何時下斷點避開校驗,何時下斷OD才能斷下來,這還需要多多總結和多多積累。

3.是不是隻能下斷12FFA4的訪問斷點?

當然不是,那只是ESP定律的一個體現,我們運用的是ESP定律的原理,而不應該是他的具體數值,不能說12FFA4,或者12FFC0就是ESP定律,他們只是ESP定律的一個應用罷了!

記憶體斷點
    1、要解決的問題是:
    1.什麼是記憶體斷點?
    2.如何在尋找OEP時使用記憶體斷點。

2、記憶體斷點尋找OEP的原理

i.   首先,在OD中記憶體斷點和普通斷點(F2下斷)是有本質區別的。

記憶體斷點等效於命令bpm,他的中斷要用到DR0-DR7的除錯暫存器,也就是說OD通過這些DR0-DR7的除錯暫存器來判斷是否斷下普通斷點(F2下 斷)等效於bpx,他是在所執行的程式碼的當前地址的一個位元組修改為CC(int3)。當程式執行到int3的時候就會產生一個異常,而這個異常將交給OD 處理,把這個異常給EIP-1以後,就正好停在了需要的中斷的地方(這個根據系統不同會不一樣),同時OD在把上面的int3修改回原來的程式碼。
記憶體斷點分為:記憶體訪問斷點,記憶體寫入斷點。
我們知道,在程式執行的時候會有3種基本的狀態產生:讀取-->寫入-->執行。

004AE242    A1 00104000   mov eax,dword ptr ds:[004AE24C]   //004AE24C處的記憶體讀取
004AE247    A3 00104000   mov dword ptr ds:[004AE24C],eax   //004AE24C處的記憶體寫入
004AE24C    83C0 01       add eax,1                        //004AE24C處的記憶體執行

   1.當對004AE24C下記憶體訪問斷點的時候,可以中斷在004AE242也可以中斷在004AE247。
   2.當對004AE24C下記憶體寫入斷點的時候,只能中斷在004AE247。
3.當執行004AE24C的時候,只能中斷在004AE24C

到這裡你可能不明白了,為什麼記憶體訪問斷點能中斷在004AE247這一句對004AE24C的寫入,而且還能中斷在004AE24C的執行呢?其實很簡 單,我們只要仔細體會一下“記憶體訪問”這四個字的含義遍可以知道,當我們對004AE24C進行讀取的時候需要“訪問”他吧,當我對004AE24C進行 寫入的時候也需要“訪問”他吧!!當然我們要執行記憶體地址004AE24C的程式碼的時候也是還是要“訪問”他的!

   所以我們不難得出下面的結論:
   1.記憶體寫入中斷的地方,一定是也可以用記憶體訪問中斷。
   2.記憶體執行的地方,也可以用記憶體訪問中斷。

如果這時你認為,那麼記憶體寫入豈不是沒用了。呵呵~那我要告訴你當然不是,如果你想快速的準確的定位到004AE247這一行的時候,那麼他就大有作用了!

總結一下:記憶體斷點不修改原始碼,不會像普通斷點那樣因為修改程式碼被程式校驗而導致中斷失敗;對於區段的訪問只是區域大了一點,其原理和上面分析的三行程式碼是一樣的。

   ii.如何使用記憶體斷點來尋找OEP呢?
   要回答這個問題首先要回答這一個問題:殼是如何解壓程式碼的?

正如我們知道的,殼如果要把原來加密或壓縮的程式碼執行起來就必須要解壓和解密原來的程式碼。而這一個過程我們難道不能將他看做是對程式碼段(code段)的寫 入嗎?好了,解壓完畢了。我們要從殼程式碼的區段JMP到原來的程式碼段的時候,難道不正是對程式碼段(code段)的執行嗎?

理清了上面的關係就好辦了,那麼如果載入OD後,我們直接對code段下記憶體訪問斷點的時候,一定會中斷在殼對code段的寫入的程式碼的上面,就像上面的 004AE247的這一行。而如果當他把code段的程式碼全部解壓解密完畢了以後,JMP到OEP的時候,我們是不是還可以停在OEP的程式碼上面呢?而且 每按下F9都會中斷,因為這時code段在執行中哦!

而如果你還要繼續問我為什麼一定要到那個地方才可以下斷呢?我難道不可以一開始就下斷嗎?

正入我上面所說的,如果你在前面下斷很可能殼對code段還沒解壓完畢呢,這時如果你不停的按F9,你將會看到OD的下方不斷的在提示你,“對 401000寫入中斷”“對401002寫入中斷”“對401004寫入中斷”.......如果你不介意按F9到他把正個code段寫完的話,我除了同 情你的“F9”以外,沒什麼其他的意見!

   那麼我們就沒有別更快一點的辦法了嗎?
   有的!那就是我們呼之欲出的兩次記憶體斷點辦法。
   怎麼理解兩次記憶體斷點呢?

讓我來做一個假設吧,假設我是一個殼的作者。一個EXE檔案的有code段,data段,rsrc段.....依次排列在你的記憶體空間中,那麼我會怎麼解 碼呢?呵呵~我比較笨一點,我會先將code段解碼,然後再將data段解壓,接著是rsrc段......那麼你不難發現,只要你在data斷或者 rsrc段下記憶體訪問斷點,那麼中斷的時候code段就已經解壓完畢了。這時我們再對code段下記憶體訪問斷點,不就可以到達OEP了嗎?

   這裡注意上面雖然下了兩次記憶體訪問斷點,但是本質是不一樣的,目的也是不一樣的。

1.對data段下記憶體訪問斷點而中斷是因為記憶體寫入中斷,目的是斷在對對data段的解壓時,這時殼要對data段寫資料,但是code段已經解壓 完畢。
2.對code段下記憶體訪問斷點而中斷是因為記憶體執行中斷,目的當然就是尋找OEP了。

總結一下:如果我們知道殼在什麼地方對code段解壓完畢我們就可以使用記憶體斷點,找到OEP。如果不知道,那麼我們就依靠2次記憶體斷點去找,如果還不行就用多次記憶體斷點。總之明白了原理在多次的記憶體斷點其實都一樣。從這個過程中我們瞭解的是殼在對區段解碼的順序!

相關推薦

ESP定律原理及其適用範圍

一.準備知識 在我們開始討論ESP定律之前,我先給你講解一下一些簡單的彙編知識。1.call這個命令是訪問子程式的一個彙編基本指令。也許你說,這個我早就知道了!別急請繼續看完。call真正的意義是什麼呢?我們可以這樣來理解:1.向堆疊中壓入下一行程式的地址;2.JMP到c

WebAPI常見的鑒權方法,及其適用範圍

安全 cat 足夠 是否 註入 前端 單純 它的 申請 在談這個問題之前,我們先來說說在WebAPI中保障接口請求合法性的常見辦法: API Key + API Secret cookie-session認證 OAuth JWT 當然還有很多其它的,比如

常見的幾種生命週期模型及其適用範圍

1.瀑布模型 瀑布模型有以下優點: 1)為專案提供了按階段劃分的檢查點。 2)當前一階段完成後,您只需要去關注後續階段。 3)可在迭代模型中應用瀑布模型。 增量迭代應用於瀑布模型。迭代1解決最大的問題。每次迭代產生一個可執行的版本,同時增加更多的功能。每次迭代必須經過質量和整合測試。 2瀑布

Canny邊緣檢測算法原理及其VC實現詳解(一)

常用 差分 實現圖 還需要 鏈接 傳感器 出了 關系 位置 轉自:http://blog.csdn.net/likezhaobin/article/details/6892176 圖象的邊緣是指圖象局部區域亮度變化顯著的部分,該區域的灰度剖面一般可以看作是一個階躍,既從

spring學習9 Spring工作原理及其作用

支持 上下 構建 並且 tro 配置管理 模塊 operate 有助於 1.springmvc請所有的請求都提交給DispatcherServlet,它會委托應用系統的其他模塊負責負責對請求進行真正的處理工作。   2.DispatcherServlet查詢一個或多個Han

淺談動態數組原理及其實現

縮小 vector 但是 align 幹什麽 可能 而不是 快速實現 param   stl中的vector是競賽中常用的容器,原因在於省內存,O(1)在後端插入和刪除、隨機下標訪問,今天就來談談它的實現。 最簡單的一個動態數組   動態數組並不是真正意義上的動態

[Go] sync.Pool 的實現原理適用場景

臨時 digg 簡單的 設置 com 運行 之前 結果 官方文檔 摘錄一: Go 1.3 的 sync 包中加入一個新特性:Pool。 官方文檔可以看這裏 http://golang.org/pkg/sync/#Pool 這個類設計的目的是用來保存和復用臨時對象,以減

rtmp和rtsp的區別和適用範圍

比較 www 實際應用 無損壓縮 使用 cnblogs tcp 參考 網頁 http://www.cnblogs.com/jiayayao/p/6536140.html 1.視頻傳輸   從網絡上接收視頻時首先要解協議(RTSP/RTMP/HTTP),然後是解格式(MK

交換機的原理及其配置(一)

存儲器 大於 fontsize 路由器 共享 pop ram 效率 機會 一。局域網交換機的基本功能 (1)交換機的基本概念 局域網交換機是一種工作在數據鏈路層的網絡設備。交換機依據進入port數據幀中的MAC地址,

拓撲排序的原理及其實現

還需要 play 結果集 3.0 硬幣 tps 進行 程序 微軟雅黑 本文將從以下幾個方面介紹拓撲排序: 拓撲排序的定義和前置條件 和離散數學中偏序/全序概念的聯系 典型實現算法 Kahn算法 基於DFS的算法 解的唯一性問題 實際例子 取材自以下材料:

DNS原理及其配置

dnsDNS----Domain Name System域名系統 工作原理: 作用: 1)將域名, 主機名解析成對應的IP地址 正向解析2)將IP地址解析成對應的主機名,域名 反向解析 DNS解析方式:遞歸客戶端只需要向DNS服務器發送一次請求叠代客戶端需要發

[逆向破解]使用ESP定律手動脫"中國菜刀"殼

eip 成了 失敗 -c 會同 方便 ebp 個人理解 cloc 0x00前言: ESC定律脫殼一般的加殼軟件在執行時,首先要初始化,保存環境(保存各個寄存器的值),一般利用PUSHAD(相當於把eax,ecx,edx,ebx,esp,ebp,esi,edi都壓棧

Java對象池技術的原理及其實現

問題 多種方式 等待 具體實現 tex sin 工作 程序 collect Java對象的生命周期分析  Java對象的生命周期大致包括三個階段:對象的創建,對象的使用,對象的清除。因此,對象的生命周期長度可用如下的表達式表示:T = T1 + T2 +T3。其中T1

PGP工作原理及其安全體制

打印 公鑰 密鑰環 see 特性 壓縮加密 解密 復制 bin 現代信息社會裏,當電子郵件廣受歡迎的同時,其安全性問題也很突出。實際上,電子郵件的傳遞過程是郵件在網絡上反復復制的過程,其網絡傳輸路徑不確定,很容易遭到不明身份者的竊取、篡改、冒用甚至惡意破壞,給收發雙方帶來麻

VMware中Bridged、NAT、host-only三種網絡連接模式的原理及其區別

only 交換機 兩臺電腦 及其 idg 網絡 原理 虛擬交換 臺電腦 VMnet0:這是VMware用於虛擬橋接網絡下的虛擬交換機;VMnet1:這是VMware用於虛擬Host-Only網絡下的虛擬交換機;VMnet8:這是VMware用於虛擬NAT網絡下的虛擬交換機;

DNS原理及其解析過程

一位 報文 body 手機客戶端 網絡通訊 sys 通訊 http 訪問網站 DNS原理及其解析過程 為什麽需要DNS解析域名為IP地址? 網絡通訊大部分是基於TCP/IP的,而TCP/IP是基於IP地址的,所以計算機在網絡上進行通訊時只能識別如“202.96.134.13

資源文件的適用範圍

源文件 -c pac clas body image files auto https 定義在哪個範圍,哪個範圍內可以識別資源文件的適用範圍

PoW挖礦算法原理及其在比特幣、以太坊中的實現

print 惡意攻擊 actions 規則 rom header() const state divisor PoW,全稱Proof of Work,即工作量證明,又稱挖礦。大部分公有鏈或虛擬貨幣,如比特幣、以太坊,均基於PoW算法,來實現其共識機制。即根據挖礦貢獻的有效工

探索HashMap實現原理及其在jdk8數據結構的改進

重點 his 說了 比較 filter new exist adf 網絡 因為網上已經太多的關於HashMap的相關文章了,為了避免大量重復,又由於網上關於java8的HashMap的相關文章比較少,至少我沒有找到比較詳細的。所以才有了本文。 本文主要的內容: 1.Ha

MYSQL復制原理及其流程

進制 寫入 發生 服務器 系統 串行化 -i 位置 數據分布 Mysql內建的復制功能是構建大型,高性能應用程序的基礎。將Mysql的數據分布到多個系統上去,這種分布的機制,是通過將Mysql的某一臺主機的數據復制到其他主機(slave)上,並重新執行一遍來實現的。復制過程