您的位置:首页 > 其它

监视系统中进程的创建和终止

2013-07-30 16:54 274 查看
原理很简单,主要功能通过一个内核驱动中使用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();

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: