AD2029: EnableIntegrityCheck¶
Summary¶
| Property | Value |
|---|---|
| ID | AD2029 |
| Name | EnableIntegrityCheck |
| Category | Security |
| Severity | Error |
| Applies to | PE (Windows) |
Description¶
Binaries that are loaded by certain Windows features must (and device drivers should) opt into Windows validation of their digital signatures by setting the /INTEGRITYCHECK linker flag.
This option sets the IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY attribute in the PE header which tells the memory manager to validate a binary's digital signature when loaded.
How It Works¶
The rule checks for the IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY flag (0x0080) in the PE optional header's DLL characteristics field.
Why This Matters¶
Integrity Check (/INTEGRITYCHECK) enforces cryptographic verification of code before it runs, ensuring that even system-level attacks cannot inject unverified code into protected scenarios. For security-critical components, this flag is not optionalβit's required.
The Chain of Trust¶
Modern Windows security relies on authenticated boot and runtime verification:
Secure Boot β Boot Loader β Kernel β ELAM β Protected Processes
β β β β β
Signed Signed Signed Signed Signed + IntegrityCheck
Without /INTEGRITYCHECK, a binary can be tampered with and still load (if signature checking isn't mandatory for that code path).
Critical Use Cases¶
| Scenario | Requirement | Consequence if Missing |
|---|---|---|
| ELAM drivers | Required | Won't load as ELAM |
| PPL binaries | Required | Signature bypass possible |
| Device drivers | Strongly recommended | Weak tamper resistance |
| UEFI code | Required | Secure boot compromise |
| Antimalware | Required | Rootkit evasion possible |
Early Launch Antimalware (ELAM)¶
ELAM drivers load before other drivers to detect rootkits:
- Boot starts - Minimal kernel loaded
- ELAM loads - Must have INTEGRITYCHECK
- ELAM scans - Checks all subsequent driver loads
- Other drivers - Loaded if ELAM approves
Without INTEGRITYCHECK, an attacker could: - Modify the ELAM driver binary - Disable malware detection at the earliest stage - Hide subsequent rootkit activity
Protected Process Light (PPL)¶
PPL provides enhanced process protection:
PPL Protection Levels:
PPL-WinTcb: Windows kernel components
PPL-Antimalware: AV/EDR software
PPL-App: Protected applications
All PPL binaries MUST have INTEGRITYCHECK.
How Verification Works¶
Without INTEGRITYCHECK:
Binary loaded β Signature optional β May run modified
With INTEGRITYCHECK:
Binary loaded β Signature REQUIRED β Modified = load fails
β
Memory manager checks Authenticode signature
β
Invalid/missing signature = binary won't load
Defense Against Tampering¶
Common tampering attacks and INTEGRITYCHECK's effect:
| Attack | Without INTEGRITYCHECK | With INTEGRITYCHECK |
|---|---|---|
| Binary patching | May succeed | Load fails |
| DLL replacement | May succeed | Load fails |
| Driver substitution | May succeed | Load fails |
| Man-in-the-middle | May succeed | Load fails |
Signing Requirements¶
Binaries with INTEGRITYCHECK must be properly signed:
- EV code signing certificate for drivers
- Standard code signing for user-mode PPL
- Timestamp to survive certificate expiration
- SHA-256 or better hash algorithm
Compliance Implications¶
| Standard | Relevance |
|---|---|
| Windows Hardware Compatibility | Required for drivers |
| Common Criteria | Tamper resistance evidence |
| FIPS 140 | Cryptographic module integrity |
| Antimalware certification | Required for ELAM |
Required for: - ELAM drivers: Early Launch Antimalware drivers - Device firmware: UEFI-related code - Protected processes: Code loading into PPL space - Secure boot: Authenticated boot chain
Benefits: - Tamper detection: Modified binaries won't load - Trust chain: Ensures authentic code execution - Compliance: Required for certain Windows features
Resolution¶
Enable Integrity Check¶
Linker flag:
Project Properties¶
- Open Project Properties
- Navigate to Linker β Advanced
- Set "Force File Output Integrity Check" to "Yes (/INTEGRITYCHECK)"
CMake¶
Sign the Binary¶
Binaries with /INTEGRITYCHECK must be signed:
When to Suppress¶
This rule can be suppressed for:
- Regular applications: Most apps don't need forced integrity
- Unsigned binaries: If you can't sign the binary
- Development builds: During development without code signing
- Internal tools: Non-production utilities
Caveats¶
- Binary MUST be signed if this flag is set, or it won't load
- Requires a valid code signing certificate
- Self-signed certs may not work in all scenarios
- Loading fails silently if signature validation fails
Who Needs /INTEGRITYCHECK¶
| Component | Required |
|---|---|
| ELAM drivers | β Yes |
| Kernel drivers | β οΈ Recommended |
| UEFI applications | β Yes |
| Protected process code | β Yes |
| Normal applications | β Optional |
| DLLs loaded by above | β Yes |
Verification¶
Check if integrity check is enabled:
Error When Unsigned¶
If the binary is marked with /INTEGRITYCHECK but not signed: