秀纳

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

最近在论坛上看到很多人都在问这个问题,花了一些时间写了这个程序,原理很简单,主要功能通过一个内核驱动中使用PsSetCreateProcessNotifyRoutine 函数来实现。效果也不错

首先新建一个驱动程序工程,在DriverEntry例程中调用PsSetCreateProcessNotifyRoutine函数向系统添加一个回调函数,并创建一个系统事件对象,当系统中有进程新建或者进程终止,回调函数将会被调用,而在进程回调函数中,保存信息并出发系统事件,通知用户态的应用程序。

 PsSetCreateProcessNotifyRoutine函数的原型声明如下:

NTSTATUS
  PsSetCreateProcessNotifyRoutine(
    IN PCREATE_PROCESS_NOTIFY_ROUTINE  NotifyRoutine,
    IN BOOLEAN  Remove
    );

回调函数的函数定义如下:

VOID
(*PCREATE_PROCESS_NOTIFY_ROUTINE) (
    IN HANDLE  ParentId,
    IN HANDLE  ProcessId,
    IN BOOLEAN  Create
    );

创建系统事件的函数:IoCreateNotificationEvent

下面是具体的代码:

 

#ifndef CPN_DRIVER_H
#define CPN_DRIVER_H


#include 
<ntddk.h>
#include 
<devioctl.h>


//自定义函数声明
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath);

NTSTATUS CPNDispatchCreateClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);

VOID CPNUnload(IN PDRIVER_OBJECT DriverObject); 

NTSTATUS CPNDispatchIoctl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);

VOID ProcessCallback(IN HANDLE hParentId, IN HANDLE hProcessId, IN BOOLEAN bCreate);

#define DEVICE_NAME L"\Device\CPNDriver"

#define LINK_NAME   L"\DosDevices\CPNDriverLink"
#define EVENT_NAME  L"\BaseNamedObjects\CPNDriverEvent"

typedef 
struct _DEVICE_EXTENSION
{
    HANDLE hProcessHandle;
    PKEVENT pProcessEvent;
    HANDLE hParentID;
    HANDLE hProcessID;
    BOOLEAN bCreate;
}DEVICE_EXTENSION,
*
PDEVICE_EXTENSION;

typedef 
struct
 _CALLBACK_INFO
{
    HANDLE  hParentId;
    HANDLE  hProcessId;
    BOOLEAN bCreate;
}CALLBACK_INFO, 
*
PCALLBACK_INFO;

#define IOCTL_CPNDRIVER_GET_PROCESSINFO CTL_CODE(FILE_DEVICE_UNKNOWN,0x0800,METHOD_BUFFERED,

    FILE_READ_ACCESS
|FILE_WRITE_ACCESS)

#endif

下面是C文件实现:

 


#include 
<ntddk.h>
#include 
<devioctl.h>
#include 
"CPNDriver.h"

PDEVICE_OBJECT g_pDeviceObject;  
//声明全局变量

DriverEntry例程:

 

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
    NTSTATUS status 
=
 STATUS_SUCCESS;
    UNICODE_STRING usDevName;
    PDEVICE_OBJECT pDevObj;
    PDEVICE_EXTENSION pDevExt;
    UNICODE_STRING usLinkName;
    UNICODE_STRING usEventName;
    
//
    DriverObject->MajorFunction[IRP_MJ_CREATE] =

    DriverObject
->MajorFunction[IRP_MJ_CLOSE] = CPNDispatchCreateClose;
    DriverObject
->MajorFunction[IRP_MJ_DEVICE_CONTROL] =
 CPNDispatchIoctl;
    DriverObject
->DriverUnload =
 CPNUnload;
    
//
    RtlInitUnicodeString(&
usDevName,DEVICE_NAME);
    
//
    status =
 IoCreateDevice(DriverObject,
        
sizeof
(DEVICE_EXTENSION),
        
&
usDevName,
        FILE_DEVICE_UNKNOWN,
        
0
,
        FALSE,
        
&
pDevObj);
    
if(!
NT_SUCCESS(status))
    {
        
return
 status;
    }
    
//
    pDevExt = (PDEVICE_EXTENSION)pDevObj->
DeviceExtension;
    
//
    RtlInitUnicodeString(&
usLinkName,LINK_NAME);
    status 
= IoCreateSymbolicLink(&usLinkName,&usDevName);  //创建关联

    if(!NT_SUCCESS(status))
    {
        IoDeleteDevice(pDevObj);
        
return
 status;
    }
    
//
    g_pDeviceObject =
 pDevObj;
    
//
    RtlInitUnicodeString(&
usEventName,EVENT_NAME);
    pDevExt
->pProcessEvent = IoCreateNotificationEvent(&usEventName,&pDevExt->
hProcessHandle);
    KeClearEvent(pDevExt
->
pProcessEvent);
    
//
    status =
 PsSetCreateProcessNotifyRoutine(ProcessCallback,FALSE);
    
return
 status;
}

其他派遣例程:

 

VOID CPNUnload(IN PDRIVER_OBJECT DriverObject)
{
    UNICODE_STRING usLink;
    PsSetCreateProcessNotifyRoutine(ProcessCallback,TRUE);   
//移除

    RtlInitUnicodeString(&usLink,LINK_NAME);
    IoDeleteSymbolicLink(
&
usLink);
    IoDeleteDevice(DriverObject
->
DeviceObject);
}

NTSTATUS CPNDispatchCreateClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
    Irp
->IoStatus.Status =
 STATUS_SUCCESS;
    IoCompleteRequest(Irp,IO_NO_INCREMENT);
    
return
 STATUS_SUCCESS;
}

NTSTATUS CPNDispatchIoctl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
    NTSTATUS status 
=
 STATUS_INVALID_DEVICE_REQUEST;
    PIO_STACK_LOCATION pIrpStack 
=
 IoGetCurrentIrpStackLocation(Irp);
    PDEVICE_EXTENSION pDevExt 
= (PDEVICE_EXTENSION)DeviceObject->
DeviceExtension;
    ULONG uIoControlCode 
= pIrpStack->
Parameters.DeviceIoControl.IoControlCode;
    PCALLBACK_INFO pCallbackInfo 
= (PCALLBACK_INFO)Irp->
AssociatedIrp.SystemBuffer;
    ULONG uInSize 
= pIrpStack->
Parameters.DeviceIoControl.InputBufferLength;
    ULONG uOutSize 
= pIrpStack->
Parameters.DeviceIoControl.OutputBufferLength;
    
switch
(uIoControlCode)
    {
    
case
 IOCTL_CPNDRIVER_GET_PROCESSINFO:
        {
            
if(uOutSize >= sizeof
(CALLBACK_INFO))
            {
                pCallbackInfo
->hParentId = pDevExt->
hParentID;
                pCallbackInfo
->hProcessId = pDevExt->
hProcessID;
                pCallbackInfo
->bCreate = pDevExt->
bCreate;
                status 
=
 STATUS_SUCCESS;
            }
        }
        
break
;
    }
    
if(status ==
 STATUS_SUCCESS)
    {
        Irp
->IoStatus.Information =
 uOutSize;
    }
    
else

    {
        Irp
->IoStatus.Information = 0;
    }
    Irp
->IoStatus.Status =
 status;
    IoCompleteRequest(Irp,IO_NO_INCREMENT);
    
return
 status;
}

回调函数如下:

 

VOID ProcessCallback(IN HANDLE hParentId, IN HANDLE hProcessId, IN BOOLEAN bCreate)
{
    PDEVICE_EXTENSION pDevExt 
= (PDEVICE_EXTENSION)g_pDeviceObject->
DeviceExtension;
    pDevExt
->hParentID =
 hParentId;
    pDevExt
->hProcessID =
 hProcessId;
    pDevExt
->bCreate =
 bCreate;
    
//触发事件

    KeSetEvent(pDevExt->pProcessEvent,0,FALSE);
    KeClearEvent(pDevExt
->
pProcessEvent);
}

编译成sys后,创建一个Windows程序,下面用BCB来实现:

使用一个线程类来从驱动程序等待并获得信息,使用DeviceIoControl。

下面是线程类的具体实现以及声明:

 

//头文件声明

class GetInformationThread : public TThread
{
public
:
  __fastcall GetInformationThread(
bool CreateSuspended, TListView*
 tv);
  
protected
:
  
void
 __fastcall Execute();
  
void
 __fastcall ReflashListView();
  AnsiString __fastcall GetProcessNameFromID(DWORD dwProcessID);
  
private
:
    HANDLE  hhParentId;
    HANDLE  hhProcessId;
    BOOLEAN bbCreate;
    TListView 
*
lv;

};

//cpp实现

__fastcall GetInformationThread::GetInformationThread(bool CreateSuspended, TListView* tv)
            :TThread(CreateSuspended)
{
  lv 
=
 tv;
}

void
 __fastcall GetInformationThread::Execute()
{
  CALLBACK_INFO CallbackInfo 
= { 0
 };
  CALLBACK_INFO CallbackTemp 
= { 0
 };
  
while(!this->
Terminated)
  {
    
while(WaitForSingleObject(hProcessEvent,INFINITE)==
WAIT_OBJECT_0)
    {
      DWORD BytesReturn;
      BOOL bRet 
= DeviceIoControl(hDriver,IOCTL_CPNDRIVER_GET_PROCESSINFO,NULL,0,&
CallbackInfo,
                                  
sizeof(CallbackInfo),&
BytesReturn,NULL);
      
if
(bRet)
      {
        
if(CallbackInfo.hParentId !=
 CallbackTemp.hParentId
           
|| CallbackInfo.hProcessId !=
 CallbackTemp.hProcessId
           
|| CallbackInfo.bCreate !=
 CallbackTemp.bCreate)
        {
          hhParentId 
=
 CallbackInfo.hParentId;
          hhProcessId 
=
 CallbackInfo.hProcessId;
          bbCreate 
=
 CallbackInfo.bCreate;
          CallbackTemp 
=
 CallbackInfo;
          Synchronize(ReflashListView);
        }
      }
      
else

      {
        ShowMessage(
"获取进程信息失败.");
        
break
;
      }
    }
  }
}

AnsiString __fastcall GetInformationThread::GetProcessNameFromID(DWORD dwProcessID)
{
  
//HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);

  PROCESSENTRY32 pe;
  ZeroMemory(
&pe,sizeof
(pe));
  pe.dwSize 
= sizeof
(pe);
  AnsiString temp 
= "Unknown"
;
  BOOL bMore 
= Process32First(hSnapshot,&
pe);
  
while
(bMore)
  {
    
if(pe.th32ProcessID ==
 dwProcessID)
    {
      temp 
=
 AnsiString(pe.szExeFile);
      
break
;
    }
    
else

    {
      bMore 
= Process32Next(hSnapshot,&pe);
    }
  }
  
return
 temp;
}

void
 __fastcall GetInformationThread::ReflashListView()
{
  AnsiString parentProcessName;
  AnsiString ProcessName;
  parentProcessName 
= this->GetProcessNameFromID((DWORD)this->
hhParentId);
  ProcessName 
= this->GetProcessNameFromID((DWORD)this->
hhProcessId);
  
if(this->
bbCreate)
  {
    hSnapshot 
= CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0
);
    parentProcessName 
= this->GetProcessNameFromID((DWORD)this->
hhParentId);
    ProcessName 
= this->GetProcessNameFromID((DWORD)this->
hhProcessId);
  }
  
else

  {
    parentProcessName 
= this->GetProcessNameFromID((DWORD)this->hhParentId);
    ProcessName 
= this->GetProcessNameFromID((DWORD)this->
hhProcessId);
    hSnapshot 
= CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0
);
  }
  TListItem 
*temp = lv->Items->
Add();
  temp
->Caption = AnsiString((int)this->
hhProcessId);
  temp
->SubItems->Add(AnsiString((int)this->
hhParentId));
  
if(this->
bbCreate)
  {
    temp
->SubItems->Add("Create"
);
    temp
->SubItems->
Add(parentProcessName);
    temp
->SubItems->
Add(ProcessName);
  }
  
else

  {
    temp
->SubItems->Add("Close");
    temp
->SubItems->
Add(parentProcessName);
    temp
->SubItems->
Add(ProcessName);
  }
}

引入一个头文件,声明驱动程序中使用的的信息返回结构(回调函数传出来的信息),以及设备控制代码的声明。

#ifndef DRIVERINFOSTRUCT_H
#define DRIVERINFOSTRUCT_H


#include 
<windows.h>
#include 
<winioctl.h>

#define IOCTL_CPNDRIVER_GET_PROCESSINFO CTL_CODE(FILE_DEVICE_UNKNOWN, 
        
0x0800, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)

//用户与内核交互的缓冲区格式,这个结构向用户程序返回进程信息

typedef struct _CALLBACK_INFO
{
    HANDLE  hParentId;
    HANDLE  hProcessId;
    BOOLEAN bCreate;
}CALLBACK_INFO, 
*
PCALLBACK_INFO;
#endif

下面就是使用SCM服务管理函数,创建服务,打开服务,然后在打开驱动程序的句柄,启动线程访问。

//h头文件实现
#ifndef Unit1H
#define Unit1H

//---------------------------------------------------------------------------
#include <Classes.hpp>
#include 
<Controls.hpp>
#include 
<StdCtrls.hpp>
#include 
<Forms.hpp>
#include 
<ComCtrls.hpp>

class TForm1 : public TForm
{
__published:    
// IDE-managed Components

        TButton *Button1;
        TButton 
*
Button2;
        TButton 
*
Button3;
        TListView 
*
ListView1;
  TGroupBox 
*
GroupBox1;
  TLabel 
*
Label1;
        
void __fastcall Button1Click(TObject *
Sender);
  
void __fastcall Button2Click(TObject *
Sender);
  
void __fastcall Button3Click(TObject *
Sender);
 
private:    // User declarations

  bool notifying;
  
char szDriverPath[256
];
  GetInformationThread 
*
th;
public:        // User declarations

        __fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------

extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------

#endif


//cpp文件实现
//---------------------------------------------------------------------------

#include <windows.h>
#include 
<tlhelp32.h>
#include 
<vcl.h>
#pragma hdrstop

#include 
"Unit1.h"
#include 
"DriverInfoStruct.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 
*Form1;
SC_HANDLE hSCM;
SC_HANDLE hService;
HANDLE hDriver;
HANDLE hProcessEvent;
char szLinkName[] = "CPNDriverLink"
;
HANDLE hSnapshot;
//---------------------------------------------------------------------------

__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
  notifying 
= false
;
  Button1
->Enabled = true
;
  Button2
->Enabled = false
;
  Button3
->Enabled = true
;
  

this->szDriverPath[0] = '\0';

}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)
{
  char *p;
  ::GetFullPathName("CPNDriver.sys",256,szDriverPath,&p);
  if(notifying==false)
  {
    hSCM = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
    if(hSCM==NULL)
    {
      ShowMessage("打开服务控制管理器失败.");
      notifying = false;
      Button1->Enabled = true;
      Button2->Enabled = false;
      Button3->Enabled = true;
      return;
    }
    hService = CreateService(hSCM,szLinkName,szLinkName,SERVICE_ALL_ACCESS,
                             SERVICE_KERNEL_DRIVER,SERVICE_DEMAND_START,
                             SERVICE_ERROR_NORMAL,szDriverPath,
                             NULL,0,NULL,NULL,NULL);
    if(hService==NULL)
    {
      int nError = GetLastError();
      if(nError==ERROR_SERVICE_EXISTS || nError==ERROR_SERVICE_MARKED_FOR_DELETE)
      {
        hService = OpenService(hSCM,szLinkName,SERVICE_ALL_ACCESS);
      }
    }
    if(hService==NULL)
    {
      ShowMessage("创建服务出错.");
      CloseServiceHandle(hSCM);
      notifying = false;
      Button1->Enabled = true;
      Button2->Enabled = false;
      Button3->Enabled = true;
      return;
    }
    if(!StartService(hService,0,NULL))
    {
      int nError = GetLastError();
      if(nError != ERROR_SERVICE_ALREADY_RUNNING)
      {
        ShowMessage("启动服务出错.");
        DeleteService(hService);
        CloseServiceHandle(hService);
        CloseServiceHandle(hSCM);
        notifying = false;
        Button1->Enabled = true;
        Button2->Enabled = false;
        Button3->Enabled = true;
        return;
      }
    }
    char szDriverFile[256] = "";
    wsprintf(szDriverFile,"\\\\.\\%s",szLinkName);
    hDriver = CreateFile(szDriverFile,GENERIC_READ|GENERIC_WRITE,
                                0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
    if(hDriver==INVALID_HANDLE_VALUE)
    {
      ShowMessage("打开设备失败.");
      DeleteService(hService);
      CloseServiceHandle(hService);
      CloseServiceHandle(hSCM);
      notifying = false;
      Button1->Enabled = true;
      Button2->Enabled = false;
      Button3->Enabled = true;
      return;
    }
    hProcessEvent = OpenEvent(SYNCHRONIZE,FALSE,"CPNDriverEvent");
    th = new GetInformationThread(true,ListView1);
    th->Resume();
    notifying = true;
    Button1->Enabled = false;
    Button2->Enabled = true;
    Button3->Enabled = false;
  }
}

void __fastcall TForm1::Button2Click(TObject *Sender)
{
  th->Terminate();
  CloseHandle(hDriver);
  SERVICE_STATUS ss;
  ControlService(hService,SERVICE_CONTROL_STOP,&ss);
  DeleteService(hService);
  CloseServiceHandle(hService);
  CloseServiceHandle(hSCM);
  notifying = false;
  Button1->Enabled = true;
  Button2->Enabled = false;
  Button3->Enabled = true;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button3Click(TObject *Sender)
{
  this->Close(); 
}

posted on 2007-11-09 02:17  秀纳  阅读(1449)  评论(0编辑  收藏  举报