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

    技术2022-05-11  49

    //write by jingzhongrong

    最近在论坛上看到很多人都在问这个问题,花了一些时间写了这个程序,原理很简单,主要功能通过一个内核驱动中使用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();  }

     


    最新回复(0)