ILSpy,如何解决依赖关系?
我想使用 ILSpy 反汇编整个 .NET 程序集。
我使用此代码作为基础:
http://skysigal.xact-solutions.com/Blog /tabid/427/entryid/2488/Default.aspx
它工作正常,就在我有一个引用 Npgsql.dll (或任何其他非 gac 程序集),然后我得到 AssemblyResolutionException。
无法解析程序集:'Npgsql,Version=2.0.11.92,Culture=neutral,PublicKeyToken=5d8b90d52f46fda7'
我知道如何获取引用的程序集,但如何将它们添加到 ast ?
// SqlWebAdmin.Models.Decompiler.DecompileAssembly("xy.dll");
public static string DecompileAssembly(string pathToAssembly)
{
//Assembly assembly = Assembly.LoadFrom(pathToAssembly);
System.Reflection.Assembly assembly = System.Reflection.Assembly.ReflectionOnlyLoadFrom(pathToAssembly);
//assembly.GetReferencedAssemblies();
//assembly.GetReferencedAssemblies(assembly);
Mono.Cecil.AssemblyDefinition assemblyDefinition =
Mono.Cecil.AssemblyDefinition.ReadAssembly(pathToAssembly);
ICSharpCode.Decompiler.Ast.AstBuilder astBuilder = new ICSharpCode.Decompiler.Ast.AstBuilder(new ICSharpCode.Decompiler.DecompilerContext(assemblyDefinition.MainModule));
astBuilder.AddAssembly(assemblyDefinition);
//new Helpers.RemoveCompilerAttribute().Run(decompiler.CompilationUnit);
using (System.IO.StringWriter output = new System.IO.StringWriter())
{
astBuilder.GenerateCode(new ICSharpCode.Decompiler.PlainTextOutput(output));
string result = output.ToString();
return result;
}
return "";
} // End Function DecompileAssembly
I want to disassemble an entire .NET assembly with ILSpy.
I used this code as base:
http://skysigal.xact-solutions.com/Blog/tabid/427/entryid/2488/Default.aspx
And it works fine, just when I have an assembly that references Npgsql.dll (or any other non-gac assembly), then I get an AssemblyResolutionException.
Failed to resolve assembly: 'Npgsql, Version=2.0.11.92, Culture=neutral, PublicKeyToken=5d8b90d52f46fda7'
I know how I can get the referenced assemblies, but how can I add them to ast ?
// SqlWebAdmin.Models.Decompiler.DecompileAssembly("xy.dll");
public static string DecompileAssembly(string pathToAssembly)
{
//Assembly assembly = Assembly.LoadFrom(pathToAssembly);
System.Reflection.Assembly assembly = System.Reflection.Assembly.ReflectionOnlyLoadFrom(pathToAssembly);
//assembly.GetReferencedAssemblies();
//assembly.GetReferencedAssemblies(assembly);
Mono.Cecil.AssemblyDefinition assemblyDefinition =
Mono.Cecil.AssemblyDefinition.ReadAssembly(pathToAssembly);
ICSharpCode.Decompiler.Ast.AstBuilder astBuilder = new ICSharpCode.Decompiler.Ast.AstBuilder(new ICSharpCode.Decompiler.DecompilerContext(assemblyDefinition.MainModule));
astBuilder.AddAssembly(assemblyDefinition);
//new Helpers.RemoveCompilerAttribute().Run(decompiler.CompilationUnit);
using (System.IO.StringWriter output = new System.IO.StringWriter())
{
astBuilder.GenerateCode(new ICSharpCode.Decompiler.PlainTextOutput(output));
string result = output.ToString();
return result;
}
return "";
} // End Function DecompileAssembly
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您需要告诉 ILSpy 正在使用的底层元数据读取器 Cecil,您的程序集在哪里。您可以这样写:
这是告诉 Cecil 在何处解析引用的程序集的最自然方式。这样,您可以删除使用 System.Reflection 加载程序集的行,并且仅使用 ILSpy 堆栈。
You need to tell Cecil, the underlying metadata reader that ILSpy is using, where your assemblies are. You can write:
This is the most natural way to tell Cecil where to resolve referenced assemblies. This way you can remove the line where you load the assembly using System.Reflection, and only use the ILSpy stack.
这是改进的@Nayan 答案。如果您想忽略丢失的程序集,请复制此类:
并像这样使用它:
This is improved @Nayan answer. If you want to ignore missing assemblies, copy this class:
and use it like that:
除了 JB Evain 的建议之外,此代码将有助于避免异常。您所要做的就是在解析器中处理异常。
我承认这不是最好的方法。但它适用于这种情况:
“如果我在不存在引用的程序集的系统上反编译 DLL,则反编译会失败(有例外)。至少,我希望看到反编译代码,无论是什么已解决。”
并像这样使用它:
我实际上希望看到反编译器的增强功能:它当前忽略该用户的
ReaderParameters
集,在DefaultAssemblyResolver
类。用法:
当前
DefaultAssemblyResolver
代码:In addition to what JB Evain suggested, this code will help in avoiding the exception. All you have to do is handle the exception in resolver.
Not the best way, I admit. But it works for this scenario:
"If I am decompiling a DLL on a system where the referred assemblies are not present, the decompilation fails (with exception.) At least, i would like to see the decompile code, for whatever has been resolved."
And use it like this:
I would actually like to see an enhancement in the decompiler: it currently ignores the
ReaderParameters
that user sets, inDefaultAssemblyResolver
class.Usage:
Current
DefaultAssemblyResolver
code:根据 Mono.Cecil 源代码,我猜测您可能可以使用 Mono.Cecil.DefaultAssemblyResolver 类来处理此问题。
而不是这个代码:
尝试这个:
编辑
虽然我最初的建议可能有效也可能无效(我从未这样做过,所以不能保证),但您可能想研究一下
Mono。 Mono.Addins 项目 中的 Addins.CecilReflector.dll
程序集可帮助缓解此类问题。它也基于 Mono.Cecil (就像 ILSpy 一样),因此即使 Mono.Addins 是一个可扩展性库的一般前提不能满足您的需求,它也可能包含一些用于您的目的或至少可以学习的代码。Based on the Mono.Cecil source, I would guess that you could probably handle this using the
Mono.Cecil.DefaultAssemblyResolver
class.Instead of this code:
try this:
EDIT
While my original suggestion may or may not work (I've never done it, so no guarantees), you may want to look into the
Mono.Addins.CecilReflector.dll
assembly from the Mono.Addins project to help mitigate these sort of problems. It is also based on Mono.Cecil (just as ILSpy is) so even though the general premise that Mono.Addins is an extensibility library doesn't meet your needs it may contain some code use for your purposes or at least learn from.