九色国产,午夜在线视频,新黄色网址,九九色综合,天天做夜夜做久久做狠狠,天天躁夜夜躁狠狠躁2021a,久久不卡一区二区三区

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
【原創(chuàng)】OllyDBG分析報(bào)告系列(4)
標(biāo) 題: 【原創(chuàng)】OllyDBG分析報(bào)告系列(4)---獲得當(dāng)前cpu狀態(tài)
作 者: angelqkm
時(shí) 間: 2008-05-25,22:48:25
鏈 接: http://bbs.pediy.com/showthread.php?t=65476

這是分析報(bào)告的第四部分,請(qǐng)多多指教。  
 

Ollydbg(以下均簡(jiǎn)稱為OD)中獲得當(dāng)前cpu狀態(tài)的主要原理是:windows操作系統(tǒng)是多線程的操作系統(tǒng),其線程運(yùn)行是分時(shí)間片的,每個(gè)程序按照其優(yōu)先級(jí)輪流運(yùn)行一段時(shí)間。當(dāng)運(yùn)行一個(gè)線程時(shí),其他線程需要把運(yùn)行環(huán)境保留到一個(gè)地方,當(dāng)時(shí)間片分配到自己時(shí),再講運(yùn)行環(huán)境讀取出來并運(yùn)行。根據(jù)windows運(yùn)行原理,調(diào)試寄存器能夠讀取、修改保存起來的線程運(yùn)行環(huán)境,這樣也就獲得了CPU的工作狀態(tài)了。其API為:GetThreadContext、SetThreadContext。
通過分析,OD會(huì)遍歷所有活動(dòng)線程,得到其線程環(huán)境,并將得到的所有信息放到一個(gè)66Ch大小的結(jié)構(gòu)體中,該結(jié)構(gòu)體的詳細(xì)情況即該系一的int3斷點(diǎn)中提及的t_thread結(jié)構(gòu)體。

關(guān)于這部分的代碼分析,在IDA中已經(jīng)詳細(xì)標(biāo)出,就直接將IDA中的分析結(jié)果貼上。這里就總的說一下這個(gè)函數(shù)的功能以及參數(shù)(函數(shù)名為GetThreadInfo):
a.  通過GetThreadContext的方法獲得線程的上下文環(huán)境,把該環(huán)境保存至OD線程信息結(jié)構(gòu)中的reg字段中,若oldreg已經(jīng)失效,則復(fù)制reg的值到oldreg中;
b.  若被調(diào)試進(jìn)程有多個(gè)線程,則循環(huán)取值,保存至OD線程信息結(jié)構(gòu)數(shù)組中;
c.  傳入?yún)?shù)為:DebugEvent.dwThreadId;
d.  返回值為:成功時(shí)為保存在OD線程信息結(jié)構(gòu)中的當(dāng)前寄存器信息結(jié)構(gòu)的指針(主線程),失敗返回0。

GetThreadInfo   proc near               ; CODE XREF: sub_42EBD0+1A p
                                        ; _Suspendprocess+45 p

reg_big[6]          = dword ptr -34h
reg_seg_reg        = dword ptr -30h
s_base_ss       = dword ptr -2Ch
f_reg_st_i       = dword ptr -28h
SelectorEntry   = _LDT_ENTRY ptr -24h
ret             = dword ptr -1Ch
pThreadInfo     = dword ptr -18h
var_11          = byte ptr -11h
src             = dword ptr -10h
segment_size           = dword ptr -0Ch
f_reg_index           = dword ptr -8
i               = dword ptr -4
ThreadId           = dword ptr  8

保存現(xiàn)場(chǎng),拉伸空間,檢查線程信息結(jié)構(gòu)體是否存在,若不存在直接跳轉(zhuǎn)到結(jié)束處,若存在則跳過退出部分的代碼:
                push    ebp
                mov     ebp, esp
                add     esp, 0FFFFFFCCh
                mov     eax, pThreadInfo
                push    ebx
                push    esi
                push    edi
                mov     [ebp+pThreadInfo], eax
                cmp     [ebp+pThreadInfo], 0
                jnz     short has_ThreadInfo
                xor     eax, eax
                jmp     _exit
