This article describes how to sign Portable Executable (PE) files with the
IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY flag set so the file will successfully load into memory beginning with Windows Vista and Windows Server 2008.
Developers who use the force integrity checking must have basic familiarity with the following tools and documentation:
You will need a copy of the Microsoft Windows Software Development Kit (SDK), which you can download from
http://go.microsoft.com/fwlink/?linkid=84091 or the Microsoft Windows Driver Kit (WDK), which you can download from
Forced Integrity checking is a policy that ensures a binary that is being loaded is signed prior to loading. The
IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY flag is set in the PE header at link time by using the /integritycheck linker flag to indicate that the binary being loaded must be signed. This flag causes the Windows memory manager to enforce a signature
check at load time on the binary file.
Applications check for presence of the flag when the binary is loaded in order to ensure that the identity of publisher is known. The Forced Integrity policy is enforced on Windows Vista, Windows Server 2008 and later releases when the
IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY flag is set.
The Forced Integrity policy is enforced on both 32 bit and 64 bit systems and in both user and kernel mode. However, Force Integrity is not enforced for boot start drivers.
The following Windows features enforce integrity checking on third-party binaries:
Signing code with the IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY flag enabled has additional requirements beyond those of normal Authenticode signing, the details of which are explained in the following sections.
The signatures procedures described in this paper satisfy the x64 kernel mode code signing requirements as listed in the
Kernel-Mode Code Signing Walkthrough paper.
Force integrity signing is independent of Plug and Play (PnP) signing. A PnP driver can be signed as per Force Integrity requirements with the embedded signature, and also be signed independently with a PnP driver package catalog.
There is a development cost associated with signing binaries with the
IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY flag set, so do not set the
IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY flag unless your component requires it.
To set the IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY flag, you must use the /integritycheck option to link your application. The /integritycheck is supported by both Windows 7 and Visual Studio 2008, including the free Express Editions.
Even though the linker option does not appear in the list that the linker's /? help option output, it is nevertheless supported by current versions of the linker. The easiest way to tell if the linker supports the /integritycheck option is to type the following:
If the linker supports the /integritycheck option, the following output appears when this option is set at the command line.
If the linker does not support the /integritycheck option, the following output appears instead.
There are a few differences from test signing as described in the Code Signing Best Practices paper. Beginning with Windows 7, you must perform the signing. You must also take additional steps to enable test signed binaries to load. The processes required
are described in detail in the Kernel-Mode Code Signing Walkthrough paper.
For information on generating a test certificate, see "Step 2: Create a Test Certificate by Using MakeCert" on pages 9-10.
For information on enabling the test signing configuration required for force integrity, see "Step 2: Enable the Kernel-Mode Test-Signing Boot Configuration Option" on pages 24-25.
For information on disabling force integrity signature checks for daily development tasks, see "How to Disable Signature Enforcement on a Test Computer" on pages 53-54.
During both test signing and release signing, you must use the /ph (page hash) flag with SignTool when signing user mode binaries with the
IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY flag set. On Windows 7 and Windows Server 2008 R2, page hashes are optional, but recommended for performance reasons. The /ph option requires the computer used to sign target files to be using Windows
Vista, Windows Server 2008 or later OS versions. Page hash enforcement verifies the signature on each page of the executable file as it loads into memory.
Test signing command line syntax
The following example shows how to test-sign an executable file by using SignTool with the test certificate generated using the command line syntax from "Step 2: Create a Test Certificate by Using MakeCert" of the
Kernel-Mode Code Signing Walkthrough paper:
signtool sign /v /ph /s PrivateCertStore /n Contoso.com(Test) /t http://timestamp.verisign.com/scripts/timestamp.dll c:\plugin.dll
A timestamp allows Windows to determine when a file was signed and ensures that the signature does not expire when the certificate expires. This, in turn, helps prevent the signature from becoming invalid while the executable file is installed on a customer
Release signing a module using the force integrity bit is fundamentally similar to the release signing documented in the "How to Release-Sign a Kernel Module" in the
Kernel-Mode Code Signing Walkthrough paper.
The primary differences are:
The example command line below shows the syntax for release signing. See "Release-Signing a Driver Image File by Using an Embedded Signature" pages 42-43 of the Kernel-Mode Code Signing Walkthrough paper for a explanation for the /ac command line option.
signtool sign /v /ph /ac MSCV-VSClass3.cer /s my /n contoso.com /t http://timestamp.verisign.com/scripts/timestamp.dll c:\plugin.dll
The Event Log is a useful tool with which to troubleshoot problems with loading executable files with the
IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY flag set. See "Enabling the Code Integrity Event Logging and System Auditing"on page 25 of the
Kernel-Mode Code Signing Walkthrough paper and "Viewing the log" on page 30.
If your executable file is failing to load, and you suspect that an invalid signature is at fault, use the following diagnostic steps to identify common problems.
Follow the procedures in the Logging and Auditing section of this document to view the event log. For additional help with Code Integrity event log errors, see Code Integrity at
If there are no log entries, it is very likely that the signature is not the issue.
Verify that the
signtool sign /ph
option is set at the command line, and signing machine is running Windows Vista or Windows Server 2008 or later.
You can check for cross-cert support by entering the following in a Command Window:
signtool sign /?
If the resulting output contains the following parameter description, the your version of SignTool supports /ph
/ph Generate page hashes for executable files if supported.
The current SignTool can be acquired as part of the following SDKs:
If you are verifying test signed binaries, ensure that you have enabled test signing on the target machine as described in the “Enabling Test Signing” section of this paper
If the resulting output contains the following parameter description, then your version of SignTool supports cross cert signing:
/ac <file>Add a cross-certificate from the .cer file to the signature.
On pre-Windows 7 SDK versions of SignTool, SignTool reports success in cases where a file is signed - even if the cross cert is not included with the signature. To fix this issue, one can either upgrade to the Windows 7 version of signtool, or use the steps
for verifying the cross-certificate see pages 39 through 41 of theKernel-Mode Code Signing Walkthrough paper.
If the /AC option does not yield the correct results, check that you have the correct cross-certificate.
You can obtain the latest cross-certificate at
Verify that the public keys of the cross-certificate and the target root certificate match.
To view the public key in the cross-certificate:
To view the public key in the root certificate:
Check that the cross-certificate .cer file is located in the current directory, or use an absolute path
For user mode code, verify you are signing correctly with the /ph option. For additional information see the "Use the /ph option with SignTool" in the "Enabling test signing" section of this topic.
Does the file verify with the Windows 7 SDK SignTool verify /kp, but fail to load causing entries in CI event log?