Browse Source

#2198: Make ILSpy more resilient in case of obfuscated assemblies.

pull/2201/head
Siegfried Pammer 6 years ago
parent
commit
f0012cbc1a
  1. 14
      ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs
  2. 28
      ICSharpCode.Decompiler/Metadata/AssemblyReferences.cs
  3. 28
      ICSharpCode.Decompiler/Metadata/MetadataExtensions.cs
  4. 20
      ICSharpCode.Decompiler/TypeSystem/DecompilerTypeSystem.cs
  5. 23
      ICSharpCode.Decompiler/TypeSystem/MetadataModule.cs
  6. 6
      ILSpy/Languages/Language.cs
  7. 26
      ILSpy/LoadedAssembly.cs
  8. 4
      ILSpy/TreeNodes/AssemblyTreeNode.cs

14
ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs

@ -639,8 +639,18 @@ namespace ICSharpCode.Decompiler.Disassembler
string currentFullAssemblyName = null; string currentFullAssemblyName = null;
if (module.Metadata.IsAssembly) if (module.Metadata.IsAssembly)
{ {
currentAssemblyName = module.Metadata.GetString(module.Metadata.GetAssemblyDefinition().Name); try
currentFullAssemblyName = module.Metadata.GetFullAssemblyName(); {
currentAssemblyName = module.Metadata.GetString(module.Metadata.GetAssemblyDefinition().Name);
}
catch (BadImageFormatException)
{
currentAssemblyName = "<ERR: invalid assembly name>";
}
if (!module.Metadata.TryGetFullAssemblyName(out currentFullAssemblyName))
{
currentFullAssemblyName = "<ERR: invalid assembly name>";
}
} }
int count = blob.ReadCompressedInteger(); int count = blob.ReadCompressedInteger();
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)

28
ICSharpCode.Decompiler/Metadata/AssemblyReferences.cs

@ -185,8 +185,32 @@ namespace ICSharpCode.Decompiler.Metadata
public bool IsWindowsRuntime => (entry.Flags & AssemblyFlags.WindowsRuntime) != 0; public bool IsWindowsRuntime => (entry.Flags & AssemblyFlags.WindowsRuntime) != 0;
public bool IsRetargetable => (entry.Flags & AssemblyFlags.Retargetable) != 0; public bool IsRetargetable => (entry.Flags & AssemblyFlags.Retargetable) != 0;
public string Name => Metadata.GetString(entry.Name); public string Name {
public string FullName => entry.GetFullAssemblyName(Metadata); get {
try
{
return Metadata.GetString(entry.Name);
}
catch (BadImageFormatException)
{
return $"AR:{Handle}";
}
}
}
public string FullName {
get {
try
{
return entry.GetFullAssemblyName(Metadata);
}
catch (BadImageFormatException)
{
return $"fullname(AR:{Handle})";
}
}
}
public Version Version => entry.Version; public Version Version => entry.Version;
public string Culture => Metadata.GetString(entry.Culture); public string Culture => Metadata.GetString(entry.Culture);
byte[] IAssemblyReference.PublicKeyToken => GetPublicKeyToken(); byte[] IAssemblyReference.PublicKeyToken => GetPublicKeyToken();

28
ICSharpCode.Decompiler/Metadata/MetadataExtensions.cs

