久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

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

 herowuking 2015-05-31
標(biāo) 題: 【原創(chuàng)】OllyDBG分析報告系列(8)---進(jìn)程加載調(diào)試原理
作 者: comewhere
時 間: 2008-12-23,21:16:16
鏈 接: http://bbs./showthread.php?t=79305

標(biāo) 題: 【原創(chuàng)】OllyDBG分析報告系(8)---進(jìn)程加載調(diào)試原理 
作 者: comewhere
時 間: 2008-12-23,21:16
鏈 接: http://bbs./showthread.php?t=79305

我還是初學(xué)者 請各位多多指教....O(∩_∩)O

OD版本:OllyICE v1.10
在從文件菜單選擇附加后,OD會在注冊一個窗口類后,,先創(chuàng)建一個0x138大小的進(jìn)程表; 再是CreateWindowExA 創(chuàng)建窗口;
00478013 loc_478013:                            
00478013                 push    0               ; int
00478015                 push    offset sub_477C10 ; int
0047801A                 push    100h            ; int
0047801F                 push    310h            ; int
00478024                 push    offset asc_4C20E8 ; "?
00478029                 push    offset byte_4ED3FC ; dest
0047802E                 call    _Createsorteddata     //此處為創(chuàng)建進(jìn)程表

表的結(jié)構(gòu)體如下:
table           struc ; (sizeof=0x138)
name            db 260 dup(?)   //表的名字
count       dd ?                //表中保存的數(shù)據(jù)個數(shù)
maxcount        dd ?           //表能保存的最大數(shù)量
currentobj      dd ?            //當(dāng)前選中的表中數(shù)據(jù)的ID,未選中時為為-1
addrcurobj       dd ?             //當(dāng)前選中數(shù)據(jù)的地址,,未選中時為0
size            dd ?            //表中每個數(shù)據(jù)的大小
field_118       dd ?
baseaddrobj           dd ?      //表中保存的數(shù)據(jù)的基地址
fncmp              dd ?        //函數(shù)首地址
field_124       dd ?
field_128      dd ?    
sign            dd ?   //標(biāo)志位,,表示是否有索引數(shù)據(jù)(也就是baseaddroffset是否有效)
baseaddroffset        dd ?       //索引數(shù)據(jù),標(biāo)示每個數(shù)據(jù)在表中的順序
field_134       dd ?
table           ends

然后OD會獲取自己的進(jìn)程ID號,,并獲取EnumProcesses ,,EnumProcessModules,GetModuleFileNameExA 三個函數(shù)的地址,;

00475138 loc_475138:                            
00475138                 xor     ebx, ebx
0047513A                 call    GetCurrentProcessId  //獲取OD本身的進(jìn)程ID
0047513F                 mov     [ebp+var_10], eax
00475142                 mov     eax, dword_4D5A0C
00475147                 test    eax, eax
00475149                 jz      loc_4752AF
0047514F                 push    offset aEnumprocesses ; "EnumProcesses"
00475154                 push    eax             ; hModule
00475155                 call    GetProcAddress//獲取EnumProcesses地址
0047515A                 mov     edi, eax
0047515C                 push    offset aEnumprocessm_0 ; "EnumProcessModules"
00475161                 mov     eax, dword_4D5A0C
00475166                 push    eax             ; hModule
00475167                 call    GetProcAddress//獲取EnumProcessModules的地址
0047516C                 mov     [ebp+var_20], eax
0047516F                 push    offset aGetmodulefil_0 ; "GetModuleFileNameExA"
00475174                 mov     edx, dword_4D5A0C
0047517A                 push    edx             ; hModule
0047517B                 call    GetProcAddress//獲取GetModuleFileNameExA地址
00475180                 mov     [ebp+var_24], eax

之后OD枚舉系統(tǒng)中的所有進(jìn)程并保存枚舉到的進(jìn)程,;

004751A3                 push    eax
004751A4                 push    400h
004751A9                 push    edx
004751AA                 call    edi   // EnumProcesses  枚舉進(jìn)程
004751AC                 test    eax, eax
004751AE                 jnz     short loc_4751B3

接著再一個循環(huán)中OD會嘗試?yán)肙penProcess打開枚舉到的所有進(jìn)程,如果進(jìn)程ID不等于OD本身ID 并且OpenProcess函數(shù)返回成功的話,,OD會利用EnumProcessModules枚舉模塊并獲取第一個模塊句柄,,如果EnumProcessModules返回成功,OD會利用GetModuleFileNameExA獲取模塊全路徑,最后把進(jìn)程ID和 模塊全路徑 按順序保存到上面建立的 進(jìn)程表 中,; 

004751DB loc_4751DB:                             
004751DB                 mov     eax, [edi]
004751DD                 cmp     eax, [ebp+var_10]// 判斷是否等于OD本身ID
004751E0                 jz      loc_47529B
004751E6                 push    eax             ; dwProcessId
004751E7                 push    0               ; bInheritHandle
004751E9                 push    410h            ; dwDesiredAccess
004751EE                 call    OpenProcess
004751F3                 mov     [ebp+hObject], eax
004751F6                 cmp     [ebp+hObject], 0//判斷進(jìn)程是否打開成功
004751FA                 jz      loc_47529B
00475200                 lea     edx, [ebp+var_C]
00475203                 lea     ecx, [ebp+var_1C]
00475206                 push    edx
00475207                 push    4
00475209                 push    ecx
0047520A                 mov     eax, [ebp+hObject]
0047520D                 push    eax
0047520E                 call    [ebp+var_20] //EnumProcessModules枚舉進(jìn)程模塊
00475211                 test    eax, eax
00475213                 jnz     short loc_475220
00475215                 mov     edx, [ebp+hObject]
00475218                 push    edx             ; hObject
00475219                 call    CloseHandle//如果EnumProcessModules不成功則關(guān)閉句柄
0047521E                 jmp     short loc_47529B

如果EnumProcessModules成功則走如下分支

00475220 loc_475220:                          
00475220                 mov     ecx, [edi]      ; int
00475222                 xor     eax, eax        ; int
00475224                 mov     dword ptr [ebp+arglist], ecx//把進(jìn)程ID保存到一臨時結(jié)構(gòu)體中
0047522A                 lea     edx, [ebp+var_528]
00475230                 mov     [ebp+var_730], 1
0047523A                 mov     [ebp+var_72C], eax
00475240                 mov     [ebp+var_528], 0
00475247                 push    104h
0047524C                 push    edx
0047524D                 mov     ecx, [ebp+var_1C]
00475250                 push    ecx
00475251                 mov     eax, [ebp+hObject]
00475254                 push    eax
00475255                 call    [ebp+var_24]//GetModuleFileNameExA獲得模塊路徑
00475258                 mov     [ebp+var_425], 0
0047525F                 mov     edx, [ebp+hObject]
00475262                 push    edx             ; hObject
00475263                 call    CloseHandle//關(guān)閉打開的進(jìn)程句柄
00475268                 push    0
0047526A                 lea     ecx, [ebp+var_728]
00475270                 push    ecx
00475271                 push    0
00475273                 push    0
00475275                 lea     eax, [ebp+var_528]
0047527B                 push    eax
0047527C                 call    004A51BC   //把模塊路徑復(fù)制到臨時變量結(jié)構(gòu)體中
00475281                 add     esp, 14h
00475284                 lea     edx, [ebp+arglist] ; int
0047528A                 mov     [ebp+var_628], 0
00475291                 push    edx             ; arglist
00475292                 push    esi             ; src
00475293                 call    _Addsorteddata //把包含了進(jìn)程ID與模塊路徑的臨時結(jié)構(gòu)體添加到進(jìn)程表中
00475298                 add     esp, 8

0047529B loc_47529B:                                                               
0047529B                 inc     [ebp+var_4]
0047529E                 add     edi, 4
004752A1                 mov     ecx, [ebp+var_4]
004752A4                 cmp     ecx, [ebp+var_8] //檢查比較次數(shù)是否小于枚舉到的進(jìn)程個數(shù)
004752A7                 jl      loc_4751DB //小于則繼續(xù)循環(huán)

枚舉完進(jìn)程后接著檢查進(jìn)程表中保存的數(shù)據(jù)是否小于等于0;如果小于等于則直接返回,;
反之則EnumWindows,并利用GetWindowText函數(shù)獲取桌面窗口的標(biāo)題
保存到 進(jìn)程表中 對應(yīng)的進(jìn)程數(shù)據(jù)中
004753E9              cmp     dword ptr [esi+104h], 0//比較進(jìn)程表中數(shù)據(jù)是否小于0
004753F0              jle     short loc_4753FD
004753F2              push    esi       //此處的參數(shù)是 進(jìn)程表的首地址
004753F3              push    offset sub_477A90 ; lpEnumFunc
004753F8              call    EnumWindows

以下是EnumWindowsProc的功能
00477AA8                 lea     edx, [ebp+dwProcessId]
00477AAB                 push    edx             ; lpdwProcessId
00477AAC                 mov     ecx, [ebp+hWnd]
00477AAF                 push    ecx        //枚舉的窗口進(jìn)程的句柄
00477AB0                 call    GetWindowThreadProcessId //獲得窗口的進(jìn)程ID

