
गिड्रा के लिए बाइनरी कोड कवरेज विज़ुअलाइज़र प्लगइन
Dragon Dance Ghidra के लिए एक प्लगइन है जो बाइनरी कोड कवरेज डेटा को विज़ुअलाइज़ और मैनिपुलेट करने में सहायता करता है। कवरेज डेटा को कई कवरेज स्रोतों से आयात किया जा सकता है। फिलहाल प्लगइन Dynamorio और Intel Pin बाइनरी इंस्ट्रुमेंटेशन टूल्स को सपोर्ट करता है। Dynamorio का अपना कवरेज संग्रह मॉड्यूल है जिसे "drcov" कहा जाता है। Intel Pin में बिल्ट-इन कवरेज संग्रह मॉड्यूल नहीं है। मॉड्यूल की कमी से निपटने के लिए मुझे Intel Pin के लिए अपना स्वयं का कवरेज संग्रह मॉड्यूल लिखना पड़ा। इसलिए मैंने Intel Pin के लिए ddph (Dragon Dance Pin Helper) नाम का एक कवरेज संग्रह मॉड्यूल लिखा। तो आप इसका उपयोग कर सकते हैं। आप ddph का स्रोत इस लिंक से देख सकते हैं। यदि आप स्वयं संकलन करने में आलसी हैं, तो आप Windows, macOS और Linux के लिए मेरे द्वारा प्रदान की गई संकलित बाइनरी का उपयोग कर सकते हैं।

Dragon Dance एक ही सत्र में एकाधिक कवरेज डेटा को आयात और उपयोग कर सकता है। (साथ ही यह मल्टी-सेशन को सपोर्ट करता है लेकिन फिलहाल यह GUI द्वारा उपयोग योग्य नहीं है)। और आप उनके बीच स्विच कर सकते हैं या एक दूसरे के साथ इंटरसेक्शन, डिफरेंस, डिस्टिंक्ट या सम ऑपरेशन लागू कर सकते हैं।
Dragon Dance आपको निष्पादित निर्देशों की तीव्रता देखने की अनुमति देता है। ताकि आपको इस बात का संकेत मिल सके कि कौन से निर्देश कितनी बार निष्पादित हुए। साथ ही आप फंक्शन ग्राफ विंडो पर कवरेज विज़ुअलाइज़ेशन भी देख सकते हैं।

Dragon Dance अपनी स्वयं की स्क्रिप्टिंग प्रणाली का भी समर्थन करता है।

