如何使用ICSharpCode.Decompiler在SQL Server中获取和查看.NET程序集

当然,您可以使用第三方实用程序,例如某些开源ILSpy,将程序集保存到磁盘,然后反编译。

图片

但是我只想连接到数据库并查看所有程序集以及其中的内容。

此外,在所有编程生命中,都有许多高质量的Opensource组件,并且使用C#编写既方便又容易:)

这样啊

为此,我们需要一个Nuget包

图片

从数据库中读取所有程序集


SqlDataReader,SQL查询很简单:

SELECT af.name, af.content FROM sys.assemblies a INNER JOIN sys.assembly_files af ON a.assembly_id = af.assembly_id 

初始化组装


即将我们的字节加载到AssemblyDefinition类中

 var _assemblyDefinition = Mono.Cecil.AssemblyDefinition.ReadAssembly(new MemoryStream(rdr.GetSqlBytes(1).Value), pars); 

rdr-这只是SqlDataReader,但是您可以将所有程序集读入列表,例如,来自此类简单类的对象列表

 public class SqlAssemblyObject { public string AssemblyName { get; set; } public SqlBytes Data { get; set; } } 

由于通常有许多装配体,因此以列表或平板电脑的形式显示它们很方便,但是内部以树的形式显示当然是很方便的!

这样的事情将成为常态

图片

我们展示


例如在TreeView中

 foreach (var typeInAssembly in _assemblyDefinition.MainModule.Types) { if (typeInAssembly.IsPublic) { var node = new TreeNode(typeInAssembly.FullName); node.Tag = typeInAssembly; } treeView1.Nodes.Add(node); } 

反编译


只有三行代码! (例如,我在treeView1_AfterSelect事件中做了)

 var decompiler = new ICSharpCode.Decompiler.CSharp.CSharpDecompiler(_assemblyDefinition.MainModule, new DecompilerSettings()); var str = decompiler.DecompileAsString(e.Node.Tag as IMemberDefinition); textbox1.Text = str; 

源本身,所有东西都汇集在一起

最终看起来像这样

图片

关于陷阱的一点


自然,程序集可以依赖程序集,而所有这些都可以位于SQL数据库中。

然后,如果您“在额头上”反编译-将出现反编译错误。

避免它很容易(因为ICSharpCode.Decompiler中有一个AssemblyResolver):

让我们通过简单地将解析器中所有可用程序集传递给解析器来编写解析器:

 public class DatabaseAssemblyResolver : IAssemblyResolver { List<SqlAssemblyObject> _databaseLibs; DefaultAssemblyResolver _resolver; public DatabaseAssemblyResolver(List<SqlAssemblyObject> dlls) { _databaseLibs = dlls; _resolver = new DefaultAssemblyResolver(); } public void Dispose() { //throw new NotImplementedException(); } public AssemblyDefinition Resolve(AssemblyNameReference name) { foreach (var item in _databaseLibs) { if(item.AssemblyName.Contains(name.Name)) { return AssemblyDefinition.ReadAssembly(new MemoryStream(item.Data.Value)); } } return _resolver.Resolve(name); } public AssemblyDefinition Resolve(AssemblyNameReference name, ReaderParameters parameters) { foreach (var item in _databaseLibs) { if (item.AssemblyName.Contains(name.Name)) { return AssemblyDefinition.ReadAssembly(new MemoryStream(item.Data.Value)); } } return _resolver.Resolve(name, parameters); } 

变量_listItems只是sys.assembly_files中所有程序集的列表

 var pars = new ReaderParameters(); pars.AssemblyResolver = new DatabaseAssemblyResolver(_listItems); _assemblyDefinition = Mono.Cecil.AssemblyDefinition.ReadAssembly(new MemoryStream(_listItems[idx].Data.Value), pars); 

现在,在反编译时,所有依赖项都可以解决!

图片

PS:莉莉·詹姆斯曾引起人们的注意。

Source: https://habr.com/ru/post/zh-CN425799/


All Articles