zoukankan      html  css  js  c++  java
  • 驱动列举进程输出到应用层

    本篇算是前两篇的综合,驱动列举出进程,并将进程名加入到一个链表中,
    最后应用层程序通过IOCTL读出驱动传递出来的数据。
    驱动irp3.h文件:
    #include <ntddk.h>  
     
    //采用缓冲区内存模式IOCTL,  
    //MY_DVC_BUFFERED_CODE是自定义的控制码  
    #define MY_DVC_BUFFERED_CODE /  
            (ULONG)CTL_CODE(FILE_DEVICE_UNKNOWN, / 
            0x900, / 
            METHOD_BUFFERED, / 
            FILE_ANY_ACCESS) 
     
    #define DWORD unsigned long  
    #define BOOL int  
     
    //---------系统信息结构---------  
    typedef enum _SYSTEM_INFORMATION_CLASS { 
        SystemBasicInformation, 
        SystemProcessorInformation, 
        SystemPerformanceInformation, 
        SystemTimeOfDayInformation, 
        SystemNotImplemented1, 
        SystemProcessesAndThreadsInformation, 
        SystemCallCounts, 
        SystemConfigurationInformation, 
        SystemProcessorTimes, 
        SystemGlobalFlag, 
        SystemNotImplemented2, 
        SystemModuleInformation, 
        SystemLockInformation, 
        SystemNotImplemented3, 
        SystemNotImplemented4, 
        SystemNotImplemented5, 
        SystemHandleInformation, 
        SystemObjectInformation, 
        SystemPagefileInformation, 
        SystemInstructionEmulationCounts, 
        SystemInvalidInfoClass1, 
        SystemCacheInformation, 
        SystemPoolTagInformation, 
        SystemProcessorStatistics, 
        SystemDpcInformation, 
        SystemNotImplemented6, 
        SystemLoadImage, 
        SystemUnloadImage, 
        SystemTimeAdjustment, 
        SystemNotImplemented7, 
        SystemNotImplemented8, 
        SystemNotImplemented9, 
        SystemCrashDumpInformation, 
        SystemExceptionInformation, 
        SystemCrashDumpStateInformation, 
        SystemKernelDebuggerInformation, 
        SystemContextSwitchInformation, 
        SystemRegistryQuotaInformation, 
        SystemLoadAndCallImage, 
        SystemPrioritySeparation, 
        SystemNotImplemented10, 
        SystemNotImplemented11, 
        SystemInvalidInfoClass2, 
        SystemInvalidInfoClass3, 
        SystemTimeZoneInformation, 
        SystemLookasideInformation, 
        SystemSetTimeSlipEvent, 
        SystemCreateSession, 
        SystemDeleteSession, 
        SystemInvalidInfoClass4, 
        SystemRangeStartInformation, 
        SystemVerifierInformation, 
        SystemAddVerifier, 
        SystemSessionProcessesInformation 
    } SYSTEM_INFORMATION_CLASS, *PSYSTEM_INFORMATION_CLASS; 
    //------------------------------  
     
    //---------线程信息结构---------  
    typedef struct _SYSTEM_THREAD { 
        LARGE_INTEGER           KernelTime; 
        LARGE_INTEGER           UserTime; 
        LARGE_INTEGER           CreateTime; 
        ULONG                   WaitTime; 
        PVOID                   StartAddress; 
        CLIENT_ID               ClientId; 
        KPRIORITY               Priority; 
        LONG                    BasePriority; 
        ULONG                   ContextSwitchCount; 
        ULONG                   State; 
        KWAIT_REASON            WaitReason; 
    } SYSTEM_THREAD, *PSYSTEM_THREAD; 
    //------------------------------  
     
    //---------进程信息结构---------  
    typedef struct _SYSTEM_PROCESS_INFORMATION { 
        ULONG                   NextEntryOffset; 
        ULONG                   NumberOfThreads; 
        LARGE_INTEGER           Reserved[3]; 
        LARGE_INTEGER           CreateTime; 
        LARGE_INTEGER           UserTime; 
        LARGE_INTEGER           KernelTime; 
        UNICODE_STRING          ImageName; 
        KPRIORITY               BasePriority; 
        HANDLE                  ProcessId; 
        HANDLE                  InheritedFromProcessId; 
        ULONG                   HandleCount; 
        ULONG                   Reserved2[2]; 
        ULONG                   PrivatePageCount; 
        VM_COUNTERS             VirtualMemoryCounters; 
        IO_COUNTERS             IoCounters; 
        SYSTEM_THREAD           Threads[0]; 
    } SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION; 
    //------------------------------  
     
    //------自定义我们的结构体------  
    typedef struct _MYPROCESSDATA 

        LIST_ENTRY myListEntry; //在结构体中插入LIST_ENTRY结构,使之成为链表节点,放在开头最合适。  
        //ULONG uID;              //进程ID  
        UNICODE_STRING usImageName; //线程名称  
    } MYPROCESSDATA, *PMYPROCESSDATA; 
    //------------------------------  
     
    //------------函数声明----------  
    NTSTATUS 
    DriverEntry(IN PDRIVER_OBJECT DriverObject, 
                IN PUNICODE_STRING registryPath); 
     
    NTSTATUS 
    MyDeviceIoControl(IN PDEVICE_OBJECT DeviceObject, 
                      IN PIRP Irp); 
     
    NTSTATUS 
    MyCreateClose(IN PDEVICE_OBJECT DeviceObject, 
                  IN PIRP Irp); 
     
    VOID 
    MyDriverOnUnload(IN PDRIVER_OBJECT DriverObject); 
     
    NTSYSAPI 
    NTSTATUS 
    NTAPI 
    NtQuerySystemInformation(IN  SYSTEM_INFORMATION_CLASS SystemInformationClass, 
                             OUT PVOID SystemInformation, 
                             IN  ULONG SystemInformationLength, 
                             OUT PULONG ReturnLength OPTIONAL); 
    //-----------------------------  
     
    PMYPROCESSDATA pMyData;      //全局变量  
    LIST_ENTRY ProcessListHead;  //进程链表头 
    #include <ntddk.h>

    //采用缓冲区内存模式IOCTL,
    //MY_DVC_BUFFERED_CODE是自定义的控制码
    #define MY_DVC_BUFFERED_CODE /
         (ULONG)CTL_CODE(FILE_DEVICE_UNKNOWN, /
      0x900, /
      METHOD_BUFFERED, /
      FILE_ANY_ACCESS)

    #define DWORD unsigned long
    #define BOOL int

    //---------系统信息结构---------
    typedef enum _SYSTEM_INFORMATION_CLASS {
     SystemBasicInformation,
     SystemProcessorInformation,
     SystemPerformanceInformation,
     SystemTimeOfDayInformation,
     SystemNotImplemented1,
     SystemProcessesAndThreadsInformation,
     SystemCallCounts,
     SystemConfigurationInformation,
     SystemProcessorTimes,
     SystemGlobalFlag,
     SystemNotImplemented2,
     SystemModuleInformation,
     SystemLockInformation,
     SystemNotImplemented3,
     SystemNotImplemented4,
     SystemNotImplemented5,
     SystemHandleInformation,
     SystemObjectInformation,
     SystemPagefileInformation,
     SystemInstructionEmulationCounts,
     SystemInvalidInfoClass1,
     SystemCacheInformation,
     SystemPoolTagInformation,
     SystemProcessorStatistics,
     SystemDpcInformation,
     SystemNotImplemented6,
     SystemLoadImage,
     SystemUnloadImage,
     SystemTimeAdjustment,
     SystemNotImplemented7,
     SystemNotImplemented8,
     SystemNotImplemented9,
     SystemCrashDumpInformation,
     SystemExceptionInformation,
     SystemCrashDumpStateInformation,
     SystemKernelDebuggerInformation,
     SystemContextSwitchInformation,
     SystemRegistryQuotaInformation,
     SystemLoadAndCallImage,
     SystemPrioritySeparation,
     SystemNotImplemented10,
     SystemNotImplemented11,
     SystemInvalidInfoClass2,
     SystemInvalidInfoClass3,
     SystemTimeZoneInformation,
     SystemLookasideInformation,
     SystemSetTimeSlipEvent,
     SystemCreateSession,
     SystemDeleteSession,
     SystemInvalidInfoClass4,
     SystemRangeStartInformation,
     SystemVerifierInformation,
     SystemAddVerifier,
     SystemSessionProcessesInformation
    } SYSTEM_INFORMATION_CLASS, *PSYSTEM_INFORMATION_CLASS;
    //------------------------------

    //---------线程信息结构---------
    typedef struct _SYSTEM_THREAD {
     LARGE_INTEGER           KernelTime;
     LARGE_INTEGER           UserTime;
     LARGE_INTEGER           CreateTime;
     ULONG                   WaitTime;
     PVOID                   StartAddress;
     CLIENT_ID               ClientId;
     KPRIORITY               Priority;
     LONG                    BasePriority;
     ULONG                   ContextSwitchCount;
     ULONG                   State;
     KWAIT_REASON            WaitReason;
    } SYSTEM_THREAD, *PSYSTEM_THREAD;
    //------------------------------

    //---------进程信息结构---------
    typedef struct _SYSTEM_PROCESS_INFORMATION {
     ULONG                   NextEntryOffset;
     ULONG                   NumberOfThreads;
     LARGE_INTEGER           Reserved[3];
     LARGE_INTEGER           CreateTime;
     LARGE_INTEGER           UserTime;
     LARGE_INTEGER           KernelTime;
     UNICODE_STRING          ImageName;
     KPRIORITY               BasePriority;
     HANDLE                  ProcessId;
     HANDLE                  InheritedFromProcessId;
     ULONG                   HandleCount;
     ULONG                   Reserved2[2];
     ULONG                   PrivatePageCount;
     VM_COUNTERS             VirtualMemoryCounters;
     IO_COUNTERS             IoCounters;
     SYSTEM_THREAD           Threads[0];
    } SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION;
    //------------------------------

    //------自定义我们的结构体------
    typedef struct _MYPROCESSDATA
    {
     LIST_ENTRY myListEntry; //在结构体中插入LIST_ENTRY结构,使之成为链表节点,放在开头最合适。
     //ULONG uID;              //进程ID
     UNICODE_STRING usImageName; //线程名称
    } MYPROCESSDATA, *PMYPROCESSDATA;
    //------------------------------

    //------------函数声明----------
    NTSTATUS
    DriverEntry(IN PDRIVER_OBJECT DriverObject,
       IN PUNICODE_STRING registryPath);

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

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

    VOID
    MyDriverOnUnload(IN PDRIVER_OBJECT DriverObject);

    NTSYSAPI
    NTSTATUS
    NTAPI
    NtQuerySystemInformation(IN  SYSTEM_INFORMATION_CLASS SystemInformationClass,
           OUT PVOID SystemInformation,
           IN  ULONG SystemInformationLength,
           OUT PULONG ReturnLength OPTIONAL);
    //-----------------------------

    PMYPROCESSDATA pMyData;      //全局变量
    LIST_ENTRY ProcessListHead;  //进程链表头
    驱动irp3.c文件:
    #include "irp3.h"  
     
    //------------列举进程----------  
    NTSTATUS EnumProcess() 

        int iCount = 1;    //进程计数  
        NTSTATUS status;   //返回值  
        PVOID pSi = NULL;  //指向SystemInformationClass的指针,此处为SystemProcessesAndThreadsInformation,即我们所要获取的信息  
        PSYSTEM_PROCESS_INFORMATION pSpiNext = NULL;  //同上  
        ULONG uSize;                 //pSi的大小,以BYTE为单位  
        ULONG pNeededSize = 0;       //系统返回所需长度,因在WIN2000下不会返回,故不只用,设置为0  
        BOOL bOver = FALSE;          //标识是否列举完成  
     
        //设定pSi大小uSize初始为32K,并为pSi分配uSize的内存,根据返回值逐步累加uSize,步长为32K  
        for (uSize = 0x8000; ((pSi = ExAllocatePoolWithTag(NonPagedPool, uSize, 'tag1')) != NULL); uSize += 0x8000) 
        { 
            //检索指定的系统信息,这里是有关进程的信息  
            status = NtQuerySystemInformation(SystemProcessesAndThreadsInformation, 
                                              pSi, 
                                              uSize, 
                                              &pNeededSize); 
            if (STATUS_SUCCESS == status)  //NtQuerySystemInformation返回成功  
            { 
                pSpiNext = (PSYSTEM_PROCESS_INFORMATION)pSi;  //使用pSpiNext操作,pSi要留到后面释放所分配的内存  
                while (TRUE) 
                { 
                    if (pSpiNext->ProcessId == 0) 
                    { 
                        //pMyData是全局变量,为其申请内存,注意是sizeof(MYPROCESSDATA),非sizeof(PMYPROCESSDATA)!下同  
                        pMyData = (PMYPROCESSDATA)ExAllocatePoolWithTag(PagedPool, sizeof(MYPROCESSDATA), 'tag2'); 
                        RtlInitUnicodeString(&pMyData->usImageName, L"System Idle Process"); 
                        InsertTailList(&ProcessListHead, (PLIST_ENTRY)&pMyData->myListEntry);  //将进程名插入链表  
                        //DbgPrint("[Aliwy] %wZ(%.8X)/n", &pMyData->usImageName, pMyData);  
                    } 
                    else 
                    { 
                        pMyData = (PMYPROCESSDATA)ExAllocatePoolWithTag(PagedPool, sizeof(MYPROCESSDATA), 'tag2'); 
                        pMyData->usImageName = pSpiNext->ImageName;                            //将进程名赋值到我们的结构元素中  
                        InsertTailList(&ProcessListHead, (PLIST_ENTRY)&pMyData->myListEntry);  //将进程名插入链表  
                        //DbgPrint("[Aliwy] %wZ(%.8X)/n", &pMyData->usImageName, pMyData);  
                    } 
                    if (pSpiNext->NextEntryOffset == 0) //如果NextEntryOffset为0即表示进程已列举完  
                    { 
                        pMyData = (PMYPROCESSDATA)ExAllocatePoolWithTag(PagedPool, sizeof(MYPROCESSDATA), 'tag2'); 
                        RtlInitUnicodeString(&pMyData->usImageName, L"EnumProcess Over");      //进程列举完成  
                        InsertTailList(&ProcessListHead, (PLIST_ENTRY)&pMyData->myListEntry);  //将进程名插入链表  
                        //DbgPrint("[Aliwy] %wZ(%.8X)/n", &pMyData->usImageName, pMyData);  
     
                        bOver = TRUE; //标识进程列举已完成  
                        break;        //跳出列举循环(while循环)  
                    } 
                    pSpiNext = (PSYSTEM_PROCESS_INFORMATION)((ULONG)pSpiNext + pSpiNext->NextEntryOffset); //指向下一个进程的信息  
                    iCount++;   //计数累加  
                } 
                ExFreePool(pSi);  //释放为sPi分配的内存  
                if (bOver)        //进程列举完成  
                { 
                    break;        //跳出内存分配循环(for循环)  
                } 
            } 
        } 
        return STATUS_SUCCESS; 

    //------------------------------  
     
    //------------驱动入口----------  
    NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING registryPath) 

        NTSTATUS ntStatus = STATUS_SUCCESS; 
        PDEVICE_OBJECT Device; 
        UNICODE_STRING DeviceName, DeviceLink;  //设备名,符号链接名  
     
        DbgPrint("[Aliwy] DriverEntry/n"); 
     
        InitializeListHead(&ProcessListHead);  //初始化链表头  
     
        EnumProcess(); //列举进程,将进程名全部加入到链表中  
     
        RtlInitUnicodeString(&DeviceName, L"//Device//Aliwy");         //初始化设备名 
        RtlInitUnicodeString(&DeviceLink, L"//DosDevices//IamAliwy");  //初始化符号链接名 
     
        /* IoCreateDevice 生成设备对象 */ 
        ntStatus = IoCreateDevice(DriverObject,         //生成设备的驱动对象  
                                  0,                    //设备扩展区内存大小  
                                  &DeviceName,          //设备名,/Device/Aliwy  
                                  FILE_DEVICE_UNKNOWN,  //设备类型  
                                  0,                    //填写0即可  
                                  FALSE,                //必须为FALSE  
                                  &Device);             //设备对象指针返回到DeviceObject中  
        if (!NT_SUCCESS(ntStatus)) 
        { 
            DbgPrint("[Aliwy] IoCreateDevice FALSE: %.8X/n", ntStatus); 
            return ntStatus;  //生成失败就返回  
        } 
        else 
            DbgPrint("[Aliwy] IoCreateDevice SUCCESS/n"); 
     
        /* IoCreateSymbolicLink 生成符号链接 */ 
        ntStatus = IoCreateSymbolicLink(&DeviceLink, &DeviceName); 
        if (!NT_SUCCESS(ntStatus)) 
        { 
            DbgPrint("[Aliwy] IoCreateSymbolicLink FALSE: %.8X/n", ntStatus); 
            IoDeleteDevice(Device);  //删除设备  
            return ntStatus; 
        } 
        else 
            DbgPrint("[Aliwy] IoCreateSymbolicLink SUCCESS/n"); 
     
        Device->Flags &= ~DO_DEVICE_INITIALIZING;  //设备初始化完成标记  
     
        DriverObject->DriverUnload = MyDriverOnUnload; 
     
        /*设备控制请求,对应Ring3 DeviceIoControl*/ 
        DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = MyDeviceIoControl; 
        /*设备打开请求,对应Ring3 CreateFile*/                      //  
        DriverObject->MajorFunction[IRP_MJ_CREATE] = MyCreateClose; //  要与应用层通信,  
        /*设备关闭请求,对应Ring3 CloseHandle*/                     //  必须有打开、关闭请求!  
        DriverObject->MajorFunction[IRP_MJ_CLOSE] = MyCreateClose;  //  
     
        return ntStatus; 

    //------------------------------  
     
    //---------设备请求处理---------  
    NTSTATUS MyDeviceIoControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) 

        PIO_STACK_LOCATION irpSp; //当前IRP调用栈空间  
        ULONG code;               //功能号  
        ULONG outBufLength;       //输出缓冲区长度  
        PCHAR outBuf;             //输出缓冲区  
        PCHAR outData ;           //要向应用层输出的信息  
        ULONG outDataLen;         //信息长度  
        ANSI_STRING asData;       //临时用到的变量  
        CHAR tmpData[128];        //临时用到的变量  
     
        DbgPrint("[Aliwy] MyDeviceIoControl/n"); 
     
        irpSp = IoGetCurrentIrpStackLocation(Irp);                           //获得当前IRP调用栈空间  
        code = irpSp->Parameters.DeviceIoControl.IoControlCode;              //得到功能号,即控制码  
        outBufLength = irpSp->Parameters.DeviceIoControl.OutputBufferLength; //得到输出缓冲区长度  
        outBuf = Irp->AssociatedIrp.SystemBuffer;                            //输出缓冲区  
     
     
        if (code == MY_DVC_BUFFERED_CODE)       //我们自定义的控制码  
        { 
            if (IsListEmpty(&ProcessListHead))  //链表头指向自身,链表为空既不再输入到用户层了  
            { 
                Irp->IoStatus.Information = 0; 
                Irp->IoStatus.Status = STATUS_SUCCESS; 
                IoCompleteRequest(Irp, IO_NO_INCREMENT); 
                DbgPrint("[Aliwy] List is Empty. MyDeviceIoControl Over/n"); 
                return Irp->IoStatus.Status; 
            } 
            pMyData = CONTAINING_RECORD(RemoveHeadList(&ProcessListHead),   //用RemoveHeadList从链表头删除一个元素,  
                                        MYPROCESSDATA,                      //从返回的指针中用CONTAINING_RECORD宏读取该链表元素数据  
                                        myListEntry); 
            //DbgPrint("[Aliwy] %wZ(%.8X)/n", &pMyData->usImageName, pMyData);  
     
            RtlInitEmptyAnsiString(&asData, tmpData, sizeof(tmpData));           //初始化一个空的AnsiString  
            RtlUnicodeStringToAnsiString(&asData, &pMyData->usImageName, TRUE);   //将UnicodeString转化成AnsiString  
            outData = (PCHAR)asData.Buffer;  //输出的信息  
            outDataLen = asData.Length + 1;  //输出的长度  
         
            RtlCopyBytes(outBuf, outData, outBufLength); //复制我们要传入的内容到输出缓冲区  
     
            DbgPrint("[Aliwy] asData: %Z(%d)  outData: %s(%d)  outBuf: %s(%d)/n", &asData, asData.Length,outData, outDataLen, outBuf, outBufLength); 
     
            Irp->IoStatus.Information = (outBufLength < outDataLen ? outBufLength : outDataLen); 
            Irp->IoStatus.Status = STATUS_SUCCESS; 
            IoCompleteRequest(Irp, IO_NO_INCREMENT); //结束IRP请求  
            ExFreePool(pMyData);  //释放为pMyData申请的内存,此处pMyData的内存指针与申请时的是对应的,故无需再用变量保存原始指针  
        } 
        else 
        { 
            Irp->IoStatus.Information = 0; 
            Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; 
            IoCompleteRequest(Irp, IO_NO_INCREMENT); 
        } 
     
        DbgPrint("[Aliwy] MyDeviceIoControl Over/n"); 
        return Irp->IoStatus.Status; 

    //------------------------------  
     
    //----------打开关闭------------  
    NTSTATUS MyCreateClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) 

        DbgPrint("[Aliwy] MyCreateClose/n"); 
        Irp->IoStatus.Information = 0; 
        Irp->IoStatus.Status = STATUS_SUCCESS; 
        IoCompleteRequest(Irp, IO_NO_INCREMENT); 
        return Irp->IoStatus.Status; 

    //------------------------------  
     
    //----------驱动卸载------------  
    VOID MyDriverOnUnload(IN PDRIVER_OBJECT DriverObject) 

        UNICODE_STRING DeviceLink; //符号链接名  
        DbgPrint("[Aliwy] MyDriverOnUnload/n"); 
     
        RtlInitUnicodeString(&DeviceLink, L"//DosDevices//IamAliwy"); 
        IoDeleteSymbolicLink(&DeviceLink); //删除符号链接  
        if (DriverObject->DeviceObject != NULL) 
        { 
            IoDeleteDevice(DriverObject->DeviceObject);  //删除设备  
        } 

    //------------------------------ 
    #include "irp3.h"

    //------------列举进程----------
    NTSTATUS EnumProcess()
    {
        int iCount = 1;    //进程计数
        NTSTATUS status;   //返回值
        PVOID pSi = NULL;  //指向SystemInformationClass的指针,此处为SystemProcessesAndThreadsInformation,即我们所要获取的信息
        PSYSTEM_PROCESS_INFORMATION pSpiNext = NULL;  //同上
        ULONG uSize;                 //pSi的大小,以BYTE为单位
        ULONG pNeededSize = 0;       //系统返回所需长度,因在WIN2000下不会返回,故不只用,设置为0
        BOOL bOver = FALSE;          //标识是否列举完成

        //设定pSi大小uSize初始为32K,并为pSi分配uSize的内存,根据返回值逐步累加uSize,步长为32K
        for (uSize = 0x8000; ((pSi = ExAllocatePoolWithTag(NonPagedPool, uSize, 'tag1')) != NULL); uSize += 0x8000)
        {
            //检索指定的系统信息,这里是有关进程的信息
            status = NtQuerySystemInformation(SystemProcessesAndThreadsInformation,
                                              pSi,
                                              uSize,
                                              &pNeededSize);
            if (STATUS_SUCCESS == status)  //NtQuerySystemInformation返回成功
            {
                pSpiNext = (PSYSTEM_PROCESS_INFORMATION)pSi;  //使用pSpiNext操作,pSi要留到后面释放所分配的内存
                while (TRUE)
                {
                    if (pSpiNext->ProcessId == 0)
                    {
         //pMyData是全局变量,为其申请内存,注意是sizeof(MYPROCESSDATA),非sizeof(PMYPROCESSDATA)!下同
                        pMyData = (PMYPROCESSDATA)ExAllocatePoolWithTag(PagedPool, sizeof(MYPROCESSDATA), 'tag2');
                        RtlInitUnicodeString(&pMyData->usImageName, L"System Idle Process");
                        InsertTailList(&ProcessListHead, (PLIST_ENTRY)&pMyData->myListEntry);  //将进程名插入链表
         //DbgPrint("[Aliwy] %wZ(%.8X)/n", &pMyData->usImageName, pMyData);
                    }
                    else
                    {
                        pMyData = (PMYPROCESSDATA)ExAllocatePoolWithTag(PagedPool, sizeof(MYPROCESSDATA), 'tag2');
                        pMyData->usImageName = pSpiNext->ImageName;                            //将进程名赋值到我们的结构元素中
                        InsertTailList(&ProcessListHead, (PLIST_ENTRY)&pMyData->myListEntry);  //将进程名插入链表
         //DbgPrint("[Aliwy] %wZ(%.8X)/n", &pMyData->usImageName, pMyData);
                    }
                    if (pSpiNext->NextEntryOffset == 0) //如果NextEntryOffset为0即表示进程已列举完
                    {
                        pMyData = (PMYPROCESSDATA)ExAllocatePoolWithTag(PagedPool, sizeof(MYPROCESSDATA), 'tag2');
                        RtlInitUnicodeString(&pMyData->usImageName, L"EnumProcess Over");      //进程列举完成
                        InsertTailList(&ProcessListHead, (PLIST_ENTRY)&pMyData->myListEntry);  //将进程名插入链表
         //DbgPrint("[Aliwy] %wZ(%.8X)/n", &pMyData->usImageName, pMyData);

                        bOver = TRUE; //标识进程列举已完成
                        break;        //跳出列举循环(while循环)
                    }
                    pSpiNext = (PSYSTEM_PROCESS_INFORMATION)((ULONG)pSpiNext + pSpiNext->NextEntryOffset); //指向下一个进程的信息
                    iCount++;   //计数累加
                }
                ExFreePool(pSi);  //释放为sPi分配的内存
                if (bOver)        //进程列举完成
                {
                    break;        //跳出内存分配循环(for循环)
                }
            }
        }
     return STATUS_SUCCESS;
    }
    //------------------------------

    //------------驱动入口----------
    NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING registryPath)
    {
        NTSTATUS ntStatus = STATUS_SUCCESS;
        PDEVICE_OBJECT Device;
        UNICODE_STRING DeviceName, DeviceLink;  //设备名,符号链接名

        DbgPrint("[Aliwy] DriverEntry/n");

        InitializeListHead(&ProcessListHead);  //初始化链表头

     EnumProcess(); //列举进程,将进程名全部加入到链表中

        RtlInitUnicodeString(&DeviceName, L"//Device//Aliwy");         //初始化设备名
        RtlInitUnicodeString(&DeviceLink, L"//DosDevices//IamAliwy");  //初始化符号链接名

        /* IoCreateDevice 生成设备对象 */
        ntStatus = IoCreateDevice(DriverObject,         //生成设备的驱动对象
                                  0,                    //设备扩展区内存大小
                                  &DeviceName,          //设备名,/Device/Aliwy
                                  FILE_DEVICE_UNKNOWN,  //设备类型
                                  0,                    //填写0即可
                                  FALSE,                //必须为FALSE
                                  &Device);             //设备对象指针返回到DeviceObject中
        if (!NT_SUCCESS(ntStatus))
        {
            DbgPrint("[Aliwy] IoCreateDevice FALSE: %.8X/n", ntStatus);
            return ntStatus;  //生成失败就返回
        }
        else
            DbgPrint("[Aliwy] IoCreateDevice SUCCESS/n");

        /* IoCreateSymbolicLink 生成符号链接 */
        ntStatus = IoCreateSymbolicLink(&DeviceLink, &DeviceName);
        if (!NT_SUCCESS(ntStatus))
        {
            DbgPrint("[Aliwy] IoCreateSymbolicLink FALSE: %.8X/n", ntStatus);
            IoDeleteDevice(Device);  //删除设备
            return ntStatus;
        }
        else
            DbgPrint("[Aliwy] IoCreateSymbolicLink SUCCESS/n");

        Device->Flags &= ~DO_DEVICE_INITIALIZING;  //设备初始化完成标记

        DriverObject->DriverUnload = MyDriverOnUnload;

        /*设备控制请求,对应Ring3 DeviceIoControl*/
        DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = MyDeviceIoControl;
        /*设备打开请求,对应Ring3 CreateFile*/                      //
        DriverObject->MajorFunction[IRP_MJ_CREATE] = MyCreateClose; //  要与应用层通信,
        /*设备关闭请求,对应Ring3 CloseHandle*/                     //  必须有打开、关闭请求!
        DriverObject->MajorFunction[IRP_MJ_CLOSE] = MyCreateClose;  //

        return ntStatus;
    }
    //------------------------------

    //---------设备请求处理---------
    NTSTATUS MyDeviceIoControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
    {
        PIO_STACK_LOCATION irpSp; //当前IRP调用栈空间
        ULONG code;               //功能号
        ULONG outBufLength;       //输出缓冲区长度
     PCHAR outBuf;             //输出缓冲区
        PCHAR outData ;           //要向应用层输出的信息
        ULONG outDataLen;         //信息长度
        ANSI_STRING asData;       //临时用到的变量
     CHAR tmpData[128];        //临时用到的变量

        DbgPrint("[Aliwy] MyDeviceIoControl/n");

        irpSp = IoGetCurrentIrpStackLocation(Irp);                           //获得当前IRP调用栈空间
        code = irpSp->Parameters.DeviceIoControl.IoControlCode;              //得到功能号,即控制码
        outBufLength = irpSp->Parameters.DeviceIoControl.OutputBufferLength; //得到输出缓冲区长度
     outBuf = Irp->AssociatedIrp.SystemBuffer;                            //输出缓冲区


        if (code == MY_DVC_BUFFERED_CODE)       //我们自定义的控制码
        {
      if (IsListEmpty(&ProcessListHead))  //链表头指向自身,链表为空既不再输入到用户层了
      {
       Irp->IoStatus.Information = 0;
       Irp->IoStatus.Status = STATUS_SUCCESS;
       IoCompleteRequest(Irp, IO_NO_INCREMENT);
       DbgPrint("[Aliwy] List is Empty. MyDeviceIoControl Over/n");
       return Irp->IoStatus.Status;
      }
      pMyData = CONTAINING_RECORD(RemoveHeadList(&ProcessListHead),   //用RemoveHeadList从链表头删除一个元素,
             MYPROCESSDATA,                      //从返回的指针中用CONTAINING_RECORD宏读取该链表元素数据
             myListEntry);
      //DbgPrint("[Aliwy] %wZ(%.8X)/n", &pMyData->usImageName, pMyData);

      RtlInitEmptyAnsiString(&asData, tmpData, sizeof(tmpData));           //初始化一个空的AnsiString
      RtlUnicodeStringToAnsiString(&asData, &pMyData->usImageName, TRUE);   //将UnicodeString转化成AnsiString
      outData = (PCHAR)asData.Buffer;  //输出的信息
      outDataLen = asData.Length + 1;  //输出的长度
     
      RtlCopyBytes(outBuf, outData, outBufLength); //复制我们要传入的内容到输出缓冲区

      DbgPrint("[Aliwy] asData: %Z(%d)  outData: %s(%d)  outBuf: %s(%d)/n", &asData, asData.Length,outData, outDataLen, outBuf, outBufLength);

      Irp->IoStatus.Information = (outBufLength < outDataLen ? outBufLength : outDataLen);
      Irp->IoStatus.Status = STATUS_SUCCESS;
      IoCompleteRequest(Irp, IO_NO_INCREMENT); //结束IRP请求
      ExFreePool(pMyData);  //释放为pMyData申请的内存,此处pMyData的内存指针与申请时的是对应的,故无需再用变量保存原始指针
        }
        else
        {
            Irp->IoStatus.Information = 0;
            Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
            IoCompleteRequest(Irp, IO_NO_INCREMENT);
        }

        DbgPrint("[Aliwy] MyDeviceIoControl Over/n");
        return Irp->IoStatus.Status;
    }
    //------------------------------

    //----------打开关闭------------
    NTSTATUS MyCreateClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
    {
        DbgPrint("[Aliwy] MyCreateClose/n");
        Irp->IoStatus.Information = 0;
        Irp->IoStatus.Status = STATUS_SUCCESS;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
        return Irp->IoStatus.Status;
    }
    //------------------------------

    //----------驱动卸载------------
    VOID MyDriverOnUnload(IN PDRIVER_OBJECT DriverObject)
    {
        UNICODE_STRING DeviceLink; //符号链接名
        DbgPrint("[Aliwy] MyDriverOnUnload/n");

        RtlInitUnicodeString(&DeviceLink, L"//DosDevices//IamAliwy");
        IoDeleteSymbolicLink(&DeviceLink); //删除符号链接
        if (DriverObject->DeviceObject != NULL)
        {
            IoDeleteDevice(DriverObject->DeviceObject);  //删除设备
        }
    }
    //------------------------------
    应用层irp3exe.cpp文件:
    #include <windows.h> 
    #include <winioctl.h> 
    #include <stdio.h>  
     
    /*采用缓冲区内存模式IOCTL,MY_DVC_IN_CODE是自定义的控制码*/
    #define MY_DVC_BUFFERED_CODE /  
           (ULONG)CTL_CODE(FILE_DEVICE_UNKNOWN, / 
            0x900, / 
            METHOD_BUFFERED, / 
            FILE_ANY_ACCESS) 
     
    void main() 

        ULONG bytesReturned; 
     
        char outBuf[50];  //用于接收驱动传出内容的缓冲区  
     
        /*打开设备,用我们自定的符号链接,响应驱动IRP_MJ_CREATE*/ 
        HANDLE hDevice = CreateFile("////.//IamAliwy", 
                                    GENERIC_READ | GENERIC_WRITE, 
                                    0, 
                                    NULL, 
                                    CREATE_ALWAYS, 
                                    FILE_ATTRIBUTE_NORMAL, 
                                    NULL); 
        if (hDevice == INVALID_HANDLE_VALUE) 
        { 
            printf("设备打开失败 %d %.8x/n", GetLastError(), hDevice); 
            return; 
        } 
     
        memset(outBuf, 0, sizeof(outBuf));  
     
        while (true) 
        { 
            /*控制设备,响应驱动IRP_MJ_DEVICE_CONTROL*/ 
            BOOL ret = DeviceIoControl(hDevice, 
                                       MY_DVC_BUFFERED_CODE, //我们自定义的功能号  
                                       NULL,                 //传入驱动的内容  
                                       0,                    //传入内容长度  
                                       &outBuf,              //驱动输出的缓冲区  
                                       sizeof(outBuf),       //驱动输出缓冲区大小  
                                       &bytesReturned,       //返回的长度  
                                       NULL); 
            if (!ret) 
            { 
                printf("Error in DeviceIoControl: %d", GetLastError()); 
                break; 
            } 
            else 
            { 
                printf("%s(%d)/n", outBuf, bytesReturned);   //打印驱动传给我们的内容  
                if (strstr(outBuf, "Over")) 
                { 
                    break; 
                } 
            } 
        } 
         
        /*关闭设备,对应驱动IRP_MJ_CLOSE*/ 
        CloseHandle(hDevice); 

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

    /*采用缓冲区内存模式IOCTL,MY_DVC_IN_CODE是自定义的控制码*/
    #define MY_DVC_BUFFERED_CODE /
        (ULONG)CTL_CODE(FILE_DEVICE_UNKNOWN, /
         0x900, /
         METHOD_BUFFERED, /
      FILE_ANY_ACCESS)

    void main()
    {
     ULONG bytesReturned;

     char outBuf[50];  //用于接收驱动传出内容的缓冲区

     /*打开设备,用我们自定的符号链接,响应驱动IRP_MJ_CREATE*/
     HANDLE hDevice = CreateFile("////.//IamAliwy",
               GENERIC_READ | GENERIC_WRITE,
               0,
               NULL,
               CREATE_ALWAYS,
               FILE_ATTRIBUTE_NORMAL,
               NULL);
     if (hDevice == INVALID_HANDLE_VALUE)
     {
      printf("设备打开失败 %d %.8x/n", GetLastError(), hDevice);
      return;
     }

     memset(outBuf, 0, sizeof(outBuf));

     while (true)
     {
      /*控制设备,响应驱动IRP_MJ_DEVICE_CONTROL*/
      BOOL ret = DeviceIoControl(hDevice,
               MY_DVC_BUFFERED_CODE, //我们自定义的功能号
               NULL,                 //传入驱动的内容
               0,                    //传入内容长度
                              &outBuf,              //驱动输出的缓冲区
               sizeof(outBuf),       //驱动输出缓冲区大小
               &bytesReturned,       //返回的长度
                  NULL);
      if (!ret)
      {
       printf("Error in DeviceIoControl: %d", GetLastError());
       break;
      }
      else
      {
       printf("%s(%d)/n", outBuf, bytesReturned);   //打印驱动传给我们的内容
       if (strstr(outBuf, "Over"))
       {
        break;
       }
      }
     }
     
     /*关闭设备,对应驱动IRP_MJ_CLOSE*/
     CloseHandle(hDevice);
    }

  • 相关阅读:
    windows系统下强制杀死某个进程
    onenote快捷键
    sublime封装代码块快捷键、eemet插件安装、Loading PyV8 binary...的解决办法
    google浏览器截长图的方法
    (转)Java基础加强之并发(二)常用的多线程实现方式
    hibernate学习(初识)
    Spring中的事务操作
    JDBC最原始的代码做查询操作
    Spring的JDBC模板
    Spring AOP
  • 原文地址:https://www.cnblogs.com/einyboy/p/2548050.html
Copyright © 2011-2022 走看看