Ps回调通知例程、Dpc定时器、内核线程使用方法.

好久没发代码了,发个以前写的东西,代码是照葫芦画瓢来的,共同学习,共同进步,欢迎拍砖.
代码:
#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);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值