dotnet / runtime

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

[API Proposal]: Align System.Reflection.PortableExecutable.DllCharacteristics with PE spec #71362

Closed sean-r-williams closed 1 year ago

sean-r-williams commented 2 years ago

Background and motivation

The current PE header parsing functionality in System.Reflection.Metadata lacks two DLL characteristic flags as described in the PE format specification:

Not having these flags supported within the .NET PE header parser causes confusing functionality when attempting to parse EXEs/DLLs that have these flags set (for example, stringification of the enum value will simply output an integer instead of a comma-separated list).

Adding these two fields ensures that the parser in this assembly can handle all combinations of PE flags seen in the wild.

API Proposal

 namespace System.Reflection.PortableExecutable {

     public enum DllCharacteristics : ushort {

+        ForceIntegrity = 0x0080,
+        ControlFlowGuard = 0x4000

     }

 }

API Usage

// Fancy the value
var sr = new FileStream("C:\Windows\system32\cmd.exe", FileMode.Open, FileAccess.Read);
var headers = new PEHeaders(sr);

// write DLL characteristics to stdout
Console.WriteLine(headers.PEHeader.DllCharacteristics);

Alternative Designs

I formed the enum names based on the [expanded] names of the PE-spec constants. It's possible that the names might need slight adjustment to comply with naming requirements in the Framework Design Guidelines.

Risks

There are 4 reserved-usage DLL characteristic flags in the PE spec and one unspecified flag (0x0010) that may need to be added to this enum at a later date, but to my knowledge there isn't any usage of these flags at the moment.

ghost commented 2 years ago

Tagging subscribers to this area: @dotnet/area-system-reflection-metadata See info in area-owners.md if you want to be subscribed.

Issue Details
### Background and motivation The current PE header parsing functionality in System.Reflection.Metadata lacks two DLL characteristic flags as described in the [PE format specification](https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#dll-characteristics): * `IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY` (0x0080) * `IMAGE_DLLCHARACTERISTICS_GUARD_CF` (0x4000) Not having these flags supported within the .NET PE header parser causes confusing functionality when attempting to parse EXEs/DLLs that have these flags set (for example, stringification of the enum value will simply output an integer instead of a comma-separated list). Adding these two fields ensures that the parser in this assembly can handle all combinations of PE flags seen in the wild. ### API Proposal ```diff namespace System.Reflection.PortableExecutable { public enum DllCharacteristics : ushort { + ForceIntegrity = 0x0080, + ControlFlowGuard = 0x4000 } } ``` ### API Usage ```csharp // Fancy the value var sr = new FileStream("C:\Windows\system32\cmd.exe", FileMode.Open, FileAccess.Read); var headers = new PEHeaders(sr); // write DLL characteristics to stdout Console.WriteLine(headers.PEHeader.DllCharacteristics); ``` ### Alternative Designs I formed the enum names based on the [expanded] names of the PE-spec constants. It's possible that the names might need slight adjustment to comply with naming requirements in the Framework Design Guidelines - ### Risks There are 4 reserved-usage DLL characteristic flags in the PE spec and one unspecified flag (0x0010) that may need to be added to this enum at a later date, but to my knowledge there isn't any usage of these flags at the moment.
Author: sewillia-msft
Assignees: -
Labels: `api-suggestion`, `area-System.Reflection.Metadata`
Milestone: -
steveharter commented 1 year ago

Looks good; adding to 8.0 to update https://learn.microsoft.com/en-us/dotnet/api/system.reflection.portableexecutable.dllcharacteristics

terrajobst commented 1 year ago

Video

namespace System.Reflection.PortableExecutable;

public enum DllCharacteristics : ushort
{
    // Existing values
    ForceIntegrity = 0x0080,
    ControlFlowGuard = 0x4000
}