


Modern Endpoint Detection and Response (EDR) solutions comprise kernel-mode and user-mode components. These components work together to monitor processes, detect suspicious behavior and block attacks. However, a few years ago, attackers discovered a technique to bypass certain EDR functions. The trick is to offload their malware to a child process launched with a special mitigation policy: MicrosoftSignedOnly.
It ensures that a process can only load libraries (DLLs) that are signed by Microsoft.
Many EDRs inject their own DLLs into processes in order to intercept API calls, a process known as 'hooking'. However, when MicrosoftSignedOnly is enabled, these EDR DLLs cannot be loaded into the process unless they are signed by Microsoft. This means that the EDR cannot redirect or analyze API calls.
Hooking is a technique used by security software to redirect certain operating system functions for monitoring purposes.
Example:
A process wants to open a file: this is a normal function call in the system. An EDR then places a 'hook' on this function, meaning the request is intercepted and checked before execution. Many of these hooks are located in user mode, which is precisely where the mitigation policy takes effect and blocks the EDR DLL. However, EDRs that place their hooks in kernel mode remain largely unaffected by this workaround.
BOOL SetProcessMitigationPolicy(
[in] PROCESS_MITIGATION_POLICY MitigationPolicy,
[in] PVOID lpBuffer,
[in] SIZE_T dwLength
);
This function enables processes with necessary permissions to activate or configure various security policies.
These include, but are not limited to:
Developers provide a structure type corresponding to the relevant policy flags (e.g. PROCESS_MITIGATION_IMAGE_LOAD_POLICY).
Depending on the mitigation policy selected, certain process actions may be permitted, restricted or prohibited entirely.
These protective measures were originally developed to prevent processes from being exploited or manipulated, thereby enhancing the system's overall security.
Adversaries have found ways to abuse these mechanisms to weaken or bypass security controls. As described within MITRE ATT&CK under Impair Defenses: Disable or Modify Tools, attackers may leverage process mitigation policies to prevent certain EDR products from injecting their user-mode monitoring components.
For example:
By spawning a process with the PROCESS_CREATION_MITIGATION_POLICY_BLOCK_NON_MICROSOFT_BINARIES_ALWAYS_ON flag - typically via UpdateProcThreadAttribute - attackers can block loading of any DLL that is not signed by Microsoft. Since many EDR solutions rely on injecting vendor-signed DLLs to perform API hooking and behavioral monitoring, this approach can significantly reduce their visibility of the process.

To understand the behavior of the system-wide mitigation policies stored under HKLM/SYSTEM/CurrentControlSet/Control/Session Manager/Kernel/MitigationOptions, it is necessary to examine the Windows boot arhitecture and the structure of early kernel initialization. The enforcement semantics of MitigationOptions are specifically linked to the kernel's Phase 0 initialization sequence, rather than to any subsequent user-mode components, such as the Session Manager (smss.exe.).
Windows initializes the SYSTEM hive during kernel startup, long before any user-mode process exists. Registry modifications use a memory-mapped model with 2-MB views and PAGE_WRITECOPY semantics. Updates are appended to per-hive transaction logs but written back to disk only by the registry lazy writer, which periodically reconciles dirty pages. Because hive pages may remain resident or be paged out, and because updates are not immediately committed to the persistent hive file, the kernel cannot rely on runtime hive state for loading security-critical configuration values such as MitigationOptions.
This separation between runtime hive state and boot-time configuration is fundamental to the immutability of mitigation policies after boot.
Windows boot proceeds through two kernel phases:
During both phases:
Only after Phase 1 does the kernel create smss.exe, the first user-mode process.
Smss.exe is the first user-mode process created by the kernel after Phase 1 completes. It is implemented as a Protected Process Light (PPL) and runs as a native application without relying on Win32 APIs. Smss.exe is responsible for initializing Session 0 (services), Session 1 (interactive logon) and additional sessions in Terminal Services environments.
During its one-time initialization, smss.exe performs several critical tasks, including:
Smss.exe is therefore the first user-mode component capable of accessing fully initialized registry hives. Importantly, this occurs only after the kernel has already constructed and frozen the global mitigation-policy table during Phase 0, meaning smss.exe has no influence on the initialization of MitigationOptions.
A crucial detail that is often overlooked in public documentation is that Windows initializes and freezes the global process mitigation table during Phase 0 of the Process Manager's start-up process.
Windows Internals (Part 2, Chapter 12) states:
“Systemwide process mitigation options are initialized and merged with the options specified in HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Kernel\MitigationOptions.”
This initialization takes place before the object manager is fully operational, before the filesystem stack is ready, and before any Win32 subsystem is available. Its position in Phase 0 ensures deterministic enforcement semantics for all subsequently created processes.
Precise initialization sequence:
1. Process manager initializes during Phase 0
2. It defines the core process, thread, job, and partition object types
3. It allocates global mitigation option structures
4. It reads the registry value HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Kernel\MitigationOptions
5. It merges:
6. The resulting mitigation configuration is then frozen and becomes the global policy table
7. The table is inherited by any process created afterwards
8. Smss.exe is only launched afterwards
In order to verify that MitigationOptions are initialized during Phase 0, a virtual Windows 11 machine was examined using KDNET remote kernel debugging. A breakpoint was established within a kernel routine that directly accesses the global mitigation table: PsIsSystemWideMitigationOptionSet.