下面是個循環(huán) 利用上面得到的進(jìn)程ID與進(jìn)程表中保存的進(jìn)程ID做比較,,如果相等 則GetWindowTextA獲得窗口標(biāo)題,,并把得到的數(shù)據(jù)保存在進(jìn)程表中對應(yīng)的位置
00477ABB loc_477ABB:                             ; CODE XREF: sub_477A90+75 j
00477ABB                 mov     edx, [ebx]
00477ABD                 cmp     edx, [ebp+dwProcessId]
00477AC0                 jnz     short loc_477AF8
00477AC2                 cmp     byte ptr [ebx+10Ch], 0
00477AC9                 jnz     short loc_477AF8
00477ACB                 push    100h            ; nMaxCount
00477AD0                 mov     ecx, eax
00477AD2                 lea     eax, [ecx+eax*2]
00477AD5                 shl     eax, 4
00477AD8                 add     eax, ecx
00477ADA                 shl     eax, 4
00477ADD                 add     esi, eax
00477ADF                 add     esi, 10Ch
00477AE5                 push    esi  //此buffer既為進(jìn)程表中不同進(jìn)程對應(yīng)的數(shù)據(jù)地址
00477AE6                 mov     eax, [ebp+hWnd]
00477AE9                 push    eax             ; hWnd
00477AEA                 call    GetWindowTextA  //獲得枚舉的窗口的標(biāo)題并保存到進(jìn)程表中對應(yīng)的進(jìn)程數(shù)據(jù)中
00477AEF                 mov     byte ptr [ebx+20Bh], 0
00477AF6                 jmp     short loc_477B07獲得后跳出循環(huán) 利用枚舉到的下一個窗口再次執(zhí)行此函數(shù)

如果進(jìn)程ID不相等則繼續(xù)循環(huán)
00477AF8                 inc     eax
00477AF9                 add     ebx, 310h  0x310為結(jié)構(gòu)體大小
00477AFF loc_477AFF:                           
00477AFF                 cmp     eax, [edi+104h] //檢查比較的次數(shù) 是否大于進(jìn)程表中 的進(jìn)程數(shù)
00477B05                 jl      short loc_477ABB

在EnumWindows函數(shù)執(zhí)行完成返回后,,OD會調(diào)用InvalidateRect函數(shù),,使顯示進(jìn)程的窗口重繪;
004782F8                 push    0               ; bErase
004782FA                 push    0               ; lpRect
004782FC                 mov     edx, dword_4ED3F8
00478302                 push    edx             ; hWnd
00478303                 call    InvalidateRect

OD會對進(jìn)程表中的 ID號,把相對應(yīng)的索引數(shù)據(jù)進(jìn)行從小到大的排序..
004AC501                 jz      short loc_4AC51C
004AC503                 mov     edx, [ebp+fcmp]
004AC506                 mov     ecx, [ebp+nelem]
004AC509                 push    ecx //第一個參數(shù)為進(jìn)程表中的數(shù)據(jù)個數(shù)
004AC50A                 mov     dword_50A5F8, edx
004AC510                 mov     eax, [ebp+base] //第二個參數(shù)為進(jìn)程表中索引數(shù)據(jù)的首地址
004AC513                 push    eax
004AC514                 call    sub_4AC310
最終函數(shù)會調(diào)用到進(jìn)程表結(jié)構(gòu)體中偏移0x120位置保存的函數(shù)地址;

當(dāng)從進(jìn)程窗口列表框中選擇要附加的進(jìn)程并點擊附加按鈕后,OD會記錄其序號,,并通過序號計算出此進(jìn)程在 進(jìn)程表中的 偏移位置,,通過偏移位置得到進(jìn)程ID
004784A5                 mov     eax, dword_4ED508//得到要附加進(jìn)程在列表框中的位置
004784AA                 test    eax, eax
004784AC                 jl      loc_47867B//如果進(jìn)程號小于0則直接返回;
004784B2                 cmp     eax, dword_4ED500/比較序號是否大于進(jìn)程總數(shù)
004784B8                 jge     loc_47867B  //大于也直接返回
004784BE                 mov     edx, dword_4ED52C
004784C4                 mov     esi, [edx+eax*4]
004784C7                 imul    esi, dword_4ED510
004784CE                 add     esi, dword_4ED518 //上面幾步是計算得出附加的進(jìn)程在進(jìn)程表中存儲的首地址
004784D4                 mov     eax, [esi]  //得到進(jìn)程ID
004784D6                 cmp     eax, dword_4D5A70 //判斷OD是否正在調(diào)試此程序
004784DC                 jnz     short loc_4784F4

