欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

无标题

无标题

【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
    哈哈,是不是很有意思呀?:)
%最后的话%
~~~~~~~~~~
    这是一些简单的反调试招。我希望你能够在你的病毒中没有任何问题的使用它们,看你了!

注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功