小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

惡意軟件反檢測(cè)技術(shù)介紹

 bazatu 2011-03-11
惡意軟件反檢測(cè)技術(shù)介紹

本文中,我們將向讀者介紹惡意軟件用以阻礙對(duì)其進(jìn)行逆向工程的各種反調(diào)試技術(shù),以幫助讀者很好的理解這些技術(shù),從而能夠更有效地對(duì)惡意軟件進(jìn)行動(dòng)態(tài)檢測(cè)和分析。
  一、反調(diào)試技術(shù)

  反調(diào)試技術(shù)是一種常見的反檢測(cè)技術(shù),因?yàn)閻阂廛浖偸瞧髨D監(jiān)視自己的代碼以檢測(cè)是否自己正在被調(diào)試。為做到這一點(diǎn),惡意軟件可以檢查自己代碼是否被設(shè)置了斷點(diǎn),或者直接通過系統(tǒng)調(diào)用來(lái)檢測(cè)調(diào)試器。

  1.斷點(diǎn)

  為了檢測(cè)其代碼是否被設(shè)置斷點(diǎn),惡意軟件可以查找指令操作碼0xcc(調(diào)試器會(huì)使用該指令在斷點(diǎn)處取得惡意軟件的控制權(quán)),它會(huì)引起一個(gè)SIGTRAP。如果惡意軟件代碼本身建立了一個(gè)單獨(dú)的處理程序的話,惡意軟件也可以設(shè)置偽斷點(diǎn)。用這種方法惡意軟件可以在被設(shè)置斷點(diǎn)的情況下繼續(xù)執(zhí)行其指令。

  惡意軟件也可以設(shè)法覆蓋斷點(diǎn),例如有的病毒采用了反向解密循環(huán)來(lái)覆蓋病毒中的斷點(diǎn)。相反,還有的病毒則使用漢明碼自我糾正自身的代碼。漢明碼使得程序可以檢測(cè)并修改錯(cuò)誤,但是在這里卻使病毒能夠檢測(cè)并清除在它的代碼中的斷點(diǎn)。

  2.計(jì)算校驗(yàn)和

  惡意軟件也可以計(jì)算自身的校驗(yàn)和,如果校驗(yàn)和發(fā)生變化,那么病毒會(huì)假定它正在被調(diào)試,并且其代碼內(nèi)部已被放置斷點(diǎn)。VAMPiRE是一款抗反調(diào)試工具,可用來(lái)逃避斷點(diǎn)的檢測(cè)。VaMPiRE通過在內(nèi)存中維護(hù)一張斷點(diǎn)表來(lái)達(dá)到目的,該表記錄已被設(shè)置的所有斷點(diǎn)。該程序由一個(gè)頁(yè)故障處理程序(PFH),一個(gè)通用保護(hù)故障處理程序(GPFH),一個(gè)單步處理程序和一個(gè)框架API組成。當(dāng)一個(gè)斷點(diǎn)被觸發(fā)的時(shí)候,控制權(quán)要么傳給PFH(處理設(shè)置在代碼、數(shù)據(jù)或者內(nèi)存映射I/O中的斷點(diǎn)),要么傳給GPFH(處理遺留的I/O斷點(diǎn))。單步處理程序用于存放斷點(diǎn),使斷點(diǎn)可以多次使用。

  3.檢測(cè)調(diào)試器

  在Linux系統(tǒng)上檢測(cè)調(diào)試器有一個(gè)簡(jiǎn)單的方法,只要調(diào)用Ptrace即可,因?yàn)閷?duì)于一個(gè)特定的進(jìn)程而言無(wú)法連續(xù)地調(diào)用Ptrace兩次以上。在Windows中,如果程序目前處于被調(diào)試狀態(tài)的話,系統(tǒng)調(diào)用isDebuggerPresent將返回1,否則返回0。這個(gè)系統(tǒng)調(diào)用簡(jiǎn)單檢查一個(gè)標(biāo)志位,當(dāng)調(diào)試器正在運(yùn)行時(shí)該標(biāo)志位被置1。直接通過進(jìn)程環(huán)境塊的第二個(gè)字節(jié)就可以完成這項(xiàng)檢查,以下代碼為大家展示的就是這種技術(shù):

  mov eax, fs:[30h]

  move eax, byte [eax+2]

  test eax, eax

  jne @DdebuggerDetected

  在上面的代碼中,eax被設(shè)置為PEB(進(jìn)程環(huán)境塊),然后訪問PEB的第二個(gè)字節(jié),并將該字節(jié)的內(nèi)容移入eax。通過查看eax是否為零,即可完成這項(xiàng)檢測(cè)。如果為零,則不存在調(diào)試器;否則,說明存在一個(gè)調(diào)試器。

  如果某個(gè)進(jìn)程為提前運(yùn)行的調(diào)試器所創(chuàng)建的,那么系統(tǒng)就會(huì)給ntdll.dll中的堆操作例程設(shè)置某些標(biāo)志,這些標(biāo)志分別是FLG_HEAP_ENABLE_TAIL_CHECK、FLG_HEAP_ENABLE_FREE_CHECK和FLG_HEAP_VALIDATE_PARAMETERS。我們可以通過下列代碼來(lái)檢查這些標(biāo)志:

  mov eax, fs:[30h]

  mov eax, [eax+68h]

  and eax, 0x70

  test eax, eax

  jne @DebuggerDetected

  在上面的代碼中,我們還是訪問PEB,然后通過將PEB的地址加上偏移量68h到達(dá)堆操作例程所使用的這些標(biāo)志的起始位置,通過檢查這些標(biāo)志就能知道是否存在調(diào)試器。

  檢查堆頭部?jī)?nèi)諸如ForceFlags之類的標(biāo)志也能檢測(cè)是否有調(diào)試器在運(yùn)行,如下所示:

  mov eax, fs:[30h]

  mov eax, [eax+18h] ;process heap

  mov eax, [eax+10h] ;heap flags

  test eax, eax

  jne @DebuggerDetected

  上面的代碼向我們展示了如何通過PEB的偏移量來(lái)訪問進(jìn)程的堆及堆標(biāo)志,通過檢查這些內(nèi)容,我們就能知道Force標(biāo)志是否已經(jīng)被當(dāng)前運(yùn)行的調(diào)試器提前設(shè)置為1了。

  另一種檢測(cè)調(diào)試器的方法是,使用NtQueryInformationProcess這個(gè)系統(tǒng)調(diào)用。我們可以將ProcessInformationClass設(shè)為7來(lái)調(diào)用該函數(shù),這樣會(huì)引用ProcessDebugPort,如果該進(jìn)程正在被調(diào)試的話,該函數(shù)將返回-1。示例代碼如下所示。

  push 0push 4push offset isdebuggedpush 7 ;ProcessDebugPortpush -1call NtQueryInformationProcesstest eax, eaxjne @ExitErrorcmp isdebugged, 0jne @DebuggerDetected

  在本例中,首先把NtQueryInformationProcess的參數(shù)壓入堆棧。這些參數(shù)介紹如下:第一個(gè)是句柄(在本例中是0),第二個(gè)是進(jìn)程信息的長(zhǎng)度(在本例中為4字節(jié)),接下來(lái)是進(jìn)程信息類別(在本例中是7,表示ProcessDebugPort),下一個(gè)是一個(gè)變量,用于返回是否存在調(diào)試器的信息。如果該值為非零值,那么說明該進(jìn)程正運(yùn)行在一個(gè)調(diào)試器下;否則,說明一切正常。最后一個(gè)參數(shù)是返回長(zhǎng)度。使用這些參數(shù)調(diào)用NtQueryInformationProcess后的返回值位于isdebugged中。隨后測(cè)試該返回值是否為0即可。

  另外,還有其他一些檢測(cè)調(diào)試器的方法,如檢查設(shè)備列表是否含有調(diào)試器的名稱,檢查是否存在用于調(diào)試器的注冊(cè)表鍵,以及通過掃描內(nèi)存以檢查其中是否含有調(diào)試器的代碼等。

  另一種非常類似于EPO的方法是,通知PE加載器通過PE頭部中的線程局部存儲(chǔ)器(TLS)表項(xiàng)來(lái)引用程序的入口點(diǎn)。這會(huì)導(dǎo)致首先執(zhí)行TLS中的代碼,而不是先去讀取程序的入口點(diǎn)。因此,TLS在程序啟動(dòng)就可以完成反調(diào)試所需檢測(cè)。從TLS啟動(dòng)時(shí),使得病毒得以能夠在調(diào)試器啟動(dòng)之前就開始運(yùn)行,因?yàn)橐恍┱{(diào)試器是在程序的主入口點(diǎn)處切入的。

 4.探測(cè)單步執(zhí)行

  惡意軟件還能夠通過檢查單步執(zhí)行來(lái)檢測(cè)調(diào)試器。要想檢測(cè)單步執(zhí)行的話,我們可以把一個(gè)值放進(jìn)堆棧指針,然后看看這個(gè)值是否還在那里。如果該值在那里,這意味著,代碼正在被單步執(zhí)行。當(dāng)調(diào)試器單步執(zhí)行一個(gè)進(jìn)程時(shí),當(dāng)其取得控制時(shí)需要把某些指令壓入棧,并在執(zhí)行下一個(gè)指令之前將其出棧。所以,如果該值仍然在那里,就意味著其它正在運(yùn)行的進(jìn)程已經(jīng)在使用堆棧。下面的示例代碼展示了惡意軟件是如何通過堆棧狀態(tài)來(lái)檢測(cè)單步執(zhí)行的:

  Mov bp,sp;選擇堆棧指針

  Push ax ;將ax壓入堆棧

  Pop ax ;從堆棧中選擇該值

  Cmp word ptr [bp -2],ax ;跟堆棧中的值進(jìn)行比較

  Jne debug ;如果不同,說明發(fā)現(xiàn)了調(diào)試器。

  如上面的注釋所述,一個(gè)值被壓入堆棧然后又被彈出。如果存在調(diào)試器,那么堆棧指針–2位置上的值就會(huì)跟剛才彈出堆棧的值有所不同,這時(shí)就可以采取適當(dāng)?shù)男袆?dòng)。

  5.在運(yùn)行時(shí)中檢測(cè)速度衰減

  通過觀察程序在運(yùn)行時(shí)是否減速,惡意代碼也可以檢測(cè)出調(diào)試器。如果程序在運(yùn)行時(shí)速度顯著放緩,那就很可能意味著代碼正在單步執(zhí)行。因此如果兩次調(diào)用的時(shí)間戳相差甚遠(yuǎn),那么惡意軟件就需要采取相應(yīng)的行動(dòng)了。Linux跟蹤工具包LTTng/LTTV通過觀察減速問題來(lái)跟蹤病毒。當(dāng)LTTng/LTTV追蹤程序時(shí),它不需要在程序運(yùn)行時(shí)添加斷點(diǎn)或者從事任何分析。此外,它還是用了一種無(wú)鎖的重入機(jī)制,這意味著它不會(huì)鎖定任何Linux內(nèi)核代碼,即使這些內(nèi)核代碼是被跟蹤的程序需要使用的部分也是如此,所以它不會(huì)導(dǎo)致被跟蹤的程序的減速和等待。

  6.指令預(yù)取

  如果惡意代碼篡改了指令序列中的下一條指令并且該新指令被執(zhí)行了的話,那么說明一個(gè)調(diào)試器正在運(yùn)行。這是指令預(yù)取所致:如果該新指令被預(yù)取,就意味著進(jìn)程的執(zhí)行過程中有其他程序的切入。否則,被預(yù)取和執(zhí)行的應(yīng)該是原來(lái)的指令。

  7.自修改代碼

  惡意軟件也可以讓其他代碼自行修改(自行修改其他代碼),這樣的一個(gè)例子是HDSpoof。這個(gè)惡意軟件首先啟動(dòng)了一些異常處理例程,然后在運(yùn)行過程中將其消除。這樣一來(lái),如果發(fā)生任何故障的話,運(yùn)行中的進(jìn)程會(huì)拋出一個(gè)異常,這時(shí)病毒將終止運(yùn)行。此外,它在運(yùn)行期間有時(shí)還會(huì)通過清除或者添加異常處理例程來(lái)篡改異常處理例程。在下面是HDSpoof清除全部異常處理例程(默認(rèn)異常處理例程除外)的代碼。

  exception handlers before:

  0x77f79bb8 ntdll.dll:executehandler2@20 + 0x003a0x0041adc9 hdspoof.exe+0x0001adc90x77e94809 __except_handler3

  exception handlers after:

  0x77e94809 __except_handler3

  0x41b770: 8b44240c mov eax,dword ptr [esp+0xc]0x41b774: 33c9 xor ecx,ecx 0x41b776: 334804 xor ecx,dword ptr [eax+0x4]0x41b779: 334808 xor ecx,dword ptr [eax+0x8]0x41b77c: 33480c xor ecx,dword ptr [eax+0xc]0x41b77f: 334810 xor ecx,dword ptr [eax+0x10]0x41b782: 8b642408 mov esp,dword ptr [esp+0x8]0x41b786: 648f0500000000 pop dword ptr fs:[0x0]

  下面是HDSpoof創(chuàng)建一個(gè)新的異常處理程序的代碼。

  0x41f52b: add dword ptr [esp],0x9ca

  0x41f532: push dword ptr [dword ptr fs:[0x0]

  0x41f539: mov dword ptr fs:[0x0],esp

  8.覆蓋調(diào)試程序信息

  一些惡意軟件使用各種技術(shù)來(lái)覆蓋調(diào)試信息,這會(huì)導(dǎo)致調(diào)試器或者病毒本身的功能失常。通過鉤住中斷INT 1和INT 3(INT 3是調(diào)試器使用的操作碼0xCC),惡意軟件還可能致使調(diào)試器丟失其上下文。這對(duì)正常運(yùn)行中的病毒來(lái)說毫無(wú)妨礙。另一種選擇是鉤住各種中斷,并調(diào)用另外的中斷來(lái)間接運(yùn)行病毒代碼。

  下面是Tequila 病毒用來(lái)鉤住INT 1的代碼:

  new_interrupt_one:

  push bp

  mov bp,sp

  cs cmp b[0a],1 ;masm mod. needed

  je 0506 ;masm mod. needed

  cmp w[bp+4],09b4

  ja 050b ;masm mod. needed

  push ax

  push es

  les ax,[bp+2]

  cs mov w[09a0],ax ;masm mod. needed

  cs mov w[09a2],es ;masm mod. needed

  cs mov b[0a],1

  pop es

  pop ax

  and w[bp+6],0feff

  pop bp

  iret

  一般情況下,當(dāng)沒有安裝調(diào)試器的時(shí)候,鉤子例程被設(shè)置為IRET。V2Px使用鉤子來(lái)解密帶有INT 1和INT 3的病毒體。在代碼運(yùn)行期間,會(huì)不斷地用到INT 1和INT 3向量,有關(guān)計(jì)算是通過中斷向量表來(lái)完成的。

[1] [2] [3]

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

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多