OD中的斷點與異常


文章一:http://blog.csdn.net/wowolook/article/details/7607206

1.前言

      在我跨入ollydbg的門的時候,就對ollydbg里面的各種斷點充滿了疑問,以前我總是不明白普通斷點,內存斷點,硬件斷點有什么區別,他們為什么有些時候不能混用,他們的原理是什么,在學習了前輩們的文章以后,終於明白了一些東西。希望這篇文章能讓你對硬件斷點的原理和使用有一些幫助

2.正文
--------------------------------------------------
    i.硬件斷點的原理

    在寄存器中,有這么一些寄存器,它們用於調試。人們把他們稱為調試寄存器,調試寄存器一共有8個名字分別從Dr0-Dr7。所以我們也把調試寄存器簡單的稱為Drx。

    對於Dr0-Dr3的四個調試寄存器,他們的作用是存放中斷的地址,例如:401000
    對於Dr4,Dr5這兩個寄存器我們一般不使用他們,保留
    對於Dr6,Dr7這兩個寄存器的作用是用來記錄你在Dr0-Dr3中下斷的地址的屬性,比如:對這個401000是硬件讀還是寫,或者是執行;是對字節還是對字,或者是雙字。

    好了,從這里你可能明白一些東西。
   
1.    為什么在OD里面只能下4個硬件斷點? 
2.    為什么下硬件斷點有byte,word,dword只分?
3.    為什么下硬件斷點有讀,寫,執行只分?

    ii.關於F4,F8,F7,F2的區別
   
    在ollydbug的help里面只是提到如何使用F7和F8的使用,並沒說明他們的實現原理

    現在我們來做一個實驗

實驗一(F4的原理)

1.隨便找一個程序,載入OD,構造一個死循環

就象這樣:

00400154   >   90                nop                                    //EP停在這里
00400155      90                nop
00400156      90                nop
00400157      90                nop
00400158    ^ EB FA             jmp short 天2國際.<ModuleEntryPoint>   //構造一個死循環
0040015A      61                popad
0040015B      94                xchg eax,esp

2.對0040015A這一行按下F4,由於死循環,程序一直運行

3.調試器的窗口里,右鍵--查看調試寄存器

結果在Drx里面顯示:

DR0 0040015A                       //地址
DR1 00000000
DR2 00000000
DR3 00000000
DR6 FFFF0FF0                      //斷點屬性
DR7 00000401

實驗二(F8原理)

1.隨便找一個程序,載入OD,構造一個子程序的死循環

就像這樣

00400154 t>   E8 0100D03F       call 4010015A          //EP,停在這里
00400159      90                nop
0040015A      90                nop               
0040015B      90                nop
0040015C      90                nop                 //對這里下F2斷點
0040015D      C3                retn               // 返回

2.按下F8,由於INT3斷點,程序中斷在0040015C

3.調試器的窗口里,右鍵--查看調試寄存器

結果在Drx里面顯示:

DR0 00400159                              //call的返回地址
DR1 00000000
DR2 00000000
DR3 00000000
DR6 FFFF4FF1                           //斷點屬性
DR7 00000401


實驗三(F7原理)

1.隨便找一個程序,載入OD

2.雙擊調試器的窗口里的T標志,將TF從原來的0變成1

3.F9運行

結果程序斷在了下面的一行

實驗四(F2的原理)

1.用98的notepad吧,載入OD,構造一個死循環

004010CC N>   90                nop                                  //EP,挺在這里
004010CD      90                nop
004010CE    ^ EB FC             jmp short NOTEPAD.<ModuleEntryPoint> //死循環
004010D0      90                nop                                 //在這里按下F2,普通斷點
004010D1      90                nop

2.按下F9,由於死循環,程序一直運行着

3.使用LordPE(不要用ollydump)將這個程序dump下來

4.重新載入OD

來看看成什么樣子了

004010CC d> $   90              nop
004010CD     .   90              nop
004010CE     .^ EB FC           jmp short dumped.<ModuleEntryPoint>
004010D0        CC              int3                                   //這里變成了CC了
004010D1        90              nop

--------------------------------------------------

3.總結

 從實驗一和實驗二我們能清楚的看到,F4是直接將該行的地址放入drx里面,F8是將下一行的地址放入到drx里面,他們都使用了調試寄存器。從實驗三中我們知道對於F7來說很可能使用的是將TF置一的辦法,也就是說當我們按下F7的時候OD把TF置一。對於F2來說他是將,第一個字節悄悄的修改成了CC,雖然並沒有顯示給我看到這個是一個CC,當我們按下F2的時候,OD還沒有運行,只是把這個表示記錄下來,當運行的時候他就把所有標記的字節修改了,盡管還是顯示原來的代碼,當然當他一暫停下來就又修改回來了。
   
