驱动列举进程输出到应用层
本篇算是前兩篇的綜合,驅動列舉出進程,并將進程名加入到一個鏈表中,
最后應用層程序通過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);
}
?
總結
以上是生活随笔為你收集整理的驱动列举进程输出到应用层的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ubuntu9.04换源
- 下一篇: 有关SQL server connect