Billy Belceb 病毒編寫教程for Win32 ----Win32 反除錯

看雪資料發表於2004-05-28

【Win32 反除錯】
~~~~~~~~~~~~~~~
    下面我將給出一些花招用來保護你的病毒或者程式不被除錯(所有級別的,應用級和系統級)。我希望你將喜歡它。

 % Win98/NT: 用 IsDebuggerPresent檢測應用級偵錯程式 %
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    這個API函式在Win95中沒有,所以你不得不自己檢測它的存在,並和應用級偵錯程式(如TD32)一起工作。而且它工作得很好。讓我們看看在Win32 API參考列表裡面是怎麼寫的。

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

    IsDebuggerPresent函式表明呼叫的程式是否是在一個偵錯程式下執行。這個函式從KERNEL32.DLL中匯出。

 BOOL IsDebuggerPresent(VOID)

引數
====
    這個函式沒有引數。

返回值
======

-如果當前程式是在一個偵錯程式下執行,返回值是非0值。

-如果當前程式不在偵錯程式下執行,返回值是0。

--------------------------------------------
   
    所以演示這個的例子很簡單。下面就是。

;--------從這兒開始剪下------------------------------------------------------

       .586p
       .model flat

extrn   GetProcAddress:PROC
extrn   GetModuleHandleA:PROC

extrn   MessageBoxA:PROC
extrn   ExitProcess:PROC

                .data

szTitle         db      "IsDebuggerPresent Demonstration",0
msg1            db      "Application Level Debugger Found",0
msg2            db      "Application Level Debugger NOT Found",0
msg3            db      "Error: Couldn't get IsDebuggerPresent.",10
                db      "We're probably under Win95",0

@IsDebuggerPresent db   "IsDebuggerPresent",0
K32             db      "KERNEL32",0

       .code

antidebug1:
        push    offset K32                      ; Obtain KERNEL32 base address
        call    GetModuleHandleA
        or      eax,eax                         ; Check for fails
        jz      error

        push    offset @IsDebuggerPresent       ; Now search for the existence
        push    eax                             ; of IsDebuggerPresent. If
        call    GetProcAddress                  ; GetProcAddress returns an
        or      eax,eax                         ; error, we assume we're in 
        jz      error                           ; Win95

        call    eax                             ; Call IsDebuggerPresent

        or      eax,eax                         ; If it's not 0, we're being
        jnz     debugger_found                  ; debugged

debugger_not_found:
        push    0                               ; Show "Debugger not found"
        push    offset szTitle
        push    offset msg2
        push    0
        call    MessageBoxA
        jmp     exit

error:
        push    00001010h                       ; Show "Error! We're in Win95"
        push    offset szTitle
        push    offset msg3
        push    0
        call    MessageBoxA
        jmp     exit

debugger_found:
        push    00001010h                       ; Show "Debugger found!"
        push    offset szTitle
        push    offset msg1
        push    0
        call    MessageBoxA

exit:
        push    00000000h                       ; Exit program
        call    ExitProcess
 
end     antidebug1

;--------到這兒為止剪下------------------------------------------------------

    很美妙吧?Micro$oft為我們做了這個工作:)但是,毫無疑問,不要期望這個方法對SoftICE有效,上帝;)

%Win32:知道我們是否被一個偵錯程式除錯的另外一個方法%
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    如果你看了由Murkry/iKX寫的在Xine-3中發表的"Win95 Structures and Secrets"這篇文章的話,你將意識到在FS暫存器中有一個非常酷的結構。看看FS:[20h]域...它是'DebugContext'。只要這麼做:

        mov     ecx,fs:[20h]
        jecxz   not_being_debugger
        [...]   <--- do whatever, we're being debugged :)

    所以,如果FS:[20h]是0,我們就沒有被除錯。只要享受這個小而簡單的方法來檢測偵錯程式!當然了,這個不能對SoftICE有效...

