You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Assemblies created with AsmResolver seem to have invalid custom attribute blobs. Several problems were noticed when loading generated assemblies into popular .NET decompilers.
How To Reproduce
The bug was initially noticed in an assembly created by Cpp2IL with the latest NuGet version of AsmResolver. Although I cannot be sure that the 5.0 beta versions were without issue, I only noticed this in the full release.
In ILSpy 8 Preview 3, the assembly attributes are decoded like this:
using System.Diagnostics;using System.Reflection;using System.Runtime.CompilerServices;[assembly:CompilationRelaxations(/*Could not decode attribute arguments.*/)][assembly:RuntimeCompatibility][assembly:Debuggable(/*Could not decode attribute arguments.*/)][assembly:InternalsVisibleTo(/*Could not decode attribute arguments.*/)][assembly:InternalsVisibleTo(/*Could not decode attribute arguments.*/)][assembly:AssemblyVersion("0.0.0.0")]
Similarly, dnSpyEx decompiles the assembly attributes as:
using System;using System.Diagnostics;using System.Reflection;using System.Runtime.CompilerServices;[assembly:AssemblyVersion("0.0.0.0")][assembly:CompilationRelaxations][assembly:RuntimeCompatibility][assembly:Debuggable][assembly:InternalsVisibleTo][assembly:InternalsVisibleTo]
However, not all cases are handled so cleanly. Attempting to view `` in ILSpy throws an exception:
System.BadImageFormatException: Read out of bounds.
at System.Reflection.Throw.OutOfBounds()
at System.Reflection.Metadata.Ecma335.CustomAttributeDecoder`1.DecodeNamedArguments(BlobReader& valueReader)
at System.Reflection.Metadata.Ecma335.CustomAttributeDecoder`1.DecodeValue(EntityHandle constructor, BlobHandle value)
at ICSharpCode.Decompiler.TypeSystem.MetadataModule.GetInternalsVisibleTo() in /_/ICSharpCode.Decompiler/TypeSystem/MetadataModule.cs:line 176
at ICSharpCode.Decompiler.TypeSystem.MetadataModule.InternalsVisibleTo(IModule module) in /_/ICSharpCode.Decompiler/TypeSystem/MetadataModule.cs:line 151
at ICSharpCode.Decompiler.CSharp.Resolver.CSharpResolver.LookInCurrentUsingScope(String identifier, IReadOnlyList`1 typeArguments, Boolean isInUsingDeclaration, Boolean parameterizeResultType) in /_/ICSharpCode.Decompiler/CSharp/Resolver/CSharpResolver.cs:line 1728
at ICSharpCode.Decompiler.CSharp.Resolver.CSharpResolver.LookupSimpleNameOrTypeName(String identifier, IReadOnlyList`1 typeArguments, NameLookupMode lookupMode) in /_/ICSharpCode.Decompiler/CSharp/Resolver/CSharpResolver.cs:line 1609
at ICSharpCode.Decompiler.CSharp.Syntax.TypeSystemAstBuilder.ConvertTypeHelper(IType genericType, IReadOnlyList`1 typeArguments) in /_/ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs:line 506
at ICSharpCode.Decompiler.CSharp.Syntax.TypeSystemAstBuilder.ConvertTypeHelper(IType type) in /_/ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs:line 424
at ICSharpCode.Decompiler.CSharp.Syntax.TypeSystemAstBuilder.ConvertType(IType type) in /_/ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs:line 238
at ICSharpCode.Decompiler.CSharp.Transforms.IntroduceUsingDeclarations.FullyQualifyAmbiguousTypeNamesVisitor.VisitSimpleType(SimpleType simpleType) in /_/ICSharpCode.Decompiler/CSharp/Transforms/IntroduceUsingDeclarations.cs:line 319
at ICSharpCode.Decompiler.CSharp.Syntax.DepthFirstAstVisitor.VisitChildren(AstNode node) in /_/ICSharpCode.Decompiler/CSharp/Syntax/DepthFirstAstVisitor.cs:line 43
at ICSharpCode.Decompiler.CSharp.Syntax.DepthFirstAstVisitor.VisitChildren(AstNode node) in /_/ICSharpCode.Decompiler/CSharp/Syntax/DepthFirstAstVisitor.cs:line 43
at ICSharpCode.Decompiler.CSharp.Transforms.IntroduceUsingDeclarations.FullyQualifyAmbiguousTypeNamesVisitor.Visit[T](T entityDeclaration, Action`1 baseCall) in /_/ICSharpCode.Decompiler/CSharp/Transforms/IntroduceUsingDeclarations.cs:line 289
at ICSharpCode.Decompiler.CSharp.Syntax.DepthFirstAstVisitor.VisitChildren(AstNode node) in /_/ICSharpCode.Decompiler/CSharp/Syntax/DepthFirstAstVisitor.cs:line 43
at ICSharpCode.Decompiler.CSharp.Transforms.IntroduceUsingDeclarations.FullyQualifyAmbiguousTypeNamesVisitor.VisitTypeDeclaration(TypeDeclaration typeDeclaration) in /_/ICSharpCode.Decompiler/CSharp/Transforms/IntroduceUsingDeclarations.cs:line 226
at ICSharpCode.Decompiler.CSharp.Syntax.DepthFirstAstVisitor.VisitChildren(AstNode node) in /_/ICSharpCode.Decompiler/CSharp/Syntax/DepthFirstAstVisitor.cs:line 43
at ICSharpCode.Decompiler.CSharp.Transforms.IntroduceUsingDeclarations.Run(AstNode rootNode, TransformContext context) in /_/ICSharpCode.Decompiler/CSharp/Transforms/IntroduceUsingDeclarations.cs:line 73
at ICSharpCode.Decompiler.CSharp.CSharpDecompiler.RunTransforms(AstNode rootNode, DecompileRun decompileRun, ITypeResolveContext decompilationContext) in /_/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs:line 564
at ICSharpCode.Decompiler.CSharp.CSharpDecompiler.Decompile(IEnumerable`1 definitions) in /_/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs:line 1088
at ICSharpCode.Decompiler.CSharp.CSharpDecompiler.Decompile(EntityHandle[] definitions) in /_/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs:line 1004
at ICSharpCode.ILSpy.CSharpLanguage.DecompileType(ITypeDefinition type, ITextOutput output, DecompilationOptions options)
at ICSharpCode.ILSpy.TreeNodes.TypeTreeNode.Decompile(Language language, ITextOutput output, DecompilationOptions options)
at ICSharpCode.ILSpy.TextView.DecompilerTextView.DecompileNodes(DecompilationContext context, ITextOutput textOutput)
at ICSharpCode.ILSpy.TextView.DecompilerTextView.<>c__DisplayClass52_0.<DecompileAsync>b__0()
dnSpyEx handles any problems silently and prints the following code:
using System;using UnityEngine;using UnityEngine.TextCore.LowLevel;namespaceTMPro{[Serializable]publicclassTMP_GlyphPairAdjustmentRecord{publicTMP_GlyphAdjustmentRecordfirstAdjustmentRecord{get{returndefault(TMP_GlyphAdjustmentRecord);}set{}}publicTMP_GlyphAdjustmentRecordsecondAdjustmentRecord{get{returndefault(TMP_GlyphAdjustmentRecord);}set{}}publicFontFeatureLookupFlagsfeatureLookupFlags{get{return(FontFeatureLookupFlags)0;}set{}}publicTMP_GlyphPairAdjustmentRecord(TMP_GlyphAdjustmentRecordfirstAdjustmentRecord,TMP_GlyphAdjustmentRecordsecondAdjustmentRecord){}internalTMP_GlyphPairAdjustmentRecord(GlyphPairAdjustmentRecordglyphPairAdjustmentRecord){}[SerializeField]privateTMP_GlyphAdjustmentRecordm_FirstAdjustmentRecord;[SerializeField]privateTMP_GlyphAdjustmentRecordm_SecondAdjustmentRecord;[SerializeField]privateFontFeatureLookupFlagsm_FeatureLookupFlags;}}
Expected Behavior
The assemblies should be valid enough for decompilers to properly load and analyze them.
Actual Behavior
The decompilers fail to load custom attribute blobs.
Additional Context
No response
The text was updated successfully, but these errors were encountered:
As discussed in discord, this was caused by invalid input to AsmResolver which propagated into its output. Cpp2IL couldn't decode custom attributes on my Unity version, so it has nothing to fill attribute constructor parameters with. Instead of providing a default value for each parameter, Cpp2IL gave it nothing and caused this issue to occur. It would be nice if AsmResolver was able to provide some validation for custom attributes.
AsmResolver Version
5.0.0
.NET Version
.NET 6
Operating System
Windows
Describe the Bug
Assemblies created with AsmResolver seem to have invalid custom attribute blobs. Several problems were noticed when loading generated assemblies into popular .NET decompilers.
How To Reproduce
The bug was initially noticed in an assembly created by Cpp2IL with the latest NuGet version of AsmResolver. Although I cannot be sure that the 5.0 beta versions were without issue, I only noticed this in the full release.
In ILSpy 8 Preview 3, the assembly attributes are decoded like this:
Similarly, dnSpyEx decompiles the assembly attributes as:
However, not all cases are handled so cleanly. Attempting to view `` in ILSpy throws an exception:
dnSpyEx handles any problems silently and prints the following code:
Expected Behavior
The assemblies should be valid enough for decompilers to properly load and analyze them.
Actual Behavior
The decompilers fail to load custom attribute blobs.
Additional Context
No response
The text was updated successfully, but these errors were encountered: