乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      【原創(chuàng)】OllyDBG分析報(bào)告系列(1)

       herowuking 2015-05-31
      標(biāo) 題: 【原創(chuàng)】OllyDBG分析報(bào)告系列(1)---Int3斷點(diǎn)
      作 者: driverox
      時(shí) 間: 2008-05-19,16:45:43
      鏈 接: http://bbs./showthread.php?t=65094

      最近學(xué)習(xí)逆向,對OD本身做了個(gè)逆向,也算是一個(gè)小小的鍛煉吧。呵呵,在這里以分析報(bào)告的形式貼出來,請大家批評指正。謝謝。

      Ollydbg(以下均簡稱為OD)中的Int3斷點(diǎn)的主要功能是:在需要下斷點(diǎn)的執(zhí)行代碼處將原來的代碼改成0xCC,程序執(zhí)行到此處后會(huì)報(bào)一個(gè)Int3異常,由OD捕獲并處理。當(dāng)要執(zhí)行該行代碼時(shí),將原來的代碼改回來并執(zhí)行,然后再恢復(fù)斷點(diǎn),這樣就不會(huì)影響程序的正常運(yùn)行了。
      這里僅描述最常見的功能,其它的有興趣的話可以分析一把。

      先說明一下OD中的兩個(gè)結(jié)構(gòu)體,在IDA中,聲明為如下格式:
      t_bpoint用來保存Int斷點(diǎn)的相關(guān)信息
      00000000 t_bpoint        struc ; (sizeof=0x11)
      00000000 addr         dd ?                    ; // Address of breakpoint
      00000004 dummy      dd ?                    ; // Always 1
      00000008 type         dd ?                    ; // Type of breakpoint, TY_xxx
      0000000C cmd         db ?                    ; // Old value of command
      0000000D passcount    dd ?                    ; // Actual pass count
      00000011 t_bpoint        ends
      其中:addr為斷點(diǎn)的地址,dummy始終為1,type為斷點(diǎn)的類型,cmd為要用0xCC替換的指令碼,passcount為需要斷下的次數(shù),0表示每次都斷下。

      t_sorted結(jié)構(gòu)體保存了一種有序的數(shù)據(jù):
      00000000 ; Descriptor of sorted table
      00000000 t_sorted        struc ; (sizeof=0x138)
      00000000 name[MAXPATH]   db 260 dup(?)     ; char  Name of table, as appears in error messages
      00000104 n               dd ?                    ; int  Actual number of entries
      00000108 nmax            dd ?                    ; int  Maximal number of entries
      0000010C selected        dd ?                    ; int  Index of selected entry or -1
      00000110 seladdr         dd ?                    ; ulong  Base address of selected entry
      00000114 itemsize        dd ?                    ; int  Size of single entry
      00000118 version         dd ?                    ; ulong  Unique version of table
      0000011C data            dd ?                    ; void*  Elements, sorted by address
      00000120 sortfunc        dd ?                  ; SORTFUNC  Function which sorts data or NULL
      00000124 destfunc        dd ?                    ; DESTFUNC  Destructor function or NULL
      00000128 sort            dd ?                    ; int  Sorting criterium (column)
      0000012C sorted          dd ?                    ; int  Whether indexes are sorted
      00000130 index           dd ?                    ; int  Indexes, sorted by criterium
      00000134 suppresserr     dd ?                    ; int  Suppress multiple overflow errors
      00000138 t_sorted        ends
      name是結(jié)構(gòu)體的名稱,用來區(qū)別不同類型的結(jié)構(gòu)體
      n是數(shù)組元素的個(gè)數(shù)
      itemsize是數(shù)組元素的大小
      data 是指向各種數(shù)據(jù)結(jié)構(gòu)數(shù)組的指針,這里使用的是int3斷點(diǎn),所以現(xiàn)在保存的是int3斷點(diǎn)數(shù)據(jù)結(jié)構(gòu)體數(shù)組的指針
      ---------------------------------------------------------------------------------------------------------------------------------

      1)Int3斷點(diǎn)的設(shè)置
      int3斷點(diǎn)的設(shè)置是通過消息來處理的,對應(yīng)右鍵點(diǎn)擊菜單中的切換,其對應(yīng)的消息為1E;此外還有熱鍵F2、雙擊反匯編窗口等也能切換int3斷點(diǎn),轉(zhuǎn)入的函數(shù)雖然不同,但是調(diào)用設(shè)置int3斷點(diǎn)的函數(shù)都是同一個(gè),就不再舉例了。傳入相應(yīng)參數(shù)調(diào)用函數(shù)00419974,改變int3斷點(diǎn),該函數(shù)的調(diào)用處如下:
      004237C8   .  51                    push    ecx    ; |Arg6
      004237C9   .  50                    push    eax    ; |Arg5 => 00000002
      004237CA   .  6A 00                 push    0      ; |Arg4 = 00000000
      004237CC   .  6A 00                 push    0      ; |Arg3 = 00000000
      004237CE   .  6A 71                 push    71     ; |Arg2 = 00000071
      004237D0   .  52                    push    edx    ; |Arg1 => 0040100C
      004237D1   .  E8 9E61FFFF           call    00419974   ; \OLLYDBG.00419974

      下面主要來分析上述的00419974這個(gè)函數(shù),經(jīng)過分析可知大致主要流程為:

      1.    判斷是否配置了“Warn when break not in code”為1,若為1的話,程序會(huì)先判斷所下斷點(diǎn)是否在代碼區(qū),不在的話,會(huì)顯示警告消息,若用戶選擇繼續(xù),則會(huì)斷下,否則退出;
      2.    若沒有配置上面的項(xiàng)目,則首先獲得斷點(diǎn)的類型(即斷點(diǎn)類型的高位是否為2,若為2則刪除斷點(diǎn),不為2則設(shè)置斷點(diǎn)),檢查該地址的斷點(diǎn)是否已經(jīng)存在,若存在,則刪除斷點(diǎn),并退出;
      3.    若該地址處無Int3斷點(diǎn),則設(shè)置斷點(diǎn),使用的是Setbreakpointext函數(shù),其流程如下:
      a)  獲得斷點(diǎn)在調(diào)試進(jìn)程中實(shí)際地址;
      b)  判斷指令碼是否有效(判斷規(guī)則是:指令碼與1F做與運(yùn)算之后為3或13的時(shí)候,說明是斷在指令碼中間;1D、1E、1F是正常指令碼,除此之外,其它的都是無法執(zhí)行的指令碼),無效的話,重新設(shè)置CPU窗口,顯示錯(cuò)誤提示并退出;
      c)  在t_sorted結(jié)構(gòu)中查找斷點(diǎn)數(shù)據(jù);
      d)  若t_sorted中不存在該斷點(diǎn),則添加;
      e)  判斷被調(diào)試進(jìn)程是否在運(yùn)行狀態(tài),若在運(yùn)行,則把所有的線程都掛起;
      f)  讀取斷點(diǎn)所在地址的內(nèi)存,若讀取成功的話,調(diào)用WriteMemory寫入0xCC斷點(diǎn)(跟入WriteMemory后,發(fā)現(xiàn)是調(diào)用WriteProcessMemory這個(gè)API函數(shù)來下Int3斷點(diǎn)的);
      g)  恢復(fù)線程運(yùn)行;
      h)  顯示信息在窗口中;
      4.  若設(shè)置斷點(diǎn)成功,則插入name并做其它的一些判斷與顯示操作,進(jìn)而退出;

      保存現(xiàn)場,提升棧幀空間,用于存放局部變量:
      00419974  /$  55         push    ebp
      00419975  |.  8BEC       mov     ebp, esp
      00419977  |.  81C4 F8FBF>add     esp, -408
      0041997D  |.  53         push    ebx
      0041997E  |.  56         push    esi
      0041997F  |.  57         push    edi
      檢查OD配置文件中的   “Warn when break not in code”是否為1,1為真,0為假,若上面的配置為0,則跳到下面的處理代碼中:
      00419980  |.  8B7D 14    mov     edi, dword ptr [ebp+14]
      00419983  |.  8B5D 08    mov     ebx, dword ptr [ebp+8]
      00419986  |.  833D C4574>cmp     dword ptr [4D57C4], 0  ; 4D57C4--Warn when break not in code
      0041998D  |.  74 5E      je      short 004199ED  ;為0則跳轉(zhuǎn)到下面的處理代碼
      檢查傳入的參數(shù)是否正確:
      0041998F  |.  837D 0C 71 cmp     dword ptr [ebp+C], 71
      00419993  |.  75 12      jnz     short 004199A7
      00419995  |.  837D 10 00 cmp     dword ptr [ebp+10], 0
      00419999  |.  75 0C      jnz     short 004199A7
      先在t_sorted列表中查找int3斷點(diǎn),找不到返回8,并跳過取得模塊信息部分:
      0041999B  |.  53         push    ebx
      0041999C  |.  E8 D703000>call    _Getbreakpointtype
      004199A1  |.  F6C4 02    test    ah, 2    ;檢查返回值是否為20h
      004199A4  |.  59         pop     ecx
      004199A5  |.  75 46      jnz     short 004199ED  ;不是則跳過取得模塊信息部分
      取得模塊信息,并檢查是否取得,若取得失敗則跳轉(zhuǎn)到顯示斷點(diǎn)錯(cuò)誤消息分支:
      004199A7  |>  53         push    ebx                       ; /Arg1
      004199A8  |.  E8 6B44040>call    _Findmodule               ; \_Findmodule
      004199AD  |.  59         pop     ecx
      004199AE  |.  8BF0       mov     esi, eax
      004199B0  |.  85C0       test    eax, eax  ;檢查是否得到模塊信息
      004199B2  |.  74 0F      je      short 004199C3  ;沒有得到則跳轉(zhuǎn)到下面錯(cuò)誤顯示分支
      004199B4  |.  3B5E 0C    cmp     ebx, dword ptr [esi+C]
      004199B7  |.  72 0A      jb      short 004199C3
      004199B9  |.  8B56 0C    mov     edx, dword ptr [esi+C]
      004199BC  |.  0356 10    add     edx, dword ptr [esi+10]
      004199BF  |.  3BDA       cmp     ebx, edx
      004199C1  |.  72 2A      jb      short 004199ED
      顯示斷點(diǎn)錯(cuò)誤消息,若用戶選擇Yes則繼續(xù),否則退出:
      004199C3  |>  68 2421000>push    2124                              ; /Style = MB_YESNO
      004199C8  |.  68 40274B0>push    004B2740                           ; |Title
      004199CD  |.  68 C3284B0>push    004B28C3                          ; |Text
      004199D2  |.  8B0D 7C3B4>mov     ecx, dword ptr [4D3B7C]              ; |
      004199D8  |.  51         push    ecx                               ; |hOwner
      004199D9  |.  E8 385B090>call    <jmp.&USER32.MessageBoxA>           ; \MessageBoxA
      004199DE  |.  8BF0       mov     esi, eax
      004199E0  |.  83FE 06    cmp     esi, 6
      004199E3  |.  74 08      je      short 004199ED
      004199E5  |.  83C8 FF    or      eax, FFFFFFFF  ;返回-1
      004199E8  |.  E9 8403000>jmp     00419D71  ;跳轉(zhuǎn)到結(jié)束處
      得到該地址int3斷點(diǎn)的屬性,如果已經(jīng)設(shè)置了int3斷點(diǎn),則將其刪除并跳轉(zhuǎn)到結(jié)束處;若沒有設(shè)置,則跳過刪除部分代碼:
      004199ED  |>  837D 0C 71 cmp     dword ptr [ebp+C], 71
      004199F1  |.  0F85 24020>jnz     00419C1B
      004199F7  |.  837D 10 00 cmp     dword ptr [ebp+10], 0
      004199FB  |.  75 20      jnz     short 00419A1D
      004199FD  |.  53         push    ebx
      004199FE  |.  E8 7503000>call    _Getbreakpointtype  ;得到該地址的int3斷點(diǎn)的屬性
      00419A03  |.  F6C4 02    test    ah, 2    ;比較是否已經(jīng)設(shè)置了int3斷點(diǎn)
      00419A06  |.  59         pop     ecx
      00419A07  |.  74 14      je      short 00419A1D  ;若沒有設(shè)置則跳過刪除斷點(diǎn)的代碼
      00419A09  |.  6A 00      push    0                         ; /Arg3 = 00000000
      00419A0B  |.  8D53 01    lea     edx, dword ptr [ebx+1]    ; |
      00419A0E  |.  52         push    edx                       ; |Arg2
      00419A0F  |.  53         push    ebx                       ; |Arg1
      00419A10  |.  E8 03FBFFF>call    _Deletebreakpoints        ; \_Deletebreakpoints
      00419A15  |.  83C4 0C    add     esp, 0C
      00419A18  |.  E9 4103000>jmp     00419D5E
      在這里有對傳入?yún)?shù)的一個(gè)比較,但是測試時(shí)無法得到0以外的值,所以無法確定該參數(shù)的作用,這樣也無法測試00419A6D后面的代碼所表示的意義:
      00419A1D  |>  837D 10 00 cmp     dword ptr [ebp+10], 0
      00419A21  |.  75 4A      jnz     short 00419A6D
      這里就是設(shè)置int3斷點(diǎn)的函數(shù),將地址傳入即可:
      00419A23  |.  6A 00      push    0                         ; /Arg4 = 00000000
      00419A25  |.  6A 00      push    0                         ; |Arg3 = 00000000
      00419A27  |.  68 0002020>push    20200                     ; |Arg2 = 00020200
      00419A2C  |.  53         push    ebx                       ; |Arg1
      00419A2D  |.  E8 2EFBFFF>call    _Setbreakpointext         ; \_Setbreakpointext
      00419A32  |.  83C4 10    add     esp, 10
      設(shè)置完int3斷點(diǎn)后,刪除int3斷點(diǎn)處的name屬性為38h、3Ch、3Bh以及30h的name,然后跳轉(zhuǎn)到結(jié)束廣播處:
      00419A35  |.  8D73 01    lea     esi, dword ptr [ebx+1]
      00419A38  |.  6A 38      push    38                        ; /Arg3 = 00000038
      00419A3A  |.  56         push    esi                       ; |Arg2
      00419A3B  |.  53         push    ebx                       ; |Arg1
      00419A3C  |.  E8 87B5040>call    _Deletenamerange          ; \_Deletenamerange
      00419A41  |.  83C4 0C    add     esp, 0C
      00419A44  |.  6A 3C      push    3C                        ; /Arg3 = 0000003C
      00419A46  |.  56         push    esi                       ; |Arg2
      00419A47  |.  53         push    ebx                       ; |Arg1
      00419A48  |.  E8 7BB5040>call    _Deletenamerange          ; \_Deletenamerange
      00419A4D  |.  83C4 0C    add     esp, 0C
      00419A50  |.  6A 3B      push    3B                        ; /Arg3 = 0000003B
      00419A52  |.  56         push    esi                       ; |Arg2
      00419A53  |.  53         push    ebx                       ; |Arg1
      00419A54  |.  E8 6FB5040>call    _Deletenamerange          ; \_Deletenamerange
      00419A59  |.  83C4 0C    add     esp, 0C
      00419A5C  |.  6A 30      push    30                        ; /Arg3 = 00000030
      00419A5E  |.  56         push    esi                       ; |Arg2
      00419A5F  |.  53         push    ebx                       ; |Arg1
      00419A60  |.  E8 63B5040>call    _Deletenamerange          ; \_Deletenamerange
      00419A65  |.  83C4 0C    add     esp, 0C
      00419A68  |.  E9 F102000>jmp     00419D5E      ;跳轉(zhuǎn)到結(jié)束廣播處
      這部分省略的代碼無法得知其調(diào)用的必要條件,不過里面的內(nèi)容跟上面相似,都是通過判斷來設(shè)置int3斷點(diǎn),這里就不再詳細(xì)說明了:
      ……
      ……
      向子窗體發(fā)送廣播,要求更新所有子窗口:
      00419D5E  |>  6A 00      push    0                         ; /Arg3 = 00000000
      00419D60  |.  6A 00      push    0                         ; |Arg2 = 00000000
      00419D62  |.  68 7404000>push    474                       ; |Arg1 = 00000474
      00419D67  |.  E8 0807040>call    _Broadcast                ; \_Broadcast
      00419D6C  |.  83C4 0C    add     esp, 0C
      最后返回0,并且恢復(fù)現(xiàn)場:
      00419D6F  |.  33C0       xor     eax, eax
      00419D71  |>  5F         pop     edi
      00419D72  |.  5E         pop     esi
      00419D73  |.  5B         pop     ebx
      00419D74  |.  8BE5       mov     esp, ebp
      00419D76  |.  5D         pop     ebp
      00419D77  \.  C3         retn

      2)Int3斷點(diǎn)的處理
      Int3斷點(diǎn)處理的大致流程是:
      1、  獲取當(dāng)前寄存器的信息,重點(diǎn)是Eip的值
      2、  根據(jù)Int3斷點(diǎn)的類型(0xCC或0xCD03)回溯指針地址
      3、  觸發(fā)Int3異常,被調(diào)試程序斷下;
      4、  若繼續(xù)跑的話,則恢復(fù)原有的指令,讓被調(diào)試程序正確執(zhí)行指令;
      5、  走完正確指令之后,再重新設(shè)置指令為Int3斷點(diǎn);

      在OD中有一個(gè)處理所有異常的函數(shù)42EBD0,從該函數(shù)入手分析Int3斷點(diǎn)的處理。
      0042EBD0  /$  55            push    ebp
      0042EBD1  |.  8BEC          mov     ebp, esp
      0042EBD3  |.  81C4 04F0FFFF add     esp, -0FFC
      0042EBD9  |.  50            push    eax
      0042EBDA  |.  81C4 00F5FFFF add     esp, -0B00
      0042EBE0  |.  53            push    ebx
      0042EBE1  |.  56            push    esi
      0042EBE2  |.  57            push    edi  ;以上是開棧幀代碼

      0042EBE3  |.  8B35 1C574D00 mov     esi, dword ptr [4D571C] ;4D571C為全局變量,保存的是DebugEvent.dwThreadId
      0042EBE9  |.  56            push    esi
      0042EBEA  |.  E8 5DF8FFFF   call    0042E44C
      函數(shù)42E44C的主要功能描述如下:

      函數(shù)功能:通過GetThreadContext的方法獲得線程的上下文環(huán)境,把該環(huán)境保存
                至OD線程信息結(jié)構(gòu)中的reg字段中,若oldreg已經(jīng)失效,則復(fù)制reg的
                值到oldreg中。
                若被調(diào)試進(jìn)程有多個(gè)線程,則循環(huán)取值,保存至OD線程信息結(jié)構(gòu)數(shù)組中。
      傳入?yún)?shù):DebugEvent.dwThreadId 
      返回值  :成功時(shí)為保存在OD線程信息結(jié)構(gòu)中的當(dāng)前寄存器信息結(jié)構(gòu)的指針(主線程)
                失敗返回0

      這里說到了兩個(gè)結(jié)構(gòu)體,在IDA中描述如下:
      00000000 t_reg           struc ; (sizeof=0x196)    ;保存寄存器信息
      00000000 r_modified      dd ?                    ; // Some regs modified, update context
      00000004 r_modifiedbyuser dd ?                   ; // Among modified, some modified by user
      00000008 r_singlestep    dd ?                    ; // Type of single step, SS_xxx
      0000000C r_EAX           dd ?
      00000010 r_ECX           dd ?
      00000014 r_EDX           dd ?
      00000018 r_EBX           dd ?
      0000001C r_ESP           dd ?
      00000020 r_EBP           dd ?
      00000024 r_ESI           dd ?
      00000028 r_EDI           dd ?
      0000002C r_EIP           dd ?                    ; // Instruction pointer (EIP)
      00000030 r_EFlags        dd ?                    ; // Flags
      00000034 r_top           dd ?                    ; // Index of top-of-stack
      00000038 r_long_double   db 80 dup(?)            ; // Float registers, f[top] - top of stack
      00000088 r_tag           db 8 dup(?)             ; // Float tags (0x3 - empty register)
      00000090 r_fst           dd ?                    ; // FPU status word
      00000094 r_fcw           dd ?                    ; // FPU control word
      00000098 r_ES            dd ?
      0000009C r_CS            dd ?
      000000A0 r_SS            dd ?
      000000A4 r_DS            dd ?
      000000A8 r_FS            dd ?
      000000AC r_GS            dd ?
      000000B0 r_base          dd 6 dup(?)             ; // Segment bases
      000000C8 r_limit         dd 6 dup(?)             ; // Segment limits
      000000E0 r_big           db 6 dup(?)             ; // Default size (0-16, 1-32 bit)
      000000E6 r_dr6           dd ?                    ; // Debug register DR6
      000000EA r_threadid      dd ?                    ; // ID of thread that owns registers
      000000EE r_lasterror     dd ?                    ; // Last thread error or 0xFFFFFFFF
      000000F2 r_ssevalid      dd ?                    ; // Whether SSE registers valid
      000000F6 r_ssemodified   dd ?                    ; // Whether SSE registers modified
      000000FA r_ssereg        db 128 dup(?)           ; // SSE registers
      0000017A r_mxcsr         dd ?                    ; // SSE control and status register
      0000017E r_selected      dd ?                    ; // Reports selected register to plugin
      00000182 r_dr0           dd ?                    ; // Debug registers DR0..DR3
      00000186 r_dr1           dd ?
      0000018A r_dr2           dd ?
      0000018E r_dr3           dd ?
      00000192 r_dr7           dd ?                    ; // Debug register DR7
      00000196 t_reg           ends
      00000196
      00000000 ; ---------------------------------------------------------------------------
      00000000
      00000000 t_thread        struc ; (sizeof=0x66C)  ;保存線程信息,同時(shí)有新舊兩份reg值,可以用來在OD的寄存器窗口為改變的值設(shè)置顏色等功能。
      00000000 th_threadid     dd ?                    ; // Thread identifier
      00000004 th_dummy        dd ?                    ; // Always 1
      00000008 th_type         dd ?                    ; // Service information, TY_xxx
      0000000C th_thread       dd ?                    ; // Thread handle
      00000010 th_datablock    dd ?                    ; // Per-thread data block
      00000014 th_entry        dd ?                    ; // Thread entry point
      00000018 th_stacktop     dd ?                    ; // Working variable of Listmemory()
      0000001C th_stackbottom  dd ?                    ; // Working variable of Listmemory()
      00000020 th_context      CONTEXT ?               ; // Actual context of the thread
      000002EC th_reg          t_reg ?                 ; // Actual contents of registers
      00000482 th_regvalid     dd ?                    ; // Whether reg is valid
      00000486 th_oldreg       t_reg ?                 ; // Previous contents of registers
      0000061C th_oldregvalid  dd ?                    ; // Whether oldreg is valid
      00000620 th_suspendcount dd ?                    ; // Suspension count (may be negative)
      00000624 th_usertime     dd ?                    ; // Time in user mode, 1/10th ms, or -1
      00000628 th_systime      dd ?                    ; // Time in system mode, 1/10th ms, or -1
      0000062C th_reserved     dd 16 dup(?)            ; // Reserved for future compatibility
      0000066C t_thread        ends


      下面的代碼是:
      0042EBEF  |.  8BF8               mov     edi, eax
      0042EBF1  |.  8B45 08            mov     eax, dword ptr [ebp+8]
      0042EBF4  |.  59                 pop     ecx
      0042EBF5  |.  8938               mov     dword ptr [eax], edi
      0042EBF7  |.  8B15 14574D00      mov     edx, dword ptr [4D5714]   ; 4D5714中保存的是調(diào)試事件的代碼DebugEvent.dwDebugEventCode
      0042EBFD  |.  83FA 09            cmp     edx, 9                 ;  Switch (cases 1..9)
      0042EC00  |.  0F87 EE270000      ja      004313F4
      0042EC06  |.  FF2495 0DEC4200    jmp     dword ptr [edx*4+42EC0D]  ; 這里是switch跳轉(zhuǎn)
      用來判斷是何種異常:
      0042EC0D  |.  F4134300           dd      OLLYDBG.004313F4  ; EXCEPTION_DEBUG_EVENT
      0042EC11  |. |35EC4200           dd      OLLYDBG.0042EC35
      0042EC15  |. |FF0C4300           dd      OLLYDBG.00430CFF
      0042EC19  |. |D70D4300           dd      OLLYDBG.00430DD7
      0042EC1D  |. |3F0F4300           dd      OLLYDBG.00430F3F
      0042EC21  |. |37104300           dd      OLLYDBG.00431037
      0042EC25  |. |2D114300           dd      OLLYDBG.0043112D
      0042EC29  |. |B7114300           dd      OLLYDBG.004311B7
      0042EC2D  |. |76124300           dd      OLLYDBG.00431276
      0042EC31  |. |C7134300           dd      OLLYDBG.004313C7

      0042EC35  |> \8B0D 0C364E00      mov     ecx, dword ptr [4E360C]              ;  Case 1 of switch 0042EBFD
      0042EC3B  |.  33C0               xor     eax, eax
      0042EC3D  |.  894D EC            mov     dword ptr [ebp-14], ecx
      0042EC40  |.  A3 0C364E00        mov     dword ptr [4E360C], eax
      0042EC45  |.  C745 A4 20574D00   mov     dword ptr [ebp-5C], 004D5720
      0042EC4C  |.  85FF               test    edi, edi  ;檢查主線程中是否有當(dāng)前寄存器的信息;
      0042EC4E  |.  75 0D              jnz     short 0042EC5D
      0042EC50  |.  8B55 A4            mov     edx, dword ptr [ebp-5C]
      0042EC53  |.  33DB               xor     ebx, ebx
      0042EC55  |.  8B4A 0C            mov     ecx, dword ptr [edx+C]
      0042EC58  |.  894D D8            mov     dword ptr [ebp-28], ecx
      0042EC5B  |.  EB 22              jmp     short 0042EC7F
      0042EC5D  |>  8B47 2C            mov     eax, dword ptr [edi+2C]              ;  ntdll.7C921231
      0042EC60  |.  8945 D8            mov     dword ptr [ebp-28], eax  ;這一段是把異常地址賦給局部變量ebp-28
      0042EC63  |.  837D EC 00         cmp     dword ptr [ebp-14], 0
      0042EC67  |.  8B5F 10            mov     ebx, dword ptr [edi+10]
      0042EC6A  |.  74 13              je      short 0042EC7F

      以下代碼是判斷產(chǎn)生中斷的指令碼是0xCC還是0xCD03,若是0xCC,則指令碼要回溯1(因?yàn)镋ip指向下一條指令,回溯后才是正確的斷點(diǎn)地址),若是0xCD03,則指令碼要回溯2,其它的不回溯。
      0042EC6C  |.  F647 31 01         test    byte ptr [edi+31], 1
      0042EC70  |.  74 0D              je      short 0042EC7F
      0042EC72  |.  8167 30 FFFEFFFF   and     dword ptr [edi+30], FFFFFEFF
      0042EC79  |.  C707 01000000      mov     dword ptr [edi], 1
      0042EC7F  |>  8B45 A4            mov     eax, dword ptr [ebp-5C]
      0042EC82  |.  8138 03000080      cmp     dword ptr [eax], 80000003          ;  Int3中斷
      0042EC88  |.  74 07              je      short 0042EC91
      0042EC8A  |.  33D2               xor     edx, edx
      0042EC8C  |.  8955 DC            mov     dword ptr [ebp-24], edx
      0042EC8F  |.  EB 79              jmp     short 0042ED0A
      0042EC91  |>  6A 02              push    2                         ; /Arg4 = 00000002
      0042EC93  |.  6A 01              push    1                         ; |Arg3 = 00000001
      0042EC95  |.  8B4D D8            mov     ecx, dword ptr [ebp-28]             ; |
      0042EC98  |.  49                 dec     ecx                   ; |減一是讓指令碼回溯
      0042EC99  |.  51                 push    ecx                              ; |Arg2
      0042EC9A  |.  8D45 BB            lea     eax, dword ptr [ebp-45]              ; |
      0042EC9D  |.  50                 push    eax                              ; |Arg1
      0042EC9E  |.  E8 69260300        call    _Readmemory                 ; \_Readmemory
      0042ECA3  |.  83C4 10            add     esp, 10
      0042ECA6  |.  83F8 01            cmp     eax, 1
      0042ECA9  |.  74 07              je      short 0042ECB2
      0042ECAB  |.  33D2               xor     edx, edx
      0042ECAD  |.  8955 DC            mov     dword ptr [ebp-24], edx
      0042ECB0  |.  EB 58              jmp     short 0042ED0A
      0042ECB2  |>  33C0               xor     eax, eax
      0042ECB4  |.  8A45 BB            mov     al, byte ptr [ebp-45]
      0042ECB7  |.  3D CC000000        cmp     eax, 0CC
      0042ECBC  |.  75 09              jnz     short 0042ECC7
      0042ECBE  |.  C745 DC 01000000   mov     dword ptr [ebp-24], 1        ;  若Readmemory在斷點(diǎn)地址讀的指令碼是CC的話,ebp-24設(shè)為1---ebp-24保存的是要回溯的指令長度
      0042ECC5  |.  EB 43              jmp     short 0042ED0A
      0042ECC7  |>  83F8 03            cmp     eax, 3
      0042ECCA  |.  74 07              je      short 0042ECD3
      0042ECCC  |.  33D2               xor     edx, edx
      0042ECCE  |.  8955 DC            mov     dword ptr [ebp-24], edx
      0042ECD1  |.  EB 37              jmp     short 0042ED0A
      0042ECD3  |>  6A 02              push    2                         ; /Arg4 = 00000002
      0042ECD5  |.  6A 01              push    1                         ; |Arg3 = 00000001
      0042ECD7  |.  8B4D D8            mov     ecx, dword ptr [ebp-28]      ; |
      0042ECDA  |.  83E9 02            sub     ecx, 2                     ; |指令碼回溯2
      0042ECDD  |.  51                 push    ecx                       ; |Arg2
      0042ECDE  |.  8D45 BB            lea     eax, dword ptr [ebp-45]        ; |
      0042ECE1  |.  50                 push    eax                        ; |Arg1
      0042ECE2  |.  E8 25260300        call    _Readmemory              ; \_Readmemory
      0042ECE7  |.  83C4 10            add     esp, 10
      0042ECEA  |.  83F8 01            cmp     eax, 1
      0042ECED  |.  75 0D              jnz     short 0042ECFC
      0042ECEF  |.  33D2               xor     edx, edx
      0042ECF1  |.  8A55 BB            mov     dl, byte ptr [ebp-45]
      0042ECF4  |.  81FA CD000000      cmp     edx, 0CD
      0042ECFA  |.  74 07              je      short 0042ED03
      0042ECFC  |>  33C9               xor     ecx, ecx
      0042ECFE  |.  894D DC            mov     dword ptr [ebp-24], ecx
      0042ED01  |.  EB 07              jmp     short 0042ED0A
      0042ED03  |>  C745 DC 02000000   mov     dword ptr [ebp-24], 2
      0042ED0A  |>  8B45 DC            mov     eax, dword ptr [ebp-24]
      0042ED0D  |.  2945 D8            sub     dword ptr [ebp-28], eax      ;  回溯指令碼,才是正確的斷點(diǎn)地址
      0042ED10  |.  8B15 08574D00      mov     edx, dword ptr [4D5708]
      0042ED16  |.  3B55 D8            cmp     edx, dword ptr [ebp-28]   ;  ntdll.DbgBreakPoint
      0042ED19  |.  75 08              jnz     short 0042ED23
      0042ED1B  |.  3B1D 0C574D00      cmp     ebx, dword ptr [4D570C]
      0042ED21  |.  74 16              je      short 0042ED39

      0042ED23  |> \33C9          xor     ecx, ecx
      0042ED25  |.  8B45 D8       mov     eax, dword ptr [ebp-28]
      0042ED28  |.  890D 10574D00 mov     dword ptr [4D5710], ecx
      0042ED2E  |.  A3 08574D00   mov     dword ptr [4D5708], eax       ;  把當(dāng)前斷點(diǎn)地址保存到全局變量4D5708中
      0042ED33  |.  891D 0C574D00 mov     dword ptr [4D570C], ebx
      0042ED39  |>  8B55 A4       mov     edx, dword ptr [ebp-5C]
      0042ED3C  |.  8B0A          mov     ecx, dword ptr [edx]

      以上找到了回溯后的斷點(diǎn)地址。然后下面是做一些別的操作,這里暫不予考慮。
      這時(shí)因?yàn)橛|發(fā)了Int3異常,被調(diào)試程序斷了下來,且已經(jīng)回溯了地址,這時(shí)按下F9的話,OD就會(huì)重新跑起來,這時(shí)OD對用戶設(shè)置的Int3斷點(diǎn)又做了兩件事:
      1、恢復(fù)原有的指令,讓被調(diào)試程序正確執(zhí)行指令;
      2、走完正確指令之后,再重新設(shè)置指令為0xCC;
      在OD的函數(shù)Go中:
      先通過Findthread獲得線程結(jié)構(gòu)體:
      00434A45  |> \8B4D 08       mov     ecx, dword ptr [ebp+8]
      00434A48  |.  51            push    ecx            ; ecx 是Go函數(shù)傳入?yún)?shù),為被調(diào)試線程的ID
      00434A49  |.  E8 2A3F0400   call    _Findthread      ; 返回OD中t_thread線程結(jié)構(gòu)體
      00434A4E  |.  59            pop     ecx
      00434A4F  |.  8945 DC       mov     dword ptr [ebp-24], eax ;把t_thread線程結(jié)構(gòu)體的地址賦給ebp-24
      然后通過線程結(jié)構(gòu)體獲得當(dāng)前要執(zhí)行的指令的地址(這個(gè)地址在前面已經(jīng)用回溯法修正過了)
      00434AB9  |.  8B99 18030000 mov     ebx, dword ptr [ecx+t_thread.th_reg.r_EIP]

      00434B2A  |.  53            push    ebx       ; ebx = t_thread.th_reg.r_EIP
      00434B2B  |.  E8 7C49FEFF   call    004194AC   ; 把Eip傳給函數(shù)004194AC

      在函數(shù)004194AC中,先獲得Int3斷點(diǎn)結(jié)構(gòu)體數(shù)組:
      004194EC  |> \56            push    esi             ;Eip
      004194ED  |.  68 E17E4D00   push    004D7EE1       ; |Arg1 = 004D7EE1 ASCII "Table of breakpoints"
      004194F2  |.  E8 19C00300   call    _Findsorteddata    ; 返回Int3斷點(diǎn)結(jié)構(gòu)體數(shù)組首地址
      OD的Int3斷點(diǎn)結(jié)構(gòu)體中有斷點(diǎn)處的原始指令碼,用來恢復(fù)被調(diào)試程序原先的指令碼。把該地址作為參數(shù)傳給函數(shù)00418C4C
      00419505  |.  50            push    eax
      00419506  |.  8915 20D64C00 mov     dword ptr [4CD620], edx
      0041950C  |.  E8 3BF7FFFF   call    00418C4C
      在函數(shù)00418C4C中層層調(diào)用,最終是調(diào)用WriteProcessMemory函數(shù)恢復(fù)指令碼的:
      00461814  |> \6A 00         push    0                             ; /pBytesWritten = NULL
      00461816  |.  A1 685A4D00   mov     eax, dword ptr [4D5A68]       ; |
      0046181B  |.  8B55 10       mov     edx, dword ptr [ebp+10]       ; |
      0046181E  |.  52            push    edx                           ; |BytesToWrite
      0046181F  |.  8B4D 08       mov     ecx, dword ptr [ebp+8]        ; |
      00461822  |.  51            push    ecx                           ; |Buffer
      00461823  |.  56            push    esi                           ; |Address
      00461824  |.  50            push    eax                           ; |hProcess => 0000026C (window)
      00461825  |.  E8 F8D90400   call    <jmp.&KERNEL32.WriteProcessMe>; \WriteProcessMemory

      在運(yùn)行完該指令之后,OD又把該指令碼設(shè)為Int3斷點(diǎn),即0xCC
      關(guān)鍵Call是函數(shù)41B5A4,在這個(gè)函數(shù)里,調(diào)用WriteMemory設(shè)置0xCC斷點(diǎn),而WriteMemory最終調(diào)用的還是上面所說的WriteProcessMemory(這里就不再詳細(xì)描述了)
      0041B6A4  |.  C60424 CC     |mov     byte ptr [esp], 0CC      ;直接設(shè)置0xCC斷點(diǎn)
      0041B6A8  |.  6A 02         |push    2                              ; /Arg4 = 00000002
      0041B6AA  |.  6A 01         |push    1                              ; |Arg3 = 00000001
      0041B6AC  |.  55            |push    ebp                            ; BreakPointAddress
      0041B6AD  |.  8D5424 0C     |lea     edx, dword ptr [esp+C]             ; [esp+C] = 0xCC
      0041B6B1  |.  52            |push    edx                            ; [edx] = 0xCC
      0041B6B2  |.  E8 71600400   |call    _Writememory                    ; \_Writememory

      通過以上方法,OD實(shí)現(xiàn)了在運(yùn)行時(shí)動(dòng)態(tài)處理Int3斷點(diǎn)的功能。


                                    武漢科銳學(xué)員: driverox
                                      2008-5-19                                 

        本站是提供個(gè)人知識管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多