كيف تأخذ فقط وترى تجميعات .NET في SQL Server باستخدام ICSharpCode.Decompiler

بالطبع ، يمكنك استخدام أدوات مساعدة لجهات خارجية ، على سبيل المثال ، بعض المصادر المفتوحة المصدر ILSpy ، وحفظ التجميع على القرص ثم فك الترجمة.

الصورة

لكني أريد فقط الاتصال بقاعدة البيانات ومشاهدة جميع التجميعات وما بداخلها.

بالإضافة إلى ذلك ، هناك الكثير من مكونات المصادر المفتوحة عالية الجودة لجميع حالات الحياة البرمجية ، والكتابة في 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.

ثم إذا قمت بفك "الجبين" - سيكون هناك خطأ في فك التجميع.

من السهل تجنبه (لأنه يوجد AssemblyResolver في ICSharpCode.Decompiler):

دعنا نكتب محللنا ببساطة عن طريق تمريره جميع التجميعات المتاحة في قاعدة بيانات 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); 

الآن ، عند فك الترجمة ، يمكن حل جميع التبعيات!

الصورة

ملاحظة: تم استخدام ليلي جيمس لجذب الانتباه.

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


All Articles