遍历驱动设备栈
参考:https://blog.csdn.net/hjxyshell/article/details/39106609
参考 《windows 驱动开发技术详解》,部分关于对象的结构,请看上节windbg命令 中介绍
公用头文件:
-
// IOCTLS.H -- IOCTL code definitions for fileio driver
-
// Copyright (C) 1999 by Walter Oney
-
// All rights reserved
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
ring3级代码
-
-
-
-
-
-
int main()
-
{
-
HANDLE hDevice = CreateFile("\\\\.\\KeListDeviceSL",
-
GENERIC_READ | GENERIC_WRITE,
-
0,
-
NULL,
-
OPEN_EXISTING,
-
FILE_ATTRIBUTE_NORMAL,
-
NULL);
-
if(hDevice == INVALID_HANDLE_VALUE)
-
{
-
printf("Failed to obtain file handle to device: "
-
"%s with Win32 error code: %d\n",
-
"MyWDMDevice", GetLastError() );
-
return 0;
-
}
-
WCHAR* InputBuffer = L"\\Driver\\ACPI";
-
DWORD dwOutput;
-
BOOL bRet;
-
bRet = DeviceIoControl(hDevice,
-
IOCTL_DUMP_DEVICE_STACK,
-
InputBuffer,
-
wcslen(InputBuffer)*2+2,
-
NULL,
-
0,
-
&dwOutput,
-
NULL);
-
CloseHandle(hDevice);
-
return 1;
-
}
ring0级代码
ListDevice.h
-
-
-
extern "C"
-
{
-
-
-
NTKERNELAPI
-
NTSTATUS
-
ObReferenceObjectByName(
-
IN PUNICODE_STRING ObjectName,
-
IN ULONG Attributes,
-
IN PACCESS_STATE PassedAccessState OPTIONAL,
-
IN ACCESS_MASK DesiredAccess OPTIONAL,
-
IN POBJECT_TYPE ObjectType,
-
IN KPROCESSOR_MODE AccessMode,
-
IN OUT PVOID ParseContext OPTIONAL,
-
OUT PVOID *Object
-
);
-
NTKERNELAPI
-
PDEVICE_OBJECT
-
NTAPI
-
IoGetBaseFileSystemDeviceObject(
-
IN PFILE_OBJECT FileObject
-
);
-
extern POBJECT_TYPE IoDeviceObjectType;
-
extern POBJECT_TYPE *IoDriverObjectType;
-
-
}
-
-
-
-
-
-
-
typedef struct _DEVICE_EXTENSION{
-
PDEVICE_OBJECT pDevice;
-
UNICODE_STRING ustrDeviceName;
-
UNICODE_STRING ustrSymLinkName;
-
-
PUCHAR buffer; //缓冲区
-
ULONG file_length; //模拟文件长度,必须小于MAX_FILE_LENGTH
-
}DEVICE_EXTENSION, *PDEVICE_EXTENSION;
-
-
//函数声明
-
//创建设备
-
NTSTATUS CreateDevice(PDRIVER_OBJECT pDriverObject, UNICODE_STRING devname, UNICODE_STRING symLinkName);
-
//卸载驱动
-
VOID DriverUnload(PDRIVER_OBJECT pDriverObject);
-
//IRP请求处理函数
-
NTSTATUS MyDispatchFunction(PDEVICE_OBJECT device, PIRP pIrp);
-
//处理消息
-
NTSTATUS DeviceIoControlDispatch(PDEVICE_OBJECT pDevObj, PIRP pIrp);
-
-
//枚举设备栈
-
PDRIVER_OBJECT EnumDeviceStack(PWSTR pwszDeviceName);
-
-
typedef struct _OBJECT_CREATE_INFORMATION
-
{
-
ULONG Attributes;
-
HANDLE RootDirectory;
-
PVOID ParseContext;
-
KPROCESSOR_MODE ProbeMode;
-
ULONG PagedPoolCharge;
-
ULONG NonPagedPoolCharge;
-
ULONG SecurityDescriptorCharge;
-
PSECURITY_DESCRIPTOR SecurityDescriptor;
-
PSECURITY_QUALITY_OF_SERVICE SecurityQos;
-
SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
-
}OBJECT_CREATE_INFORMATION, *POBJECT_CREATE_INFORMATION;
-
-
typedef struct _OBJECT_HEADER
-
{
-
LONG PointerCount;
-
union
-
{
-
LONG HandleCount;
-
PSINGLE_LIST_ENTRY SEntry;
-
};
-
POBJECT_TYPE Type;
-
UCHAR NameInfoOffset;
-
UCHAR HandleInfoOffset;
-
UCHAR QuotaInfoOffset;
-
UCHAR Flags;
-
union
-
{
-
POBJECT_CREATE_INFORMATION ObjectCreateInfo;
-
PVOID QuotaBlockCharged;
-
};
-
PSECURITY_DESCRIPTOR SecurityDescriptor;
-
QUAD Body;
-
}OBJECT_HEADER, * POBJECT_HEADER;
-
-
-
-
typedef struct _OBJECT_DIRECTORY
-
{
-
struct _OBJECT_DIRECTORY_ENTRY* HashBuckets[NUMBER_HASH_BUCKETS];
-
struct _OBJECT_DIRECTORY_ENTRY** LookupBucket;
-
BOOLEAN LookupFound;
-
USHORT SymbolicLinkUsageCount;
-
struct _DEVICE_MAP* DeviceMap;
-
} OBJECT_DIRECTORY, * POBJECT_DIRECTORY;
-
-
typedef struct _OBJECT_HEADER_NAME_INFO
-
{
-
POBJECT_DIRECTORY Directory;
-
UNICODE_STRING Name;
-
ULONG QueryReferences;
-
-
ULONG QueryReferences2 ;
-
LONG DbgDereferenceCount ;
-
-
} OBJECT_HEADER_NAME_INFO, * POBJECT_HEADER_NAME_INFO;
-
//////////////////////////////////////////////////////////////////////////
-
// ----OBJECT----
-
// ----------------------------
-
// | Object_Header |
-
// ----------------------------
-
// | Object_Body(QUAD Body) |
-
// ----------------------------
-
//example(device object):
-
//
-
//dt nt!_object_header
-
// +0x000 PointerCount : Int4B
-
// +0x004 HandleCount : Int4B
-
// +0x004 NextToFree : Ptr32 Void
-
// +0x008 Type : Ptr32 _OBJECT_TYPE
-
// +0x00c NameInfoOffset : UChar
-
// +0x00d HandleInfoOffset : UChar
-
// +0x00e QuotaInfoOffset : UChar
-
// +0x00f Flags : UChar
-
// +0x010 ObjectCreateInfo : Ptr32 _OBJECT_CREATE_INFORMATION
-
// +0x010 QuotaBlockCharged : Ptr32 Void
-
// +0x014 SecurityDescriptor : Ptr32 Void
-
// +0x018 Body : _QUAD //此处内容即下面的对象
-
//
-
//dt nt!_DEVICE_OBJECT
-
// +0x000 Type : Int2B
-
// +0x002 Size : Uint2B
-
// +0x004 ReferenceCount : Int4B
-
// +0x008 DriverObject : Ptr32 _DRIVER_OBJECT
-
// +0x00c NextDevice : Ptr32 _DEVICE_OBJECT
-
// +0x010 AttachedDevice : Ptr32 _DEVICE_OBJECT
-
// +0x014 CurrentIrp : Ptr32 _IRP
-
// +0x018 Timer : Ptr32 _IO_TIMER
-
// +0x01c Flags : Uint4B
-
// +0x020 Characteristics : Uint4B
-
// +0x024 Vpb : Ptr32 _VPB
-
// +0x028 DeviceExtension : Ptr32 Void
-
// +0x02c DeviceType : Uint4B
-
// +0x030 StackSize : Char
-
// +0x034 Queue : <unnamed-tag>
-
// +0x05c AlignmentRequirement : Uint4B
-
// +0x060 DeviceQueue : _KDEVICE_QUEUE
-
// +0x074 Dpc : _KDPC
-
// +0x094 ActiveThreadCount : Uint4B
-
// +0x098 SecurityDescriptor : Ptr32 Void
-
// +0x09c DeviceLock : _KEVENT
-
// +0x0ac SectorSize : Uint2B
-
// +0x0ae Spare1 : Uint2B
-
// +0x0b0 DeviceObjectExtension : Ptr32 _DEVOBJ_EXTENSION
-
// +0x0b4 Reserved : Ptr32 Void
-
//
-
//////////////////////////////////////////////////////////////////////////
-
-
-
-
-
-
ListDevice.cpp
-
// _ooOoo_
-
// o8888888o
-
// 88" . "88
-
// (| -_- |)
-
// O\ = /O
-
// ____/`---'\____
-
// . ' \\| |// `.
-
// / \\||| : |||// \
-
// / _||||| -:- |||||- \
-
// | | \\\ - /// | |
-
// | \_| ''\---/'' | |
-
// \ .-\__ `-` ___/-. /
-
// ___`. .' /--.--\ `. . __
-
// ."" '< `.___\_<|>_/___.' >'"".
-
// | | : `- \`.;`\ _ /`;.`/ - ` : | |
-
// \ \ `-. \_ __\ /__ _/ .-` / /
-
// ======`-.____`-.___\_____/___.-`____.-'======
-
// `=---='
-
//
-
// .............................................
-
// 佛祖镇楼 BUG辟易
-
// 佛曰:
-
// 写字楼里写字间,写字间里程序员;
-
// 程序人员写程序,又拿程序换酒钱。
-
// 酒醒只在网上坐,酒醉还来网下眠;
-
// 酒醉酒醒日复日,网上网下年复年。
-
// 但愿老死电脑间,不愿鞠躬老板前;
-
// 奔驰宝马贵者趣,公交自行程序员。
-
// 别人笑我忒疯癫,我笑自己命太贱;
-
// 不见满街漂亮妹,哪个归得程序员?
-
-
-
-
NTSTATUS
-
DriverEntry(PDRIVER_OBJECT pDriverObject,PUNICODE_STRING pRegistryPath)
-
{
-
DbgPrint("Enter DriverEntry\n");
-
-
NTSTATUS status;
-
pDriverObject->DriverUnload = DriverUnload;
-
for (int i = 0; i< IRP_MJ_MAXIMUM_FUNCTION; i++)
-
{
-
pDriverObject->MajorFunction[i] = MyDispatchFunction;
-
}
-
-
pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DeviceIoControlDispatch;
-
//准备创建设备
-
UNICODE_STRING ustrDevName, ustrSymbolicName;
-
RtlInitUnicodeString(&ustrDevName, L"\\Device\\KeListDevice");
-
RtlInitUnicodeString(&ustrSymbolicName, L"\\DosDevices\\KeListDeviceSL");
-
status = CreateDevice(pDriverObject, ustrDevName, ustrSymbolicName);
-
if(!NT_SUCCESS(status))
-
{
-
KdPrint(("Failed to Create Device ...\n"));
-
return STATUS_UNSUCCESSFUL;
-
}
-
KdPrint(("Exit DriverEntry\n"));
-
return STATUS_SUCCESS;
-
}
-
-
NTSTATUS CreateDevice(PDRIVER_OBJECT pDriverObject, UNICODE_STRING devname, UNICODE_STRING symLinkName)
-
{
-
NTSTATUS status;
-
PDEVICE_OBJECT pDevObj;
-
PDEVICE_EXTENSION pDevExt;
-
//创建设备
-
status = IoCreateDevice(pDriverObject,
-
sizeof(DEVICE_EXTENSION),
-
&devname,
-
FILE_DEVICE_UNKNOWN,
-
0,
-
TRUE,
-
&pDevObj);
-
if(!NT_SUCCESS(status))
-
return status;
-
-
pDevObj->Flags |= DO_BUFFERED_IO;
-
pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;
-
pDevExt->pDevice = pDevObj;
-
pDevExt->ustrDeviceName = devname;
-
pDevExt->ustrSymLinkName = symLinkName;
-
-
//创建设备连接
-
status = IoCreateSymbolicLink(&symLinkName, &devname);
-
if(!NT_SUCCESS(status))
-
{
-
KdPrint(("Failed to IoCreateSymbolicLink and delete DeviceObject --- errorcode = %d ...\n",status));
-
IoDeleteDevice(pDevObj);
-
return status;
-
}
-
return status;
-
}
-
//卸载驱动
-
VOID DriverUnload(PDRIVER_OBJECT pDriverObject)
-
{
-
PDEVICE_OBJECT pNextObj;
-
KdPrint(("Enter DriverUnload...\n"));
-
pNextObj = pDriverObject->DeviceObject;
-
//循环遍历删除所有该驱动上的设备
-
while(pNextObj != NULL)
-
{
-
//设备的名称和链接名称均在扩展结构中存储
-
PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pNextObj->DeviceExtension;
-
//删除符号链接
-
UNICODE_STRING LinkName = pDevExt->ustrSymLinkName;
-
IoDeleteSymbolicLink(&LinkName);
-
pNextObj = pNextObj->NextDevice;
-
IoDeleteDevice(pDevExt->pDevice);
-
}
-
}
-
//IRP请求处理函数
-
NTSTATUS MyDispatchFunction(PDEVICE_OBJECT device, PIRP pIrp)
-
{
-
NTSTATUS status = STATUS_SUCCESS;
-
//完成IRP,此处不做任何特殊处理
-
pIrp->IoStatus.Status = status;
-
pIrp->IoStatus.Information = 0;
-
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
-
KdPrint(("Leave MyDispatchFunction\n"));
-
return status;
-
}
-
//处理消息
-
NTSTATUS DeviceIoControlDispatch(PDEVICE_OBJECT pDevObj, PIRP pIrp)
-
{
-
-
NTSTATUS status = STATUS_SUCCESS;
-
-
KdPrint(("Enter DeviceIoControlDispatch...\n"));
-
PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp);
-
ULONG cbin = stack->Parameters.DeviceIoControl.InputBufferLength;
-
ULONG cbout = stack->Parameters.DeviceIoControl.OutputBufferLength;
-
//得到IOCTL码
-
ULONG code = stack->Parameters.DeviceIoControl.IoControlCode;
-
ULONG info = 0;
-
switch(code)
-
{
-
case IOCTL_DUMP_DEVICE_STACK:
-
{
-
KdPrint(("IOCTL_DUMP_DEVICE_STACK\n"));
-
WCHAR* InputBuffer = (WCHAR*)pIrp->AssociatedIrp.SystemBuffer; //ring3级传入的是WCHAR类型的字符串
-
EnumDeviceStack(InputBuffer);
-
}
-
default:
-
status = STATUS_INVALID_VARIANT;
-
}
-
//完成IRP,此处不做任何特殊处理
-
pIrp->IoStatus.Status = status;
-
pIrp->IoStatus.Information = info;
-
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
-
KdPrint(("Leave MyDispatchFunction\n"));
-
return status;
-
}
-
-
//获取设备对象的信息
-
VOID GetDeviceObjectInfo(PDEVICE_OBJECT DevObj)
-
{
-
POBJECT_HEADER ObjectHeader;
-
POBJECT_HEADER_NAME_INFO ObjectNameInfo;
-
-
if(DevObj == NULL)
-
{
-
DbgPrint("DevObj is NULL!\n");
-
return;
-
}
-
ObjectHeader = OBJECT_TO_OBJECT_HEADER(DevObj); //由对象得到对象头
-
if(ObjectHeader)
-
{
-
//查询设备对象名称并打印
-
ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
-
if(ObjectNameInfo && ObjectNameInfo->Name.Buffer)
-
{
-
//打印设备相关信息
-
DbgPrint(" Driver Name : %wZ - Device Name :%wZ -Driver Address :0x%x - Device Address: 0x%x\n",
-
&(DevObj->DriverObject->DriverName),
-
&(ObjectNameInfo->Name),
-
DevObj->DriverObject,
-
DevObj);
-
}
-
//无名子设备处理
-
else if (DevObj->DriverObject)
-
{
-
//打印设备相关信息
-
DbgPrint(" Driver Name : %wZ - Device Name :%wZ -Driver Address :0x%x - Device Address: 0x%x\n",
-
&(DevObj->DriverObject->DriverName),
-
L"NULL",
-
DevObj->DriverObject,
-
DevObj);
-
}
-
}
-
}
-
-
//遍历一个设备上所有的附加设备
-
VOID GetAttachedDeviceInfo(PDEVICE_OBJECT DevObj)
-
{
-
PDEVICE_OBJECT AtDeviceObject; //附加的设备
-
if(DevObj == NULL)
-
{
-
DbgPrint("DevObj is NULL!\n");
-
return;
-
}
-
-
AtDeviceObject = DevObj->AttachedDevice;
-
-
while(AtDeviceObject)
-
{
-
DbgPrint( "Attached Driver Name:%wZ,Attached Driver Address:0x%x,Attached DeviceAddress:0x%x\n",
-
&(AtDeviceObject->DriverObject->DriverName),
-
AtDeviceObject->DriverObject,
-
AtDeviceObject );
-
AtDeviceObject = AtDeviceObject->AttachedDevice;
-
}
-
}
-
//枚举设备栈
-
PDRIVER_OBJECT EnumDeviceStack(PWSTR pwszDeviceName)
-
{
-
UNICODE_STRING DriverName;
-
PDRIVER_OBJECT DriverObject = NULL;
-
PDEVICE_OBJECT DeviceObject = NULL;
-
-
RtlInitUnicodeString(&DriverName, pwszDeviceName); //本例是获得 高级电源管理驱动的设备栈
-
-
ObReferenceObjectByName(&DriverName,
-
OBJ_CASE_INSENSITIVE,
-
NULL,
-
0,
-
(POBJECT_TYPE)IoDriverObjectType,
-
KernelMode,
-
NULL,
-
(PVOID*)&DriverObject);
-
-
if(DriverObject == NULL)
-
return NULL;
-
-
DeviceObject = DriverObject->DeviceObject;
-
while(DeviceObject)
-
{
-
GetDeviceObjectInfo(DeviceObject);
-
//判断是否有过滤驱动(附加驱动)
-
if(DeviceObject->AttachedDevice)
-
GetAttachedDeviceInfo(DeviceObject);
-
-
//进一步判断设备上的VPB 中设备
-
if(DeviceObject->Vpb && DeviceObject->Vpb->DeviceObject)
-
{
-
GetDeviceObjectInfo(DeviceObject->Vpb->DeviceObject);
-
if(DeviceObject->Vpb->DeviceObject->AttachedDevice)
-
GetAttachedDeviceInfo(DeviceObject->Vpb->DeviceObject);
-
}
-
//得到驱动上的下一个设备DEVICE_OBJECT
-
DeviceObject = DeviceObject->NextDevice;
-
}
-
return DriverObject;
-
}