如果此時OD正在調(diào)試此程序則會彈出一錯誤框提示 進(jìn)程“xxxx”是你正在調(diào)試的程序……
并直接返回,。
004784DE                 add     esi, 0Ch
004784E1                 push    esi             ; arglist
004784E2                 push    offset asc_4C2122 ; "?
004784E7                 call    _Error
004784EC                 add     esp, 8
004784EF                 jmp     loc_47867B//直接返回..

接著OD會申請一定的空間并初始化一些表,,如:dll句柄表,,線程表,,統(tǒng)計表,等等…

004784F4 loc_4784F4:                           
004784F4                 push    1
004784F6                 call    sub_4758A4
004784FB                 pop     ecx
004784FC                 test    eax, eax
004784FE                 jnz     loc_47867B
00478504                 call    sub_47540C //此函數(shù)用于申請空間并初始化表
00478509                 test    eax, eax //判斷是否初始化成功,。
0047850B                 jz      short loc_47851D
0047850D                 push    offset aIFUC    ; "無法分配足夠內(nèi)存"
00478512                 call    _Error//如果不成功則會報告內(nèi)存內(nèi)存不足…并直接返回
00478517                 pop     ecx
00478518                 jmp     loc_47867B

在0046b258這個函數(shù)中OD會根據(jù)用戶設(shè)置的導(dǎo)入庫保存在ollydbg.ini文件中的[Import libraries]項解析調(diào)試程序中的庫函數(shù);
下面就是處理的一個循環(huán)過程

0046B268 loc_46B268:                          
0046B268                 push    ebx
0046B269                 lea     eax, [edi+4F8h]
0046B26F                 push    eax             ; format
0046B270                 lea     edx, [esp+318h+buffer]
0046B277                 push    edx             ; buffer
0046B278                 call    _sprintf
0046B27D                 add     esp, 0Ch
0046B280                 push    offset FileName ; lpFileName
0046B285                 push    104h            ; nSize
0046B28A                 lea     ecx, [esp+318h+path]
0046B28E                 push    ecx             ; lpReturnedString
0046B28F                 lea     eax, [edi+4]
0046B292                 push    eax             ; lpDefault
0046B293                 lea     edx, [esp+320h+buffer]
0046B29A                 push    edx             ; lpKeyName
0046B29B                 lea     ecx, [edi+503h]
0046B2A1                 push    ecx             ; lpAppName
0046B2A2                 call    GetPrivateProfileStringA  //得到ollydbg.ini 文件中[Import libraries]項中的路徑
0046B2A7                 cmp     [esp+310h+path], 0
0046B2AB                 jz      short loc_46B2E6
0046B2AD                 mov     eax, hCursor
0046B2B2                 push    eax             ; hCursor
0046B2B3                 call    SetCursor
0046B2B8                 mov     esi, eax
0046B2BA                 xor     eax, eax
0046B2BC                 mov     dword_4EAE50, eax
0046B2C1                 push    0               ; int
0046B2C3                 lea     edx, [esp+314h+arglist]
0046B2CA                 push    edx             ; arglist
0046B2CB                 lea     ecx, [esp+318h+path]
0046B2CF                 push    ecx             ; path
0046B2D0                 call    sub_469818//此函數(shù)里面主要是負(fù)責(zé)解析的函數(shù)
0046B2D5                 add     esp, 0Ch
0046B2D8                 call    sub_46718C
0046B2DD                 cmp     dword_4EAE50, 0
0046B2E4                 jnz     short loc_46B2F3
0046B2E6
0046B2E6 loc_46B2E6:     
0046B2E6                 inc     ebx
0046B2E7                 cmp     ebx, 0C8h
0046B2ED                 jl      loc_46B268

等做完上面的工作后,,OD才開始真正的附加 主要是通過DebugActiveProcess對程序附加
00478522                 mov     eax, [esi]
00478524                 push    eax             /要附加的進(jìn)程ID
00478525                 call    DebugActiveProcess
0047852A                 test    eax, eax

之后OD按一定格式設(shè)置窗口標(biāo)題;
004785A5                 push    edx
004785A6                 push    offset byte_4D5A7C
004785AB                 push    offset aOllyice ; "OllyICE"
004785B0                 push    offset aSSS_0   ; "%s - %s%s"
004785B5                 lea     ecx, [ebp+buffer]
004785BB                 push    ecx             ; buffer
004785BC                 call    _sprintf
004785C1                 add     esp, 14h
004785C4                 lea     eax, [ebp+buffer] ; int
004785CA                 push    eax             ; lpString
004785CB                 mov     edx, hWnd
004785D1                 push    edx             ; hWnd
004785D2                 call    SetWindowTextA
然后OD會對ollydbg.ini文件中的[History],[Arguments]兩項進(jìn)行設(shè)置……下面只貼出部分代碼

00476F08                 lea     edx, [ebx+1]
00476F0B                 push    edx
00476F0C                 lea     ecx, [edi+6DAh]
00476F12                 push    ecx             ; format
00476F13                 lea     eax, [ebp+buffer]
00476F19                 push    eax             ; buffer
00476F1A                 call    _sprintf
00476F1F                 mov     edx, ebx
00476F21                 add     esp, 0Ch
00476F24                 shl     edx, 6
00476F27                 lea     ecx, [ebp+var_518]
00476F2D                 add     edx, ebx
00476F2F                 push    offset FileName ; lpFileName
00476F34                 shl     edx, 2
00476F37                 lea     eax, [ebp+buffer]
00476F3D                 add     edx, ecx
00476F3F                 push    edx             ; lpString
00476F40                 lea     edx, [edi+6E9h]
00476F46                 push    eax             ; lpKeyName
00476F47                 push    edx             ; lpAppName
00476F48                 call    WritePrivateProfileStringA

接著OD設(shè)置程序狀態(tài),,并退出Dialog對話框…

0047860E                 push    0               ; name
00478610                 push    offset byte_4D5A7C ; int
00478615                 call    sub_409370
0047861A                 add     esp, 8
0047861D                 push    3  //設(shè)置狀態(tài)為運行
0047861F                 call    sub_431978
00478624                 pop     ecx
00478625                 push    0               ; nResult
00478627                 push    ebx             ; hDlg
00478628                 call    EndDialog //結(jié)束附加窗口
0047862D                 jmp     short loc_47867B

DebugActiveProcess附加程序后,系統(tǒng)會為進(jìn)程中的每一個創(chuàng)建線程,,向調(diào)試器發(fā)送CREATE_THREAD_DEBUG_EVENT調(diào)試事件,會為進(jìn)程中的每個動態(tài)加載DLL向調(diào)試器發(fā)送LOAD_DLL_DEBUG_EVENT調(diào)試事件..  OD通過WaitForDebugEvent函數(shù)獲得這些事件,,做相應(yīng)處理,并調(diào)用ContinueDebugEvent使程序繼續(xù)執(zhí)行…..當(dāng)這些都做完后,,系統(tǒng)恢復(fù)進(jìn)程中的所有線程,并且在第一個線程恢復(fù)的時候會執(zhí)行 一個 斷點指令,,最后會調(diào)用Ntdll.dll中的DbgBreakPoint函數(shù) 而根據(jù)跟蹤得知DbgBreakPoint中的實現(xiàn) 就是一個int3指令;

dwDebugEventCode事件處理表:
0042EBF7                 mov     edx, DebugEvent.dwDebugEventCode
0042EBFD                 cmp     edx, 9          ; switch 10 cases
0042EC00                 ja      loc_4313F4      ; default
0042EC00                                         ; jumptable 0042EC06 case 0
0042EC06                 jmp     ds:off_42EC0D[edx*4] ; switch jump
0042EC06 ; ---------------------------------------------------------------------------
0042EC0D off_42EC0D      dd offset loc_4313F4    ; DATA XREF: sub_42EBD0+36 r
0042EC0D                 dd offset loc_42EC35    ; jump table for switch 
0042EC0D                 dd offset loc_430CFF
0042EC0D                 dd offset loc_430DD7
0042EC0D                 dd offset loc_430F3F
0042EC0D                 dd offset loc_431037
0042EC0D                 dd offset loc_43112D
0042EC0D                 dd offset loc_4311B7
0042EC0D                 dd offset loc_431276
0042EC0D                 dd offset loc_4313C7

DbgBreakPoint的實現(xiàn)

7C92120E >  CC              int3     
7C92120F    C3              retn

因此當(dāng)程序執(zhí)行到此時,,會引起一個EXCEPTION_DEBUG_EVENT事件,OD通過WaitForDebugEvent函數(shù)會獲得此調(diào)試事件…OD在獲得EXCEPTION_DEBUG_EVENT事件后,,之后并沒有調(diào)用ContinueDebugEvent使程序執(zhí)行。因此OD會停到DbgBreakPoint處,,也就是EIP會指在retn處。


         武漢科銳學(xué)員: comewhere                                 

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

    0條評論

    發(fā)表

    請遵守用戶 評論公約