Windows System Software -- Consulting, Training, Development -- Unique Expertise, Guaranteed Results

Before Posting... Please check out the Community Guidelines in the
Announcements and Administration Category.

Non-zero Code Integrity statistic found: Execute Pool Type Count

When I ran HLK for my old WDM driver for WIndows 10 64, I have got failures for HVCI code integrity test as below,

"WDTF_TEST : Non-zero Code Integrity statistic found: Execute Pool Type Count: == 71"

Could anybody help me to identify these violations in the code?
How to verify the actual allocations for IRP/MDL/MEMORY in my driver code, which making these failure count.?

Driver was built with WDK 7.

Comments

  • Steve Walkin wrote:
    >
    > Could anybody help me to identify these violations in the code?

    Use the 'Code Integrity Check' option of the Driver Verifier (Windows 10).
  • You?ll inevitably need to use POOL_NX_OPTIN:

    https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/single-binary-opt-in-pool-nx-optin

    -scott
    OSR
    @OSRDrivers

    -scott
    OSR

  • Tim_RobertsTim_Roberts Posts: 12,622
    xxxxx@gmail.com wrote:
    > When I ran HLK for my old WDM driver for WIndows 10 64, I have got failures for HVCI code integrity test as below,
    >
    > "WDTF_TEST : Non-zero Code Integrity statistic found: Execute Pool Type Count: == 71"
    >
    > Could anybody help me to identify these violations in the code?
    > How to verify the actual allocations for IRP/MDL/MEMORY in my driver code, which making these failure count.?

    I'd like to expand on Scott's answer, which is the correct one.

    The issue here is that, traditionally, memory allocations with
    ExAllocatePool have been done with PagedPool or NonPagedPool.  Those
    types allocate R/W/X pages.  In Windows 8, Microsoft added the
    NonPagedPoolNx type, which allocated R/W pages that cannot be executed. 
    Starting with Windows 10, you are now REQUIRED to use NonPagedPoolNx.

    That presents a problem for multi-platform drivers, because
    NonPagedPoolNx is not valid in Windows 7.  Scott's reference describes
    that workaround.

    Personally, I do not understand why Microsoft didn't simply redefine
    NonPagedPool to mean R/W and add a new type, NonPagedPoolExecute.  That
    would have been a MUCH less impactful solution.  Those very, very few
    drivers that need R/W/X pages would have caused an easily correctable
    BSOD, while the overwhelming majority of drivers that only needed R/W
    could have continued life unimpeded.

    --
    Tim Roberts, xxxxx@probo.com
    Providenza & Boekelheide, Inc.

    Tim Roberts, [email protected]
    Providenza & Boekelheide, Inc.

  • Thanks for your reply and suggestions, Aleh, Scott & Tim.

    Let me see whether I can get it fixed with it.
  • Mark_RoddyMark_Roddy Posts: 4,269
    I think the annoying reason to not make the much simpler change was to
    retain compatibility binary with existing code, even if that code presented
    a security risk. Although if it was my driver that suddenly stopped working
    I would not find this annoying.

    Mark Roddy

    On Tue, Jan 9, 2018 at 12:44 PM, xxxxx@probo.com wrote:

    > xxxxx@gmail.com wrote:
    > > When I ran HLK for my old WDM driver for WIndows 10 64, I have got
    > failures for HVCI code integrity test as below,
    > >
    > > "WDTF_TEST : Non-zero Code Integrity statistic found: Execute Pool Type
    > Count: == 71"
    > >
    > > Could anybody help me to identify these violations in the code?
    > > How to verify the actual allocations for IRP/MDL/MEMORY in my driver
    > code, which making these failure count.?
    >
    > I'd like to expand on Scott's answer, which is the correct one.
    >
    > The issue here is that, traditionally, memory allocations with
    > ExAllocatePool have been done with PagedPool or NonPagedPool. Those
    > types allocate R/W/X pages. In Windows 8, Microsoft added the
    > NonPagedPoolNx type, which allocated R/W pages that cannot be executed.
    > Starting with Windows 10, you are now REQUIRED to use NonPagedPoolNx.
    >
    > That presents a problem for multi-platform drivers, because
    > NonPagedPoolNx is not valid in Windows 7. Scott's reference describes
    > that workaround.
    >
    > Personally, I do not understand why Microsoft didn't simply redefine
    > NonPagedPool to mean R/W and add a new type, NonPagedPoolExecute. That
    > would have been a MUCH less impactful solution. Those very, very few
    > drivers that need R/W/X pages would have caused an easily correctable
    > BSOD, while the overwhelming majority of drivers that only needed R/W
    > could have continued life unimpeded.
    >
    > --
    > Tim Roberts, xxxxx@probo.com
    > Providenza & Boekelheide, Inc.
    >
    >
    > ---
    > NTDEV is sponsored by OSR
    >
    > Visit the list online at: showlists.cfm?list=ntdev>
    >
    > MONTHLY seminars on crash dump analysis, WDF, Windows internals and
    > software drivers!
    > Details at
    >
    > To unsubscribe, visit the List Server section of OSR Online at <
    > http://www.osronline.com/page.cfm?name=ListServer>;
    >
  • I have used NonPagedPoolNx and thereby I am able to stripe out the Execute Pool Type Count completely. Thanks.

    But I still have errors on "Section Alignment Failures =8" and "Execute-Write Section Count=1".

    The "Execute-Write Section Count=1" appearing only in Windows 10 10586 build, whereas all the later builds does not showing this error.

    Any further insight for me resolve these failures.
  • Driver Compatibility with Device Guard
    https://docs.microsoft.com/en-us/windows-hardware/test/hlk/testref/driver-compatibility-with-device-guard

    How to build compatible drivers

    ...

    * Don't use sections that are both writable and executable

    * Section Alignment must be a multiple of 0x1000 (PAGE_SIZE).
    E.g. DRIVER_ALIGNMENT=0x1000
  • Wherever I used ExAllocatePoolWithTag , I have used the pool tag with a multiple of 0x100.

    I have enabled the driver verifier and debugged remotely with Windbg. I am getting following 8 Code integrity issues.
    How can I trace this .text, .rdata , .data etc to the code for page alignment issues ?
    Since it is a Verifier crash, I am not able to debug even with the .pdb file in Windbg.
    Any thoughts to identify the root cause of this failure ? Please help.


    Driver Verifier: Enabled for driverxxx.sys, flags 0x2000000, build 10586, key xxxxxxxx
    *********** Verifier Detected a Code Integrity Issue ************
    **
    ** The image driverxxx.sys contains section 0xFFFFF800873401F0 that is not page aligned (name .text).
    **
    *****************************************************************
    *********** Verifier Detected a Code Integrity Issue ************
    **
    ** The image driverxxx.sys contains section 0xFFFFF80087340218 that is not page aligned (name .rdata).
    **
    *****************************************************************
    *********** Verifier Detected a Code Integrity Issue ************
    **
    ** The image driverxxx.sys contains section 0xFFFFF80087340240 that is not page aligned (name .data).
    **
    *****************************************************************
    *********** Verifier Detected a Code Integrity Issue ************
    **
    ** The image driverxxx.sys contains section 0xFFFFF80087340268 that is not page aligned (name .pdata).
    **
    *****************************************************************
    *********** Verifier Detected a Code Integrity Issue ************
    **
    ** The image driverxxx.sys contains section 0xFFFFF80087340290 that is not page aligned (name .CRT).
    **
    *****************************************************************
    *********** Verifier Detected a Code Integrity Issue ************
    **
    ** The image driverxxx.sys contains section 0xFFFFF800873402B8 that is not page aligned (name INIT).
    **
    *****************************************************************
    *********** Verifier Detected a Code Integrity Issue ************
    **
    ** The image driverxxx.sys contains section 0xFFFFF800873402E0 that is not page aligned (name .rsrc).
    **
    *****************************************************************
    *********** Verifier Detected a Code Integrity Issue ************
    **
    ** The image driverxxx.sys contains section 0xFFFFF80087340308 that is not page aligned (name .reloc).
    **
    *****************************************************************
  • Tim_RobertsTim_Roberts Posts: 12,622
    xxxxx@gmail.com wrote:
    > Wherever I used ExAllocatePoolWithTag , I have used the pool tag with a multiple of 0x100.

    I don't think that's really what you meant, but it's also not relevant
    to this issue.

     
    > I have enabled the driver verifier and debugged remotely with Windbg. I am getting following 8 Code integrity issues.
    > How can I trace this .text, .rdata , .data etc to the code for page alignment issues ?
    > Since it is a Verifier crash, I am not able to debug even with the .pdb file in Windbg.
    > Any thoughts to identify the root cause of this failure ? Please help.

    Yes.  The root cause is that, in your build, you have overridden the
    default value for the linker's /ALIGN parameter.  The default value of
    /ALIGN is 4096, which results in all sections being page-aligned.  Some
    people override that in a foolish attempt to save disk space for the
    executable, but the kernel requires that sections actually have page
    alignment.

    --
    Tim Roberts, xxxxx@probo.com
    Providenza & Boekelheide, Inc.

    Tim Roberts, [email protected]
    Providenza & Boekelheide, Inc.

  • I have added below ones into my build, still the page alignment issues persists.

    First try.
    LINKER_FLAGS=/ALIGN:4096

    Second try.
    LINKER_FLAGS=/SECTION:.text!RX,ALIGN:4096
    DRIVER_ALIGNMENT=0x1000

    Any idea of what is going wrong ?
  • Tim_RobertsTim_Roberts Posts: 12,622
    xxxxx@gmail.com wrote:
    > I have added below ones into my build, still the page alignment issues persists.
    >
    > First try.
    > LINKER_FLAGS=/ALIGN:4096
    >
    > Second try.
    > LINKER_FLAGS=/SECTION:.text!RX,ALIGN:4096
    > DRIVER_ALIGNMENT=0x1000

    You shouldn't need either of those; 4096 is the default.  What is your
    build environment?  Is that in a "sources" file?  If you look in the
    buildxxx.log file, do you see an "align" value?  If you do "link /dump
    /headers xxxx.sys", what do you see for "section alignment"?  Are the
    virtual addresses for the individual sections actually page aligned?

    And, the stupid question, are you sure you're testing with the newly
    build driver?

    --
    Tim Roberts, xxxxx@probo.com
    Providenza & Boekelheide, Inc.

    Tim Roberts, [email protected]
    Providenza & Boekelheide, Inc.

  • Tim_RobertsTim_Roberts Posts: 12,622
    xxxxx@gmail.com wrote:
    > I have added below ones into my build, still the page alignment issues persists.
    > ...
    > Any idea of what is going wrong ?

    Is it possible you're setting _NT_TARGET_VERSION to XP?  In XP, the
    default driver alignment was only 0x80.

    --
    Tim Roberts, xxxxx@probo.com
    Providenza & Boekelheide, Inc.

    Tim Roberts, [email protected]
    Providenza & Boekelheide, Inc.

  • Yes Tim, I am using build environment from "sources" file. In the buildxxx.log file shows align value as 1>/align:0x0080

    So I specifically put _NT_TARGET_VERSION=$(_NT_TARGET_VERSION_LATEST) in the "sources" file and rebuilt. Still it is not page aligned.

    Dump of file C:\VS-OLD\objfre_win7_amd64\amd64\driverxxx.sys

    File Type: EXECUTABLE IMAGE

    Summary

    80 .CRT
    A80 .data
    1F00 .pdata
    2200 .rdata
    880 .reloc
    480 .rsrc
    40B00 .text
    D80 INIT
  • Tim_RobertsTim_Roberts Posts: 12,622
    On Feb 4, 2018, at 9:06 PM, xxxxx@gmail.com <xxxxx@lists.osr.com> wrote:
    >
    > Yes Tim, I am using build environment from "sources" file. In the buildxxx.log file shows align value as 1>/align:0x0080

    Well, that says you haven't found the magic recipe yet. Are you doing a full/clean build each time? Just because you modify "sources" doesn't mean it will actually redo the linking.


    > So I specifically put _NT_TARGET_VERSION=$(_NT_TARGET_VERSION_LATEST) in the "sources" file and rebuilt. Still it is not page aligned.
    >
    > Dump of file C:\VS-OLD\objfre_win7_amd64\amd64\driverxxx.sys

    This output is from "link /dump", not from "link /dump /headers".

    Tim Roberts, xxxxx@probo.com
    Providenza & Boekelheide, Inc.

    Tim Roberts, [email protected]
    Providenza & Boekelheide, Inc.

  • You said it right Tim. I did not get either the magic recipe or the proper headers :(.
    I used to build "bld -cew" command every time i changes.

    Here is the complete header details. I could see each section are "Not paged". Can you guide more.

    FILE HEADER VALUES
    8664 machine (x64)
    8 number of sections
    5A780F9A time date stamp Mon Feb 05 13:32:34 2018
    0 file pointer to symbol table
    0 number of symbols
    F0 size of optional header
    22 characteristics
    Executable
    Application can handle large (>2GB) addresses

    OPTIONAL HEADER VALUES
    20B magic # (PE32+)
    9.00 linker version
    41800 size of code
    5880 size of initialized data
    0 size of uninitialized data
    459E4 entry point (00000000000559E4) GsDriverEntry
    380 base of code
    10000 image base (0000000000010000 to 00000000000573FF)
    80 section alignment
    80 file alignment
    6.01 operating system version
    6.01 image version
    1.10 subsystem version
    0 Win32 version
    47400 size of image
    380 size of headers
    492AA checksum
    1 subsystem (Native)
    2000 DLL characteristics
    WDM Driver
    40000 size of stack reserve
    1000 size of stack commit
    100000 size of heap reserve
    1000 size of heap commit
    0 loader flags
    10 number of directories
    0 [ 0] RVA [size] of Export Directory
    45A04 [ 50] RVA [size] of Import Directory
    46700 [ 438] RVA [size] of Resource Directory
    43A00 [ 1ECC] RVA [size] of Exception Directory
    0 [ 0] RVA [size] of Certificates Directory
    46B80 [ 510] RVA [size] of Base Relocation Directory
    41150 [ 1C] RVA [size] of Debug Directory
    0 [ 0] RVA [size] of Architecture Directory
    0 [ 0] RVA [size] of Global Pointer Directory
    0 [ 0] RVA [size] of Thread Storage Directory
    0 [ 0] RVA [size] of Load Configuration Directory
    0 [ 0] RVA [size] of Bound Import Directory
    40E00 [ 350] RVA [size] of Import Address Table Directory
    0 [ 0] RVA [size] of Delay Import Directory
    0 [ 0] RVA [size] of COM Descriptor Directory
    0 [ 0] RVA [size] of Reserved Directory


    SECTION HEADER #1
    .text name
    40A15 virtual size
    380 virtual address (0000000000010380 to 0000000000050D94)
    40A80 size of raw data
    380 file pointer to raw data (00000380 to 00040DFF)
    0 file pointer to relocation table
    0 file pointer to line numbers
    0 number of relocations
    0 number of line numbers
    68000020 flags
    Code
    Not Paged
    Execute Read

    SECTION HEADER #2
    .rdata name
    215C virtual size
    40E00 virtual address (0000000000050E00 to 0000000000052F5B)
    2180 size of raw data
    40E00 file pointer to raw data (00040E00 to 00042F7F)
    0 file pointer to relocation table
    0 file pointer to line numbers
    0 number of relocations
    0 number of line numbers
    48000040 flags
    Initialized Data
    Not Paged
    Read Only

    Debug Directories

    Time Type Size RVA Pointer
    -------- ------ -------- -------- --------
    5A780F9A cv 57 000427B0 427B0 Format: RSDS, {75ACD3F0-83E2-44A6-BA4F-E9BCB3A138B3}, 1, c:\winddk\vs-old\objfre_win7_amd64\amd64\driverxxx.pdb

    SECTION HEADER #3
    .data name
    A40 virtual size
    42F80 virtual address (0000000000052F80 to 00000000000539BF)
    A80 size of raw data
    42F80 file pointer to raw data (00042F80 to 000439FF)
    0 file pointer to relocation table
    0 file pointer to line numbers
    0 number of relocations
    0 number of line numbers
    C8000040 flags
    Initialized Data
    Not Paged
    Read Write

    SECTION HEADER #4
    .pdata name
    1ECC virtual size
    43A00 virtual address (0000000000053A00 to 00000000000558CB)
    1F00 size of raw data
    43A00 file pointer to raw data (00043A00 to 000458FF)
    0 file pointer to relocation table
    0 file pointer to line numbers
    0 number of relocations
    0 number of line numbers
    48000040 flags
    Initialized Data
    Not Paged
    Read Only

    SECTION HEADER #5
    .CRT name
    58 virtual size
    45900 virtual address (0000000000055900 to 0000000000055957)
    80 size of raw data
    45900 file pointer to raw data (00045900 to 0004597F)
    0 file pointer to relocation table
    0 file pointer to line numbers
    0 number of relocations
    0 number of line numbers
    48000040 flags
    Initialized Data
    Not Paged
    Read Only

    SECTION HEADER #6
    INIT name
    D3A virtual size
    45980 virtual address (0000000000055980 to 00000000000566B9)
    D80 size of raw data
    45980 file pointer to raw data (00045980 to 000466FF)
    0 file pointer to relocation table
    0 file pointer to line numbers
    0 number of relocations
    0 number of line numbers
    E2000020 flags
    Code
    Discardable
    Execute Read Write

    SECTION HEADER #7
    .rsrc name
    438 virtual size
    46700 virtual address (0000000000056700 to 0000000000056B37)
    480 size of raw data
    46700 file pointer to raw data (00046700 to 00046B7F)
    0 file pointer to relocation table
    0 file pointer to line numbers
    0 number of relocations
    0 number of line numbers
    42000040 flags
    Initialized Data
    Discardable
    Read Only

    SECTION HEADER #8
    .reloc name
    838 virtual size
    46B80 virtual address (0000000000056B80 to 00000000000573B7)
    880 size of raw data
    46B80 file pointer to raw data (00046B80 to 000473FF)
    0 file pointer to relocation table
    0 file pointer to line numbers
    0 number of relocations
    0 number of line numbers
    42000040 flags
    Initialized Data
    Discardable
    Read Only

    Summary

    80 .CRT
    A80 .data
    1F00 .pdata
    2180 .rdata
    880 .reloc
    480 .rsrc
    40A80 .text
    D80 INIT
  • Steve Walkin wrote:

    > I have added below ones into my build, still the page alignment issues persists.
    >
    > First try.
    > LINKER_FLAGS=/ALIGN:4096
    >
    > Second try.
    > LINKER_FLAGS=/SECTION:.text!RX,ALIGN:4096
    > DRIVER_ALIGNMENT=0x1000
    >
    > Any idea of what is going wrong ?

    Remove the following line from your 'sources' file:

    DRIVERTYPE=WDM

    Probably this is a bug: when compiling in x64 mode this directive
    causes an invalid section alignment. I using the following template
    and everything works fine:

    !IF "$(DDK_TARGET_OS)"=="WinXP"
    DRIVER_ALIGNMENT=4096
    !ELSE
    LINKER_FLAGS = $(LINKER_FLAGS) /ALIGN:4096
    !ENDIF
  • Aleh, that's a perfect catch. It worked for me too.
    Now it is page aligned as
    1000 .CRT
    1000 .data
    2000 .pdata
    3000 .rdata
    1000 .reloc
    1000 .rsrc
    41000 .text
    1000 INIT

    Thanks for the prompt reply.

    Can we remove the the RWX from INIT section, while in the same build environment. Any parameter or any settings in make files ?.

    Any clues on this, please suggest.
  • Steve Walkin wrote:

    > Can we remove the the RWX from INIT section, while in the same build
    > environment. Any parameter or any settings in make files ?

    You can't achieve this until WDK 10. Yes, some compiler and linker options
    may be helpful, but all of them have undesirable side effects.

    But as far as I know, the INIT/RWX section is a special exclusion for
    Driver Verifier, HLK and HVCI/DevGuard. For example, it is not generate a
    violation when running on Windows 10 under HVCI or Verifier.
    Some time ago I successfully passed HLK tests for a minifilter that was
    built in WDK 7.1 with RWX attributes of INIT section.

    FYI:
    When running under HVCI/DevGuard the RWX section is silently converted to RX...
  • Thanks Aleh for the clarification.

    I have another suggestion to propose. How efficient and error free is the below approach.

    Use the 'MapAndLoad' to identify the image(.sys) properties via LOADED_IMAGE structure.
    Use the IMAGE_SECTION_HEADER structure, to retrieve the parameter 'Characteristics' to get the Writable section.
    Strip the value IMAGE_SCN_MEM_WRITE from the identified section.
    Use 'UnMapAndLoad' by adding the correct checksum in the header.

    Can we reuse this image(.sys) ? What will be the implications.
    Please suggest.
  • Steve Walkin wrote:

    > Can we reuse this image(.sys) ? What will be the implications.

    You must fix checksum of image (see PE optional header).

    I think the better is to remove the 'Writable' flag from 'INIT' section during build.
    For example: ImageNtHeader -> patch -> ChecksumMappedFile -> flush on disk.
  • Absolutely Aleh, The checksum has to be fixed from PE optional header.

    Thanks to all, for the every info shared. Indeed it helped a lot to fix the concerns.
Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!