InlineIL.Fody: Invalid assembly after weaving
Not sure if this is an InlineIL.Fody, Fody or Mono.Cecil bug.
Repro: https://github.com/CosmosOS/Cosmos/tree/inline-il
The verification fails, and if I try to load the assembly at runtime it fails with BadImageFormatException. ILSpy loads it correctly.
I tried adding ExcludeAssets="All" here: Cosmos.Core_Asm.csproj#L13, and then used ildasm on both assemblies, and the main difference (ignoring the parts which were not weaved) is the .imagebase, which is 0x00400000 when weaved, and 0x10000000 when not.
Any help would be appreciated.
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Comments: 16 (9 by maintainers)
That was a hack to support a niche edge case I once had. To do with mixing signed and unsigned dlls when using ilmerge. That use case is no longer valid and that property copy could be removed
Yay \o/
Indeed, I can see that Cosmos sets
SignAssemblyin the “targets” file. Glad you got it figured out.@SimonCropp why does Fody copy
SignAssemblytoFodySignAssemblyinFody.targets? The commit that introduces this change only says “perf hacks”…@jp2masa FYI this should be fixed in Fody v3.2.10
I found the problem:
SignAssemblyis being set toTrueafter Fody “captures” its value onFodySignAssembly, so the assembly was being signed by the compiler, but not by Fody.Thanks for the help!
Some other stuff: in
IMAGE_COR20_HEADER,StrongNameSignature.VirtualAddressandStrongNameSignature.Sizeare both zero in the weaved assembly. That doesn’t look right either, but when I round-trip the dll through dnSpy, PEVerify happily loads it. After round-tripping, these headers are nonzero. So that looks like a decent clue.I added a strong name to my isolated project, and these fields are nonzero in the build output. Everything works fine there.
This definitely starts to look like a strong naming issue. Maybe Fody can’t find the key file for some reason.
Could you please do the following? This could help me pinpoint the issue.
msbuild Cosmos.Core_Asm.csproj /p:Configuration=Release /t:Restore,Rebuild /bl:output.binlog(if the broject doesn’t build well as standalone, build the whole solution instead)I’ll take a look at it tomorrow.
Ok, so here’s a first quick analysis.
Here’s a dnSpy dump of both files’ headers, if you want to diff them:
Not weaved
Weaved
Major differences: non weaved -> weaved
IMAGE_FILE_HEADER.Characteristics: Non weaved:ExecutableImage, LargeAddressAware, DLLWeaved:ExecutableImage, 32BitMachine, DLLThat 32BitMachine bit should not be there in an MSIL assembly.IMAGE_OPTIONAL_HEADER32.ImageBase: Non weaved:10000000Weaved:00400000This is what you noticed.IMAGE_OPTIONAL_HEADER32.CheckSum: Non weaved:00015FEFWeaved:00000000Ok, so this one seems really bad, but actually Cecil hardcodes zero here, as the docs say:I thought the first one was the issue, but then I compared that to a known good netstandard2.0 assembly that uses InlineIL, and the values match. Actually, it’s Cecil that encodes this header like so.
I’l keep looking at this.