好久没发代码了,发个以前写的东西,代码是照葫芦画瓢来的,共同学习,共同进步,欢迎拍砖.
代码:
#ifndef _SAFENOTIFYROUTINE_H #define _SAFENOTIFYROUTINE_H /************************************************************************/ /************************************************************************/ #include <ntifs.h> #include <wdm.h> /************************************************************************/ /************************************************************************/ extern POBJECT_TYPE *PsProcessType; typedef struct _DEVICE_TIMER { PVOID thread_pointer; BOOLEAN terminate_thread; KEVENT request_event; KTIMER kTimer; KDPC KiTimerExpireDpc; } DEVICE_TIMER, *PDEVICE_TIMER; typedef class SafeNotifyRoutine* PSafeNotifyRoutine; /************************************************************************/ /************************************************************************/ #endif
代码:
#ifndef SAFENOTIFYROUTINE_H #define SAFENOTIFYROUTINE_H /************************************************************************/ /************************************************************************/ #include "_SafeNotifyRoutine.h" /************************************************************************/ /************************************************************************/ class SafeNotifyRoutine { public: BOOLEAN InitializeCallBackNotify(); BOOLEAN CleanupCallBackNotify(); BOOLEAN InitializeTimerNotify(ULONG Millisecond); BOOLEAN CleanupTimerNotify(); private: VOID _ZeroMemoryMember(); static VOID LoadImageNotifyCallBack(PUNICODE_STRING FullImageName,HANDLE ProcessId,PIMAGE_INFO ImageInfo); static VOID CreateThreadNotifyCallBack(HANDLE ProcessId,HANDLE ThreadId,BOOLEAN Create); static VOID CreateProcessNotifyCallBack(HANDLE ParentId,HANDLE ProcessId,BOOLEAN Create); static VOID DpcTimerNotifyCallBack(struct _KDPC* Dpc,PVOID DeferredContext,PVOID SystemArgument1,PVOID SystemArgument2); static VOID ThreadNotifyCallBack(PVOID Context); BOOLEAN GetFullPathByProcessId(ULONG ProcessId, PUNICODE_STRING FullImageName); BOOLEAN LdrLoadDllByProcessId(ULONG ProcessId,char* szDllPath); private: BOOLEAN IsLoadImage; BOOLEAN IsCreateProcess; BOOLEAN IsCreateThread; PEPROCESS _pEprocess; public: DEVICE_TIMER _Timer; }; #endif
代码:
/************************************************************************/ /************************************************************************/ #include "SafeNotifyRoutine.h" /************************************************************************/ /************************************************************************/ PSafeNotifyRoutine g_pThis = NULL; /************************************************************************/ /************************************************************************/ BOOLEAN SafeNotifyRoutine::InitializeCallBackNotify() { this->_ZeroMemoryMember(); if(!NT_SUCCESS(PsSetLoadImageNotifyRoutine(SafeNotifyRoutine::LoadImageNotifyCallBack))) return FALSE; else this->IsLoadImage = TRUE; if(!NT_SUCCESS(PsSetCreateThreadNotifyRoutine(SafeNotifyRoutine::CreateThreadNotifyCallBack))) return FALSE; else this->IsCreateThread = TRUE; if(!NT_SUCCESS(PsSetCreateProcessNotifyRoutine(SafeNotifyRoutine::CreateProcessNotifyCallBack,FALSE))) return FALSE; else this->IsCreateProcess = TRUE; g_pThis = this; return TRUE; } /************************************************************************/ /************************************************************************/ BOOLEAN SafeNotifyRoutine::InitializeTimerNotify(ULONG Millisecond) { __try { LARGE_INTEGER duetime = {0}; HANDLE ThreadHandle; KeInitializeEvent(&this->_Timer.request_event,NotificationEvent,FALSE); KeInitializeTimerEx(&this->_Timer.kTimer, NotificationTimer); KeInitializeDpc(&this->_Timer.KiTimerExpireDpc,SafeNotifyRoutine::DpcTimerNotifyCallBack,NULL); KeSetTimerEx(&this->_Timer.kTimer, duetime,Millisecond,&this->_Timer.KiTimerExpireDpc); this->_Timer.terminate_thread = FALSE; if(!NT_SUCCESS(PsCreateSystemThread(&ThreadHandle,0,NULL,NULL,NULL,SafeNotifyRoutine::ThreadNotifyCallBack,NULL))) { KdPrint(("PsCreateSystemThread Fail.\n")); return FALSE; } if(!NT_SUCCESS(ObReferenceObjectByHandle(ThreadHandle,THREAD_ALL_ACCESS,NULL,KernelMode,&this->_Timer.thread_pointer,NULL))) { KdPrint(("ObReferenceObjectByHandle Fail.\n")); ZwClose(ThreadHandle); this->_Timer.terminate_thread = TRUE; KeSetEvent(&this->_Timer.request_event,(KPRIORITY)0,FALSE); return FALSE; } else { ZwClose(ThreadHandle); } return TRUE; } __except(EXCEPTION_EXECUTE_HANDLER) { KdPrint(("InitializeTimerNotify Except Fail.\n")); return FALSE; } } /************************************************************************/ /************************************************************************/ BOOLEAN SafeNotifyRoutine::CleanupTimerNotify() { __try { KeCancelTimer(&g_pThis->_Timer.kTimer); g_pThis->_Timer.terminate_thread = TRUE; KeSetEvent(&g_pThis->_Timer.request_event,(KPRIORITY)0,FALSE); KeWaitForSingleObject(g_pThis->_Timer.thread_pointer,Executive,KernelMode,FALSE,NULL); ObDereferenceObject(g_pThis->_Timer.thread_pointer); } __except(EXCEPTION_EXECUTE_HANDLER) { KdPrint(("CleanupTimerNotify Except Fail.\n")); return FALSE; } return TRUE; } /************************************************************************/ /************************************************************************/ BOOLEAN SafeNotifyRoutine::CleanupCallBackNotify() { if(this->IsLoadImage) PsRemoveLoadImageNotifyRoutine(SafeNotifyRoutine::LoadImageNotifyCallBack); if(this->IsCreateThread) PsRemoveCreateThreadNotifyRoutine(SafeNotifyRoutine::CreateThreadNotifyCallBack); if(this->IsCreateProcess) PsSetCreateProcessNotifyRoutine(SafeNotifyRoutine::CreateProcessNotifyCallBack,TRUE); this->_ZeroMemoryMember(); return TRUE; } /************************************************************************/ /************************************************************************/ VOID SafeNotifyRoutine::_ZeroMemoryMember() { this->IsLoadImage = FALSE; this->IsCreateThread = FALSE; this->IsCreateProcess = FALSE; } /************************************************************************/ /************************************************************************/ VOID SafeNotifyRoutine::LoadImageNotifyCallBack(PUNICODE_STRING FullImageName,HANDLE ProcessId,PIMAGE_INFO ImageInfo) { if(KeGetCurrentIrql()!=PASSIVE_LEVEL) return; DbgPrint("ImageName:%wZ ProcessId:%d\n",FullImageName,(ULONG)ProcessId); g_pThis->LdrLoadDllByProcessId((ULONG)ProcessId,NULL); } /************************************************************************/ /************************************************************************/ VOID SafeNotifyRoutine::CreateThreadNotifyCallBack(HANDLE ProcessId,HANDLE ThreadId,BOOLEAN Create) { if(KeGetCurrentIrql()==PASSIVE_LEVEL&&Create) { DbgPrint("ProcessId:%d ThreadId:%d\n",(ULONG)ProcessId,(ULONG)ThreadId); } } /************************************************************************/ /************************************************************************/ VOID SafeNotifyRoutine::CreateProcessNotifyCallBack(HANDLE ParentId,HANDLE ProcessId,BOOLEAN Create) { if(KeGetCurrentIrql()==PASSIVE_LEVEL&&Create) { UNICODE_STRING FullImageName = {512,1024,(PWCH)ExAllocatePoolWithTag(PagedPool,1024,'Safe')}; g_pThis->GetFullPathByProcessId((ULONG)ProcessId,&FullImageName); DbgPrint("ParentId:%d ProcessId:%d FullImageName:%wZ\n",(ULONG)ParentId,(ULONG)ProcessId,FullImageName); ExFreePoolWithTag((PVOID)FullImageName.Buffer,'Safe'); } } /************************************************************************/ /************************************************************************/ VOID SafeNotifyRoutine::DpcTimerNotifyCallBack(struct _KDPC* Dpc,PVOID DeferredContext,PVOID SystemArgument1,PVOID SystemArgument2) { KdPrint(("haha dpc function work\n")); KeSetEvent(&g_pThis->_Timer.request_event,(KPRIORITY)0,FALSE); } /************************************************************************/ /************************************************************************/ VOID SafeNotifyRoutine::ThreadNotifyCallBack(PVOID Context) { KeSetPriorityThread(KeGetCurrentThread(), LOW_REALTIME_PRIORITY); for(;;) { do { KdPrint(("thread work ok !!\n")); goto failselabel; } while(TRUE); failselabel: KeWaitForSingleObject(&g_pThis->_Timer.request_event,Executive,KernelMode,FALSE,NULL); KeResetEvent(&g_pThis->_Timer.request_event); if(g_pThis->_Timer.terminate_thread) PsTerminateSystemThread(STATUS_SUCCESS); } } /************************************************************************/ /************************************************************************/ BOOLEAN SafeNotifyRoutine::GetFullPathByProcessId(ULONG ProcessId, PUNICODE_STRING FullImageName) { HANDLE ProcessHandle = NULL; ULONG NumberOfBytes = 8; if(!NT_SUCCESS(PsLookupProcessByProcessId((HANDLE)ProcessId,&this->_pEprocess))) { KdPrint(("PsLookupProcessByProcessId Fail\n")); return FALSE; } if(!NT_SUCCESS(ObOpenObjectByPointer(this->_pEprocess,OBJ_KERNEL_HANDLE ,0,GENERIC_READ,*PsProcessType,0,&ProcessHandle))) { KdPrint(("ObOpenObjectByPointer Fail\n")); return FALSE; } if(!NT_SUCCESS(NtQueryInformationProcess(ProcessHandle,ProcessImageFileName,0,0,&NumberOfBytes))) { KdPrint(("NtQueryInformationProcess Fail\n")); return FALSE; } if(FullImageName->MaximumLength<NumberOfBytes-sizeof(UNICODE_STRING)) { KdPrint(("FullImageName->MaximumLength Buffer Length Too Small\n")); return FALSE; } PUNICODE_STRING TmpImageName= (PUNICODE_STRING)ExAllocatePoolWithTag(PagedPool,NumberOfBytes,'Safe'); if(TmpImageName==NULL) { KdPrint(("ExAllocatePoolWithTag Fail\n")); return FALSE; } if(NT_SUCCESS(NtQueryInformationProcess(ProcessHandle,ProcessImageFileName,TmpImageName,NumberOfBytes,&NumberOfBytes))) { KdPrint(("FullImageName %wZ\n",TmpImageName->Buffer)); wcsncpy(FullImageName->Buffer,TmpImageName->Buffer,TmpImageName->Length); } ExFreePoolWithTag((PVOID)TmpImageName,'Safe'); return (NT_SUCCESS(ZwClose(ProcessHandle))); } /************************************************************************/ /************************************************************************/ BOOLEAN SafeNotifyRoutine::LdrLoadDllByProcessId(ULONG ProcessId,char* szDllPath) { HANDLE ProcessHandle = NULL; PVOID pMemSpace = NULL; if(!NT_SUCCESS(PsLookupProcessByProcessId((HANDLE)ProcessId,&this->_pEprocess))) { KdPrint(("PsLookupProcessByProcessId Fail\n")); return FALSE; } ULONG size = 2000; if(!NT_SUCCESS(ObOpenObjectByPointer(this->_pEprocess,OBJ_KERNEL_HANDLE,NULL,PROCESS_ALL_ACCESS,NULL,KernelMode,&ProcessHandle))) { KdPrint(("ObOpenObjectByPointer Fail\n")); return FALSE; } if(!NT_SUCCESS(NtAllocateVirtualMemory(ProcessHandle,&pMemSpace,0,&size,MEM_COMMIT,PAGE_EXECUTE_READWRITE))) { KdPrint(("NtAllocateVirtualMemory Fail\n")); return FALSE; } if(ProcessHandle!=NULL) ObfDereferenceObject(ProcessHandle); DbgPrint("MEM SPACE ADDR:%x\n",(ULONG)pMemSpace); }