AVP主动防御之隐藏进程

来源:互联网 发布:数据的统计方法 编辑:程序博客网 时间:2024/04/30 14:49
卡巴主动防御中检测隐藏进程的方法:    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;} 阐述中存在错误,望指教,谢谢!转载请注明地址 :)