The new bits of the WDK have been released, and it seems that finally, we are starting to see a glimpse of some of the new filtering technologies that were promised in Vista SP1 to help with incompatibilities due to PatchGuard. Although Vista added powerful Registry filtering support on top of the existing File filtering architecture, hooking some native calls would still have been necessary in order to filter other kinds of system behaviour. The first which seems to have been addressed are handles, and Vista SP1 now supports Object Manager Filters.

Currently, only create and duplicate can be filtered, but the ability for both pre and post notifications exist. As with the new filter model, Object Manager Filters also support Altitudes, and are fully versionned. Unfortunately, this new set of APIs seems rather disappointing to me. For starters, this functionality was already available, even behind Patchguard’s back, through native Object Manager callbacks present in the OBJECT_TYPE’s ObjectTypeInitializer structure which contains all the callbacks for the object type. This interface seems to do nothing more but expose in a more public and accessible way the same ObCreateMethod interface that has existed since NT4, except that it only works for create and duplicate (while the internal interface allows for open and inherit as well).

Nevertheless, this new filtering mechanism is clearly written to be extensible for other Object Manager actions, so hopefully we’ll see some new improvements before SP1 actually ships. For the curious, here are some of the new toys to play with:

//
// Registration version for Vista SP1 and Windows Server 2007
//
#define OB_FLT_REGISTRATION_VERSION_0100* 0×0100

//
// This value should be used by filters for registration
//
#define OB_FLT_REGISTRATION_VERSION OB_FLT_REGISTRATION_VERSION_0100

typedef ULONG OB_OPERATION;

#define OB_OPERATION_HANDLE_CREATE************* 0×00000001
#define OB_OPERATION_HANDLE_DUPLICATE********** 0×00000002

typedef struct _OB_PRE_CREATE_HANDLE_INFORMATION {
*** __inout ACCESS_MASK******** DesiredAccess;
*** __in ACCESS_MASK*********** OriginalDesiredAccess;
} OB_PRE_CREATE_HANDLE_INFORMATION, *POB_PRE_CREATE_HANDLE_INFORMATION;

typedef struct _OB_PRE_DUPLICATE_HANDLE_INFORMATION {
*** __inout ACCESS_MASK******** DesiredAccess;
*** __in ACCESS_MASK*********** OriginalDesiredAccess;
*** __in PVOID***************** SourceProcess;
*** __in PVOID***************** TargetProcess;
} OB_PRE_DUPLICATE_HANDLE_INFORMATION, * POB_PRE_DUPLICATE_HANDLE_INFORMATION;

typedef union _OB_PRE_OPERATION_PARAMETERS {
*** __inout OB_PRE_CREATE_HANDLE_INFORMATION******* CreateHandleInformation;
*** __inout OB_PRE_DUPLICATE_HANDLE_INFORMATION**** DuplicateHandleInformation;
} OB_PRE_OPERATION_PARAMETERS, *POB_PRE_OPERATION_PARAMETERS;

typedef struct _OB_PRE_OPERATION_INFORMATION {
*** __in OB_OPERATION********** Operation;
*** union {
******* __in ULONG Flags;
******* struct {
*********** __in ULONG KernelHandle:1;
*********** __in ULONG Reserved:31;
******* };
*** };
*** __in PVOID************************ Object;
*** __in POBJECT_TYPE***************** ObjectType;
*** __out PVOID*********************** CallContext;
*** __in POB_PRE_OPERATION_PARAMETERS* Parameters;
} OB_PRE_OPERATION_INFORMATION, *POB_PRE_OPERATION_INFORMATION;

typedef struct _OB_POST_CREATE_HANDLE_INFORMATION {
*** __in ACCESS_MASK*********** GrantedAccess;
} OB_POST_CREATE_HANDLE_INFORMATION, *POB_POST_CREATE_HANDLE_INFORMATION;

typedef struct _OB_POST_DUPLICATE_HANDLE_INFORMATION {
*** __in ACCESS_MASK*********** GrantedAccess;
} OB_POST_DUPLICATE_HANDLE_INFORMATION, * POB_POST_DUPLICATE_HANDLE_INFORMATION;

typedef union _OB_POST_OPERATION_PARAMETERS {
*** __in OB_POST_CREATE_HANDLE_INFORMATION****** CreateHandleInformation;
*** __in OB_POST_DUPLICATE_HANDLE_INFORMATION*** DuplicateHandleInformation;
} OB_POST_OPERATION_PARAMETERS, *POB_POST_OPERATION_PARAMETERS;

typedef struct _OB_POST_OPERATION_INFORMATION {
*** __in OB_OPERATION* Operation;
*** union {
******* __in ULONG Flags;
******* struct {
*********** __in ULONG KernelHandle:1;
*********** __in ULONG Reserved:31;
******* };
*** };
*** __in PVOID************************* Object;
*** __in POBJECT_TYPE****************** ObjectType;
*** __in PVOID************************* CallContext;
*** __in NTSTATUS********************** ReturnStatus;
*** __in POB_POST_OPERATION_PARAMETERS* Parameters;
} OB_POST_OPERATION_INFORMATION,*POB_POST_OPERATION_INFORMATION;

typedef enum _OB_PREOP_CALLBACK_STATUS {
*** OB_PREOP_SUCCESS
} OB_PREOP_CALLBACK_STATUS, *POB_PREOP_CALLBACK_STATUS;

typedef OB_PREOP_CALLBACK_STATUS
(*POB_PRE_OPERATION_CALLBACK) (
*** __in PVOID RegistrationContext,
*** __inout POB_PRE_OPERATION_INFORMATION OperationInformation
*** );

typedef VOID
(*POB_POST_OPERATION_CALLBACK) (
*** __in PVOID RegistrationContext,
*** __in POB_POST_OPERATION_INFORMATION OperationInformation
*** );

typedef struct _OB_OPERATION_REGISTRATION {
*** __in POBJECT_TYPE*************** *ObjectType;
*** __in OB_OPERATION*************** Operations;
*** __in POB_PRE_OPERATION_CALLBACK* PreOperation;
*** __in POB_POST_OPERATION_CALLBACK PostOperation;
} OB_OPERATION_REGISTRATION, *POB_OPERATION_REGISTRATION;

typedef struct _OB_CALLBACK_REGISTRATION {
*** __in USHORT******************** Version;
*** __in USHORT******************** OperationRegistrationCount;
*** __in UNICODE_STRING************ Altitude;
*** __in PVOID********************* RegistrationContext;
*** __in OB_OPERATION_REGISTRATION* *OperationRegistration;
} OB_CALLBACK_REGISTRATION, *POB_CALLBACK_REGISTRATION;

#if (NTDDI_VERSION >= NTDDI_VISTASP1)
NTKERNELAPI
NTSTATUS
ObRegisterCallbacks (
*** __in POB_CALLBACK_REGISTRATION CallbackRegistration,
*** __deref_out PVOID *RegistrationHandle
*** );

NTKERNELAPI
VOID
ObUnRegisterCallbacks (
*** __in PVOID RegistrationHandle
*** );

NTKERNELAPI
USHORT
ObGetFilterVersion ();
#endif



http://www.alex-ionescu.com/?p=38