zoukankan      html  css  js  c++  java
  • 监视系统中进程的创建和终止

    原理很简单,主要功能通过一个内核驱动中使用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"DeviceCPNDriver"

    #define LINK_NAME   L"DosDevicesCPNDriverLink"
    #define EVENT_NAME  L"BaseNamedObjectsCPNDriverEvent"

    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] = '';

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

    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();  
    }

  • 相关阅读:
    VIVADO固化
    Keil MDK 编译器 AC5 和 AC6 优化选项重要内容和区别
    STM32时钟
    STlink/v2中SWD模式连线方式
    搭载M33内核,支持最新蓝牙5.1,晚到的DA1469x生正逢时
    超全国内外蓝牙芯片原厂总结(含芯片型号)
    芯片封装类型大全
    国务院办公厅关于2012年部分节假日安排的通知
    美国摇滚乐队Metro致敬黄家驹,全粤语翻唱Beyond经典《海阔天空》
    国务院办公厅发布2010年部分节假日安排通知
  • 原文地址:https://www.cnblogs.com/vcerror/p/4289242.html
Copyright © 2011-2022 走看看