
مكتبة فريق FLARE مفتوحة المصدر لتفكيك تعليمات Common Intermediate Language (CIL).

dncil هي مكتبة تفكيك للغة الوسيطة المشتركة (CIL) مكتوبة بلغة Python تدعم تحليل الترويسة والتعليمات ومعالجات الاستثناءات للطرق المُدارة في .NET. يتم عرض البيانات المحللة من خلال واجهة برمجة تطبيقات موجهة للكائنات لمساعدتك على تطوير أدوات تحليل CIL بسرعة باستخدام dncil.
لماذا Python؟ المكتبات الحالية التي تدعم تفكيك CIL، مثل dnLib، مكتوبة بلغة C#. للاستفادة من هذه الأدوات، يجب عليك بناء تطبيقات C#، الأمر الذي يتطلب خبرة في تطوير C#. باستخدام dncil، البديل النقي بلغة Python، يمكنك:
C# لتحليل CIL برمجيًا.CIL الخاصة بك بسرعة.CIL الخاصة بك بسهولة مع مشاريع Python الحالية.يستخدم السكربت المثال print_cil_from_dn_file.py مكتبة dncil مع مكتبة تحليل .NET dnfile لتفكيك الطرق المُدارة الموجودة في ملف تنفيذي .NET. دعونا نرى ما يمكنه فعله.
أولاً، نقوم بتجميع الكود المصدري التالي بلغة C#:
using System;
public class HelloWorld
{
public static void Main(string[] args)
{
Console.WriteLine ("Hello World!");
}
}
ينتج عن التجميع ملف تنفيذي PE يحتوي على بيانات وصفية لـ .NET تُعلم Common Language Runtime (CLR) بكيفية تنفيذ الكود الخاص بنا. نستخدم dnfile لتحليل هذه البيانات الوصفية، وهو ما يعطينا إزاحة الطريقة المُدارة Main. ثم نستخدم dncil لتفكيك وعرض تعليمات CIL المخزنة في هذا الموقع.
دعونا نرى ما سبق عمليًا:
$ python scripts/print_cil_from_dn_file.py hello-world.exe
Method: Main
0000 00 nop
0001 72 01 00 00 70 ldstr "Hello World!"
0006 28 04 00 00 0a call System.Console::WriteLine
000B 00 nop
000C 2a ret
يتم تمثيل الطريقة Main الخاصة بنا بواسطة الفئة CilMethodBody. تحتفظ هذه الفئة ببيانات تتضمن الترويسة، وتعليمات CIL، ومعالجات الاستثناءات الخاصة بأي طريقة مُدارة معينة. كما تعرض أيضًا عددًا من الدوال المساعدة:
> main_method_body.flags
SmallFormat : false
TinyFormat : false
FatFormat : false
TinyFormat1 : true
MoreSects : false
InitLocals : false
CompressedIL : false
> main_method_body.size
14
> hexdump.hexdump(main_method_body.get_bytes())
00000000: 36 00 72 01 00 00 70 28 04 00 00 0A 00 2A 6.r...p(.....*
> hexdump.hexdump(main_method_body.get_header_bytes())
00000000: 36 6
> hexdump.hexdump(main_method_body.get_instruction_bytes())
00000000: 00 72 01 00 00 70 28 04 00 00 0A 00 2A .r...p(.....*
يتم تمثيل كل تعليمة CIL موجودة في الطريقة المُدارة Main بواسطة الفئة Instruction. تحتفظ هذه الفئة ببيانات تتضمن الإزاحة، والرمز التذكاري (mnemonic)، ورمز العملية (opcode)، والمعامل (operand) لأي تعليمة CIL معينة. كما تعرض أيضًا عددًا من الدوال المساعدة:
> len(main_method_body.instructions)
5
> insn = main_method_body.instructions[1]
> insn.offset
1
> insn.mnemonic
'ldstr'
> insn.operand
token(0x70000001)
> insn.is_ldstr()
True
> insn.size
5
> hexdump.hexdump(insn.get_bytes())
00000000: 72 01 00 00 70 r...p
> hexdump.hexdump(insn.get_opcode_bytes())
00000000: 72 r
> hexdump.hexdump(insn.get_operand_bytes())
00000000: 01 00 00 70 ...p
لتثبيت dncil استخدم pip لجلب وحدة dncil:
$ pip install dncil
لتشغيل السكربتات المثال، تأكد من تثبيت dnfile. بدلاً من ذلك، قم بتثبيت dncil مع تبعيات التطوير كما هو موضح في قسم Development أدناه.
انظر print_cil_from_bytes.py للحصول على مثال سريع لاستخدام dncil لطباعة تعليمات CIL الموجودة في تدفق بايتات يحتوي على طريقة .NET مُدارة.
إذا كنت ترغب في مراجعة وتعديل الكود المصدري لـ dncil، فستحتاج إلى تنزيله من GitHub وتثبيته محليًا.
استخدم الأمر التالي لتثبيت dncil محليًا مع تبعيات التطوير:
$ pip install /local/path/to/src[dev]
ستحتاج إلى تبعيات تطوير dncil لتشغيل الاختبارات والتدقيق البرمجي كما هو موضح أدناه.
استخدم الأمر التالي لتشغيل الاختبارات:
$ pytest /local/path/to/src/tests
استخدم الأوامر التالية لتحديد أخطاء التنسيق:
$ black -l 120 -c /local/path/to/src
$ isort --profile black --length-sort --line-width 120 -c /local/path/to/src
$ mypy --config-file /local/path/to/src/.github/mypy/mypy.ini /local/path/to/src/dncil/ /local/path/to/src/scripts/ /local/path/to/src/tests/
dncil مبني على كود تحليل CIL الموجود في dnLib.