
स्क्रिप्टेबल बाइनरी एमुलेशन फ्रेमवर्क जो IDA Pro/Radare2 को Unicorn इंजन के साथ एकीकृत करता है, जो x86, ARM, और ARM64 आर्किटेक्चर पर स्वचालित मैलवेयर विश्लेषण, स्ट्रिंग डिक्रिप्शन और कोड पथ अन्वेषण के लिए उपयोग होता है।
flare-emu एक समर्थित बाइनरी विश्लेषण ढांचे, जैसे IDA Pro या Radare2, को Unicorn के एमुलेशन ढांचे के साथ जोड़ता है ताकि उपयोगकर्ता को एमुलेशन कार्यों की स्क्रिप्टिंग के लिए एक उपयोग में आसान और लचीला इंटरफ़ेस प्रदान किया जा सके। इसे आपके समर्थित आर्किटेक्चर के लिए एक लचीला और मजबूत एमुलेटर स्थापित करने के सभी प्रबंधन को संभालने के लिए डिज़ाइन किया गया है ताकि आप अपनी कोड विश्लेषण समस्याओं को हल करने पर ध्यान केंद्रित कर सकें। वर्तमान में, flare-emu x86, x86_64, ARM, और ARM64 आर्किटेक्चर का समर्थन करता है।
यह वर्तमान में आपकी एमुलेशन आवश्यकताओं को पूरा करने के लिए पाँच अलग-अलग इंटरफ़ेस प्रदान करता है, साथ ही संबंधित सहायक और उपयोगिता कार्यों की एक श्रृंखला भी प्रदान करता है।
emulateRange – यह API उपयोगकर्ता-निर्दिष्ट संदर्भ के भीतर निर्देशों की एक श्रेणी, या एक फ़ंक्शन का अनुकरण करने के लिए उपयोग किया जाता है। यह व्यक्तिगत निर्देशों और जब "call" निर्देशों का सामना किया जाता है, दोनों के लिए उपयोगकर्ता-परिभाषित हुक के विकल्प प्रदान करता है। उपयोगकर्ता तय कर सकता है कि एमुलेटर फ़ंक्शन कॉल को छोड़ देगा या उनमें प्रवेश करेगा। यह इंटरफ़ेस उपयोगकर्ता को दिए गए रजिस्टरों और स्टैक तर्कों के लिए मान निर्दिष्ट करने का एक आसान तरीका प्रदान करता है। यदि एक बाइटस्ट्रिंग निर्दिष्ट की जाती है, तो इसे एमुलेटर की मेमोरी में लिखा जाता है और पॉइंटर को रजिस्टर या स्टैक वेरिएबल में लिखा जाता है। एमुलेशन के बाद, उपयोगकर्ता एमुलेटेड मेमोरी या रजिस्टरों से डेटा पढ़ने के लिए flare-emu के उपयोगिता कार्यों का उपयोग कर सकता है, या सीधे जांच के लिए वापस आए Unicorn एमुलेशन ऑब्जेक्ट का उपयोग कर सकता है। emulateRange के लिए एक छोटा रैपर फ़ंक्शन, जिसे emulateSelection नाम दिया गया है, का उपयोग IDA Pro में वर्तमान में हाइलाइट किए गए निर्देशों की श्रेणी का अनुकरण करने के लिए किया जा सकता है।
iterate - यह API किसी फ़ंक्शन के भीतर विशिष्ट शाखाओं पर एमुलेशन को बलपूर्वक ले जाने के लिए उपयोग किया जाता है ताकि किसी दिए गए लक्ष्य तक पहुंचा जा सके। उपयोगकर्ता लक्ष्य पतों की एक सूची, या एक फ़ंक्शन का पता निर्दिष्ट कर सकता है जिससे फ़ंक्शन के क्रॉस-रेफरेंस की सूची को लक्ष्य के रूप में उपयोग किया जाता है, साथ ही जब कोई लक्ष्य प्राप्त होता है तो एक कॉलबैक भी प्रदान किया जाता है। लक्ष्यों तक पहुंचा जाएगा, भले ही एमुलेशन के दौरान ऐसी स्थितियां हों जिनके कारण भिन्न शाखाएं ली गई हों। emulateRange API की तरह, व्यक्तिगत निर्देशों और जब "call" निर्देशों का सामना किया जाता है, दोनों के लिए उपयोगकर्ता-परिभाषित हुक के विकल्प प्रदान किए जाते हैं। iterate API का एक उदाहरण उपयोग हमारे argtracker टूल के समान कुछ प्राप्त करना है।
iterateAllPaths - यह API काफी हद तक iterate के समान है, सिवाय इसके कि एक लक्ष्य पता या पते प्रदान करने के बजाय, आप एक लक्ष्य फ़ंक्शन प्रदान करते हैं जिसके माध्यम से यह सभी पथ खोजने और अनुकरण करने का प्रयास करेगा। यह तब उपयोगी होता है जब आप कोड विश्लेषण कर रहे हों जो किसी फ़ंक्शन के हर बेसिक ब्लॉक तक पहुंचना चाहता हो।
emulateBytes – यह API बाहरी शेलकोड के एक ब्लॉब को सरलता से अनुकरण करने का एक तरीका प्रदान करता है। प्रदान किए गए बाइट्स IDB में नहीं जोड़े जाते हैं और जैसे हैं वैसे ही अनुकरण किए जाते हैं। यह एमुलेशन वातावरण तैयार करने के लिए उपयोगी हो सकता है। उदाहरण के लिए, flare-emu स्वयं इस API का उपयोग ARM64 CPU के लिए एक मॉडल विशिष्ट रजिस्टर (MSR) में हेरफेर करने के लिए करता है जो Unicorn द्वारा उजागर नहीं किया गया है ताकि वेक्टर फ्लोटिंग पॉइंट (VFP) निर्देशों और रजिस्टर एक्सेस को सक्षम किया जा सके। Unicorn एमुलेशन ऑब्जेक्ट उपयोगकर्ता द्वारा आगे की जांच के लिए वापस किया जाता है।
emulateFrom - यह API उन मामलों में उपयोगी है जहां फ़ंक्शन सीमाएं स्पष्ट रूप से परिभाषित नहीं होती हैं, जैसा कि अक्सर अस्पष्ट बायनरी या शेलकोड के साथ होता है। आप एक प्रारंभिक पता प्रदान करते हैं, और यह तब तक अनुकरण करेगा जब तक अनुकरण करने के लिए कुछ नहीं बचता या आप अपने किसी हुक में अनुकरण रोक देते हैं। IDA Pro के साथ, इसे strict पैरामीटर को False पर सेट करके बुलाया जा सकता है ताकि गतिशील कोड खोज सक्षम हो सके; flare-emu IDA Pro को एमुलेशन के दौरान सामने आने वाले निर्देशों को बनाने के लिए कहेगा।
flare-emu को IDA Pro के लिए स्थापित करने के लिए, बस flare_emu.py, flare_emu_ida.py, और flare_emu_hooks.py को अपने IDA Pro के python निर्देशिका में डालें और इसे अपने IDAPython स्क्रिप्ट में एक मॉड्यूल के रूप में आयात करें।
flare-emu को Rizin के लिए स्थापित करने के लिए, बस सुनिश्चित करें कि flare_emu.py, flare_emu_rizin.py, और flare_emu_hooks.py मॉड्यूल आयात करने के लिए Python के खोज पथ में हैं। जब Rizin का उपयोग flare-emu के लिए बाइनरी विश्लेषण घटक के रूप में किया जाता है, तो rzpipe आवश्यक है।
flare-emu को Radare2 के लिए स्थापित करने के लिए, बस सुनिश्चित करें कि flare_emu.py, flare_emu_radare.py, और flare_emu_hooks.py मॉड्यूल आयात करने के लिए Python के खोज पथ में हैं। जब Radare2 का उपयोग flare-emu के लिए बाइनरी विश्लेषण घटक के रूप में किया जाता है, तो r2pipe आवश्यक है।
किसी भी स्थिति में, flare-emu Unicorn और इसके Python बाइंडिंग पर निर्भर करता है।
महत्वपूर्ण नोट
flare-emu को नए IDA Pro 7x API का उपयोग करके लिखा गया था, यह IDA Pro के पिछले संस्करणों के साथ पिछड़ा संगत नहीं है।
जबकि flare-emu का उपयोग कई अलग-अलग कोड विश्लेषण समस्याओं को हल करने के लिए किया जा सकता है, इसका एक सामान्य उपयोग मैलवेयर बायनरी में स्ट्रिंग्स को डिक्रिप्ट करने में सहायता करना है। FLOSS एक बेहतरीन टूल है जो अक्सर आपके लिए स्वचालित रूप से ऐसा कर सकता है, स्ट्रिंग डिक्रिप्ट करने वाले फ़ंक्शन(ओं) की पहचान करने का प्रयास करके और हर क्रॉस-रेफरेंस पर पास की गई स्ट्रिंग्स को डिक्रिप्ट करने के लिए एमुलेशन का उपयोग करके। हालांकि, FLOSS के लिए हमेशा इन फ़ंक्शनों की पहचान करना और अपने सामान्य दृष्टिकोणों का उपयोग करके उन्हें ठीक से अनुकरण करना संभव नहीं है। कभी-कभी आपको थोड़ा और काम करना पड़ता है, और यह वह जगह है जहां flare-emu आपका बहुत समय बचा सकता है जब आप इसके साथ सहज हो जाते हैं। आइए एक सामान्य परिदृश्य पर चलते हैं जो एक मैलवेयर विश्लेषक एन्क्रिप्टेड स्ट्रिंग्स से निपटने के दौरान सामना करता है।
आपने एक x86_64 बायनरी में सभी स्ट्रिंग्स को डिक्रिप्ट करने वाले फ़ंक्शन की पहचान कर ली है। यह फ़ंक्शन हर जगह कॉल किया जाता है और कई अलग-अलग स्ट्रिंग्स को डिक्रिप्ट करता है। IDA Pro में, आप इस फ़ंक्शन का नाम decryptString रखते हैं। यहाँ आपकी flare-emu स्क्रिप्ट है जो इन सभी स्ट्रिंग्स को डिक्रिप्ट करेगी और प्रत्येक फ़ंक्शन कॉल पर डिक्रिप्ट किए गए स्ट्रिंग्स के साथ टिप्पणियाँ रखेगी, साथ ही प्रत्येक डिक्रिप्टेड स्ट्रिंग और उस पते को लॉग करेगी जिस पर इसे डिक्रिप्ट किया गया है।```
from future import print_function
import flare_emu
def decrypt(argv): myEH = flare_emu.EmuHelper() myEH.emulateRange(myEH.analysisHelper.getNameAddr("decryptString"), registers = {"arg1":argv[0], "arg2":argv[1], "arg3":argv[2], "arg4":argv[3]}) return myEH.getEmuString(argv[0])
def iterateCallback(eh, address, argv, userData): s = decrypt(argv) print("%s: %s" % (eh.hexString(address), s)) eh.analysisHelper.setComment(address, s, False)
if name == 'main':
eh = flare_emu.EmuHelper()
eh.iterate(eh.analysisHelper.getNameAddr("decryptString"), iterateCallback)
`__main__` में, हम `flare-emu` से `EmuHelper` वर्ग का एक उदाहरण बनाकर शुरू करते हैं। यह वह वर्ग है जिसका उपयोग हम `flare-emu` के साथ सब कुछ करने के लिए करते हैं। इसके बाद, हम `iterate` API का उपयोग करते हैं, जिसमें हम अपने `decryptString` फ़ंक्शन का पता और अपने कॉलबैक फ़ंक्शन का नाम देते हैं जिसे `EmuHelper` प्रत्येक क्रॉस-रेफरेंस के लिए कॉल करेगा जिसका अनुकरण किया जाता है।