Как просто взять и посмотреть .NET сборки в SQL Server с помощью ICSharpCode.Decompiler

от автора

Можно конечно взять сторонние утилиты, например какой-нибудь опенсорсный ILSpy, сохранить сборку на диск и потом декомпилировать.
image
Но хочется просто подключиться к БД и посмотреть все сборки и что там внутри.
И к тому же, есть очень много качественных Opensource компонент на все случаи программистской жизни, да и писать на C# удобно и легко 🙂

Итак

Для этого нам потребуется Nuget-пакет www.nuget.org/packages/ICSharpCode.Decompiler
image

Читаем из базы все сборки

SqlDataReader-ом, SQL-запрос тривиальный:

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

Инициализируем сборку

i.e. загружаем наши байты в класс 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; }     } 

Поскольку сборок обычно много, то их удобно выводить на экран в виде списка или таблички, а вот внутренности в виде дерева конечно же!
Примерно так будет норм
image

Выводим на экран

например в 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; 

Сам исходник, где всё сведено воедино

выглядит в итоге примерно так
image

Немного о подводных камнях

Естественно сборки могут зависеть от сборок, и всё это может лежать в SQL базе.
Тут если декомпилировать «в лоб» — будет ошибка декомпиляции.
Избежать ее легко (т. к. в ICSharpCode.Decompiler есть AssemblyResolver):

Напишем свой резолвер, просто передав ему все доступные сборки в анализируемой SQL базе:

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

теперь при декомпиляции все зависимости удается разрешить!
image

PS: Лили Джеймс была использована для привлечения внимания)))


ссылка на оригинал статьи https://habr.com/post/425799/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *