filter driver installations

Hi.

I’m looking for a possibility to properly install my filter driver (wdm/win7).
I’m new in driver developement, so be patient in responding to this thread.

  1. When I’m using osrloader to load my driver - then I assume that system simply loads this driver and creates kernel process that is running in ring0 - correct?

  2. Is it possible (e.g via inf file) to install driver as service in the system - so that if driver that I want to filter will be loaded - then my service will be active/loaded? sorry I don’t catch idea of upper filter and so on - are there any copmlete tutorials somewhere on this?

  3. Could you please describe all possibilities how drivers (filter driver in particular case) can be loaded?

Thank you again for your time and help.
joe

xxxxx@gmail.com wrote:

I’m looking for a possibility to properly install my filter driver (wdm/win7).
I’m new in driver developement, so be patient in responding to this thread.

The word “filter driver” is badly overloaded. It has been used to
describe WDM device filter drivers, WDM class filter drivers, network
filtering drivers, and AVStream filters, among other things. Which one
are you writing?

  1. When I’m using osrloader to load my driver - then I assume that system simply loads this driver and creates kernel process that is running in ring0 - correct?

Partly. There are no kernel processes created. In fact, there’s really
no such thing as a kernel process (pedants may disagree). Drivers ONLY
run in response to requests from user processes, or sometimes from other
drivers. They run on whatever thread created the request.

Osrloader is not necessarily the right tool for loading drivers. We’ll
know more when you tell us more precisely what kind of driver it is.

  1. Is it possible (e.g via inf file) to install driver as service in the system - so that if driver that I want to filter will be loaded - then my service will be active/loaded? sorry I don’t catch idea of upper filter and so on - are there any copmlete tutorials somewhere on this?

If you want to filter a device that has a driver, then all you need to
do is make an entry in the registry. Your driver will then
automatically be loaded when the device starts.

  1. Could you please describe all possibilities how drivers (filter driver in particular case) can be loaded?

Tell us a little more about your circumstances, and we can give you all
the poop.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Tim Thanks a lot for quick response.

Well I’m just doing some execises for myself.
And I’ve got simple wdm driver that is software/virtual only (I mean this is not any hw device that the driver is connected to). This driver has two IOCTLs that can be passed from user space to this driver: IOCTL_GET_MAGIC_NUMBER and IOCTL_SET_MAGIC_NUMBER.

Now I want to know what kind of a path I can have to install my filter driver (its purpose is to drop some communication).

Tim you just said: “If you want to filter a device that has a driver, then all you need to do is make an entry in the registry. Your driver will then automatically be loaded when the device starts” can you please give some more details - some links - tutorials -howtos - how to achieve this?
As I said - This is my first driver do I don’t have any experience in this area - but I want to learn a lot…

Also if you can give me all possibilities in installing fileter drivers for wdm driver that has virtual device. and so on…

Thank you again and a lot!
joe

I forgot to mention that I’ve found ClasFilt.inf sample but it is probably for class filter driver (I still don’t see a big difference - sorry :frowning: )

I’ve also found this http://msdn.microsoft.com/en-us/library/ff547595(v=vs.85).aspx

Guys do you think that above sample from link for filter device driver should work as service that will be activated when device will be started?

Thank you again!

xxxxx@gmail.com wrote:

Well I’m just doing some execises for myself.
And I’ve got simple wdm driver that is software/virtual only (I mean this is not any hw device that the driver is connected to). This driver has two IOCTLs that can be passed from user space to this driver: IOCTL_GET_MAGIC_NUMBER and IOCTL_SET_MAGIC_NUMBER.

OK, but there are two basic types of WDM driver. A legacy driver is
installed like a service, started and stopped using the Service Control
Manager, or “net start” and “net stop”, or the Osrdriverloader. A PnP
driver has an INF file, and is loaded when a device that matches its INF
file appears. For Root\ or SW\ devices, that happens with “devcon
install” or at boot time.

In practical terms, legacy drivers cannot be filtered. The filter
concept applies only to PnP drivers. So, we first have to figure out
what kind of driver you’re trying to filter.

Now I want to know what kind of a path I can have to install my filter driver (its purpose is to drop some communication).

Tim you just said: “If you want to filter a device that has a driver, then all you need to do is make an entry in the registry. Your driver will then automatically be loaded when the device starts” can you please give some more details - some links - tutorials -howtos - how to achieve this?

If the driver you’re driver to filter is PnP, then it has an entry
somewhere in HKLM\System\CurrentControlSet\Enum. To add a filter to
that driver, you add a new registry key called UpperFilters,
REG_MULTI_SZ, and put your filter driver’s service name there. That’s
all you have to do. There are SetupDi APIs to handle this task in an
installer.

Also if you can give me all possibilities in installing fileter drivers for wdm driver that has virtual device. and so on…

There are still too many unanswered questions here.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

>kernel process that is running in ring0 - correct?

No, there is no such thing as “kernel process” in Windows.

  1. Is it possible (e.g via inf file) to install driver as service in the system - so that if driver that I want to filter will be
    loaded - then my service will be active/loaded?

Yes, just write your filter to UpperFilters of Control\Class{guid}


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

Tim, Thank you for response,

Maxim thak you for joining.

Ok. I would like to make everything clear.

  1. Driver I want to filter is WDM driver (no frameworks is used) - that has two defined: IOCTL_GET_MAGIC_NUMBER , IOCTL_SET_MAGIC_NUMBER - both uses method_buffered.
    First returns value from registry, seconf sets value in registry (as I mentioned before - this is only my exercises - so there is not much sense probably).
    2.Driver is installed via OpenSCManager and CreateService from user space application.
  2. Driver is creating device object via IoCreateDevice() called RegDev0
  3. Driver do not handle any PnP codes (only two irps I’ve defined plus mj_create)
  4. My role is to create filter driver to driver I described before so that it will be attaching to RegDev0 and logging every kind of registry get/set operations. Filter should be activated dynamically - I mean by first loading filter driver as service and then when ‘real’ driver is loaded (via user space application) filter should be activated.
  5. Filter driver should be only targeted to RegDev0 driver - so not class od devices.

According to yours suggestions I’ve prepared this kind of inf file, but I still don;t understand how it really works:

;-------------------------------------------------------------------------
; RegDev0.INF – driver filter
;
;-------------------------------------------------------------------------
[version]
Signature = “$Windows NT$”

Provider = %DDDD%
DriverVer = 13/07/2011,6.0.5019.0

[Manufacturer]
%DDDD%=MEWS,NTx86,NTia64,NTamd64

;-------------------------------------------------------------------------
; Installation Section
;-------------------------------------------------------------------------
[Install]
AddReg=Inst_Flt
Characteristics = 0x40000
Copyfiles = regdev0flt.copyfiles.sys

[SourceDisksNames]
1=%REGDEV0FLT_Desc%,“”,

[SourceDisksFiles]
RegDev0Flt.sys=1

[DestinationDirs]
DefaultDestDir=12
RegDev0Flt.copyfiles.sys=12

[regdev0flt.copyfiles.sys]
RegDev0Flt.sys,2

;-------------------------------------------------------------------------
; installation support
;-------------------------------------------------------------------------
[Inst_Flt]
HKR,“UpperFilters”,0x00010000,“regdev0flt” ; REG_MULTI_SZ value

;-------------------------------------------------------------------------
; Service installation support
;-------------------------------------------------------------------------
[Install.Services]
AddService=RegDev0Flt,RegDev0Flt_Service_Inst

[RegDev0Flt_Service_Inst]
DisplayName = %REGDEV0FLT_Desc%
ServiceType = 1 ;SERVICE_KERNEL_DRIVER
StartType = 2 ;SERVICE_DEMAND
ErrorControl = 1 ;SERVICE_ERROR_NORMAL
ServiceBinary = %12%\RegDev0.sys

Description = %REGDEV0FLT_Desc%

[Install.Remove.Services]
DelService=RegDev0Flt,0x200

