Scanning for File Objects

The Microsoft Windows kernel represents opened files by an _FILE_OBJECT structure. With some help from the Microsoft Debugger, the object type information about files and the Volatility memory analysis framework it is an easy task to craft a file object scanner. This scanner may reveal files even if they are hidden by a rootkit.

Fortunately, _FILE_OBJECT is a common structure. So we don't have reverse parts of the kernel or have to rely on rare debug symbols with full type information in order to learn about the details. Here is, what the debugger tells about the file object on Windows XP with ServicePack 2:

struct _FILE_OBJECT, 27 elements, 0x70 bytes
   +0x000 Type             : Int2B
   +0x002 Size             : Int2B
   +0x004 DeviceObject     : Ptr32 _DEVICE_OBJECT
   +0x008 Vpb              : Ptr32 _VPB
   +0x00c FsContext        : Ptr32 Void
   +0x010 FsContext2       : Ptr32 Void
   +0x014 SectionObjectPointer : Ptr32 _SECTION_OBJECT_POINTERS
   +0x018 PrivateCacheMap  : Ptr32 Void
   +0x01c FinalStatus      : Int4B
   +0x020 RelatedFileObject : Ptr32 _FILE_OBJECT
   +0x024 LockOperation    : UChar
   +0x025 DeletePending    : UChar
   +0x026 ReadAccess       : UChar
   +0x027 WriteAccess      : UChar
   +0x028 DeleteAccess     : UChar
   +0x029 SharedRead       : UChar
   +0x02a SharedWrite      : UChar
   +0x02b SharedDelete     : UChar
   +0x02c Flags            : Uint4B
   +0x030 FileName         : _UNICODE_STRING
   +0x038 CurrentByteOffset : _LARGE_INTEGER
   +0x040 Waiters          : Uint4B
   +0x044 Busy             : Uint4B
   +0x048 LastLock         : Ptr32 Void
   +0x04c Lock             : _KEVENT
   +0x05c Event            : _KEVENT
   +0x06c CompletionContext : Ptr32 _IO_COMPLETION_CONTEX

From the list of kernel object types we learn that file objects reside in the paged pool. Allocations are tagged with "File". Running !poolfind File in the debuggers retrives a list of matching pool allocations. As you will find out, the minimum block size is 0x98.

Knowing about the data structure, pool type, pool tag and allocation size, it is easy to craft a plugin for the Volatility memory analysis framework. The archive also contains two modified source files of the Volatility core. Please create a backup copy of your Volatility installation first, and then extract the archive in your Volatility base directory.

04/11/2009: The modified files have been added to the Volatility SVN version. Thanks moyix!

Below is an excerpt of the results from the scanning hogfly's exemplar18.vmem for file objects.

Phys.Addr. Obj Type   #Ptr #Hnd Access Name
0x016cea70 0x817b8730    1    0 R--r-d \WINDOWS\Temp\tempo-447187.tmp
0x016c76f0 0x817b8730    1    0 R--r-d \WINDOWS\Temp\gaopdx447031.tmp
0x016dcc08 0x817b8730    1    0 R--r-d \WINDOWS\system32\drivers\gaopdxserv.sys
0x018b3ae0 0x817b8730    1    0 -W-r-- \WINDOWS\system32\gaopdxcounter
0x019e3398 0x817b8730    1    0 R--r-d \WINDOWS\system32\gaopdxtmsnsftaavppfgmkbshkvxtlvnrjypjq.dll

These are typical file names for W32/TDSS or W32.Tidserv.

The plugin displays the following values:

  • Phys.Addr - the physical address of the file object in the memory image
  • Obj Type - object type pointer of the "File" class. The value may change between systems or even reboots, but while Windows is running it should be the same among all objects of the same class.
  • #Ptr - the number of pointers to the File object
  • #Hnd - the number of handles to the File object
  • Access - R/W/D indicates Read, Write and Delete access, r/w/d indicates shared read, shared write and shared delete access
  • Name - name associated with the File object

Thanks to hogfly for making the interesting samples from his collection available to the public! You might also want to read his article on that sample.


This blog is a project of:
Andreas Schuster
Im Äuelchen 45
D-53177 Bonn

Copyright © 2005-2012 by
Andreas Schuster
All rights reserved.