dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.25k stars 4.73k forks source link

System.Reflection.PortableExecutable: IMAGE_DLL_CHARACTERISTICS_GUARD_CF missing from DLLCharacteristics enum #71354

Closed sean-r-williams closed 2 years ago

sean-r-williams commented 2 years ago

Description

When parsing EXEs/DLLs using [System.Reflection.PortableExecutable.PEHeaders], images with Control Flow Guard enabled (DLL characteristic 0x4000 per https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#dll-characteristics) trigger unexpected behavior when attempting to parse/inspect the value of the .PEHeader.DllCharacteristics field.

The characteristic bit is set in the enum - as there's no corresponding flag for that bit, however, attempts to stringify it into something human-readable has no effect.

Reproduction Steps

This requires a CFG-enabled EXE/DLL (on my machine running Windows 11, cmd.exe fits this requirement) .

Using Powershell:

$cmdheaders = [System.Reflection.PortableExecutable.PEHeaders]::new([System.IO.FileStream]::new("C:\Windows\System32\cmd.exe", "Open", "read"))
$cmdheaders.PEHeader.DLLCharacteristics.ToString()

Expected behavior

Enum includes CFG flag (e.g. ControlFlowGuard) and is expressed in stringified output.

For example, if the inspected EXE has characteristic flags 0xc160 (as it does on my machine), string output would be HighEntropyVirtualAddressSpace, DynamicBase, NxCompatible, ControlFlowGuard, TerminalServerAware

Actual behavior

The aforementioned flag is missing, so calling .ToString() on the enum simply returns the string 49504.

Regression?

Unknown

Known Workarounds

The flag is still present and can be inspected using binary operators. No workaround exists for formatting, to my knowledge.

Configuration

Other information

No response

dotnet-issue-labeler[bot] commented 2 years ago

I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.

danmoseley commented 2 years ago

Modifying public API like this enum requires an API proposal. Could you please update the top post here to follow the general structure of an issue opened with this template? https://github.com/dotnet/runtime/issues/new?assignees=&labels=api-suggestion&template=02_api_proposal.yml&title=%5BAPI+Proposal%5D%3A+

then the owners of this area can if they wish mark it api-ready-for-review

danmoseley commented 2 years ago

or if it's easier you can just close this and create a new issue with that template.

sean-r-williams commented 2 years ago

Sure, I don't think I can add labels myself so I'll re-open a separate API proposal.

I wasn't sure if this required an API proposal as the example showed a more complex change than an enum update and previous commits to this file didn't appear to have one associated.

danmoseley commented 2 years ago

previous commits to this file didn't appear to have one associated.

If they added members to the enum, they apparently bypassed the process 😕 or predated it. Or maybe just didn't link to it.