看流星社区

 找回密码
 注册账号
查看: 1774|回复: 0

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

[复制链接]

该用户从未签到

发表于 2013-4-1 09:22:22 | 显示全部楼层 |阅读模式
好久没发代码了,发个以前写的东西,代码是照葫芦画瓢来的,共同学习,共同进步,欢迎拍砖.

代码:
#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);
}
点击按钮快速添加回复内容: 支持 高兴 激动 给力 加油 苦寻 生气 回帖 路过 感恩
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

小黑屋|手机版|Archiver|看流星社区 |网站地图

GMT+8, 2024-4-30 14:04

Powered by Kanliuxing X3.4

© 2010-2019 kanliuxing.com

快速回复 返回顶部 返回列表