Mitigation routine was hooked successfully:

When the system hit the breakpoint in PsIsSystemWideMitigationOptionSet, the disassembly clearly showed that the routine reads directly from the global mitigation table:

Immediately afterwards, the content of nt!PspSystemMitigationOptions was dumped. The structure was already allocated and populated, even though no user-mode process existed yet and smss.exe had not been created.
The initial dump (before modifying the registry) showed the kernel defaults:

After writing a new mitigation configuration into HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Kernel\MitigationOptions and rebooting the system, the kernel showed updated bits in the same structure:

The kernel debugger evidence demonstrates that the global process mitigation table PspSystemMitigationOptions is allocated, populated from boot-time registry configuration, and finalized during Phase 0 of kernel initialization, before smss.exe is created and long before the Windows subsystem becomes operational. Any registry changes to MitigationOptions made at runtime are therefore ignored until the next reboot.
The fact that smss.exe later loads additional registry hives (including SOFTWARE, SAM and SECURITY) does not influence the mitigation state, because the global table has already been finalized.
Therefore, any change to MitigationOptions requires:
Once the Session Manager (smss.exe) has completed its core initialization tasks, including loading the Software hive, creating the KnownDlls directory and coordinating subsystem setup, the remaining executive components finalize their initialization. During this late-boot phase, the I/O manager fully mounts the file system, Event Tracing for Windows (ETW) flushes buffered boot-time events once stable hive access is available, and the Service Control Manager finishes initializing the user-mode driver (UMDF) after the Win32 subsystem becomes operational. These components implicitly rely on the fact that global process mitigation settings have already been computed during Phase 0, after which the system assumes mitigation policy immutability and all late-boot subsystems operate under the fixed mitigation environment established early in kernel initialization.
This analysis examined how attackers can exploit certain mitigation policies to create processes that are no longer monitored by many EDR solutions. This approach is not new and is described in the MITRE ATT&CK Framework under the 'Impair Defenses' technique (T1562) Disable or Modify Tools'. Windows provides several mechanisms for setting process mitigation policies. As well as API-based configuration options such as SetProcessMitigationPolicy and UpdateProcThreadAttribute, there is another, lesser-known approach that is controlled via the Windows registry.
Microsoft allows security-related parameters to be set in the kernel configuration area via PowerShell or native registry APIs, such as RegOpenKeyExA, RegSetValueExA and RegCreateKeyExA.
One particularly relevant key is located at:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\kernel
The binary value MitigationOptions exists there:

The technique described here, called 'Fairy Law', sets the MitigationOptions value to enable the MicrosoftSignedOnly policy globally.
This means:
Only binaries signed by Microsoft may be loaded into processes. All other DLLs are blocked by the loader.
This disables all EDR components that require DLLs that are not signed by Microsoft to operate.
Many EDR solutions feature anti-tamper protection designed to prevent their components from being disabled or manipulated. If MicrosoftSignedOnly is enabled globally, the operating system itself will block these components before the EDR has the opportunity to protect itself.
The following is to be understood:
Exception: EDRs with Microsoft-signed components.
Some EDR vendors, such as CrowdStrike in this example, have modules that are officially signed by Microsoft, such as “Microsoft Windows Hardware Compatibility Publisher” or “Microsoft Third Party Component CA”. These modules can still be loaded even when MicrosoftSignedOnly is enabled globally. Such EDRs can continue to provide some of their functionality. Conversely, products without Microsoft signatures lose a large proportion of their monitoring capabilities.

PowerShell offers a simple way to create or overwrite the corresponding registry value with administrator permission:
Set-ProcessMitigation -System -Enable MicrosoftSignedOnly
In addition to the MicrosoftSignedOnly policy, there are several other policies that can be configured. A full list is available on the Microsoft’s documentation.

Not all mitigations can be used with the -System option, as applying some of them would result in essential Windows functionality being broken. For instance, DisallowChildProcessCreation would stop Windows from creating the necessary system processes.
The main advantage of using PowerShell is that you do not need to know the underlying bitmask value for each mitigation, the cmdlet resolves this automatically. By contrast, when configuring mitigations from a C program, you have to specify the correct bit value for each mitigation you want to enable manually.
The same modification can be performed programmatically using the Windows registry API.
Following C++ program demonstrates how an attacker or administrator could:
PROCESS_MITIGATION_BINARY_SIGNATURE_POLICY sig{}; GetProcessMitigationPolicy(GetCurrentProcess(), ProcessSignaturePolicy, &sig, sizeof(sig)); This retrieves the current process signature policy flags.
If sig.MicrosoftSignedOnly == 1, the mitigation is already active.
Verifying administrative privileges
if (!IsProcessElevated()) { RestartElevated(); return 0; } Writing to HKLM requires administrator privileges.
If the program is not elevated, it attempts to restart itself with elevated permissions.
Opening or creating the registry key
// Open or create the registry key LONG result = RegCreateKeyExA( HKEY_LOCAL_MACHINE, // root hive subkey, // subkey path 0, NULL, // class type (unused) REG_OPTION_NON_VOLATILE, // key persists after reboot KEY_WRITE | KEY_READ, // access rights NULL, // security attributes &hKey, // returned key handle &disposition // tells if key was created or opened ); if (result != ERROR_SUCCESS) { printf("Error opening/creating registry key: %ld\n", result); return 1; } if (disposition == REG_CREATED_NEW_KEY) { printf("Registry key was created.\n"); } else { printf("Registry key already exists.\n"); } This ensures that the kernel registry key either exists or is created if it doesn’t.
Writing the MitigationOptions value
// The REG_BINARY value for MicrosoftSignedOnly BYTE mitigationValue[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; // Set or overwrite the REG_BINARY value result = RegSetValueExA( hKey, valueName, // value name 0, REG_BINARY, // binary value mitigationValue, // data buffer sizeof(mitigationValue) // size of the binary data ); if (result != ERROR_SUCCESS) { printf("Error writing value: %ld\n", result); RegCloseKey(hKey); return 1; } printf("MitigationOptions successfully written.\n"); RegCloseKey(hKey); This 20-byte binary value activates the MicrosoftSignedOnly bit in the global mitigation configuration.
As a result: All third-party or custom DLLs are blocked at load time
Persistence and reboot
AddToStartup(); RunPowerShell("Restart-Computer -Force"); The code optionally adds itself to the system startup and triggers an immediate reboot.
Again, the reboot is essential because Windows enforces mitigation settings only during system initialization.

The illustration shows how the MicrosoftSignedOnly countermeasure prevented SRServer.exe from loading the signed DLL, qrcodelib.dll.
To evaluate practical consequences of enforcing the MicrosoftSignedOnly global mitigation policy, several leading Endpoint Detection and Response (EDR) solutions were examined in a controlled laboratory environment. The objective was to assess whether each vendor’s endpoint agent would remain operational if Windows blocked the loading of all non-Microsoft-signed user-mode libraries, and whether any self-protection, telemetry or fallback mechanisms could compensate for this. This analysis does not include two market-leading solutions: CrowdStrike Falcon and Microsoft Defender for Endpoint. Both vendors deploy Microsoft-signed components.
All tests were conducted with the tamper-protection feature enabled for each product to determine whether the vendors' self-protection mechanisms can maintain functionality under these restrictive conditions.
After modifying the mitigation configuration, SentinelOne did not generate any alerts indicating degradation or loss of protective functionality. However, when the system was rebooted, which was necessary for the new mitigation settings to take effect, the agent's user-mode components failed immediately during startup. Windows rejected loading of several SentinelOne DLLs, including SentinelAgentCore.dll and SentinelOneAgentUI.dll, with the standard 'Bad Image' error and status code 0xc0000428. This indicates a failure of signature validation under the enforced policy.


