Jaa


Tips for Writing a File System Filter

There have been a few questions posted to the newsgroup over the past few months on the scope the initial setup, and the registry settings of file system filters. I hope to answer some of the most commonly asked questions here.

File system filter scope:

With Windows CE version 4.0 any file system can be filtered with the exception of the ROM\RAM file system. Because version 4.0 allows the boot device to be something other than ROM\RAM when using the hive-based registry, OEMs can put the registry hive on a boot device and filter it. OEMs can filter the boot device but others may not be able to because the image used to boot must include the registry settings pertaining to the filter early in the boot phase, which requires changing the ROM image.

With other media besides the boot device, the filter registry keys can be added to the registry then the media dismounted and remounted, which loads the filter. If you dismount and remount the boot device, the registry hive will become "invalid" leading to crashes, strange behavior, etc. Needless to say, dismounting the boot device is not recommended.

Initial setup

:

The initial setup of the filter can be taken from the filter example FSDSPY which is under

%_WINCEROOT%\public\common\oak\drivers\fsd\fsdspy\

The filter is initialized during HookVolume, which will need to set up some type of volume object that will store the FilterHook. Make sure to actually memcpy() the FilterHook. Simply using a pointer to the FilterHook can lead to problems if there are filters loaded above yours because the API set that the FSDMGR is pointing to can change.

The .def file needs to include every file system function that you plan to implement or pass through to the underlying file system. If you are stubbing a function entirely, then it can be left out of the .def file.

The FILTERHOOK file system functions are declared as .pReadFile, pFlushFileBuffers, etc. (listed in full here https://msdn.microsoft.com/library/default.asp?url=/library/en-us/wceobjst/html/cerefFILTERHOOK.asp ) Below the FilterHook declaration are pointers to the various MyFSD functions that describe the function parameters.

Registry Keys:

The most important registry key is that which gets your filter loaded. There are three places that the FSDMGR will look for the dll for non-autoload file systems when media is loaded. If we are using MSFlash, using FATFS, the filter is named MyFilter, and the filter's dll is named myfilterdll.dll, then the three places are:

This key will add the filter to every volume:
  [HKEY_LOCAL_MACHINE\System\StorageManager\Filters\MyFilter]
This key will add the filter to every volume that has the profile MSFLASH:
  [HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\MSFlash\Filters\MyFilter]
This key will add the filter to every volume that has the profile MSFLASH and uses FATFS:
  [HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\MSFlash\FATFS\Filters\MyFilter]

There are similar places for autoload file system filters to be loaded, such as RELFSD:
  [HKEY_LOCAL_MACHINE\System\StorageManager\AutoLoad\Relfsd\Filters\MyFilter]

The value and its value are: "Dll"="myfilterdll.dll" An additional value "Order" can be used, with the values from 0 to (DWORD)-1. The lower the filter's order, the higher it is on the file system stack (the farther it is from the FSD, and the closer to it is to the user). In other words, the filter with the highest order number is loaded first, with the next highest being loaded on top of it.  If there is only one filter, this does not matter, but if you're layering filters, this is quite important. If the order is left unspecified then the ordering of the filters is also unspecified.

If you are able to make your own images, and you want to put the filter on the boot device, wrap the registry key containing your "Dll" value in a hive boot section:

  ; HIVE BOOT SECTION
  [HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\MSFlash\FATFS\Filters\MyFilter]
       "Dll"="myfilterdll.dll"
       "Order"=dword:2
  ; END HIVE BOOT SECTION

In Windows CE version 4.0 and up, there are functions available to filters that can be called to easily open registry keys. The functions are those that are prefixed with FSDMGR_GetRegistry*. The full list is located here:

https://msdn.microsoft.com/library/default.asp?url=/library/en-us/wcedata5/html/wce50grffsdfunctions.asp

The HDSK used as the first parameter for the GetRegistry functions is the HDSK passed to the FilterHook during HookVolume.  The registry key these functions look at is:

[HKEY_LOCAL_MACHINE\System\StorageManager\Filters\MyFilter]
   "MyValue"=dword:4

Other registry keys can be used or created, but they need to be opened, read, and closed as usual

-- Please note, when the filter is installed on the boot device, reading or writing to the registry anytime outside of the HookVolume call is not a good idea, regardless of whether the filter or a function the filter calls does the registry operation. Registry access in this situation can and will lead to deadlocks within the file system.--

Ariane

Comments

  • Anonymous
    December 02, 2005
    You mentioned that any file system can be filtered with the exception of the ROMRAM file system in CE 4.0. Has this functionality changed in 5.0, i.e. is there any way to filter the ROMRAM file system?
  • Anonymous
    December 02, 2005
    Filtering the ROMRAM file system has been a question/request from many people; unfortunately, there is no way to do it at this point.
  • Anonymous
    December 06, 2005
    Well, you can do api hooking to hook CreateFile etc to achieve the same result for RAMROM filtering. Definitely, using file system filtering driver is a much clean way. Currently, AV companies are forced to do it by using API hooking
  • Anonymous
    December 08, 2005
    One way to filter RAM is to mount a ramdisk which can be filtered.
  • Anonymous
    December 10, 2005
    eamonn is right, you can filter RAMDISK, but ONLY the RAM disk mounted, nothing else. I really hope microsoft considers change this to allow RAM/ROM filtering. API hooking is not documented, already created a mess.

    Nice article!

    One question here: is there any way to set FILE_ATTRIBUTE_ENCRYPTED?
  • Anonymous
    December 12, 2005
    FILE_ATTRIBUTE_ENCRYPTED exists, but it conflicts with FILE_ATTRIBUTE_INROM. Fortunately, or unfortunately (depending on your project) the INROM attribute is respected by the file system and shell, so if you attempt to use ENCRYPTED, your files are suddenly read only.


    I have seen people locally declare this attribute to something different and intercept it in a filter (cough). The problem with local declaration is that the underlying file system will often mask off any "extra" bits, so the attribute has to be put on before the file information is returned and possibly taken away before the file data is returned.


    After changing the ENCRYPTED bit for the file while it is in memory, when the file is re-opened there can be different encryption-detection problems, which leads to more fun with multi-threading/multi-user scenarios. Have fun!

    Ariane
  • Anonymous
    June 17, 2009
    PingBack from http://pooltoysite.info/story.php?id=3493
  • Anonymous
    June 18, 2009
    PingBack from http://thestoragebench.info/story.php?id=10102