; ---------------------------------------------------------------------------
下面開始即是一個(gè)大的循環(huán)體,這里初始值變量,然后跳轉(zhuǎn)到循環(huán)體的判斷處:
has_ThreadInfo:                         ; CODE XREF: GetThreadInfo+15 j
                xor     edx, edx
                mov     [ebp+ret], edx
                xor     ecx, ecx
                mov     [ebp+i], ecx
                jmp     loc_42E7C1
; ---------------------------------------------------------------------------
這里開始為循環(huán)體的內(nèi)部處理,即讀取當(dāng)前cpu狀態(tài)到結(jié)構(gòu)體中:
getThreadInfo:                          ; CODE XREF: GetThreadInfo+37E j
先將線程信息結(jié)構(gòu)體中幾個(gè)標(biāo)識(shí)修改狀態(tài)的值置零,即標(biāo)識(shí)還沒有修改:
                mov     eax, [ebp+pThreadInfo]
                xor     edx, edx
                mov     [eax+t_Thread.reg.modified], edx ; 標(biāo)識(shí)寄存器是否修改
                mov     ecx, [ebp+pThreadInfo]
                xor     eax, eax
                mov     [ecx+t_Thread.reg.modifiedbyuser], eax ; 標(biāo)識(shí)被用戶修改
                mov     edx, [ebp+pThreadInfo]
                xor     ecx, ecx
                mov     [edx+t_Thread.reg.singlestep], ecx ; 標(biāo)識(shí)單步
將CONTEXT結(jié)構(gòu)體的ContextFlags設(shè)置為取得所有信息,然后調(diào)用GetThreadContext取當(dāng)前線程信息,檢查是否取得線程信息,若取得則跳過錯(cuò)誤處理,繼續(xù)設(shè)置:
                mov     esi, [ebp+pThreadInfo]
                add     esi, 20h
                mov     dword ptr [esi], 1001Fh
                push    esi             ; lpContext
                mov     eax, [ebp+pThreadInfo]
                mov     edx, [eax+t_Thread.thread] ; HANDLE  Thread handle
                push    edx             ; hThread
                call    GetThreadContext
                test    eax, eax
                jnz     short loc_42E4C7
這里為沒有得到線程信息的處理,設(shè)置其線程信息有效值為0,即無效,然后跳轉(zhuǎn)到循環(huán)體判斷處遍歷下一個(gè)線程信息:
                mov     ecx, [ebp+pThreadInfo]
                xor     eax, eax
                mov     [ecx+t_Thread.regvalid], eax ; int  Whether reg is valid
                jmp     j_next_Thread
; ---------------------------------------------------------------------------
檢查得到線程信息的線程ID是否與要得到線程的ID相同,若相同則設(shè)置返回值為其寄存器結(jié)構(gòu)體的首地址,若不同則跳過對(duì)返回值的設(shè)置:
loc_42E4C7:                             ; CODE XREF: GetThreadInfo+69 j
                mov     eax, [ebp+pThreadInfo]
                mov     ebx, [ebp+pThreadInfo]
                add     ebx, 2ECh       ; ebx : ThreadInfo.reg
                mov     edx, [eax]      ; edx : ThreadInfo.dwThreadId
                cmp     edx, [ebp+ ThreadId]
                jnz     short loc_42E4DD
                mov     [ebp+ret], ebx
