since w8 Microsoft introduced for PnP devices management new structure with lots of function pointers - PiPnpRtlCtx
It`s called from lots of exported functions, but I think most comfortable for RE are IoOpenDeviceRegistryKey& IoOpenDeviceInterfaceRegistryKey. You can gather address of PiPnpRtlCtx with one pass of disassembling - it will be first loaded address in .data section after call to ExAcquireResourceExclusiveLite
This structure allocating and partially initializing in function PnpCtxOpenMachine. There are at least 3 version with different size:
There is also function PnpCtxSetNtPlugPlayRoutine which set up to 6 pfns:
It`s called from lots of exported functions, but I think most comfortable for RE are IoOpenDeviceRegistryKey& IoOpenDeviceInterfaceRegistryKey. You can gather address of PiPnpRtlCtx with one pass of disassembling - it will be first loaded address in .data section after call to ExAcquireResourceExclusiveLite
This structure allocating and partially initializing in function PnpCtxOpenMachine. There are at least 3 version with different size:
- 0xac for 32 bit/0x158 for x64 - used in w8, w8.1 and in w10 up to est.build 14279
- 0xb0 for 32 bit/0x160 for x64 - used in w10 up to est. build 16299
- 0x10c for 32 bit/0x210 for x64 - used in w10 since est. build 17134
This struct has lots of pointer to functions (see also PiPnpRtlInit):
Size | 0xac/0x156 | 0xb0/0x160 | 0x10c/0x210 |
---|---|---|---|
PiRtlObjectActionCallback offset | 0x98/0x130 | 0x9c/0x138 | 0xf8/0x1e8 |
PiRtlCmActionCallback offset | 0xa0/0x140 | 0xa4/0x148 | 0x100/0x1f8 |
PiRtlObjectEventCallback offset | 0x9c/0x138 | 0xa0/0x140 | 0xfc/0x1f0 |
PnpDispatchDevice offset | 0x44/0x88 | 0x48/0x90 | 0x9c/0x130 |
PnpDispatchInstallerClass offset | 0x48/0x90 | 0x4c/0x98 | 0xa0/0x138 |
PnpDispatchDeviceInterface offset | 0x4c/0x98 | 0x50/0xa0 | 0xa4/0x140 |
PnpDispatchInterfaceClass offset | 0x50/0xa0 | 0x54/0xa8 | 0xa8/0x148 |
PnpDispatchInterfaceClass offset | 0x54/0xa8 | 0x58/0xb0 | 0xac/0x150 |
PnpDispatchDevicePanel offset | 0xb0/0x158 | ||
There is also function PnpCtxSetNtPlugPlayRoutine which set up to 6 pfns:
- PiPnpRtlGetDeviceNtPropertyRoutine
- PiPnpRtlGetDeviceStatus
- PiPnpRtlGetDeviceRelatedDeviceRoutine
- PiPnpRtlGetDeviceRelationsList
- PiPnpRtlGetDeviceInterfaceEnabled
As you can assume with names of this functions by patching struct PiPnpRtlCtx we can have monitor of Pnp devices, their connecting, properties getting etc