这一篇基本上就没有什么新东西了, 就是上几篇的应用. 遍历一个驱动的所有设备对象, 还有绑定在设备上面的所有的驱动对象, 设备对象.

其实就是对驱动对象和设备对象的结构挑选了几个字段过来显示下, 基本上如果了解了驱动对象的一些机构和设备对象的一些结构, 那么就没有什么问题了, 当然了解了两个对象以后还有点小问题, 首先一个问题就是获取驱动对象的地址, 上一篇我们已经谈到如何获取某个名称所对应的对象地址, 这里就派上用场了.

就是这号函数ObReferenceObjectByName. 这号函数可以通过名称获取某个对象的地址. OK有了对象的地址其他的就很简单了, 在驱动对象中有其设备对象的链表, 而在每个设备对象中都有上层绑定设备的地址, 如果有那么不停的遍历就可以遍历完所有的设备对象和绑定对象了..

没有什么新意. 这边是代码:

        EnumDeviceStack.rar

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/*	遍历驱动设备, 查询设备名称和绑定的设备
	编译方法参见makefile. TAB = 8
*/
#include <ntddk.h>
#include "EnumDeviceStack.h"

//===========================================================================
//获取某个设备对象信息
//===========================================================================
VOID GetDeviceObjectInfo( PDEVICE_OBJECT pDeviceObj ) {
	POBJECT_HEADER ObjHeader = NULL;
	POBJECT_HEADER_NAME_INFO ObjName = NULL;

	//得到对象头
	ObjHeader = OBJECT_TO_OBJECT_HEADER( pDeviceObj );
	ASSERT( pDeviceObj != NULL );

	if ( ObjHeader  ) {

		//查询设备名称
		ObjName = OBJECT_HEADER_TO_NAME_INFO( ObjHeader );

		if ( ObjName && ObjName->Name.Buffer ) {

			KdPrint( ( "驱动名称:%wZ 设备名称:%wZ 驱动地址:%p 设备地址:%p\\n",
				   &pDeviceObj->DriverObject->DriverName,
				   &ObjName->Name, pDeviceObj->DriverObject, pDeviceObj
				 ) );
		}
//---------------------------------------------------------------------------
		//对于没有名称的设备打印NULL
//---------------------------------------------------------------------------
	} else if( pDeviceObj->DriverObject ) {

		KdPrint( ( "驱动名称:%wZ 设备名称:%wZ 驱动地址:%p 设备地址:%p\\n",
			   &pDeviceObj->DriverObject->DriverName,
			   NULL,  pDeviceObj->DriverObject,  pDeviceObj ) );
	}
	return;
}

//===========================================================================
//获取绑定在设备栈上的设备信息
//===========================================================================
VOID GetAttachedDeviceObjectInfo( PDEVICE_OBJECT pDeviceObj ) {
	PDEVICE_OBJECT pAttrDeviceObj = NULL;

	ASSERT( pDeviceObj != NULL );

	//获取绑定设备的地址
	pAttrDeviceObj = pDeviceObj->AttachedDevice;

	while ( pAttrDeviceObj ) {
		KdPrint( ( "\\t绑定驱动名称:%wZ  绑定驱动地址:%p 绑定设备地址:%p\\n",
			   &pAttrDeviceObj->DriverObject->DriverName,
			   pAttrDeviceObj->DriverObject, pAttrDeviceObj ) );

		//往上遍历
		pAttrDeviceObj = pAttrDeviceObj->AttachedDevice;
	}
}
//===========================================================================
//枚举设备栈
//===========================================================================
NTSTATUS EnumDeviceStack( PUNICODE_STRING pUSzDriverName ) {
	NTSTATUS Status;
	PDEVICE_OBJECT pDeviceObj = NULL;
	PDRIVER_OBJECT pDriverObj = NULL;

	//通过驱动对象名称获取驱动对象指针
	Status = ObReferenceObjectByName( pUSzDriverName, OBJ_CASE_INSENSITIVE, NULL, 0,
					  *IoDriverObjectType, KernelMode, NULL, &pDriverObj );
	if ( !NT_SUCCESS( Status ) || !pDriverObj  ) {
		return STATUS_UNSUCCESSFUL;
	}

	//通过驱动对象得到其设备对象指针
	pDeviceObj = pDriverObj->DeviceObject;

	__try {

		while ( pDeviceObj ) {

			//获取设备信息
			GetDeviceObjectInfo( pDeviceObj );

			//如果还有绑定在其之上的设备
			if ( pDeviceObj->AttachedDevice ) {
				//获取绑定在设备之上的的设备信息
				GetAttachedDeviceObjectInfo( pDeviceObj );

			}

			//进一步判断当前设备上的VPB中的设备
			if ( pDeviceObj->Vpb && pDeviceObj->Vpb->DeviceObject ) {

				//获取设备对象信息
				GetDeviceObjectInfo( pDeviceObj->Vpb->DeviceObject );

				//如果还有绑定设备
				if ( pDeviceObj->Vpb->DeviceObject->AttachedDevice ) {
					//获取绑定设备信息
					GetAttachedDeviceObjectInfo( pDeviceObj->Vpb->DeviceObject );
				}

			}
			pDeviceObj = pDeviceObj->NextDevice;
		}

	} __finally {
		if ( pDriverObj ) {
			ObDereferenceObject( pDriverObj );
		}

	}
	return Status;
}

NTSTATUS DriverEntry( PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pUSzRegPath ) {
	NTSTATUS Status;
	UNICODE_STRING USzDriverName = RTL_CONSTANT_STRING( L"\\\\Driver\\\\ACPI" );

	Status = EnumDeviceStack( &USzDriverName );
	if ( !NT_SUCCESS( Status ) ) {
		KdPrint( ( "枚举设备失败!\\n" ) );
		return Status;
	}

	return STATUS_UNSUCCESSFUL;
}