So nehmen Sie einfach .NET-Assemblys in SQL Server mit ICSharpCode.Decompiler auf und zeigen sie an

Natürlich können Sie Dienstprogramme von Drittanbietern verwenden, z. B. Open Source ILSpy, die Assembly auf der Festplatte speichern und dann dekompilieren.

Bild

Aber ich möchte nur eine Verbindung zur Datenbank herstellen und alle Assemblys und deren Inhalt sehen.

Außerdem gibt es viele hochwertige Opensource-Komponenten für alle Fälle des Programmierlebens, und das Schreiben in C # ist bequem und einfach :)

Also.

Dafür benötigen wir ein Nuget-Paket

Bild

Lesen Sie alle Assemblys aus der Datenbank


SqlDataReader, SQL-Abfrage ist trivial:

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

Baugruppe initialisieren


dh laden Sie unsere Bytes in die AssemblyDefinition- Klasse

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

rdr - hier ist nur SqlDataReader, aber Sie können alle Assemblys in eine Liste einlesen, z. B. eine Liste von Objekten aus einer so einfachen Klasse

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

Da es normalerweise viele Baugruppen gibt, ist es praktisch, sie in Form einer Liste oder eines Tablets anzuzeigen, aber die Innenseiten natürlich in Form eines Baumes!

So etwas wird die Norm sein

Bild

Wir zeigen


B. in TreeView

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

Dekompilierung


Nur drei Codezeilen! (Zum Beispiel habe ich das Ereignis treeView1_AfterSelect verwendet. )

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

Die Quelle selbst, wo alles zusammengebracht wird

Am Ende sieht es so aus

Bild

Ein bisschen über die Fallstricke


Assemblys können natürlich von Assemblys abhängen, und all dies kann in der SQL-Datenbank liegen.

Wenn Sie dann "auf der Stirn" dekompilieren, tritt ein Dekompilierungsfehler auf.

Es ist einfach zu vermeiden (da ICSharpCode.Decompiler einen AssemblyResolver enthält):

Schreiben wir unseren Resolver, indem wir ihm einfach alle verfügbaren Assemblys in der analysierten SQL-Datenbank übergeben:

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

Die Variable _listItems ist nur eine Liste aller Assemblys aus sys.assembly_files

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

Jetzt können beim Dekompilieren alle Abhängigkeiten aufgelöst werden!

Bild

PS: Lily James wurde verwendet, um Aufmerksamkeit zu erregen.

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


All Articles