Disk Filtering - Old and New Driver Module
When a device receives a request such as IRP_MJ_SCSI, it queues it to the disk via IoStartPacket, which eventually calls the address held by the DriverStartIo field of the driver's object; thus hooking DriverStartIo would intercept any disk I/O requests, not just IRP_MJ_SCSI.
TDL Warning
Detecting Major Function Hooks with WinDbg
Now we can examine the driver object (specifically the dispatch table) for major function pointer hooks. On a clean system all the dispatch routines should have addresses which resolve to symbols in either the miniport, port or ntoskrnl. On TDL4 infected systems the !drvobj command won't work, so you'll have to use dds (iv'e shown how to use both below).
![]() |
| Major functions on a clean system shown with !drvobj |
![]() |
| Major functions on a clean system shown with dds |
On an infected system (TDL4) we will see something similar to the below.
![]() |
| Note: all the dispatch routines point to the same address, which resides in pool memory (not normal). |
![]() |
| In an attempt to trick av tools, Rovnix redirects the pointers to jumps it wrote to unused space at the end of atapi.sys, hence the addresses don't resolve to a function, only a module. |
If the driver dispatch table appears to be clean, the next thing to do is disassemble the address pointed to by IRP_MJ_SCSI (IRP_MJ_INTERNAL_DEVICE_CONTROL), as this is the dispatch routine which handles disk read/write requests and could be inline hooked. In my case IRP_MJ_SCSI points to ataport!IdePortDispatch.
![]() |
| A example of a clean IRP_MJ_SCSI handler |
It may be difficult to detect inline hooks, especially if existing jump/calls are modified. One should compare the module in memory against its disk image, accounting for relocation and imports (the best way to do this would be to have a driver map the disk image into memory and relocate it to point to the original module, allowing you to simply compare the two).









SOCIAL SHARE CARD GENERATOR