Drivers extend the functionality of the kernel, e.g. by implementing a network communication protocol or an interface to a new piece of hardware. They are loadable kernel-mode modules, what allows them to modify any system behavior. Several rootkits are implemented by drivers. In this post I present a plugin for the Volatility memory analysis framework, that scans for driver objects.
A driver object is represented by a, you guessed it, _DRIVER_OBJECT structure. This structure tells about the address of the driver's code in memory and provides pointers to a variety of request handling functions.
kd> dt _DRIVER_OBJECT ntdll!_DRIVER_OBJECT struct _DRIVER_OBJECT, 15 elements, 0xa8 bytes +0x000 Type : Int2B +0x002 Size : Int2B +0x004 DeviceObject : Ptr32 _DEVICE_OBJECT +0x008 Flags : Uint4B +0x00c DriverStart : Ptr32 Void +0x010 DriverSize : Uint4B +0x014 DriverSection : Ptr32 Void +0x018 DriverExtension : Ptr32 _DRIVER_EXTENSION +0x01c DriverName : _UNICODE_STRING +0x024 HardwareDatabase : Ptr32 _UNICODE_STRING +0x028 FastIoDispatch : Ptr32 _FAST_IO_DISPATCH +0x02c DriverInit : Ptr32 long +0x030 DriverStartIo : Ptr32 void +0x034 DriverUnload : Ptr32 void +0x038 MajorFunction :  Ptr32 long
The object also links to an extension. It tells us about the "ServiceKeyName". That's the registry key below HKLM\SYSTEM\controlset\Services, where the driver stores its configuration data.
kd> dt _DRIVER_EXTENSION ntdll!_DRIVER_EXTENSION struct _DRIVER_EXTENSION, 6 elements, 0x1c bytes +0x000 DriverObject : Ptr32 _DRIVER_OBJECT +0x004 AddDevice : Ptr32 long +0x008 Count : Uint4B +0x00c ServiceKeyName : _UNICODE_STRING +0x014 ClientDriverExtension : Ptr32 _IO_CLIENT_EXTENSION +0x018 FsFilterCallbacks : Ptr32 _FS_FILTER_CALLBACKS
Both structures point to the other. So, one might assume, they are stored in different locations of the memory. But interestingly nt!IoCreateDriver allocates a single block of memory that is large enough to hold both of them. The allocation is made from the nonpaged pool and tagged with "Driv".
The final in-memory structure, as assembled by IoCreateDriver, looks as follows:
- extra object name information
Here's a little plugin for the Volatility memory analysis framework to search for and parse these structures. Please create a backup copy of your Volatility installation first. Then unzip the archive in your Volatility base directory. If you use the current version from the Volatility SVN repository, then please install only the plugin file.
Below are the results on an infection with Unreal.A. Even though the rootkit tried to hide its name, the plugin found it in object meta-data. The zeroed object type pointer should raise some suspicion, too.
Obj Type #Ptr #Hnd Start Size Service key Name 0x00000000 0 0 0xfca49000 5888 unreal 0x812b5ad0 3 0 0xfc62b000 57600 usbhub usbhub \Driver\usbhub 0x812b5ad0 4 0 0xfa8ef000 76256 hgfs hgfs \FileSystem\hgfs