ILSpy icon indicating copy to clipboard operation
ILSpy copied to clipboard

ilspycmd: Add support for Xamarin compressed DLLs

Open Techbrunch opened this issue 3 years ago • 10 comments

Steps to reproduce

ilspycmd -p -o test Test.dll

Error message shown

System.BadImageFormatException: Image is too small.
   at System.Reflection.Throw.ImageTooSmall()
   at System.Reflection.PortableExecutable.SectionHeader..ctor(PEBinaryReader& reader)
   at System.Reflection.PortableExecutable.PEHeaders.ReadSectionHeaders(PEBinaryReader& reader)
   at System.Reflection.PortableExecutable.PEHeaders..ctor(Stream peStream, Int32 size, Boolean isLoadedImage)
   at System.Reflection.PortableExecutable.PEReader.InitializePEHeaders()
   at System.Reflection.PortableExecutable.PEReader.get_HasMetadata()
   at ICSharpCode.Decompiler.Metadata.PEFile..ctor(String fileName, PEReader reader, MetadataReaderOptions metadataOptions)
   at ICSharpCode.Decompiler.Metadata.PEFile..ctor(String fileName, Stream stream, PEStreamOptions streamOptions, MetadataReaderOptions metadataOptions)
   at ICSharpCode.Decompiler.Metadata.UniversalAssemblyResolver.Resolve(IAssemblyReference name)
   at ICSharpCode.Decompiler.TypeSystem.DecompilerTypeSystem..ctor(PEFile mainModule, IAssemblyResolver assemblyResolver, TypeSystemOptions typeSystemOptions)
   at ICSharpCode.Decompiler.TypeSystem.DecompilerTypeSystem..ctor(PEFile mainModule, IAssemblyResolver assemblyResolver, DecompilerSettings settings)
   at ICSharpCode.Decompiler.CSharp.ProjectDecompiler.WholeProjectDecompiler.WriteCodeFilesInProject(PEFile module, CancellationToken cancellationToken)
   at ICSharpCode.Decompiler.CSharp.ProjectDecompiler.WholeProjectDecompiler.DecompileProject(PEFile moduleDefinition, String targetDirectory, TextWriter projectFileWriter, CancellationToken cancellationToken)
   at ICSharpCode.Decompiler.CSharp.ProjectDecompiler.WholeProjectDecompiler.DecompileProject(PEFile moduleDefinition, String targetDirectory, CancellationToken cancellationToken)
   at ICSharpCode.Decompiler.Console.ILSpyCmdProgram.DecompileAsProject(String assemblyFileName, String outputDirectory) in D:\GitWorkspace\ILSpy\ICSharpCode.Decompiler.Console\IlspyCmdProgram.cs:line 186
   at ICSharpCode.Decompiler.Console.ILSpyCmdProgram.OnExecute(CommandLineApplication app) in D:\GitWorkspace\ILSpy\ICSharpCode.Decompiler.Console\IlspyCmdProgram.cs:line 83

Details

  • Tested with : ilspycmd (6.2.0.6124 and 7.0.0.6372-preview3)
  • Tested on macOS Big Sur 11.2.2
  • The DLL final comes from a Xamarin App and was first decompressed (lz4) using a Python script (if needed I can send you the DLL on your Gmail)
  • On Windows the DLL is decompiled without any issues

If you need more info let me know.

Techbrunch avatar Apr 01 '21 22:04 Techbrunch

I am pretty sure Siegi can't repro the problem without the assembly, so please send it to him. Just to make sure: ilspycmd on Mac didn't work, ilspycmd on Windows worked? Or is it ILSpy on Windows worked?

christophwille avatar Apr 02 '21 08:04 christophwille

Hi @christophwille,

thanks, I'll send the DLL to Siegi. I forgot to specify in my last message that it worked on Windows using dotBeek by JetBrains.

Techbrunch avatar Apr 02 '21 12:04 Techbrunch

Thanks for sending the file! Sorry, currently I don't have time to look at it, but I will try to follow up as soon as possible.

siegfriedpammer avatar Apr 08 '21 12:04 siegfriedpammer

Thanks for taking the time to investigate. I'll answer your email here since it might be helpful to someone else and probably future me :)

The problem is related to a file on your system, which the decompiler is trying to load as a reference. However, it then crashes, because the file it is trying to load is not a valid managed DLL.