上面的是實驗中,F7的原理只是猜測,還沒有很好的辦法能證明他就是使用TF,下面我繼續猜測一下內存斷點的原理

1.將設置的內存斷點的地址記錄下來

2.對這個地址的內存頁面修改其屬性

如果是內存寫斷點,就修改為RE(可讀,可執行)
如果是內存訪問斷點,就修改為NO ACCESS(不可訪問)

3.只要訪問到這個頁面就會產生相應的異常,然后由OD來判斷是否與記錄的斷點一致,從而是否中斷下來
   
--------------------------------------------------
4.后話

      對於上面的F7和內存斷點的原理,我還沒想出什么好的辦法去找出OD的原理,或許去調試一下ollydbg.exe是一個不錯的建議。如果有哪位兄弟知道有什么好辦法,希望能告訴我。當然也很歡迎各位和我討論。

 

文章二:http://www.voidcn.com/blog/nightsay/article/p-3414045.html

今天繼續接着上次的分析,來繼續分析OD原理,這次先分析OD最基本的功能,斷點,單步和運行到指定位置。

類似的文章前輩們已經寫了很多了,這里只是將前輩們的思路實踐了一下,順便加入一點自己的理解和認識!

一般載入OD之后,往往大家會先下斷點,或者直接單步運行。

一般當我們着手分析一個程序的時候總是會下一個INT 3斷點,其實這個就是F2的原理

隨便載入一個程序,點一下F2,然后用ollydbg保存的時候,發現提示說是文件未被修改,其實這個也能理解,因為我們按下F2的時候,程序還沒被運行,所以dump下來吧,但是dump需要要求程序連同f2能夠斷下,所以改一下程序:

構建一個這樣的死循環,這樣,程序在運行的時候會一直在013B2165前運行,而斷點在后,內存中斷點被記錄,所以dump下來就可以看到程序的變化

Dump下重新加載:

 

Int 3粗線了,原理得證明(基址加載的時候肯定會變化)

 

 

F4原理:

改一個這樣的程序

 

 

看一下調試寄存器

 

F4后將F4地址放在了調試寄存器里,運行程序的時候就會中斷到那個地方

 

 

F8(步過)原理:

隨便寫一個程序,然后修改一下匯編,使之構成一個循環

 

00F11DE8處F2斷點

在函數的時候F8步過,發現函數停在00F11DE8處,然后在調試窗口右擊查看調試寄存器,發現

 

關於調試寄存器,具體說明請看裝載的這篇文章,

有了對調試寄存器大致的了解之后,貌似我們弄懂了一些在逆向時候的問題

比如為什么硬件斷點只能有4個(只有4個調試寄存器)

我們發現在DR0處存放了一個中斷地址,但是這個地址不是F2斷的地方,而是函數的下一條地址,那么在單步的時候,我們在查看一下調試寄存器:

發現調試寄存器根本沒有變化,其實這個很好理解,因為在沒有執行到函數之前的F8其實就是相當於F2功能

 

F7原理:步入

這個說法不一,查詢了前輩們的說法,認為是標志寄存器T的原因:

TF被設置位1時,CPU進入單步模式,所謂單步模式就是CPU在每執行一步指令后都產生一個單步中斷。主要用於程序的調試。8086/8088中沒有專門用來置位和清零TF的命令,需要用其他辦法。

自己想了一個方法證明:

構造一個這樣的循環:

 

 

 

在運行到call的時候,改變T的標志位,然后直接讓程序運行,發現程序停在開始處,得證。

 

在這和之后,在貼一段前輩們的總結:

TF置1:程序將斷在下一條原子操作處,並將TF位清零。原子操作是指不會被線程調度機制打斷的操作;這種操作一旦開始,就一直運行倒結束,中間不會有任何 context switch (切換到另一個線程)。call指令是原子操作,它的作用是:將返回地址壓棧,並跳轉。所以,在調用call的時候,如果我們將TF置1,那么程序將在call指令的功能完成以后(即將返回地址壓棧並跳轉)斷下來。而執行call內的語句則僅僅是call的邏輯功能(我們理解的功能),並非實際的功能(CPU理解的功能)。

 

 

 

以上差不多硬件斷點的一些原理都介紹了,驗證的方法其實就是怎么去構造那段匯編代碼,其實這個也很好想啊,想驗證對函數的操作,步入或者步過,就要構造一個call啊,想要了解運行到斷點處和光標處,就要想着讓他跳轉啊,所以有jmp,然后之所以都構成循環,是因為讓程序停在我們需要驗證的地方啊。

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM