C贸mo simplemente tomar y ver ensamblados .NET en SQL Server usando ICSharpCode.Decompiler

Por supuesto, puede tomar utilidades de terceros, por ejemplo, algunos ILSpy de c贸digo abierto, guardar el ensamblado en el disco y luego descompilarlo.

imagen

Pero solo quiero conectarme a la base de datos y ver todos los ensamblajes y lo que hay dentro.

Y adem谩s, hay muchos componentes Opensource de alta calidad para todos los casos de vida de programaci贸n, y escribir en C # es conveniente y f谩cil :)

Entonces

Para esto necesitamos un paquete Nuget

imagen

Leer todos los ensamblajes de la base de datos


SqlDataReader, la consulta SQL es trivial:

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

Inicializar ensamblaje


es decir, cargar nuestros bytes en la clase AssemblyDefinition

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

rdr: aqu铆 es solo SqlDataReader, pero puede leer todos los ensamblajes en una lista, por ejemplo, una lista de objetos de una clase tan simple

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

Como generalmente hay muchos ensamblajes, es conveniente mostrarlos en forma de lista o tableta, 隆pero el interior en forma de 谩rbol, por supuesto!

Algo como esto ser谩 la norma

imagen

Mostramos


por ejemplo, en TreeView

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

Descompilaci贸n


隆Solo tres l铆neas de c贸digo! (por ejemplo, lo hice en el evento 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; 

La fuente misma, donde todo se une

Se ve as铆 al final

imagen

Un poco sobre las trampas


Naturalmente, los ensamblajes pueden depender de ensamblajes, y todo esto puede estar en la base de datos SQL.

Luego, si descompila "en la frente", habr谩 un error de descompilaci贸n.

Evitarlo es f谩cil (porque hay un AssemblyResolver en ICSharpCode.Decompiler):

Escribamos nuestra resoluci贸n simplemente pas谩ndola a todos los ensamblajes disponibles en la base de datos SQL analizada:

 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); } 

La variable _listItems es solo una lista de todos los ensamblados de sys.assembly_files

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

Ahora, al descompilar, 隆todas las dependencias se pueden resolver!

imagen

PD: Lily James se utiliz贸 para llamar la atenci贸n.

Source: https://habr.com/ru/post/es425799/


All Articles