यह आपको कवरेज डेटा के साथ खेलने का लचीला तरीका प्रदान करता है। आप उन पर लोड, डिलीट, शो, इंटरसेक्ट, डिफ, डिस्टिंक्ट, सम ऑपरेशन कर सकते हैं। निम्नलिखित अनुभाग में स्क्रिप्टिंग सिस्टम और API शामिल होंगे। स्क्रिप्ट निष्पादित करने के लिए Alt + Enter कुंजियाँ दबाएँ।
बिल्ट-इन फ़ंक्शन आंतरिक कवरेज ऑपरेशनों के कार्यान्वयन हैं जो स्क्रिप्टिंग सिस्टम को एक इंटरफ़ेस प्रदान करते हैं। बिल्ट-इन फ़ंक्शन कवरेज ऑब्जेक्ट वेरिएबल या कुछ भी वापस कर सकता है। बिल्ट-इन के उपनाम हो सकते हैं।
वे पैरामीटर के रूप में बिल्ट-इन Arg स्वीकार करते हैं। पैरामीटर परिवर्तनीय लंबाई के हो सकते हैं।
बिल्ट-इन Arg विभिन्न प्रकार के मान को धारण करने के लिए एक संदर्भ है। बिल्ट-इन Args बाएँ से दाएँ क्रम में पास किए जाते हैं। बिल्ट-इन Arg निम्नलिखित मान प्रकार धारण कर सकता है:
वेरिएबल केवल कवरेज ऑब्जेक्ट को धारण करने के लिए जिम्मेदार होते हैं। उन्हें बिल्ट-इन फ़ंक्शन द्वारा लोड किया जा सकता है। उन्हें बिल्ट-इन फ़ंक्शन में पैरामीटर (बिल्ट-इन Arg) के रूप में पास किया जा सकता है।
कवरेज ऑब्जेक्ट दो प्रकार के होते हैं।
भौतिक कवरेज ऑब्जेक्ट और तार्किक कवरेज ऑब्जेक्ट
भौतिक कवरेज ऑब्जेक्ट एक कवरेज ऑब्जेक्ट को इंगित करता है जो सीधे कवरेज फ़ाइल से लोड किया जाता है। वे GUI पर कवरेज तालिका में दिखाई देते हैं। इसलिए आप GUI संचालन के माध्यम से उनके साथ इंटरैक्ट कर सकते हैं।
तार्किक कवरेज ऑब्जेक्ट एक कवरेज ऑब्जेक्ट को इंगित करता है जिसे किसी बिल्ट-इन फ़ंक्शन में संसाधित किया गया है और परिणामस्वरूप उससे वापस किया गया है। वे GUI पर दिखाई नहीं देते हैं लेकिन वे एक वेरिएबल में तब तक रह सकते हैं जब तक कि वे नष्ट न हो जाएँ।
कवरेज ऑब्जेक्ट दोनों प्रकार के कवरेज ऑब्जेक्ट के लिए स्वचालित रूप से वेरिएबल ऑब्जेक्ट द्वारा बनाए रखा जाता है। उदाहरण के लिए;``` cov1 = load("firstcoverage.out") cov2 = load("secondcov.out")
cov1 = diff(cov1,cov2)
इस उदाहरण में cov1 और cov2 चर हैं। और दोनों चरों में भौतिक कवरेज ऑब्जेक्ट है। diff बिल्ट-इन दोनों चरों को लेता है और रिटर्न वैल्यू को cov1 चर में सेट करता है। वह ओवरराइट संचालन परिणाम कवरेज ऑब्जेक्ट को चर में सेट करेगा लेकिन कवरेज ऑब्जेक्ट को हटाता नहीं है क्योंकि वह एक भौतिक कवरेज ऑब्जेक्ट है। वह कवरेज डेटा सत्र और GUI तालिका में बना रहेगा।
पिछले उदाहरण को इस प्रकार सोचें;```
cov1 = load("first.out")
cov2 = load("second.out")
cov3 = load("third.out")
rvar = sum(cov1,cov2,cov3)
rvar = diff(rvar, cov2)
इस उदाहरण में तीन भौतिक कवरेज चर योग संक्रिया में जाते हैं और योग संक्रिया तार्किक परिणाम कवरेज वस्तु लौटाती है। फिर अंतर संक्रिया एक तार्किक और एक भौतिक चर लेती है और rvar नामक चर को अधिलेखित करती है।
इस स्थिति में, परिणाम rvar पर सेट हो जाएगा और इसका पिछला कवरेज मान तुरंत नष्ट हो जाएगा। क्योंकि यह एक तार्किक वस्तु थी और वस्तु रिसाव को रोकने के लिए इसे हटा दिया जाना चाहिए। यदि आप किसी ऐसे चर को नष्ट करना चाहते हैं जिसमें कोई भौतिक कवरेज वस्तु है, तो आपको ऐसा करने के लिए discard अंतर्निहित को कॉल करना होगा। सभी अंतर्निहित विधियों का विवरण नीचे दिया जाएगा।
आप नेस्टेड अंतर्निहित कॉल का उपयोग करके जटिल स्क्रिप्ट लिख सकते हैं, आप कुछ इस प्रकार लिख सकते हैं:
cres = diff(intersect(a, load("another.log"), c, d), sum(e,f) )
आपको तर्क को पंक्ति दर पंक्ति लिखने की आवश्यकता नहीं है।
निम्नलिखित API दस्तावेज़ीकरण और उनके व्यवहार अंतिम संस्करण तक पहुँचने तक बदल सकते हैं।
clear()
| गुण | विवरण |
|---|---|
| वापसी मान | कोई नहीं |
| न्यूनतम पैरामीटर गणना | 0 |
| अधिकतम पैरामीटर गणना | 0 |
| विवरण | यह अंतर्निहित दृश्यमान कवरेज को साफ करता है और सक्रिय कवरेज को शून्य पर सेट करता है। |
| उपनाम | कोई नहीं |
cwd( स्ट्रिंग : कार्यशीलनिर्देशिका )
| गुण | विवरण |
|---|---|
| वापसी मान | कोई नहीं |
| न्यूनतम पैरामीटर गणना | 1 |
| अधिकतम पैरामीटर गणना | 1 |
| विवरण | दिए गए पथ के साथ वर्तमान कार्यशील निर्देशिका सेट करता है। cwd के बाद बिना निरपेक्ष पथ वाले सभी आयात कॉल सक्रिय कार्यशील निर्देशिका में कवरेज फ़ाइलों की खोज करेंगे। |
| उपनाम | कोई नहीं |
diff( चर : var1, var2, ..... varN )
| गुण | विवरण |
|---|---|
| वापसी मान | चर |
| न्यूनतम पैरामीटर गणना | 2 |
| अधिकतम पैरामीटर गणना | असीमित |
| विवरण | दिए गए परिवर्तनीय लंबाई के चरों पर अंतर संक्रिया लागू करता है और परिणामी कवरेज चर लौटाता है। |
| उपनाम | कोई नहीं |
discard( चर : var1, var2, ..... varN )