%Win32:用SEH來停止應用級偵錯程式%
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    我仍然還不知道為什麼,但是如果程式簡單地使用了SEH,應用級偵錯程式就死了。而且如果我們製造錯誤,程式碼模擬器也死了:)SEH,正如我在我的發表在DDT#1中的一篇文章所說的,可以用來達到很多有意思的目的。你可以看看“高階Win32技術”(Advanced Win32 techniques)這一章的SEH部分。

    你所必須做的是使SEH handler指向你想繼續執行程式碼的地方,而當SEH handler被安裝了,你啟用了一個標誌(一個好的選擇是在00000000h記憶體地址試圖做些事情);)

    我希望你看懂了這個。如果沒有...恩,忘記它:)而且,正如以前其它的方法一樣,這個對SoftICE沒有用。

%Win9X:檢測SoftICE (I) %
~~~~~~~~~~~~~~~~~~~~~~~~
    這裡,我必須向Super/29A致敬,因為他是告訴我這個方法的人。我把這個分成兩個部分:在這個部分中,我們將看到從一個Ring-0病毒的角度該怎麼做。我不會給出整個例子程式,因為它將佔一些不必要的行,但是你必須知道這個方法必須是在Ring-0下執行,而且因為Call-back問題(你還記得嗎?),VxDCall必須重建。

    我們將使用Virtual Machine Manager (VMM) 的Get_DDB服務,所以這個服務將為00010146h (VMM_Get_DDB)。讓我們看看SDK中關於這個服務的資訊。

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

         mov    eax, Device_ID
         mov    edi, Device_Name
         int    20h                             ; VMMCall Get_DDB
         dd     00010146h
         mov    [DDB], ecx

- 確定一個VxD是否對特定裝置安裝了,如果安裝了就會返回一個那個裝置的DDB。

- 使用ECX,flags(標誌)。

- 如果函式成功會返回指定裝置的DDB;
- 否則,返回0。

?Device_ID:裝置標誌符。對於基於名字的裝置,這個引數可以為0。

?Device_Name:一個8-字元的裝置名,不夠用空字元填充。如果Device_ID為0的時候,這個引數才被需要。裝置名大小寫敏感。

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

    現在,你想要知道為什麼了,非常簡單,SoftICE VxD的Device_ID域對於所以程式來說是一個常量,正如它在Micro$oft註冊的,所以我們就有了對付不可思議的SoftICE的武器了。它的Device_ID總是202h。所以我們應該使用如下的程式碼:

        mov     eax,00000202h
        VxDCall VMM_Get_DDB
        xchg    eax,ecx
        jecxz   NotSoftICE
        jmp     DetectedSoftICE

    NotSoftICE應該是繼續我們的病毒程式碼的地方,而DetectedSoftICE標記應該是既然我們已經知道我們的敵人還活著,該採取一些行動的地方,我不建議任何破壞性的事情,因為,例如,將會傷害我的電腦,因為我總是使得SoftICE處於啟用狀態:)

% Win9X: 檢測 SoftICE (II) %
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    下面是另外一種方法來檢測我所鍾愛得SoftICE的存在,但是基於以前的同樣的觀點: 202h ;) 我必須再次對Super致敬:)好了,在Ralph Brown的中斷列表中,我們可以看到一個在中斷2Fh(多元)的1684h服務。

----------------------------------------------
 Inp.:
        AX = 1684h
        BX = virtual device (VxD) ID (看 #1921)
        ES:DI = 0000h:0000h
 返回:  ES:DI -> VxD API  入口, 或者 0:0 如果這個 VxD 不支援一個API
 說明:  一些Windows增強-模式虛擬裝置提供了一些應用程式可以訪問的服務。例如,Virtual  Display Device(VDD)提供了由WINOLDAP輪流使用的API。

----------------------------------------------
    所以,你在BX中放一個202h,並指向這個函式。然後你要說了...“嗨,Billy... 我用於中斷多傻呀?"。我的回答是...使用VxDCALL0!!!

 % Win32: 檢測SoftICE (III) %
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    你正等待的是比較權威的和令人驚奇的招...同時在Win9x 和 WinNT環境尋找SoftICE!它非常簡單,100%基於API,而且沒有"髒"招來進行相容性。這個答案並沒有你想的那麼隱蔽...關鍵是在你肯定以前已經用過的API函式中:CreateFile。是的,那個API...不迷人嗎?好了,我得試圖開啟下面的東西:

        + SoftICE for Win9x : "\\.\SICE"
        + SoftICE for WinNT : "\\.\NTICE"

    如果這個API返回給我們和-1 (INVALID_HANDLE_VALUE)不同的東西,SoftICE就是處於啟用狀態!下面是演示程式:

;--------從這裡開始剪下--------------------------------------------------------

        .586p
        .model  flat

extrn   CreateFileA:PROC
extrn   CloseHandle:PROC
extrn   MessageBoxA:PROC
extrn   ExitProcess:PROC

        .data

szTitle         db      "SoftICE detection",0

szMessage       db      "SoftICE for Win9x : "
answ1           db      "not found!",10
                db      "SoftICE for WinNT : "
answ2           db      "not found!",10
                db      "(c) 1999 Billy Belcebu/iKX",0

nfnd            db      "found!    ",10

SICE9X          db      "\\.\SICE",0
SICENT          db      "\\.\NTICE",0

        .code

DetectSoftICE:
        push    00000000h                       ; Check for the presence of
        push    00000080h                       ; SoftICE for Win9x envirome-
        push    00000003h                       ; nts...
        push    00000000h
  push    00000001h
        push    0C0000000h
        push    offset SICE9X
        call    CreateFileA

        inc     eax
        jz      NoSICE9X
        dec     eax

        push    eax                             ; Close opened file
        call    CloseHandle

        lea     edi,answ1                       ; SoftICE found!
        call    PutFound
NoSICE9X:       
        push    00000000h                       ; And now try to open SoftICE
        push    00000080h                       ; for WinNT...
        push    00000003h
        push    00000000h
  push    00000001h
        push    0C0000000h
        push    offset SICENT
        call    CreateFileA

        inc     eax
        jz      NoSICENT
        dec     eax

        push    eax                             ; Close file handle
        call    CloseHandle

        lea     edi,answ2                       ; SoftICE for WinNT found!
        call    PutFound
NoSICENT:
        push    00h                             ; Show a MessageBox with the
        push    offset szTitle                  ; results
        push    offset szMessage
        push    00h
        call    MessageBoxA                     

        push    00h                             ; Terminate program
        call    ExitProcess

PutFound:
        mov     ecx,0Bh                         ; Change "not found" by 
        lea     esi,nfnd                        ; "found"; address of where 
        rep     movsb                           ; to do the change is in EDI
        ret

end     DetectSoftICE

;--------到這裡為止剪下--------------------------------------------------------

    這個真的起作用了,相信我:)這個同樣的方法可以應用於其它"敵對"驅動,只要對它研究一點點就可以了。

 % Win9X: 殺掉偵錯程式硬體斷點 %
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    你是否在想除錯暫存器(DR?),我們有一個小問題:它們在WinNT下是特權級指令。這一招由這些簡單的事情組成:注意DR0, DR1, DR2 和DR3(它們由偵錯程式用來作為硬體斷點的)。所以,簡單的使用這個程式碼,你就可以避開偵錯程式:

        xor     edx,edx
        mov     dr0,edx
        mov     dr1,edx
        mov     dr2,edx
        mov     dr3,edx

    哈哈,是不是很有意思呀?:)

%最後的話%
~~~~~~~~~~
    這是一些簡單的反除錯招。我希望你能夠在你的病毒中沒有任何問題的使用它們,看你了!

相關文章