好久没发代码了,发个以前写的东西,代码是照葫芦画瓢来的,共同学习,共同进步,欢迎拍砖.
#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);
}
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课