Failure of these components prevents SentinelOne from loading its behavioral monitoring pipeline, user-mode hooks, event interception logic and telemetry dispatch modules. Therefore, after rebooting, the endpoint is no longer monitored and is left fully unprotected.
Palo Alto Cortex XDR showed identical degradation characteristics. After activating MicrosoftSignedOnly and rebooting the machine, Cortex’s user-mode loader (cytray.exe) failed to initialize because it attempted to load the unsigned module.

As a result, the agent was unable to start, leaving the system without endpoint protection capabilities. As with the other products evaluated, Cortex did not generate a local alert to indicate that the agent was not functioning.
Trend Micro exhibited a similar outcome. Once the mitigation policy was enabled and the system rebooted, the Apex One agent silently failed during initialization. The agent simply failed to start.
The enforcement of MicrosoftSignedOnly has consequences that extend beyond EDR products.
Several SIEM and log-collection agents rely on:
These modules may also be unsigned. When MicrosoftSignedOnly is active, such components are denied access during process initialization, which may result in:
The result of this is a compound visibility gap: the endpoint is left unprotected and unmonitored after reboot, with no telemetry leaving the host.
Although MicrosoftSignedOnly can unintentionally disable several endpoint security solutions, it also significantly constrains attackers.
Notably, the policy prevents:
Therefore, attackers must rely alternative techniques that do not involve loading external binaries, such as:
These constraints reduce the attacker’s flexibility, even though they do not mitigate all threat vectors.
The analysis shows that enabling MicrosoftSignedOnly via the MitigationOptions registry value significantly impacts endpoint security products that rely on libraries that are not signed by Microsoft. Without these signed components, the functionality of several EDR solutions is lost after a reboot, leaving the system without monitoring and telemetry. While DLL-based injection techniques are restricted by the policy, memory-resident execution paths remain vulnerable to attack.
Windows provides a mechanism that allows system-wide protection measures to be either overridden or applied for individual executable files. This approach enables targeted exceptions and can be legitimately used by EDR vendors whose DLLs are not signed by Microsoft to address this vulnerability. At the same time, however, it can also be abused by attackers to bypass the globally enforced MicrosoftSignedOnly restriction, for example by ensuring that ordinary applications like Chrome or Firefox can still run despite the system-wide policy.
This mechanism is implemented through the Image File Execution Options (IFEO), which allow specific protection measures to be defined for individual executables. If a deviating protection measure is configured for a particular process (e.g., disabling MicrosoftSignedOnly for a third-party vendor’s binary), the corresponding executable remains functional even if it would otherwise be blocked by the system-wide policy.
IFEO configurations are stored under the following registry path:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options
Image File Execution Options offer precise control over the execution behavior of specific processes and were initially designed for debugging, instrumentation and compatibility purposes.

The left window shows binaryninja.exe, which is blocked due to the system-wide MicrosoftSignedOnly mitigation that prevents unsigned third-party DLLs from loading. This results in a 'Bad Image' error caused by an unsigned QtWidgets6.dll file. By contrast, Firefox.exe (on the right) runs successfully because an IFEO entry explicitly disables MicrosoftSignedOnly for Firefox. This demonstrates how IFEO overrides can selectively bypass global mitigations.

The MitigationOptions value explicitly overrides the global MicrosoftSignedOnly mitigation, allowing Firefox to load unsigned DLLs despite the system-wide restriction. We have designed our own detection approaches to reveal unusual or atypical changes in this technology's environment at an early stage. This often enables anomalies to be identified before they result in the protective mechanisms failing.
[1] Russinovich, M. E., Solomon, D. A. & Ionescu, A. (2016). Windows Internals, Part 1 & 2 (7. Edition.). Microsoft Press.
[2] iRED Team. Preventing 3rd Party DLLs from Injecting into your Malware.
https://www.ired.team/offensive-security/defense-evasion/preventing-3rd-party-dlls-from-injecting-into-your-processes
[3] Microsoft Docs. Set-ProcessMitigation.
https://learn.microsoft.com/en-us/powershell/module/processmitigations/set-processmitigation?view=windowsserver2025-ps
[4] MITRE ATT&CK®. Impair Defenses: Disable or Modify Tools.
https://attack.mitre.org/techniques/T1562/001/
[5] Microsoft Docs. Image File Execution Options
https://learn.microsoft.com/en-us/previous-versions/windows/desktop/xperf/image-file-execution-options