FastIO

In my previous posts about Stuxnet, I talked about the FileSystem Filter functionality of the Rootkit. I covered the idea of an “IO Request Packet” or IRP for short. IRPs are the general way for drivers to pass data to the lower layers in their device stacks. Filesystems often write to relatively slow backing stores (such as hard disks). To get an idea of the difference in timescale we are talking about, CPUs often operate in the microsecond domain, while hard disks operate in the millisecond domain. Due to this time scale difference, the Windows Engineers decided to provide an optimized I/O mechanism to write to such slow storage mediums. This caching mechanism is implemented in the Windows Cache Manager, and the FastIO infrastructure is the way to take advantage of it from a driver.

FastIO can be thought of as logically parallel to the IRP infrastructure in Windows, but with higher performance. Instead of waiting for each IRP to get to the disk, FastIO interacts with the Windows Cache Manager. The windows cache manager stores an in-memory cache of frequently accessed data on the disk (See chapters 9 and 10 of Windows Internals 5th edition by Mark Russinovich and David Solomon). This increases performance because on a cache lookup, the memory is hit (which has no moving parts and is fast) rather than the disk being hit (which has to seek to the correct sector, thereby incurring the cost of mechanical slowness). In addition to the disk not being hit on a read/write, FastIO also allows us to avoid the overhead incurred in synthesizing new IRPs to pass down the device stack.

The FastIO infrastructure is brought together by the FAST_IO_DISPATCH structure, which can be seen in wdm.h in the Windows Driver Development Kit. In the Rootkits book by Hoglund and Butler, they describe this structure as beginning with a size field, and containing all the function pointers for the FastIO functions supported by the driver. When attempting to call a FastIO function, the system first has to figure out whether or not the device in question supports FastIO. As a fallback, if the device does not support FastIO, an IRP is created and sent down the device stack.