diff --git a/Mono.Cecil.PE/Image.cs b/Mono.Cecil.PE/Image.cs index 109206187..97e69c010 100644 --- a/Mono.Cecil.PE/Image.cs +++ b/Mono.Cecil.PE/Image.cs @@ -25,9 +25,10 @@ sealed class Image : IDisposable { public string FileName; public ModuleKind Kind; + public uint Characteristics; public string RuntimeVersion; public TargetArchitecture Architecture; - public ModuleCharacteristics Characteristics; + public ModuleCharacteristics DllCharacteristics; public ushort LinkerVersion; public ushort SubSystemMajor; public ushort SubSystemMinor; diff --git a/Mono.Cecil.PE/ImageReader.cs b/Mono.Cecil.PE/ImageReader.cs index 84fdeb660..535812924 100644 --- a/Mono.Cecil.PE/ImageReader.cs +++ b/Mono.Cecil.PE/ImageReader.cs @@ -88,8 +88,9 @@ void ReadImage () ReadMetadata (); ReadDebugHeader (); + image.Characteristics = characteristics; image.Kind = GetModuleKind (characteristics, subsystem); - image.Characteristics = (ModuleCharacteristics) dll_characteristics; + image.DllCharacteristics = (ModuleCharacteristics) dll_characteristics; } TargetArchitecture ReadArchitecture () diff --git a/Mono.Cecil.PE/ImageWriter.cs b/Mono.Cecil.PE/ImageWriter.cs index 7e5e923de..a8a3fa82b 100644 --- a/Mono.Cecil.PE/ImageWriter.cs +++ b/Mono.Cecil.PE/ImageWriter.cs @@ -194,12 +194,18 @@ void WritePEFileHeader () WriteUInt32 (metadata.timestamp); WriteUInt32 (0); // PointerToSymbolTable WriteUInt32 (0); // NumberOfSymbols - WriteUInt16 (SizeOfOptionalHeader ()); // SizeOfOptionalHeader + WriteUInt16 (SizeOfOptionalHeader ()); // SizeOfOptionalHeader - // ExecutableImage | (pe64 ? 32BitsMachine : LargeAddressAware) - var characteristics = (ushort) (0x0002 | (!pe64 ? 0x0100 : 0x0020)); + const ushort LargeAddressAware = 0x0020; + + // ExecutableImage | (!pe64 ? 32BitsMachine : LargeAddressAware) + var characteristics = (ushort) (0x0002 | (!pe64 ? 0x0100 : LargeAddressAware)); if (module.Kind == ModuleKind.Dll || module.Kind == ModuleKind.NetModule) characteristics |= 0x2000; + + if (module.Image != null && (module.Image.Characteristics & LargeAddressAware) != 0) + characteristics |= LargeAddressAware; + WriteUInt16 (characteristics); // Characteristics } diff --git a/Mono.Cecil/ModuleDefinition.cs b/Mono.Cecil/ModuleDefinition.cs index 8fb35a540..b17f7c466 100644 --- a/Mono.Cecil/ModuleDefinition.cs +++ b/Mono.Cecil/ModuleDefinition.cs @@ -586,7 +586,7 @@ internal ModuleDefinition (Image image) this.RuntimeVersion = image.RuntimeVersion; this.architecture = image.Architecture; this.attributes = image.Attributes; - this.characteristics = image.Characteristics; + this.characteristics = image.DllCharacteristics; this.linker_version = image.LinkerVersion; this.subsystem_major = image.SubSystemMajor; this.subsystem_minor = image.SubSystemMinor; diff --git a/Test/Mono.Cecil.Tests/ImageReadTests.cs b/Test/Mono.Cecil.Tests/ImageReadTests.cs index de7a2ccdd..ef6ab06ff 100644 --- a/Test/Mono.Cecil.Tests/ImageReadTests.cs +++ b/Test/Mono.Cecil.Tests/ImageReadTests.cs @@ -100,6 +100,14 @@ public void X64Module () }, verify: !Platform.OnMono); } + [Test] + public void AnyCPU32BitPreferred () + { + TestModule ("anycpu32bitpreferred.exe", module => { + Assert.AreNotEqual (0, module.Image.Characteristics & 0x0020); + }); + } + [Test] public void X64ModuleTextOnlySection () { diff --git a/Test/Resources/assemblies/anycpu32bitpreferred.exe b/Test/Resources/assemblies/anycpu32bitpreferred.exe new file mode 100644 index 000000000..e758a7fce Binary files /dev/null and b/Test/Resources/assemblies/anycpu32bitpreferred.exe differ