@ -78,6 +78,20 @@ namespace ICSharpCode.Decompiler.Metadata
$"PublicKeyToken={publicKey}"; $"PublicKeyToken={publicKey}";
} }
public static bool TryGetFullAssemblyName(this MetadataReader reader, out string assemblyName)
{
try
{
assemblyName = GetFullAssemblyName(reader);
return true;
}
catch (BadImageFormatException)
{
assemblyName = null;
return false;
}
}
public static string GetFullAssemblyName(this SRM.AssemblyReference reference, MetadataReader reader) public static string GetFullAssemblyName(this SRM.AssemblyReference reference, MetadataReader reader)
{ {
string publicKey = "null"; string publicKey = "null";
@ -101,6 +115,20 @@ namespace ICSharpCode.Decompiler.Metadata
$"PublicKeyToken={publicKey}{properties}"; $"PublicKeyToken={publicKey}{properties}";
} }
public static bool TryGetFullAssemblyName(this SRM.AssemblyReference reference, MetadataReader reader, out string assemblyName)
{
try
{
assemblyName = GetFullAssemblyName(reference, reader);
return true;
}
catch (BadImageFormatException)
{
assemblyName = null;
return false;
}
}
public static string ToHexString(this IEnumerable<byte> bytes, int estimatedLength) public static string ToHexString(this IEnumerable<byte> bytes, int estimatedLength)
{ {
if (bytes == null) if (bytes == null)

20
ICSharpCode.Decompiler/TypeSystem/DecompilerTypeSystem.cs

@ -185,17 +185,23 @@ namespace ICSharpCode.Decompiler.TypeSystem
var mainMetadata = mainModule.Metadata; var mainMetadata = mainModule.Metadata;
foreach (var h in mainMetadata.GetModuleReferences()) foreach (var h in mainMetadata.GetModuleReferences())
{ {
var moduleRef = mainMetadata.GetModuleReference(h); try
var moduleName = mainMetadata.GetString(moduleRef.Name);
foreach (var fileHandle in mainMetadata.AssemblyFiles)
{ {
var file = mainMetadata.GetAssemblyFile(fileHandle); var moduleRef = mainMetadata.GetModuleReference(h);
if (mainMetadata.StringComparer.Equals(file.Name, moduleName) && file.ContainsMetadata) var moduleName = mainMetadata.GetString(moduleRef.Name);
foreach (var fileHandle in mainMetadata.AssemblyFiles)
{ {
assemblyReferenceQueue.Enqueue((false, mainModule, moduleName)); var file = mainMetadata.GetAssemblyFile(fileHandle);
break; if (mainMetadata.StringComparer.Equals(file.Name, moduleName) && file.ContainsMetadata)
{
assemblyReferenceQueue.Enqueue((false, mainModule, moduleName));
break;
}
} }
} }
catch (BadImageFormatException)
{
}
} }
foreach (var refs in mainModule.AssemblyReferences) foreach (var refs in mainModule.AssemblyReferences)
{ {

23
ICSharpCode.Decompiler/TypeSystem/MetadataModule.cs

@ -63,13 +63,28 @@ namespace ICSharpCode.Decompiler.TypeSystem
if (metadata.IsAssembly) if (metadata.IsAssembly)
{ {
var asmdef = metadata.GetAssemblyDefinition(); var asmdef = metadata.GetAssemblyDefinition();
this.AssemblyName = metadata.GetString(asmdef.Name); try
this.FullAssemblyName = metadata.GetFullAssemblyName(); {
this.AssemblyName = metadata.GetString(asmdef.Name);
this.FullAssemblyName = metadata.GetFullAssemblyName();
}
catch (BadImageFormatException)
{
this.AssemblyName = "<ERR: invalid assembly name>";
this.FullAssemblyName = "<ERR: invalid assembly name>";
}
} }
else else
{ {
var moddef = metadata.GetModuleDefinition(); try
this.AssemblyName = metadata.GetString(moddef.Name); {
var moddef = metadata.GetModuleDefinition();
this.AssemblyName = metadata.GetString(moddef.Name);
}
catch (BadImageFormatException)
{
this.AssemblyName = "<ERR: invalid assembly name>";
}
this.FullAssemblyName = this.AssemblyName; this.FullAssemblyName = this.AssemblyName;
} }
var customAttrs = metadata.GetModuleDefinition().GetCustomAttributes(); var customAttrs = metadata.GetModuleDefinition().GetCustomAttributes();

6
ILSpy/Languages/Language.cs

@ -142,9 +142,13 @@ namespace ICSharpCode.ILSpy
{ {
WriteCommentLine(output, metadata.GetString(name.Name) + " [WinRT]"); WriteCommentLine(output, metadata.GetString(name.Name) + " [WinRT]");
} }
else if (metadata.TryGetFullAssemblyName(out string assemblyName))
{
WriteCommentLine(output, assemblyName);
}
else else
{ {
WriteCommentLine(output, metadata.GetFullAssemblyName()); WriteCommentLine(output, "ERR: Could not read assembly name");
} }
} }
else else

26
ILSpy/LoadedAssembly.cs

@ -378,16 +378,24 @@ namespace ICSharpCode.ILSpy
{ {
foreach (LoadedAssembly loaded in assemblyList.GetAssemblies()) foreach (LoadedAssembly loaded in assemblyList.GetAssemblies())
{ {
var module = loaded.GetPEFileOrNull(); try
var reader = module?.Metadata;
if (reader == null || !reader.IsAssembly)
continue;
var asmDef = reader.GetAssemblyDefinition();
var asmDefName = loaded.GetTargetFrameworkIdAsync().Result + ";" + (isWinRT ? reader.GetString(asmDef.Name) : reader.GetFullAssemblyName());
if (key.Equals(asmDefName, StringComparison.OrdinalIgnoreCase))
{ {
LoadedAssemblyReferencesInfo.AddMessageOnce(fullName.FullName, MessageKind.Info, "Success - Found in Assembly List"); var module = loaded.GetPEFileOrNull();
return loaded; var reader = module?.Metadata;
if (reader == null || !reader.IsAssembly)
continue;
var asmDef = reader.GetAssemblyDefinition();
var asmDefName = loaded.GetTargetFrameworkIdAsync().Result + ";"
+ (isWinRT ? reader.GetString(asmDef.Name) : reader.GetFullAssemblyName());
if (key.Equals(asmDefName, StringComparison.OrdinalIgnoreCase))
{
LoadedAssemblyReferencesInfo.AddMessageOnce(fullName.FullName, MessageKind.Info, "Success - Found in Assembly List");
return loaded;
}
}
catch (BadImageFormatException)
{
continue;
} }
} }

4
ILSpy/TreeNodes/AssemblyTreeNode.cs

@ -96,10 +96,10 @@ namespace ICSharpCode.ILSpy.TreeNodes
tooltip = new TextBlock(); tooltip = new TextBlock();
var module = LoadedAssembly.GetPEFileOrNull(); var module = LoadedAssembly.GetPEFileOrNull();
var metadata = module?.Metadata; var metadata = module?.Metadata;
if (metadata?.IsAssembly == true) if (metadata?.IsAssembly == true && metadata.TryGetFullAssemblyName(out var assemblyName))
{ {
tooltip.Inlines.Add(new Bold(new Run("Name: "))); tooltip.Inlines.Add(new Bold(new Run("Name: ")));
tooltip.Inlines.Add(new Run(metadata.GetFullAssemblyName())); tooltip.Inlines.Add(new Run(assemblyName));
tooltip.Inlines.Add(new LineBreak()); tooltip.Inlines.Add(new LineBreak());
} }
tooltip.Inlines.Add(new Bold(new Run("Location: "))); tooltip.Inlines.Add(new Bold(new Run("Location: ")));

Loading…
Cancel
Save