Introduction
The EaseFilter Registry Filter Driver SDK is a kernel-mode driver development kit designed to intercept, monitor, and control Windows Registry access in real time. Running as part of the Windows Executive above the Configuration Manager, it provides developers with a robust API to protect system configurations, audit registry activities, and create virtualized registry views without the need to write custom kernel drivers from scratch.
Architectural Overview
The SDK operates by registering a RegistryCallback routine with the Windows Configuration Manager. This allows the filter driver to intercept registry I/O requests before they reach their intended target.
- Pre-Notification: The driver receives a callback before the Configuration Manager processes the operation. Developers can inspect input buffers, modify parameters, or block the operation entirely (e.g., by returning
STATUS_ACCESS_DENIED). - Post-Notification: The driver receives a callback after the operation has completed, allowing for auditing and logging of the actual changes made to the registry.
SDK Component Architecture
The EaseFilter SDK is structured into two primary components that must be correctly deployed to ensure the driver functions across different Windows architectures (32-bit and 64-bit):
EaseFlt.sys: The kernel-mode filter driver. It sits above the registry component within the Windows executive, allowing it to intercept I/O requests at the lowest possible level before they are processed by the Configuration Manager.FilterAPI.dll: The user-mode wrapper DLL. It acts as the bridge between your application and the kernel driver. It exports the necessary APIs to define filter rules, register callbacks, and manage communication between the kernel-mode driver and your managed or native code application.
Deployment Requirement: BothEaseFlt.sysandFilterAPI.dllmust be present and correctly matched to the target platform (32-bit or 64-bit). Place these files in the same directory as your application executable.
Core Capabilities
| Capability | Description |
|---|---|
| Real-time Monitoring | Track all registry activities (creates, reads, writes, deletes, security modifications) in real time. Log the process ID, user name, and exact data payload. |
| Registry Protection | Implement dynamic access control policies. Block unauthorized processes or specific users from modifying critical system or application registry keys on the fly. |
| Registry Virtualization | Modify output parameters during pre-notification to return custom data. This allows applications to simulate registry keys and values that do not physically exist in the system registry. |
| Granular Filtering | Define precise filter rules based on process names, process IDs, user names, and registry key paths using wildcard masks. |
Supported Registry Operations & Notification Classes
The EaseFilter Registry Filter Driver operates by subscribing to specific notification classes via the Windows Configuration Manager.
Pre-Notification Classes for Blocking
To actively prevent unauthorized registry modifications, register for "Pre-Operation" notifications. If your callback returns STATUS_ACCESS_DENIED during these events, the Configuration Manager blocks the operation.
Reg_Pre_Create_Key/Reg_Pre_Create_KeyEx: Intercepts attempts to create new keys.Reg_Pre_Delete_Key: Intercepts requests to remove an existing key.Reg_Pre_Set_Value_Key: Intercepts attempts to create or modify data within a value.Reg_Pre_Delete_Value_Key: Intercepts attempts to delete a specific value.Reg_Pre_SetInformation_Key: Intercepts attempts to change metadata or security information.Reg_Pre_Rename_Key: Intercepts attempts to rename an existing key.Reg_Pre_Restore_Key: Intercepts attempts to restore a registry hive from a file.Reg_Pre_Replace_Key: Intercepts attempts to replace a key and its subkeys with a hive file.
Callback Data Structures
When a callback is triggered, the SDK provides a notification-specific structure containing:
- The Registry Handle/Path: Identifying the key being targeted.
- The Operation Type: Identifying which
REG_NOTIFY_CLASSis currently being executed. - Input/Output Buffers: Allowing you to inspect or modify the data being written to (or read from) the registry.
Registry Access Control Flags (RegControlFlag)
The RegControlFlag enumeration provides a bitmask mechanism to enforce strict access control policies on registry filter rules. Because the SDK utilizes a default-deny approach when access control is enforced, omitting a flag means the corresponding operation will be blocked.
Flag Categories
Key Lifecycle and Navigation
| Flag | Value | Description |
|---|---|---|
REG_ALLOW_OPEN_KEY |
0x00000001 |
Allows applications to open existing keys. |
REG_ALLOW_CREATE_KEY |
0x00000002 |
Allows creation of new keys. |
REG_ALLOW_QUERY_KEY |
0x00000004 |
Allows querying key metadata. |
REG_ALLOW_RENAME_KEY |
0x00000008 |
Allows renaming existing keys. |
REG_ALLOW_DELETE_KEY |
0x00000010 |
Allows deletion of keys. |
REG_ALLOW_ENUMERATE_KEY |
0x00000080 |
Allows listing subkeys within a parent key. |
REG_ALLOW_KEY_CLOSE |
0x00100000 |
Allows handles to keys to be closed cleanly. |
REG_ALLOW_QUERY_KEYNAME |
0x00200000 |
Allows querying the object manager name of the key. |
Value Modification and Reading
| Flag | Value | Description |
|---|---|---|
REG_ALLOW_SET_VALUE_KEY_INFORMATION |
0x00000020 |
Allows modifying or creating data within a value. |
REG_ALLOW_QUERY_VALUE_KEY |
0x00000100 |
Allows reading the data of a specific value. |
REG_ALLOW_ENUMERATE_VALUE_KEY |
0x00000200 |
Allows listing all values contained in a key. |
REG_ALLOW_QUERY_MULTIPLE_VALUE_KEY |
0x00000400 |
Allows reading multiple values in a single call. |
REG_ALLOW_DELETE_VALUE_KEY |
0x00000800 |
Allows deletion of specific values. |
Security and Metadata
| Flag | Value | Description |
|---|---|---|
REG_ALLOW_SET_INFORMATION_KEY |
0x00000040 |
Allows modifying key metadata. |
REG_ALLOW_QUERY_KEY_SECURITY |
0x00001000 |
Allows reading the security descriptor. |
REG_ALLOW_SET_KEY_SECURITY |
0x00002000 |
Allows modifying the security descriptor. |
System and Hive Level Operations
| Flag | Value | Description |
|---|---|---|
REG_ALLOW_RESTORE_KEY |
0x00004000 |
Allows restoring data from a hive file. |
REG_ALLOW_REPLACE_KEY |
0x00008000 |
Allows replacing a key and its subkeys from a file. |
REG_ALLOW_SAVE_KEY |
0x00010000 |
Allows saving a key and its subkeys to a hive file. |
REG_ALLOW_FLUSH_KEY |
0x00020000 |
Allows forcing cached data to be written to disk. |
REG_ALLOW_LOAD_KEY |
0x00040000 |
Allows loading a hive file into the active registry. |
REG_ALLOW_UNLOAD_KEY |
0x00080000 |
Allows unloading a loaded hive from the active registry. |
The Auditing Flag
ENABLE_FILTER_SEND_DENIED_REG_EVENT = 0x80000000
When a process attempts an operation missing from the allowed RegControlFlag list, the kernel driver blocks it. If this flag is enabled, the driver dispatches an event to the user-mode application notifying it of the blocked attempt. This is critical for Intrusion Detection Systems (IDS) and auditing tools.
Implementation Guide
Integrating the SDK involves initializing the driver, defining filter rules, and handling callbacks.
Defining Filter Rules
A rule tells the driver which registry paths to intercept and what access controls to apply.
- Registry Key Mask: Target paths using wildcards (e.g.,
\REGISTRY\MACHINE\SOFTWARE\YourCompany\*). - Process Filter Mask: Specify processes to monitor or block (e.g.,
*for all, orcmd.exe). - Exclusion Masks: Exclude trusted processes or users (e.g.,
NT AUTHORITY\SYSTEM). - Control Flags: Assign the combined
RegControlFlagbitmask.
Handling Callbacks
- Monitor Callbacks: Log the registry key, value, data, and context asynchronously.
- Control Callbacks: Fire synchronously. Your application processes the event and returns an authorization status.
Common Use Cases & Code Examples
The following scenarios demonstrate how to combine filter rules, access control flags, and callbacks to achieve specific security and monitoring objectives.
Use Case: Protecting Critical System Keys (Anti-Malware)
Scenario: You want to protect the Windows startup keys (e.g., the Run key) from being modified by unauthorized software or ransomware, while still allowing the system to read them to boot correctly. Trusted installers (like msiexec.exe) are excluded from this rule.
// Initialize the Filter Control
FilterControl filterControl = new FilterControl();
filterControl.StartFilter(
filterType, serviceThreads, connectionTimeOut, licenseKey, ref lastError);
// Create a rule targeting the Windows Run key
RegistryFilterRule protectionRule = new RegistryFilterRule();
protectionRule.RegistryKeyNameFilterMask = @"\REGISTRY\MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run\*";
protectionRule.ProcessNameFilterMask = "*";
// Exclude trusted processes so they can still modify the key
protectionRule.ExcludeProcessNameFilterMask = "explorer.exe;msiexec.exe;trustedinstaller.exe";
// Define a read-only policy. Writing, creating, and deleting are omitted and thus blocked.
uint protectFlags = (uint)(
RegControlFlag.REG_ALLOW_OPEN_KEY |
RegControlFlag.REG_ALLOW_QUERY_KEY |
RegControlFlag.REG_ALLOW_ENUMERATE_KEY |
RegControlFlag.REG_ALLOW_QUERY_VALUE_KEY |
RegControlFlag.REG_ALLOW_ENUMERATE_VALUE_KEY |
RegControlFlag.REG_ALLOW_KEY_CLOSE |
RegControlFlag.ENABLE_FILTER_SEND_DENIED_REG_EVENT // Notify us of blocked attempts
);
protectionRule.ControlFlag = protectFlags;
filterControl.AddRegistryFilterRule(protectionRule);
// Log when malware attempts to write to the startup key
filterControl.OnDeniedRegistryAccess += (sender, args) =>
{
Console.WriteLine($"[ALERT] Blocked process {args.ProcessName} from modifying startup key: {args.KeyName}");
};
Use Case: Silent Auditing of Registry Modifications
Scenario: You need to monitor when a specific application's settings are altered for compliance or debugging purposes. You do not want to block any actions; you only want to log successful modifications after they happen.
FilterControl filterControl = new FilterControl();
filterControl.StartFilter(
filterType, serviceThreads, connectionTimeOut, licenseKey, ref lastError);
RegistryFilterRule auditRule = new RegistryFilterRule();
auditRule.RegistryKeyNameFilterMask = @"\REGISTRY\MACHINE\SOFTWARE\MyTargetApp\*";
auditRule.ProcessNameFilterMask = "*";
// Do not set ControlFlag. Leaving it default (0) with no blocking logic means
// the driver will simply pass operations through.
filterControl.AddRegistryFilterRule(auditRule);
// Subscribe to the POST notification to ensure we only log successful changes
filterControl.OnPostRegistryKeySetValue += OnPostRegistryKeySetValue_AuditCallback;
void OnPostRegistryKeySetValue_AuditCallback(object sender, RegistryEventArgs args)
{
// Ensure the registry write actually succeeded at the OS level
if (args.IsSuccess)
{
Console.WriteLine($"[AUDIT] Process {args.ProcessName} modified value in {args.KeyName}.");
// Note: For production, dispatch this to a background thread to avoid bottlenecking the OS
}
}
Use Case: Dynamic Access Control (Conditional Blocking)
Scenario: You want to restrict access to sensitive application configuration keys based on dynamic factors, such as the time of day, rather than a static read-only rule.
FilterControl filterControl = new FilterControl();
filterControl.StartFilter(
filterType, serviceThreads, connectionTimeOut, licenseKey, ref lastError);
RegistryFilterRule dynamicRule = new RegistryFilterRule();
dynamicRule.RegistryKeyNameFilterMask = @"\REGISTRY\MACHINE\SOFTWARE\RestrictedApp\*";
dynamicRule.ProcessNameFilterMask = "*";
filterControl.AddRegistryFilterRule(dynamicRule);
// Subscribe to PRE notification so we can intervene before the OS processes the request
filterControl.OnPreRegistryKeySetValue += OnPreRegistryKeySetValue_ConditionalCallback;
void OnPreRegistryKeySetValue_ConditionalCallback(object sender, RegistryEventArgs args)
{
// Check dynamic conditions (e.g., only allow modifications during business hours)
if (DateTime.Now.Hour < 9 || DateTime.Now.Hour > 17)
{
Console.WriteLine($"[BLOCK] Modification attempt outside business hours by {args.ProcessName}");
// Setting IsBlocked to true instructs the kernel driver to return STATUS_ACCESS_DENIED
args.IsBlocked = true;
}
}
Best Practices & Considerations
- Performance Overhead: Registry operations occur thousands of times per second. Broad rules without proper exclusions can severely impact system performance.
- Critical Exclusions: Always exclude critical system processes (e.g.,
smss.exe,csrss.exe,lsass.exe) and theSYSTEMaccount unless absolutely necessary, to prevent system deadlocks. - Asynchronous Logging: For monitoring tasks, dispatch your logging or database-writing logic to a separate thread pool. Blocking the kernel's registry thread inside your callback function freezes the application making the registry call.
- Virtualization Complexity: When implementing registry virtualization, thoroughly test customized output data structures. Malformed data returned to the OS can crash calling applications.