下面將得到的線程信息結(jié)構(gòu)體中 寄存器結(jié)構(gòu)體的信息一一賦值到OD為其準(zhǔn)備的線程信息結(jié)構(gòu)體處:
loc_42E4DD:                             ; CODE XREF: GetThreadInfo+8C j
                mov     ecx, [esi+CONTEXT._Eax]
                mov     [ebx+t_reg.r_eax], ecx ; ulong  register
                mov     eax, [esi+CONTEXT._Ecx]
                mov     [ebx+t_reg.r_ecx], eax ; ulong  register
                mov     edx, [esi+CONTEXT._Edx]
                mov     [ebx+t_reg.r_edx], edx ; ulong  register
                mov     ecx, [esi+CONTEXT._Ebx]
                mov     [ebx+t_reg.r_ebx], ecx ; ulong  register
                mov     eax, [esi+CONTEXT._Esp]
                mov     [ebx+t_reg.r_esp], eax ; ulong  register
                mov     edx, [esi+CONTEXT._Ebp]
                mov     [ebx+t_reg.r_ebp], edx ; ulong  register
                mov     ecx, [esi+CONTEXT._Esi]
                mov     [ebx+t_reg.r_esi], ecx ; ulong  register
                mov     eax, [esi+CONTEXT._Edi]
                mov     [ebx+t_reg.r_edi], eax ; ulong  register
                mov     edx, [esi+CONTEXT._Eip]
                mov     [ebx+t_reg.r_eip], edx ; ulong  Instruction pointer (EIP)
初始化浮點(diǎn)寄存器的棧頂、狀態(tài)等變量:
                lea     edx, [ebx+t_reg.f_reg_st0] ; long double  Float registers, f[top] - top of stack
                mov     ecx, [esi+CONTEXT.EFlags]
                mov     [ebx+t_reg.flags], ecx ; ulong  Flags
                mov     eax, [esi+CONTEXT.FloatSave.StatusWord]
                shr     eax, 0Bh
                and     eax, 7
                xor     edi, edi
                mov     [ebx+t_reg.top], eax ; int  Index of top-of-stack
                lea     eax, [ebx+t_reg.tag[8]] ; uchar  Float tags (0x3 - empty register)
                mov     [ebp+s_base_ss], eax
                mov     [ebp+f_reg_st_i], edx
這段是循環(huán)遍歷8個(gè)浮點(diǎn)寄存器,對(duì)其檢查并進(jìn)行賦值:
loc_42E554:                             ; CODE XREF: GetThreadInfo+158 j
8減去浮點(diǎn)寄存器的棧頂序號(hào),再與80000007位與之后若為正則跳過對(duì)負(fù)數(shù)的處理,若為負(fù)數(shù)則取其補(bǔ)碼,由于浮點(diǎn)棧頂?shù)男蛱?hào)為0,所以與80000007位與之后還是0,這里一個(gè)錯(cuò)誤檢查:
                lea     ecx, [edi+8]
                sub     ecx, [ebx+t_reg.top] ; int  Index of top-of-stack
                and     ecx, 80000007h
                jns     short loc_42E567
                dec     ecx
                or      ecx, 0FFFFFFF8h
                inc     ecx
這里是一個(gè)循環(huán)體,根據(jù)序號(hào)給浮點(diǎn)寄存器結(jié)構(gòu)體賦值,每個(gè)浮點(diǎn)寄存器10個(gè)字節(jié):
loc_42E567:                             ; CODE XREF: GetThreadInfo+114 j
                mov     [ebp+f_reg_index], ecx
                mov     eax, [ebp+f_reg_st_i]
                mov     edx, [ebp+f_reg_index]
                lea     edx, [edx+edx*4]
                mov     ecx, dword ptr [esi+edx*2+CONTEXT.FloatSave.RegisterArea]
                mov     [eax], ecx
                mov     ecx, dword ptr [esi+edx*2+(CONTEXT.FloatSave.RegisterArea+4)]
                mov     [eax+4], ecx
                mov     cx, word ptr [esi+edx*2+(CONTEXT.FloatSave.RegisterArea+8)]
                mov     [eax+8], cx
由于TagWord寄存器16位寬,只有一個(gè)作用,就是記錄每1個(gè)浮點(diǎn)寄存器的使用情況,8個(gè)浮點(diǎn)寄存器分為占用2位,所以每個(gè)寄存器有4個(gè)狀態(tài),分別為:00有效(Valid)、01零值(Zero)、10特殊的(Spical)、11空閑(Empty),這里就是按照序號(hào)標(biāo)識(shí)其狀態(tài):
                mov     ecx, edi
                add     ecx, ecx
                mov     eax, [esi+CONTEXT.FloatSave.TagWord]
                shr     eax, cl
                and     al, 3
                mov     edx, [ebp+s_base_ss]
                mov     [edx], al
序號(hào)、寄存器基址、寄存器結(jié)構(gòu)體指針自加,檢查是否遍歷完8個(gè)寄存器,若沒有遍歷完則繼續(xù):
                inc     edi
                inc     [ebp+s_base_ss]
                add     [ebp+f_reg_st_i], 0Ah  ; 
                cmp     edi, 8
                jl      short loc_42E554
最后設(shè)置控制字與狀態(tài)字寄存器:
                mov     eax, [esi+CONTEXT.FloatSave.StatusWord]
                xor     edi, edi
                mov     [ebx+t_reg.fst], eax ; ulong  FPU status word
                mov     edx, [esi+CONTEXT.FloatSave.ControlWord]
                mov     [ebx+t_reg.fcw], edx ; ulong  FPU control word
下面開始為對(duì)段寄存器的賦值,標(biāo)識(shí)都已注明:
                mov     ecx, [esi+CONTEXT.SegEs]
                mov     [ebx+t_reg.s_reg_es], ecx ; ulong  Segment register
                mov     eax, [esi+CONTEXT.SegCs]
                mov     [ebx+t_reg.s_reg_cs], eax ; ulong  Segment register
                mov     edx, [esi+CONTEXT.SegSs]
                mov     [ebx+t_reg.s_reg_ss], edx ; ulong  Segment register
                mov     ecx, [esi+CONTEXT.SegDs]
                mov     [ebx+t_reg.s_reg_ds], ecx ; ulong  Segment register
                mov     eax, [esi+CONTEXT.SegFs]
                mov     [ebx+t_reg.s_reg_fs], eax ; ulong  Segment register
                lea     eax, [ebx+t_reg.big[6]] ; uchar  Default size (0-16, 1-32 bit)
                mov     edx, [esi+CONTEXT.SegGs]
                mov     [ebx+t_reg.s_reg_gs], edx ; ulong  Segment register
初始化段寄存器的兩個(gè)變量(size、segment_reg):
                lea     edx, [ebx+t_reg.s_reg_es] ; ulong  Segment register
                mov     [ebp+reg_big[6]], eax
                mov     [ebp+reg_seg_reg], edx
這段是循環(huán)遍歷6個(gè)段寄存器,得到其大小,放入reg_big[6]結(jié)構(gòu)體中,即得到該段的大?。?br>loc_42E614:                             ; CODE XREF: GetThreadInfo+278 j
                lea     ecx, [ebp+SelectorEntry]
                push    ecx             ; lpSelectorEntry
                mov     eax, [ebp+reg_seg_reg]
                mov     edx, [eax]
                push    edx             ; dwSelector
                mov     ecx, [ebp+pThreadInfo]
                mov     eax, [ecx+0Ch]
                push    eax             ; hThread
                call    GetThreadSelectorEntry    ; 取得當(dāng)前線程描述符表
                test    eax, eax
                jz      short loc_42E697
                movzx   ecx, [ebp+SelectorEntry.BaseLow]
                mov     dl, byte ptr [ebp+SelectorEntry.HighWord]
                mov     al, byte ptr [ebp+SelectorEntry.HighWord+3]
                and     edx, 0FFh
                and     eax, 0FFh
                shl     edx, 10h
                and     ecx, 0FFFFh
                shl     eax, 18h
                and     edx, 0FF0000h
                add     edx, ecx
                and     eax, 0FF000000h
                add     edx, eax
                mov     [ebp+segment_size], edx
                movzx   edx, [ebp+SelectorEntry.LimitLow]
                mov     al, byte ptr [ebp+SelectorEntry.HighWord+2]
                and     edx, 0FFFFh
                and     eax, 0Fh
                shl     eax, 10h
                and     eax, 0F0000h
                add     eax, edx
                test    byte ptr [ebp+SelectorEntry.HighWord+2], 80h
                jz      short loc_42E689
                shl     eax, 0Ch
                add     eax, 0FFFh

loc_42E689:                             ; CODE XREF: GetThreadInfo+233 j
                mov     cl, byte ptr [ebp+SelectorEntry.HighWord+2]
                shr     ecx, 6
                and     ecx, 1
                mov     [ebp+var_11], cl
                jmp     short loc_42E6A2
; ---------------------------------------------------------------------------

loc_42E697:                             ; CODE XREF: GetThreadInfo+1E0 j
                xor     edx, edx
                mov     eax, edx
                mov     [ebp+segment_size], edx
                mov     [ebp+var_11], 1

loc_42E6A2:                             ; CODE XREF: GetThreadInfo+249 j
                mov     ecx, [ebp+reg_seg_reg]
                mov     edx, [ebp+segment_size]
                mov     [ecx+18h], edx    ; reg_seg_reg + 18h 剛好是其對(duì)應(yīng)的reg_big[6]所在的位置
                mov     ecx, [ebp+reg_seg_reg]
                mov     [ecx+30h], eax
                mov     eax, [ebp+reg_big[6]]
                mov     dl, [ebp+var_11]
                mov     [eax], dl
檢查6個(gè)段寄存器是否遍歷完畢,若完畢則退出循環(huán):
                inc     edi
                inc     [ebp+reg_big[6]]
                add     [ebp+reg_seg_reg], 4
                cmp     edi, 6
                jl      loc_42E614
下面是對(duì)調(diào)試寄存器的賦值:
                mov     eax, [esi+CONTEXT.Dr0]
                mov     [ebx+t_reg.drlin_dr0], eax ; ulong  Debug register
                mov     ecx, [esi+CONTEXT.Dr1]
                mov     [ebx+t_reg.drlin_dr1], ecx ; ulong  Debug register
                mov     eax, [esi+CONTEXT.Dr2]
                mov     [ebx+t_reg.drlin_dr2], eax ; ulong  Debug register
                mov     edx, [esi+CONTEXT.Dr3]
                mov     [ebx+t_reg.drlin_dr3], edx ; ulong  Debug register
                mov     ecx, [esi+CONTEXT.Dr6]
                mov     [ebx+t_reg.dr6], ecx ; ulong  Debug register DR6
                mov     eax, [esi+CONTEXT.Dr7]
                mov     [ebx+t_reg.dr7], eax ; ulong  Debug register DR7
                mov     edx, [ebp+arg_0]
                mov     [ebx+t_reg.threadid], edx ; ulong  ID of thread that owns registers
                mov     eax, VersionInformation.dwPlatformId
檢查子系統(tǒng)屬性,根據(jù)其進(jìn)行相應(yīng)的設(shè)置:
                cmp     eax, 2      ; 檢查是否是windows圖形界面
                jnz     short loc_42E71A
                mov     eax, 34h      ; 若是則使 EAX = 34h
                jmp     short loc_42E728
; ---------------------------------------------------------------------------

loc_42E71A:                             ; CODE XREF: GetThreadInfo+2C5 j
                cmp     eax, 1      ; 檢查是否為本地屬性
                jnz     short loc_42E726
                mov     eax, 60h      ; 若是則使EAX = 60h
                jmp     short loc_42E728
; ---------------------------------------------------------------------------

loc_42E726:                             ; CODE XREF: GetThreadInfo+2D1 j
                xor     eax, eax      ; 若都不是則設(shè)置EAX = 0

loc_42E728:                             ; CODE XREF: GetThreadInfo+2CC j
                                        ; GetThreadInfo+2D8 j
                test    eax, eax
                jz      short loc_42E75C
                cmp     dword_4D579C, 0
                jz      short loc_42E75C
                push    3               ; char
                push    4               ; n
                mov     edx, [ebp+pThreadInfo]
                add     eax, [edx+t_Thread.datablock] ; ulong  Per-thread data block
                push    eax             ; arglist
                lea     ecx, [ebp+src]
                push    ecx             ; src
                call    _Readmemory
                add     esp, 10h
                cmp     eax, 4
                jnz     short loc_42E75C
                mov     eax, [ebp+src]
                mov     [ebx+0EEh], eax
                jmp     short loc_42E766
; ---------------------------------------------------------------------------

loc_42E75C:                             ; CODE XREF: GetThreadInfo+2DE j
                                        ; GetThreadInfo+2E7 j ...
                mov     dword ptr [ebx+0EEh], 0FFFFFFFFh
將剛得到的寄存器信息設(shè)置為有效,并檢查線程信息結(jié)構(gòu)體中oldreg的屬性是否有效,若無效則將當(dāng)前的寄存器值賦值進(jìn)去:
loc_42E766:                             ; CODE XREF: GetThreadInfo+30E j
                xor     edx, edx
                xor     ecx, ecx
                mov     [ebx+0F2h], edx
                mov     [ebx+0F6h], ecx
                mov     eax, [ebp+pThreadInfo]
                mov     [eax+t_Thread.regvalid], 1 ; int  Whether reg is valid
                mov     edx, [ebp+pThreadInfo]
                cmp     dword ptr [edx+t_Thread.oldregvalid], 0 ; check ThreadInfo is read
                jnz     short j_next_Thread
                mov     ecx, [ebp+pThreadInfo]
                mov     eax, [ebp+pThreadInfo]
                lea     esi, [ecx+t_Thread.reg] ; struct  Actual contents of registers
                lea     edi, [eax+t_Thread.oldreg] ; struct  Previous contents of registers
                mov     ecx, 65h
                rep movsd               ; Thread.reg copy to Thread.oldreg
                movsw
                mov     eax, [ebp+pThreadInfo]
                mov     dword ptr [eax+61Ch], 1
將線程計(jì)數(shù)自加1,將線程信息結(jié)構(gòu)體指針指向下一個(gè)結(jié)構(gòu)體的首地址(ThreadInfo的大小為66Ch):
j_next_Thread:                          ; CODE XREF: GetThreadInfo+76 j
                                        ; GetThreadInfo+341 j
                inc     [ebp+i]
                add     [ebp+pThreadInfo], 66Ch ; pThreadInfo -> next ThreadInfo
這里為循環(huán)體的判斷處,檢查是否遍歷完所有線程,若沒有遍歷完,則繼續(xù)遍歷:
loc_42E7C1:                             ; CODE XREF: GetThreadInfo+28 j
                mov     edx, [ebp+i]
                cmp     edx, Num_Thread
                jl      getThreadInfo
                mov     eax, [ebp+ret]
最后恢復(fù)現(xiàn)場(chǎng):
_exit:                                  ; CODE XREF: GetThreadInfo+19 j
                pop     edi
                pop     esi
                pop     ebx
                mov     esp, ebp
                pop     ebp
                retn
GetThreadInfo   endp
                              武漢科銳學(xué)員: angelqkm
                                2008-5-25                                 
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
逆向工程
高級(jí)文件格式分析(原創(chuàng))
算法分析第一課
匯編語言的準(zhǔn)備知識(shí)
IDA簡(jiǎn)易教程
軟件脫殼、破重啟驗(yàn)證、追碼、制作內(nèi)存注冊(cè)機(jī)
更多類似文章 >>
生活服務(wù)
熱點(diǎn)新聞
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服