[Strings]
DDDD = “jojo”
REGDEV0FLT_Desc = “sample filter driver”
REGDEV0FLT_HelpText = “sample filter driver”

-------------------------------------------eof--------------------------------------

First - this is probably not working - I just prepared in text editor to give you where I am now - probably it won’t even be properly parsed.

  1. First of all I don’t catch where is information about which device my filter driver will be filtering?
    I undestand that somewhere here should be string like REgDev0 or somthin’?

  2. I’m not really sure if AddReg is properly constructed - maybe in subkey I should put string in registry to RegDev0 service?

Can you help be?
Thank you for your patience.

xxxxx@gmail.com wrote:

Ok. I would like to make everything clear.

  1. Driver I want to filter is WDM driver (no frameworks is used) - that has two defined: IOCTL_GET_MAGIC_NUMBER , IOCTL_SET_MAGIC_NUMBER - both uses method_buffered.
    First returns value from registry, seconf sets value in registry (as I mentioned before - this is only my exercises - so there is not much sense probably).
    2.Driver is installed via OpenSCManager and CreateService from user space application.

As I suspected. This is a legacy driver, and cannot be filtered. The
filter concept only applies to PnP drivers.

  1. My role is to create filter driver to driver I described before so that it will be attaching to RegDev0 and logging every kind of registry get/set operations. Filter should be activated dynamically - I mean by first loading filter driver as service and then when ‘real’ driver is loaded (via user space application) filter should be activated.

That cannot be done, at least not through any documented means. You
have to get a pointer to the driver to be filtered using
IoGetDeviceObjectPointer, and then attach yourself to it. You can only
do that after the other driver has loaded.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Tim,

IIRC IoAttachDeviceToDeviceStack works on legacy (non-PnP) drivers.
Filtering of legacy drivers worked on NT 4 even.

Thomas F. Divine


From: “Tim Roberts”
Sent: Friday, August 26, 2011 3:21 PM
To: “Windows System Software Devs Interest List”
Subject: Re: [ntdev] filter driver installations

> xxxxx@gmail.com wrote:
>> Ok. I would like to make everything clear.
>> 1. Driver I want to filter is WDM driver (no frameworks is used) - that
>> has two defined: IOCTL_GET_MAGIC_NUMBER , IOCTL_SET_MAGIC_NUMBER - both
>> uses method_buffered.
>> First returns value from registry, seconf sets value in registry (as I
>> mentioned before - this is only my exercises - so there is not much sense
>> probably).
>> 2.Driver is installed via OpenSCManager and CreateService from user space
>> application.
>
> As I suspected. This is a legacy driver, and cannot be filtered. The
> filter concept only applies to PnP drivers.
>
>> 5. My role is to create filter driver to driver I described before so
>> that it will be attaching to RegDev0 and logging every kind of registry
>> get/set operations. Filter should be activated dynamically - I mean by
>> first loading filter driver as service and then when ‘real’ driver is
>> loaded (via user space application) filter should be activated.
>
> That cannot be done, at least not through any documented means. You
> have to get a pointer to the driver to be filtered using
> IoGetDeviceObjectPointer, and then attach yourself to it. You can only
> do that after the other driver has loaded.
>
> –
> Tim Roberts, xxxxx@probo.com
> Providenza & Boekelheide, Inc.
>
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer

Tim & Thomas,

Thank you again for valuable input in this discussion.
From your last responses I understand that it is still possible to filter driver even if it is legacy driver loaded via SCManager.

The problem I’ve got still unresolved is with my inf file.
Can you please look on this and tell me how should this file be prepared so that it would activated during device object RegDev0 start?
Also my previous two questions are left without answer :
"1. First of all I don’t catch where is information about which device my filter driver will be filtering? I undestand that somewhere here should be string like REgDev0 or somthin’?
2. I’m not really sure if AddReg is properly constructed - maybe in subkey I should put string in registry to RegDev0 service?
"

Thank you so much.
joe joe

I’ve found this, but in this example I still don’t see answers to my questons.

It’s actually IoAttachDevice (not IoAttachDeviceToDeviceStack) that’s been around since the beginning of the world, and that’s used to attach legacy (NTV4 style) devices.

You’re writing a LEGACY (NT V4-style) filter, to filter that legacy target driver, right? No INF required. Just, ah, install it with the service control manager. You can make it “Depend On Service” the legacy driver you want to filter (that is make a Depend on Service registry entry for your driver, and name the driver you want to filter). Create your device object, then do IoGetDeviceObjectPointer and IoAttachDevice… simple.

Peter
OSR

xxxxx@osr.com wrote:

You’re writing a LEGACY (NT V4-style) filter, to filter that legacy target driver, right? No INF required. Just, ah, install it with the service control manager. You can make it “Depend On Service” the legacy driver you want to filter (that is make a Depend on Service registry entry for your driver, and name the driver you want to filter). Create your device object, then do IoGetDeviceObjectPointer and IoAttachDevice… simple.

Does that work? I thought the “depend on service” thing just caused a
driver to fail if the dependency was not satisfied. Are you saying
that, when a driver loads, service manager will go enumerate the other
service keys and load the drivers that depend on it?


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Peter Thank you for joining and for your response.
Tim, Peter

I’ve just checked solution proposed by Peter in following way:

BOOL InstallService(LPCTSTR ServiceName,
LPCTSTR ServiceExec)
{
SC_HANDLE ServiceControlManagerHandle; // Handle to service control manager.
SC_HANDLE ServiceHandle; // Handle to service.

// [1] Create depedencies list.
LPCTSTR ServiceDependencies = __TEXT(“modulexxx\0”);

// [2] Open connection to service control manager.
ServiceControlManagerHandle = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (NULL == ServiceControlManagerHandle)
{
printf(“Could not open connection to service control manager. ErrorCode=%X\n”, GetLastError());
getchar();
return FALSE;
}

// [3] Create service
ServiceHandle = CreateService( ServiceControlManagerHandle, // Handle to service control manager.
ServiceName, // Name of service
ServiceName, // Service name to display
SERVICE_ALL_ACCESS, // Desired access
SERVICE_KERNEL_DRIVER, // Service type
SERVICE_DEMAND_START, // Start type
SERVICE_ERROR_NORMAL, // Error control type
ServiceExec, // Path to service’s binary
NULL, // No load ordering group
NULL, // No tag identifier
ServiceDependencies, // No dependencies
NULL, // LocalSystem account
NULL); // No password
if (NULL == ServiceHandle)
{
printf(“Could not create service. ErrorCode=%d %X\n”, GetLastError(), GetLastError());
getchar();
return FALSE;
}

if (FALSE == StartService(ServiceHandle, // service identifier
0, // number of arguments
NULL // pointer to arguments
))
{
printf(“Could not create service. ErrorCode=%d %X\n”, GetLastError(), GetLastError());
getchar();
return FALSE;

}

// [4] Reached promised land.
printf(“Service is up!\n”);
getchar();

// [5] Destruction part.
CloseServiceHandle(ServiceControlManagerHandle);
CloseServiceHandle(ServiceHandle);

return TRUE;
}

(please ignore fact, that this code is dirty and doesn;t free resources).
Result is - that service fails to start when depedency is not loaded - so I belive that Tim is right - OR maybe you thought about something different?

Tim - how about my inf file - can you correct me - tell me what is wrong and answer to my previous 2 questions?

Thank you again for all responses.

xxxxx@gmail.com wrote:

Result is - that service fails to start when depedency is not loaded - so I belive that Tim is right - OR maybe you thought about something different?

Tim - how about my inf file - can you correct me - tell me what is wrong and answer to my previous 2 questions?

INF files are not used with legacy drivers. The code you have posted
above serves the same purpose that an INF serves for PnP drivers.

Look, the problem you face is significant. Your driver needs to attach
to the other driver between the time the application loads it, and the
time the application starts issuing requests. That time might be very,
very short. If the application doesn’t do a CreateService call every
time, then you could modify the Services key of the other driver in the
registry to have it load your driver binary instead of the original.
But if the application calls CreateService, that will rewrite the key.

You may be left with the ugly alternative of “hooking” the application,
so you can intercept its calls to CreateFile to know when it’s time to
get your driver involved. That won’t be fun.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Tim, thank you again for your input - it is not good news (I knew that I can hook api call (even NtDeviceIoControlFile), but I was looking for any elegant and pretty solution) for me.

  1. Assuming that legacy driver that I want to filter out is top level driver what do You think about using ObRegisterCallbacks() for tracking opening handles and then catch somehow moment of creating handle to device - sorry maybe above sentence has no sense at all - I have never used this api and still do not know if it is working as I think it is. So how about that?

  2. I was also wondering if PsSetLoadImageNotifyRoutine could be good choice - but probably it won’t since this api is called BEFORE driver will be loaded - right?

Thank you!
joe joe

xxxxx@gmail.com wrote:

  1. Assuming that legacy driver that I want to filter out is top level driver what do You think about using ObRegisterCallbacks() for tracking opening handles and then catch somehow moment of creating handle to device - sorry maybe above sentence has no sense at all - I have never used this api and still do not know if it is working as I think it is. So how about that?

ObRegisterCallbacks would tell you when a new process or thread is being
created. How would you expect to use that to solve your problem?

  1. I was also wondering if PsSetLoadImageNotifyRoutine could be good choice - but probably it won’t since this api is called BEFORE driver will be loaded - right?

After it is loaded, but before it has been initialized, and possibly
before it has been patched for relocations. Conceivably, you could
patch the driver’s DriverEntry to call your driver when it was finished,
but that’s relatively advanced hacking.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Tim - thank you again.

I was rather thinking about something like this

OB_CALLBACK_REGISTRATION obReg;
OB_OPERATION_REGISTRATION opReg;
//…
obReg.OperationRegistrationCount = 1;
obReg.RegistrationContext = NULL;
RtlInitUnicodeString(&obReg.Altitude, L"321000");
obReg.OperationRegistration = &opReg;
//…
opReg.ObjectType = IoFileObjectType;
opReg.Operations = OB_OPERATION_HANDLE_CREATE;
opReg.PreOperation = (POB_PRE_OPERATION_CALLBACK)&preCall;
//…
status = ObRegisterCallbacks(&obReg, &__Handle);

then callback could look like this (pseudo-code):
OB_PREOP_CALLBACK_STATUS
preObCall(PVOID RegistrationContext, POB_PRE_OPERATION_INFORMATION OperationInformation)
{
PFILE_OBJECT fileobject = OperationInformation->Object;

UNREFERENCED_PARAMETER(RegistrationContext);

if (fileobject is same as we’re interseted in )
{
try to attach
}

return OB_PREOP_SUCCESS;
}

so it would work as handle tracker - then when handle to specified sys file is opened - try to atatch - still don’t know if it is no too early - but please could you take a look on this and try to figure out if it is possible to solve it that way?

Thank you!
joe joe

xxxxx@gmail.com wrote:

I was rather thinking about something like this

opReg.ObjectType = IoFileObjectType;
opReg.Operations = OB_OPERATION_HANDLE_CREATE;
opReg.PreOperation = (POB_PRE_OPERATION_CALLBACK)&preCall;

Where did you find that code? The ObRegisterCallbacks documentation
specifically says the only valid options for ObjectType are
PsProcessType and PsThreadType.

then callback could look like this (pseudo-code):
OB_PREOP_CALLBACK_STATUS
preObCall(PVOID RegistrationContext, POB_PRE_OPERATION_INFORMATION OperationInformation)
{
PFILE_OBJECT fileobject = OperationInformation->Object;
UNREFERENCED_PARAMETER(RegistrationContext);
if (fileobject is same as we’re interseted in )

Assuming the callback worked, how would you make that assessment?


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

> Does that work? I thought the “depend on service” thing just caused a

driver to fail if the dependency was not satisfied. Are you saying
that, when a driver loads, service manager will go enumerate the other
service keys and load the drivers that depend on it?

No.

For user-mode services and non-PnP drivers, this sets the start ordering of the services.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com