To achieve this, an interrupt handler places a work item, containing a pointer to a callback routine, in the queue using
IoQueueWorkItem. Once the work item gets to the head of the queue, one of the system worker threads takes it out of the queue and executes the callback routine, which takes care of the pending work for the handler. These threads always run under the system process with process ID 4.
TDL creates exactly these kind of work items using what are known as asynchronous process calls (APCs). Let's see if we find some on Hansy's computer. Using
!process 0 f system I call up detailed information on the thread and stack status of the system processes.
The output is lengthy and not particularly readable. While I leaf through it, my eyes are drawn to the message "Warning: Frame IP not in any module. Following frames may be wrong." The address,
0x820d873b, is very close to that of what I previously identified as a
load image notify routine. I'm guessing this is indeed the callback handler from the rootkit's work item.
Next I want to find out whether the rootkit is somehow monitoring access to the hard drive or filesystem. I start by determining the hard drive's device object and then use
!devstack with its address to obtain a list of device drivers registered for it.
disk.sys are OK, but rather than the expected
atapi.sys IDE miniport driver, which communicates with the physical device directly, I am confronted with the message "Invalid type for DeviceObject 0x8217eaf0". There's something strange going on here, which I'd do well to get to the bottom of.
So I use
dt _device_object to view the data structure for this invalid device object. Someone's definitely been fiddling with the type. The correct value is 3, but instead it's set to 0, which can't be implemented with the kernel's normal API functions. I suspect this is an attempt to hide from rootkit scanners searching for this kind of object in the nonpaged pool. It probably wouldn't fool a suitably well-crafted tool, but there's no harm in trying.