Yes now it makes sense, the context is that I was trying to decompile a DLL coming from a Xamarin app but I only decompressed one DLL (cf: #2137, #1637). which is probably referencing other DLL that I did not decompress in the same folder.

Have you tried running the command with the bug.dll being in a separate directory?

Doing this resulted in another error but I'm guessing this is to be expected and my file was correctly decompiled:

System.NotSupportedException: Cannot decompile this assembly to a SDK style project. Use default project format instead.
   at ICSharpCode.Decompiler.CSharp.ProjectDecompiler.ProjectFileWriterSdkStyle.WriteAssemblyInfo(XmlTextWriter xml, PEFile module, IProjectInfoProvider project, ProjectType projectType)
   at ICSharpCode.Decompiler.CSharp.ProjectDecompiler.ProjectFileWriterSdkStyle.<>c__DisplayClass10_0.<Write>b__0()
   at ICSharpCode.Decompiler.CSharp.ProjectDecompiler.ProjectFileWriterSdkStyle.PlaceIntoTag(String tagName, XmlTextWriter xml, Action content)
   at ICSharpCode.Decompiler.CSharp.ProjectDecompiler.ProjectFileWriterSdkStyle.Write(XmlTextWriter xml, IProjectInfoProvider project, IEnumerable`1 files, PEFile module)
   at ICSharpCode.Decompiler.CSharp.ProjectDecompiler.ProjectFileWriterSdkStyle.Write(TextWriter target, IProjectInfoProvider project, IEnumerable`1 files, PEFile module)
   at ICSharpCode.Decompiler.CSharp.ProjectDecompiler.WholeProjectDecompiler.DecompileProject(PEFile moduleDefinition, String targetDirectory, TextWriter projectFileWriter, CancellationToken cancellationToken)
   at ICSharpCode.Decompiler.CSharp.ProjectDecompiler.WholeProjectDecompiler.DecompileProject(PEFile moduleDefinition, String targetDirectory, CancellationToken cancellationToken)
   at ICSharpCode.Decompiler.Console.ILSpyCmdProgram.DecompileAsProject(String assemblyFileName, String outputDirectory) in D:\GitWorkspace\ILSpy\ICSharpCode.Decompiler.Console\IlspyCmdProgram.cs:line 193
   at ICSharpCode.Decompiler.Console.ILSpyCmdProgram.OnExecute(CommandLineApplication app) in D:\GitWorkspace\ILSpy\ICSharpCode.Decompiler.Console\IlspyCmdProgram.cs:line 86

Let me know if I need to create an issue for this error.

I have added some fixes/additions to the decompiler to make debugging such problems easier. However, there is currently no precompiled ilspycmd.exe for you to download. Could you try compiling ILSpy on your machine and then using a debug build to investigate the issue further? Thank you!

I'm don't know how to do that. I installed ilspycmdon my mac using:

dotnet tool update ilspycmd -g --version 7.0.0.6372-preview3

Can I get the master nuget package from the CI ? If so I should be able to install it locally.

On #2137 you mentionned you said about decompilling DLL coming from Xamarin apps:

Unless support for these is contributed, it won't happen.

I might give it a try but I have no idea how hard it would be to implement. Could you give me some pointer on how someone would go about adding this feature ? Could this be done with a plugin ? If it's too much work don't worry I'll keep using the python script ;)

Techbrunch avatar Apr 16 '21 20:04 Techbrunch

Found this issue but no further information, what the content of the python script was. Apparently it is a newly introduced compression using lz4. First 12 bytes are metadata, 8-12 is the uncompressed length, remaining bytes after that are the compressed data: https://www.x41-dsec.de/security/news/working/research/2020/09/22/xamarin-dll-decompression/

gravityFlower avatar Oct 05 '21 13:10 gravityFlower

I think the main issue here was already fixed in #2137. The open request here is adding support for compressed DLLs to ilspycmd as well.

siegfriedpammer avatar Dec 26 '21 17:12 siegfriedpammer

I am currently trying to reproduce XALZ DLLs in order to be able to test the feature properly. I am following the steps listed here, but I cannot create XALZ DLLs using VS 2022. The only thing I get is an assemblies.blob file inside the apk, which starts with the sequence "XABA" and probably contains multiple compressed assemblies. @Techbrunch @gravityFlower @jingliancui I would really appreciate your help with this, as I have not much experience with Xamarin.Forms projects. Thank you very much!

siegfriedpammer avatar Apr 19 '22 19:04 siegfriedpammer

Have a look at this: https://github.com/xamarin/xamarin-android/tree/main/tools/assembly-store-reader

developerfromjokela avatar Oct 18 '22 21:10 developerfromjokela

Glad that I can help you. Maybe this week later. I try to write some reproduce steps for you.

jingliancui avatar Oct 19 '22 02:10 jingliancui

I think the newest version of ilspy from MS Store is perfectly solve this problem. The newest version of xamarin.android use "Embedded assemblies store", refer this link:https://learn.microsoft.com/en-us/xamarin/android/release-notes/12/12.2

So if we want to disable this feature, just add this node to csproj file: <AndroidUseAssemblyStore>false</AndroidUseAssemblyStore>

jingliancui avatar Oct 21 '22 06:10 jingliancui