nt!IopGetRootDevices函数的nt!PipApplyFunctionToSubKeys函数后面下断点可以查看根节点中建立的设备对象的数量context.DeviceCount
19 e Disable Clear 80cb096f [d:\srv03rtm\base\ntos\io\pnpmgr\pnpdd.c @ 905] 0001 (0001) nt!IopGetRootDevices+0x157
1: kd> kc
#
00 nt!IopInitializeDeviceKey
01 nt!PipApplyFunctionToSubKeys
02 nt!IopGetRootDevices
03 nt!IopPnPDispatch
04 nt!IofCallDriver
05 nt!IopSynchronousCall
06 nt!IopQueryDeviceRelations
07 nt!PipEnumerateDevice
08 nt!PipProcessDevNodeTree
09 nt!PiProcessReenumeration
0a nt!PipDeviceActionWorker
0b nt!PipRequestDeviceAction
0c nt!IopInitializePlugPlayServices
0d nt!IoInitSystem
0e nt!Phase1Initialization
0f nt!PspSystemThreadStartup
10 nt!KiThreadStartup
1: kd> kv
# ChildEBP RetAddr Args to Child
00 f789a1d8 80c87246 800004c0 f789a1f8 f789a23c nt!IopInitializeDeviceKey+0x48 (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\base\ntos\io\pnpmgr\pnpdd.c @ 1008]
01 f789a210 80cb096f 800004b0 800004c0 000f003f nt!PipApplyFunctionToSubKeys+0xec (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\base\ntos\io\pnpmgr\pnpsubs.c @ 1976]
02 f789a26c 80cb0bc8 f789a29c 899c5d08 89994008 nt!IopGetRootDevices+0x157 (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\base\ntos\io\pnpmgr\pnpdd.c @ 905]
03 f789a294 80a2675c 00000000 89994008 8999409c nt!IopPnPDispatch+0x92 (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\base\ntos\io\pnpmgr\pnpdd.c @ 405]
04 f789a2b0 80c95e00 00000000 899c5bc8 899c5bc8 nt!IofCallDriver+0x62 (FPO: [Non-Fpo]) (CONV: fastcall) [d:\srv03rtm\base\ntos\io\iomgr\iosubs.c @ 2237]
05 f789a2e0 80a2e3f3 00000000 f789a2fc 899c5ca8 nt!IopSynchronousCall+0x1aa (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\base\ntos\io\pnpmgr\pnpirp.c @ 258]
06 f789a320 80c8d810 00000000 899c5d08 00000001 nt!IopQueryDeviceRelations+0x39 (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\base\ntos\io\pnpmgr\pnpirp.c @ 1131]
07 f789a33c 80c94e01 899c5bc8 00000001 899c5bc8 nt!PipEnumerateDevice+0x56 (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\base\ntos\io\pnpmgr\pnpenum.c @ 980]
08 f789a588 80c954e7 899c5bc8 00000000 00000000 nt!PipProcessDevNodeTree+0x273 (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\base\ntos\io\pnpmgr\pnpenum.c @ 4699]
09 f789a5c0 80a2de90 89996df0 80b1f6f8 00000000 nt!PiProcessReenumeration+0xaf (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\base\ntos\io\pnpmgr\pnpenum.c @ 6115]
0a f789a5e8 80a2e161 00000000 e1278d82 00000000 nt!PipDeviceActionWorker+0x174 (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\base\ntos\io\pnpmgr\pnpenum.c @ 801]
0b f789a600 80e68579 899c5d08 00000008 00000000 nt!PipRequestDeviceAction+0x139 (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\base\ntos\io\pnpmgr\pnpenum.c @ 598]
0c f789a694 80e6554b 8000048c 80000494 00034000 nt!IopInitializePlugPlayServices+0x619 (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\base\ntos\io\pnpmgr\pnpinit.c @ 762]
0d f789a838 80e632fd 80077000 00000000 899a1020 nt!IoInitSystem+0x68f (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\base\ntos\io\iomgr\ioinit.c @ 599]
0e f789adac 80d391f0 80077000 00000000 00000000 nt!Phase1Initialization+0x9b3 (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\base\ntos\init\init.c @ 2221]
0f f789addc 80b00d52 80e6294a 80077000 00000000 nt!PspSystemThreadStartup+0x2e (FPO: [Non-Fpo]) (CONV: stdcall) [d:\srv03rtm\base\ntos\ps\create.c @ 2213]
10 00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x16 [d:\srv03rtm\base\ntos\ke\i386\threadbg.asm @ 81]
windbg> .open -a ffffffff80a2e3f3
NTSTATUS
IopGetRootDevices (
PDEVICE_RELATIONS *DeviceRelations
)
{
//
// Enumerate all subkeys under the System\CCS\Enum\Root.
//
context.Status = STATUS_SUCCESS;
context.KeyName = &workName;
status = PipApplyFunctionToSubKeys(baseHandle,
NULL,
KEY_ALL_ACCESS,
FUNCTIONSUBKEY_FLAG_IGNORE_NON_CRITICAL_ERRORS,
IopInitializeDeviceKey,
&context
);//这里下断点:
ZwClose(baseHandle);
//
// Build returned information from ROOT_ENUMERATOR_CONTEXT.
//
status = context.Status;
if (NT_SUCCESS(status) && context.DeviceCount != 0) {
deviceRelations = (PDEVICE_RELATIONS) ExAllocatePool(
PagedPool,
sizeof (DEVICE_RELATIONS) + sizeof(PDEVICE_OBJECT) * context.DeviceCount
);
if (deviceRelations == NULL) {
status = STATUS_INSUFFICIENT_RESOURCES;
} else {
deviceRelations->Count = context.DeviceCount;
RtlCopyMemory(deviceRelations->Objects,
context.DeviceList,
sizeof (PDEVICE_OBJECT) * context.DeviceCount);
*DeviceRelations = deviceRelations;
}
第二种方式:在nt!PipEnumerateCompleted函数下断点,查看DeviceNode->OverUsed1.PendingDeviceRelations->Count
表示当前节点子节点的数量:
查看DeviceNode->OverUsed1.PendingDeviceRelations
1: kd> dt _DEVICE_NODE -r
nt!_DEVICE_NODE
+0x000 Sibling : Ptr32 _DEVICE_NODE
+0x0e0 OverUsed1 : __unnamed
+0x000 PendingDeviceRelations : Ptr32 _DEVICE_RELATIONS
+0x000 Count : Uint4B
+0x004 Objects : [1] Ptr32 _DEVICE_OBJECT
NTSTATUS
PipProcessDevNodeTree(
IN PDEVICE_NODE SubtreeRootDeviceNode,
IN BOOLEAN LoadDriver,
IN BOOLEAN ReallocateResources,
IN ENUM_TYPE EnumType,
IN BOOLEAN Synchronous,
IN BOOLEAN ProcessOnlyIntermediateStates,
IN PADD_CONTEXT AddContext,
IN PPI_DEVICE_REQUEST Request
)
{
case DeviceNodeEnumerateCompletion:
status = PipEnumerateCompleted(currentNode);
nextNode = ChildNode;
break;
NTSTATUS
PipEnumerateCompleted(
IN PDEVICE_NODE DeviceNode
)
{
//
// Check all the PDOs returned see if any new one or any one disappeared.
//
for (i = 0; i < DeviceNode->OverUsed1.PendingDeviceRelations->Count; i++) {
childDeviceObject = DeviceNode->OverUsed1.PendingDeviceRelations->Objects[i];
ASSERT_INITED(childDeviceObject);
ExFreePool(DeviceNode->OverUsed1.PendingDeviceRelations);
DeviceNode->OverUsed1.PendingDeviceRelations = NULL;
这里赋值为NULL,自此以后就看不到了。以后也用不到了。信息已经跑到设备数里面了。