zoukankan      html  css  js  c++  java
  • AVP主动防御之隐藏进程

    卡巴主动防御中检测隐藏进程的方法:
        Hook掉系统的SwapContext,这种方法是在2003年被提出的;这个函数被KiSwapThread调用,负责线程调度;下面这部分代码就是卡巴Detour SwapContext的汇编代码的分析(后面附上对应的c代码):

    (PS:突破这种方式来隐藏进程的方法也在随后就出来了,自己实现线程调度,详见:http://hi-tech.nsys.by/33/)

    一:KlifSetSwapContextHook

    .text:0002DE60 KlifSetSwapContextHook proc near      
    .text:0002DE60
    .text:0002DE60 var_5C          = dword ptr -5Ch
    .text:0002DE60 var_58          = dword ptr -58h
    .text:0002DE60 var_54          = dword ptr -54h
    .text:0002DE60 var_50          = dword ptr -50h
    .text:0002DE60 var_48          = dword ptr -48h
    .text:0002DE60 var_38          = dword ptr -38h
    .text:0002DE60 var_34          = dword ptr -34h
    .text:0002DE60 var_30          = word ptr -30h
    .text:0002DE60 var_24          = dword ptr -24h
    .text:0002DE60 var_20          = dword ptr -20h
    .text:0002DE60 var_1C          = dword ptr -1Ch
    .text:0002DE60 var_18          = dword ptr -18h
    .text:0002DE60 var_10          = dword ptr -10h
    .text:0002DE60 var_4           = dword ptr -4
    .text:0002DE60
    .text:0002DE60                 push    ebp
    .text:0002DE61                 mov     ebp, esp
    .text:0002DE63                 push    0FFFFFFFFh
    .text:0002DE65                 push    offset dword_13158
    .text:0002DE6A                 push    offset sub_2E46C
    .text:0002DE6F                 mov     eax, large fs:0
    .text:0002DE75                 push    eax
    .text:0002DE76                 mov     large fs:0, esp
    .text:0002DE7D                 sub     esp, 4Ch
    .text:0002DE80                 push    ebx
    .text:0002DE81                 push    esi
    .text:0002DE82                 push    edi
    .text:0002DE83                 mov     [ebp+var_18], esp
    .text:0002DE86                 mov     ecx, g_NtoskrnlAddr
    .text:0002DE8C                 cmp     word ptr [ecx], 5A4Dh ; Ms dos stub - MZ
    .text:0002DE91                 jnz     Routine_Error
    .text:0002DE97                 mov     eax, [ecx+3Ch]  ; e_lfanew
    .text:0002DE9A                 add     eax, ecx
    .text:0002DE9C                 cmp     dword ptr [eax], 4550h ; PE
    .text:0002DEA2                 jnz     Routine_Error
    .text:0002DEA8                 xor     edx, edx
    .text:0002DEAA                 mov     dx, [eax+14h]      ; SizeOfOptionalHeader
    .text:0002DEAE                 lea     eax, [edx+eax+18h] ; 指向第一Section(.text)
    .text:0002DEB2                 mov     esi, [eax+0Ch]
    .text:0002DEB5                 add     esi, ecx           ;.text区的内存地址
    .text:0002DEB7                 mov     eax, [eax+10h]     ;.text区的内存大小
    .text:0002DEBA                 xor     ebx, ebx
    .text:0002DEBC                 mov     [ebp+var_20], ebx
    .text:0002DEBF                 mov     [ebp+var_4], ebx
    .text:0002DEC2                 mov     ecx, ds:NtBuildNumber
    .text:0002DEC8                 mov     cx, [ecx]
    .text:0002DECB                 cmp     cx, 2600        ; 1575 - 2195 Win2K
    .text:0002DECB                                         ; 2202 - 2600 WinXP
    .text:0002DECB                                         ; 3501 - 3790 Win2003
    .text:0002DED0                 jle     Is2kORxp
    .text:0002DED6                 mov     [ebp+var_1C], 5
    .text:0002DEDD                 cmp     cx, 3790
    .text:0002DEE2                 jl      short Is2003Release
    .text:0002DEE4                 mov     ecx, offset g_2003CharCode ; 2003的特征码
    .text:0002DEE9                 mov     [ebp+var_58], ecx
    .text:0002DEEC                 mov     edx, 9
    .text:0002DEF1                 mov     [ebp+var_54], edx
    .text:0002DEF4                 xor     edi, edi
    .text:0002DEF6                 jmp     short Is2003
    .text:0002DEF8
    .text:0002DEF8 Is2003Release:
    .text:0002DEF8                 cmp     cx, 3604
    .text:0002DEFD                 jle     short Is2003Beta3
    .text:0002DEFF                 mov     ecx, offset g_ReleaseCharCode ; 2003Beat3-Release的特征码
    .text:0002DF04                 mov     [ebp+var_58], ecx
    .text:0002DF07                 mov     edx, 8
    .text:0002DF0C                 mov     [ebp+var_54], edx
    .text:0002DF0F                 mov     edi, 0Ah
    .text:0002DF14                 jmp     short Is2003
    .text:0002DF16
    .text:0002DF16 Is2003Beta3:
    .text:0002DF16                 mov     ecx, offset g_Bete3CharCode ; 2003的Beta-Beta3特征码
    .text:0002DF1B                 mov     [ebp+var_58], ecx
    .text:0002DF1E                 mov     edx, 7
    .text:0002DF23                 mov     [ebp+var_54], edx
    .text:0002DF26                 mov     edi, 9
    .text:0002DF2B
    .text:0002DF2B Is2003:
    .text:0002DF2B                 mov     [ebp+var_50], edi
    .text:0002DF2E                 push    edx
    .text:0002DF2F                 push    ecx
    .text:0002DF30                 push    eax
    .text:0002DF31                 push    esi
    .text:0002DF32                 call    KilfGetAddrByCharCode ; arg_c 特征码的长度
    .text:0002DF32                                               ; arg_8 特征码的地址
    .text:0002DF32                                               ; arg_4 搜索的最大范围
    .text:0002DF32                                               ; arg_0 搜索的起始地址
    .text:0002DF37                 mov     [ebp+var_24], eax
    .text:0002DF3A                 cmp     eax, 0FFFFFFFFh
    .text:0002DF3D                 jz      Search_Failed
    .text:0002DF43                 add     eax, edi
    .text:0002DF45                 add     esi, eax
    .text:0002DF47                 cmp     dword ptr [esi], 0FF1043FFh
    .text:0002DF4D                 jnz     short Search_Failed
    .text:0002DF4F                 mov     ebx, esi
    .text:0002DF51                 mov     [ebp+var_20], ebx
    .text:0002DF54                 mov     [ebp+var_4], 0FFFFFFFFh
    .text:0002DF5B                 jmp     SetSwapContextHook
    .text:0002DF60
    .text:0002DF60 Is2kORxp:
    .text:0002DF60                 push    5
    .text:0002DF62                 push    offset g_2kCharCode ; 2k的特征码
    .text:0002DF67                 push    eax
    .text:0002DF68                 push    esi
    .text:0002DF69                 call    KilfGetAddrByCharCode ; arg_c 特征码的长度
    .text:0002DF69                                               ; arg_8 特征码的地址
    .text:0002DF69                                               ; arg_4 搜索的最大范围
    .text:0002DF69                                               ; arg_0 搜索的起始地址
    .text:0002DF6E                 mov     [ebp+var_24], eax
    .text:0002DF71                 cmp     eax, 0FFFFFFFFh
    .text:0002DF74                 jz      short Search_Failed
    .text:0002DF76                 mov     edx, ds:NtBuildNumber
    .text:0002DF7C                 cmp     word ptr [edx], 2195
    .text:0002DF81                 jle     short Is2k
    .text:0002DF83
    .text:0002DF83 Isxp:
    .text:0002DF83                 add     esi, eax
    .text:0002DF85                 mov     [ebp+var_5C], esi
    .text:0002DF88                 mov     [ebp+var_1C], 7
    .text:0002DF8F                 push    4
    .text:0002DF91                 push    offset g_XpCharCode ; xp的特征码
    .text:0002DF96                 push    100h
    .text:0002DF9B                 push    esi
    .text:0002DF9C                 call    KilfGetAddrByCharCode ; arg_c 特征码的长度
    .text:0002DF9C                                               ; arg_8 特征码的地址
    .text:0002DF9C                                               ; arg_4 搜索的最大范围
    .text:0002DF9C                                               ; arg_0 搜索的起始地址
    .text:0002DFA1                 mov     [ebp+var_24], eax
    .text:0002DFA4                 cmp     eax, 0FFFFFFFFh
    .text:0002DFA7                 jz      short Search_Failed
    .text:0002DFA9                 lea     ebx, [esi+eax+2]
    .text:0002DFAD                 mov     [ebp+var_20], ebx
    .text:0002DFB0                 mov     [ebp+var_4], 0FFFFFFFFh
    .text:0002DFB7                 jmp     short SetSwapContextHook
    .text:0002DFB9
    .text:0002DFB9 Is2k:
    .text:0002DFB9                 lea     ebx, [eax+esi]
    .text:0002DFBC                 mov     [ebp+var_20], ebx
    .text:0002DFBF                 mov     [ebp+var_1C], 5
    .text:0002DFC6
    .text:0002DFC6 Search_Failed:
    .text:0002DFC6                 mov     [ebp+var_4], 0FFFFFFFFh
    .text:0002DFCD                 jmp     short SetSwapContextHook
    .text:0002DFCF
    .text:0002DFCF SEH_Routine:    
    .text:0002DFCF                 mov     eax, 1
    .text:0002DFD4                 retn
    .text:0002DFD5
    .text:0002DFD5 SEH_Routine2:      
    .text:0002DFD5                 mov     esp, [ebp-18h]
    .text:0002DFD8                 mov     dword ptr [ebp-4], 0FFFFFFFFh
    .text:0002DFDF                 mov     ebx, [ebp-20h]
    .text:0002DFE2
    .text:0002DFE2 SetSwapContextHook:
    .text:0002DFE2                 test    ebx, ebx
    .text:0002DFE4                 jz      Routine_Error
    .text:0002DFEA                 mov     eax, 90909090h
    .text:0002DFEF                 mov     [ebp+var_38], eax
    .text:0002DFF2                 mov     [ebp+var_34], eax
    .text:0002DFF5                 mov     [ebp+var_30], ax
    .text:0002DFF9                 mov     byte ptr [ebp+var_38], 0E9h ; JMP
    .text:0002DFFD                 mov     ecx, offset KlifSwapContext
    .text:0002E002                 sub     ecx, ebx        ; EBX是SwapContext+offset的地址
    .text:0002E004                 sub     ecx, 5
    .text:0002E007                 mov     [ebp+var_38+1], ecx
    .text:0002E00A
    .text:0002E00A Klif_Store_SC_Addr:                     ; 保存原来的指令
    .text:0002E00A                 mov     ecx, [ebp+var_1C]
    .text:0002E00D                 lea     edx, [ecx+ebx]
    .text:0002E010                 mov     g_SwapContextAddr, edx
    .text:0002E016                 mov     esi, ebx
    .text:0002E018                 mov     edi, offset g_SwapContextOpcode
    .text:0002E01D                 mov     eax, ecx
    .text:0002E01F                 shr     ecx, 2
    .text:0002E022                 rep movsd
    .text:0002E024                 mov     ecx, eax
    .text:0002E026                 and     ecx, 3
    .text:0002E029                 rep movsb
    .text:0002E02B                 lea     ecx, [ebp+var_48]
    .text:0002E02E                 push    ecx
    .text:0002E02F                 push    1
    .text:0002E031                 push    ebx
    .text:0002E032                 call    KlifSetInterruptStauts
    .text:0002E037                 test    al, al
    .text:0002E039                 jz      short Routine_Error
    .text:0002E03B                 mov     ecx, offset g_kernelLock
    .text:0002E040                 call    KlifClearInterruptAndLock
    .text:0002E045
    .text:0002E045 Klif_Set_SC_Hook:                         ; detour开始
    .text:0002E045                 mov     ecx, [ebp+var_1C] ; 覆盖的Opcodes Num
    .text:0002E048                 lea     esi, [ebp+var_38] ; Jmp Klif+0x????
    .text:0002E04B                 mov     edi, ebx
    .text:0002E04D                 mov     edx, ecx
    .text:0002E04F                 shr     ecx, 2
    .text:0002E052                 rep movsd
    .text:0002E054                 mov     ecx, edx
    .text:0002E056                 and     ecx, 3
    .text:0002E059                 rep movsb
    .text:0002E05B                 mov     edx, eax
    .text:0002E05D                 mov     ecx, offset g_kernelLock
    .text:0002E062                 call    KlifUnLock
    .text:0002E067                 lea     eax, [ebp+var_48]
    .text:0002E06A                 push    eax
    .text:0002E06B                 mov     ecx, [ebp+var_48]
    .text:0002E06E                 push    ecx
    .text:0002E06F                 push    ebx
    .text:0002E070                 call    KlifSetInterruptStauts
    .text:0002E075                 mov     al, 1
    .text:0002E077                 mov     ecx, [ebp+var_10]
    .text:0002E07A                 mov     large fs:0, ecx
    .text:0002E081                 pop     edi
    .text:0002E082                 pop     esi
    .text:0002E083                 pop     ebx
    .text:0002E084                 mov     esp, ebp
    .text:0002E086                 pop     ebp
    .text:0002E087                 retn
    .text:0002E088 Routine_Error:                         
    .text:0002E088                 xor     al, al
    .text:0002E08A                 mov     ecx, [ebp+var_10]
    .text:0002E08D                 mov     large fs:0, ecx
    .text:0002E094                 pop     edi
    .text:0002E095                 pop     esi
    .text:0002E096                 pop     ebx
    .text:0002E097                 mov     esp, ebp
    .text:0002E099                 pop     ebp
    .text:0002E09A                 retn
    .text:0002E09A KlifSetSwapContextHook endp


    二:KlifSwapContext

    .text:0002DE10 KlifSwapContext:                      
    .text:0002DE10                 pushf
    .text:0002DE11                 pusha
    .text:0002DE12                 mov     ebp, esp
    .text:0002DE14                 sub     esp, 10h
    .text:0002DE17                 add     esi, dword_2FC90
    .text:0002DE1D                 add     edi, dword_2FC90
    .text:0002DE23                 mov     eax, [esi]      ; Address of next thread
    .text:0002DE25                 mov     [ebp-8], eax
    .text:0002DE28                 mov     eax, [edi]      ; Address of previous thread
    .text:0002DE2A                 mov     [ebp-0Ch], eax
    .text:0002DE2D                 mov     ecx, offset g_kernelLock
    .text:0002DE32                 call    KlifClearInterruptAndLock
    .text:0002DE37                 mov     [ebp-4], eax
    .text:0002DE3A                 mov     eax, [ebp-8]
    .text:0002DE3D                 push    eax             ; Address of next thread
    .text:0002DE3E                 call    KlifSwapContextMain ;//MAIN!!!
    .text:0002DE43                 mov     edx, [ebp-4]
    .text:0002DE46                 mov     ecx, offset g_kernelLock
    .text:0002DE4B                 call    KlifUnLock
    .text:0002DE50                 add     esp, 10h
    .text:0002DE53                 popa
    .text:0002DE54                 popf
    .text:0002DE55                 jmp     g_OldSwapContext
    .text:0002DE5B                 align 10h


    三:KlifSetSwapContextHook 对应C代码

    PVOID g_NtoskrnlAddr;
    char  g_2003CharCode[8]    = {0xFF, 0x43, 0x10, 0xFF, 0x33, 0x83, 0x7B, 0x08};
    char  g_ReleaseCharCode[8] = {0x80, 0x7E, 0x5D, 0x00, 0x74, 0x04, 0xF3, 0x90};
    char  g_Bete3CharCode[8]   = {0xF7, 0x46, 0x24, 0x01, 0x00, 0x00, 0x00, 0x00};
    char  g_2kCharCode[8]      = {0x26, 0xC6, 0x46, 0x2D, 0x02, 0x00, 0x00, 0x00};
    char  g_xpCharCode[4]      = {0x8B, 0x0B, 0x83, 0xBB};
    int   g_SwapContextOpcode[4] = {0x90909090, 0x90909090, 0x9090FF25, g_SwapContextAddr};
    int   g_SwapContextAddr;
    char  g_kernelLock;

    BOOL KlifSetSwapContextHook()
    {
     METUEX ProtectMutex;        //这个不大准确
     int    nOffset          = 0;//特征码距Ntoskrnl的偏移移
     int    nReplaceNum      = 0;//要替换SwapContext几个字节
     char*  pSwapContextAddr = 0;//要替换的地址
     
     int   nCompareNum  = 0;
     char* pCompareCode = 0;
     
     PIMAGE_DOS_HEADER     pImageDos =  (PIMAGE_DOS_HEADER)g_NtoskrnlAddr;
     PIMAGE_NT_HEADERS     pImageNt  =  (PIMAGE_NT_HEADERS)(g_NtoskrnlAddr+pImageDos->e_lfanew);
     PIMAGE_SECTION_HEADER pImageSec =  (PIMAGE_SECTION_HEADER )((char*)pImageNt+pImageNt->FileHeader.SizeOfOptionalHeader);
     
     char* pSearchAddr = (char*)g_NtoskrnlAddr + pImageSec->VirtualAddress;
     int   nSearchArea = pImageSection->SizeOfRawData;
     
     if (*(WORD*)g_NtoskrnlAddr               == 0x5A4D &&
         *(WORD*)((char*)g_NtoskrnlAddr+0x3C) == 0x4550)
     {
      return FALSE;
     }
     
     //Windows 2003
     if (*NtBuildNumber > 2600)
     {
      nReplaceNum = 5;

      int nOrgOffset = 0;
      if (*NtBuildNumber >= 3790)
      {
       nCompareNum = 9;
       pCompareCode = g_2003CharCode;
       
      }else
      {
       if (*NtBuildNumber > 3604)
       {
        nOrgOffset   = 10;
        nCompareNum  = 8;
        pCompareCode = g_ReleaseCharCode;
       }else
       {
        nOrgOffset   = 9;
        nCompareNum  = 7;
        pCompareCode = g_Bete3CharCode;
         
       }
      }
      
      nOffset = KilfGetAddrByCharCode(nCompareNum, 
                                      pCompareCode,
                                      nSearchArea,
                                      pSearchAddr);
      if (nOffset == -1)
      {
       return FALSE;
      }
      
      pSwapContextAddr = pSearchAddr + nOffset + nOrgOffset;
      
      if (*((int*)pSwapContextAddr) != 0xFF1043FF)
      {
       return FALSE;
      }
      
     }else
     {
      //Win2K
      nOffset = KilfGetAddrByCharCode(5,
                                      g_2kCharCode,
                                      nSearchArea,
                                      pSearchAddr);
      if (nOffset == -1)
      {
       return FALSE;
      }
      
      //WinXP
      if (*NtBuildNumber > 2395)
      {
       nOffset = KilfGetAddrByCharCode(4,
                                       g_xpCharCode,
                                       nSearchArea,
                                       pSearchAddr);   
       if (nOffset == -1)
       {
        return FALSE;
       }
       nReplaceNum      = 7;
       pSwapContextAddr = pSearchAddr + nOffset + 2;

      }else
      {
       nReplaceNum      = 5;
       pSwapContextAddr = pSearchAddr + nOffset;
      }
     }

     if (!pSwapContextAddr)
     {
      return FALSE;
     }

     char NewSwapContext[9] = {0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90};

     NewSwapContext[0]           = 0xE9;
     *((int*)&NewSwapContext[1]) = (int)KlifSwapContext - (int)pSwapContextAddr - 5;


     //保存原来的指令
     g_SwapContextAddr = pSwapContextAddr + nReplaceNum;//跳回来的地址

     for(int i = nReplaceNum; i>0; i--)
     {
      g_SwapContextOpcode[i] = pSwapContextAddr[i];
     }
     

     if (!KlifSetInterruptStauts(pSwapContextAddr, 1, &ProtectMutex))
     {
      return FALSE;
     }

     KlifClearInterruptAndLock(g_kernelLock);

     //覆盖原来指令
     for(i = nReplaceNum; i>0; i--)
     {
      pSwapContextAddr[i] = NewSwapContext[i];
     }
     KlifUnLock(g_kernelLock);

     KlifSetInterruptStauts(pSwapContextAddr, ProtectMutex, &ProtectMutex);

     return TRUE;
    }

    阐述中存在错误,望指教,谢谢!转载请注明地址 :)



    转载于:http://blog.vckbase.com/windowssky
  • 相关阅读:
    laravel进阶知识大纲
    spring boot 配置多个DispatcherServlet
    RepeatReadRequestWrapper
    RestTemplate HttpClient详解及如何设置忽略SSL
    Swagger注解-@ApiModel 和 @ApiModelProperty
    SpringBoot 接收 单个String入参之解决方案
    spring boot添加 LocalDateTime 等 java8 时间类序列化和反序列化的支持
    Mybatisplus实现MetaObjectHandler接口自动更新创建时间更新时间
    关于SpringBoot 2.0,Pageable 无法注入,提示缺少默认构造方法的解决办法
    OP_REQUIRES failed at save_restore_v2_ops.cc:109 : Permission denied: model/variables/variables_t emp; Permission denied
  • 原文地址:https://www.cnblogs.com/flying_bat/p/976385.html
Copyright © 2011-2022 走看看