views:

108

answers:

2

I have a few libraries I use in my project that are unsigned. Because my application is strongly signed, the libraries must be as well.

I sign these libraries using:

"%PROGRAMFILES%\Microsoft SDKs\Windows\v7.1\Bin\ildasm.exe" /nobar /all /out=library.il library.dll
"%WINDIR%\Microsoft.NET\Framework64\v4.0.30319\ilasm.exe" /dll /key=MyKey.snk library.il

The problem is that any metadata, such as version numbers, get lost in the now-signed DLL. This is a problem because now some dependencies between the libraries are broken. How do I retain the version numbers without resorting to actually compiling the source code of those libraries?

UPDATE

It's actually a particular DLL that shows this problem and I've found out that is built using ILMerge. Perhaps this is causing the problem. Just to be clear: the DLL that is produced by ILMerge does have the proper metadata, only after disassembling and reassembling it, the metadata disappears.

UPDATE 2

I opened the DLL in Reflector and it appears that at least the version number is still there. I was checking using the file properties dialog/details tab in Windows Explorer all the time. So I figure it is the manifest that is missing instead.

+3  A: 

I'm wondering why this happens. I have quite good experience in round-trip compiling using ilasm and ildasm on unsigned and signed assemblies likewise. Can you verify the metadata output by ILasm still contains the version information (bottom of the assembly scope):

.assembly ConsoleApplication1
{
  //...
  .hash algorithm 0x00008004
  .ver 1:0:0:0
} 

Just checked again, it "works on my machine" (using the exact same commandline switches as you did).

What will actually be lost is the FileVersion attribute (the one you see in windows explorer when hovering over the assembly. The AssemblyVersion attribute is still present and correct. Could it be you're confusing the two? Only the AssemblyVersion is important for binding information. See this SO post for more info.

Hope I could help, otherwise you'd need to provide more context.

Johannes Rudolph
I've tried it again in an isolated environment and again all metadata disappears. In the generated IL file, I can see the version number at the bottom of the assembly scope, like you suggested. Meanwhile, I came to realize that perhaps the fact that this particular DLL is built using ILMerge is causing the problem.
Sandor Drieënhuizen
Have you checked the output of ILMerge? Basically I can't imagine it matters what happened to the assembly before, if the assembly version is present in ildasms output ilasm should handle it correctly.
Johannes Rudolph
I opened the DLL in Reflector and it appears that at least the version number is still there. I was checking using the file properties dialog/details tab in Windows Explorer all the time. So I figure it is the manifest that is missing instead. This should not have any influence on assembly binding, right?
Sandor Drieënhuizen
no, you should be fine as long as the AssemblyVersion is still present. Glad I could help.
Johannes Rudolph
+1  A: 

If you have the source code, then just recompile the libraries with strong names - disassembling and reassembling usually works pretty well, but it's still a hack.

To keep dependencies between the libraries working, you need to update the references in the .il code to use the public key of the assembly they are referencing, otherwise they will try to reference an unsigned version of the assembly, and thus fail to load it at runtime.

You can do this by hand, but it gets very tedious after 2 or 3 assemblies. A quick fix for this is signer, which deals with a lot of the difficulties involved for you, and does a great job - it's usually pretty quick and clean.

(Note that at present it's been built against an old .NET version. If you use C# 4/.NET 4 assemblies you'll need to download the source, change it to target .NET 4 and rebuild it to get a signer.exe that will correctly handle .NET 4 assemblies).

Jason Williams
In my case I'm running a script that downloads the latest source code of several interdependent libraries and compiles them in the right order, passing through the just compiled DLLs. That should circumvent the problem you describe concerning reference mismatches. Thanks for pointing out Signer by the way, looks very interesting. I'll give it a try.
Sandor Drieënhuizen