Other Resources
Security Developer Center
Cryptography Topics on MSDN
Follow us on Twitter

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.

 

 

Introduction

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 http://go.microsoft.com/fwlink/?LinkID=96667.

What is Force Integrity checking?

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:

  • Windows Vista and Windows 7: Windows Security Center, Appinit.dll extensions, Object Manager filter registration, and extended process filter registration APIs
  • Windows 7: Windows Biometric Framework, LSA extensions, and NTOS kernel extensions

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.

How to set the IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY flag by using Link.exe

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:

link /integritycheck

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.

Enabling test signing

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.

Use the /ph option with SignTool

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

Argument Description
sign Signs the executable file.
/v Displays successful execution and warning messages.
/ph Generates page hashes for the pages in the executable file.
/s CertStore specifies the certificate store that contains the certificate. This example uses a certificate from the PrivateCertStore certificate store.
/n CertName Specifies the certificate name. This example uses Contoso.com(Test).
/t URL Adds a time stamp to the digital signature. The URL indicates the time stamp authority (TSA). This example uses the VeriSign TSA, whose URL is http://timestamp.verisign.com/scripts/timestamp.dll.
filename Specifies the name and path of the file to be signed.

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 system.

Release signing

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 code is linked with the /integritycheck flag set.
  • The /ph option is used to generate page hashes to sign code to run on Windows Vista and Windows Server 2008. On Windows 7 and Windows Server 2008 R2 this flag is optional, but is recommended for performance reasons.

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

Logging and Auditing

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.

Diagnosing Signing Issues

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.

  • Are there failures in the Code Integrity Event Log?

    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 http://go.microsoft.com/fwlink/?linkid=155903.

    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

  • Verify that you have a version of Signtool.exe that supports /ac and /kp

    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, then your version of SignTool supports cross cert signing:

    /ac <file>Add a cross-certificate from the .cer file to the signature.

  • Is the cross-certificate in the certificate chain?

    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 http://go.microsoft.com/fwlink/?linkid=155789.

    Verify that the public keys of the cross-certificate and the target root certificate match.

    To view the public key in the cross-certificate:

    1. Double click on the .cer file.
    2. Click on the details tab.
    3. Selecting the public key, and examine the public key value details.

    To view the public key in the root certificate:

    1. Right click on a signed binary.
    2. Select properties.
    3. Select the digital signatures tab.
    4. Select the signature click details.
    5. Click view certificate.
    6. Click on the certificate path tab.
    7. Select the root certificate.
    8. Click view certificate.
    9. Select the details tab.
    10. Select the public key and examine the public key value details.
  • 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?

  • If these steps fail, then see How to prevent signature verification failures caused by invalid PointerToRawData field values.

Additional References:


See Also