
إضافة تصور تغطية الكود الثنائي لـ Ghidra
Dragon Dance هو إضافة لـ Ghidra تتيح تصور ومعالجة بيانات تغطية الشفرة الثنائية. يمكن استيراد بيانات التغطية من مصادر تغطية متعددة. حاليًا، تدعم الإضافة أدوات Dynamorio و Intel Pin لتنصيب الشفرة الثنائية. Dynamorio لديه وحدة جمع تغطية خاصة به تسمى "drcov". لا توفر Intel Pin وحدة جمع تغطية مدمجة. للتعامل مع غياب الوحدة، كان علي كتابة وحدة جمع تغطية خاصة بي لـ Intel Pin. لذا كتبت وحدة جمع تغطية لـ Intel Pin باسم ddph (مساعد Dragon Dance Pin). يمكنك استخدامها. يمكنك الاطلاع على مصدر ddph من هذا الرابط. إذا كنت لا ترغب في التجميع بنفسك، يمكنك استخدام الملفات الثنائية المجمعة التي قدمتها لأنظمة Windows و macOS و Linux.

يمكن لـ Dragon Dance استيراد واستخدام بيانات تغطية متعددة في نفس الجلسة. (كما أنها تدعم الجلسات المتعددة ولكن حاليًا غير قابلة للاستخدام من خلال الواجهة الرسومية). ويمكنك التبديل بينها أو تطبيق عمليات التقاطع والاختلاف والتمييز والجمع مع بعضها البعض بسرعة.
يتيح لك Dragon Dance عرض كثافة التعليمات المنفذة. وبالتالي يمكنك الحصول على فكرة عن التعليمات التي يتم تنفيذها بشكل متكرر. كما يمكنك عرض تصور التغطية على نافذة رسم الدالة.

يدعم Dragon Dance أيضًا نظام البرمجة النصية الخاص به.

يتيح لك طريقة مرنة للتعامل مع بيانات التغطية. يمكنك تحميلها، حذفها، عرضها، إجراء عمليات التقاطع، الاختلاف، التمييز، الجمع عليها. سيحتوي القسم التالي على نظام البرمجة النصية وواجهة API. اضغط على مفاتيح Alt + Enter لتنفيذ البرنامج النصي.
الدوال المضمنة هي تنفيذ لعمليات التغطية الداخلية لتوفير واجهة لنظام البرمجة النصية. يمكن لدالة مضمنة إرجاع متغير كائن تغطية أو لا شيء. قد تحتوي الدوال المضمنة على أسماء مستعارة. تقبل وسيطًا مضمنًا كمعامل. يمكن أن تكون المعاملات ذات طول متغير.
الوسيط المضمن هو مرجع يحمل أنواعًا مختلفة من القيم. يتم تمرير الوسائط المضمنة من اليسار إلى اليمين. يمكن للوسيط المضمن حمل أنواع القيم التالية:
المتغيرات مسؤولة عن حمل كائن التغطية فقط. يمكن تحميلها بواسطة الدوال المضمنة. يمكن تمريرها كمعامل (وسيط مضمن) إلى الدوال المضمنة.
هناك نوعان من كائن التغطية. كائن تغطية فيزيائي و كائن تغطية منطقي
كائن التغطية الفيزيائي يشير إلى كائن تغطية تم تحميله مباشرة من ملف التغطية. وهي مرئية في جدول التغطية الموجود في الواجهة الرسومية. وبالتالي يمكنك التفاعل معها عبر عمليات الواجهة الرسومية.
كائن التغطية المنطقي يشير إلى كائن تغطية تمت معالجته في دالة مضمنة وإرجاعه كنتيجة. ليست مرئية في الواجهة الرسومية لكن يمكن أن تعيش في متغير حتى يتم تدميرها.
يتم الحفاظ على كائن التغطية بواسطة كائن المتغير تلقائيًا لكلا نوعي كائن التغطية. على سبيل المثال؛``` cov1 = load("firstcoverage.out") cov2 = load("secondcov.out")
cov1 = diff(cov1,cov2)
في هذا المثال، cov1 و cov2 متغيران. وكلا المتغيرين لهما physical coverage object. الدالة المدمجة diff تأخذ كلا المتغيرين وتضع القيمة المرتجعة في المتغير cov1. عملية الكتابة هذه ستضع result coverage object في المتغير، لكنها لا تحذف coverage object لأنه physical coverage object. ستظل بيانات التغطية هذه موجودة في الجلسة وأيضًا في GUI table.
دعنا نفكر في المثال السابق بهذه الطريقة؛```
cov1 = load("first.out")
cov2 = load("second.out")
cov3 = load("third.out")
rvar = sum(cov1,cov2,cov3)
rvar = diff(rvar, cov2)
في هذا المثال، ثلاثة متغيرات تغطية فيزيائية تدخل في عملية sum، وترجع عملية sum كائن نتيجة تغطية منطقية. ثم تأخذ عملية diff متغيرًا منطقيًا وآخر فيزيائيًا وتستبدل المتغير المسمى rvar.
في هذه الحالة، سيتم تعيين النتيجة إلى rvar وسيتم تدمير قيمة التغطية السابقة على الفور. لأن هذا كان كائنًا منطقيًا ويجب حذفه لمنع تسرب الكائن. إذا كنت تريد تدمير متغير يحتوي على كائن تغطية فيزيائي، عليك استدعاء الدالة المضمنة discard للقيام بذلك. سيتم تفصيل جميع الدوال المضمنة أدناه.
يمكنك كتابة سكريبتات معقدة باستخدام استدعاءات متداخلة للدوال المضمنة، يمكنك كتابة شيء مثل:
cres = diff(intersect(a, load("another.log"), c, d), sum(e,f) )
ليس عليك كتابة المنطق سطرًا بسطر.
قد تتغير وثائق API التالية وسلوكياتها حتى الوصول إلى الإصدار النهائي.
clear()
| الخاصية | الوصف |
|---|---|
| قيمة الإرجاع | لا شيء |
| الحد الأدنى لعدد المعاملات | 0 |
| الحد الأقصى لعدد المعاملات | 0 |
| الوصف | تقوم هذه الدالة المضمنة بمسح التغطية التي يتم عرضها وتضبط التغطية النشطة على قيمة فارغة. |
| الأسماء المستعارة | لا شيء |
cwd( String : workingDirectory )
| الخاصية | الوصف |
|---|---|
| قيمة الإرجاع | لا شيء |
| الحد الأدنى لعدد المعاملات | 1 |
| الحد الأقصى لعدد المعاملات | 1 |
| الوصف | يضبط دليل العمل الحالي بالمسار المعطى. جميع استدعاءات الاستيراد بدون مسار مطلق بعد cwd سيتم البحث عن ملفات التغطية في دليل العمل النشط. |
| الأسماء المستعارة | لا شيء |
diff( Variable : var1, var2, ..... varN )
| الخاصية | الوصف |
|---|---|
| قيمة الإرجاع | متغير |
| الحد الأدنى لعدد المعاملات | 2 |
| الحد الأقصى لعدد المعاملات | غير محدود |
| الوصف | يطبق عملية الفرق على متغيرات ذات طول متغير. ويعيد متغير نتيجة التغطية. |
| الأسماء المستعارة | لا شيء |
discard( Variable : var1, var2, ..... varN )
| الخاصية | الوصف |
|---|---|
| قيمة الإرجاع | لا شيء |
| الحد الأدنى لعدد المعاملات | 1 |
| الحد الأقصى لعدد المعاملات | غير محدود |
| الوصف | يدمر المتغيرات سواء كانت فيزيائية أو منطقية. سيقوم أولاً بتدمير كائن التغطية ثم يلغي تسجيل اسم المتغير من قائمة المتغيرات. بعد هذا الاستدعاء، تصبح جميع المتغيرات المعطاة غير معرفة. |
| الأسماء المستعارة | del |
distinct( Variable : var1, var2, ..... varN )