
إطار عمل قابل للبرمجة لمحاكاة الثنائيات يدمج IDA Pro/Radare2 مع محرك Unicorn للتحليل الآلي للبرامج الضارة، وفك تشفير السلاسل النصية، واستكشاف مسارات الكود عبر معماريات x86 و ARM و ARM64.
flare-emu يدمج إطار تحليل ثنائيات مدعوم، مثل IDA Pro أو Radare2، مع إطار المحاكاة Unicorn لتوفير واجهة سهلة الاستخدام ومرنة للمستخدم لبرمجة مهام المحاكاة. صُمم ليتولى جميع المهام المنزلية لإنشاء محاكي قوي ومرن للهياكل المدعومة، بحيث يمكنك التركيز على حل مشكلات تحليل الشيفرة. حاليًا، يدعم flare-emu هياكل x86 و x86_64 و ARM و ARM64.
يوفر حاليًا خمس واجهات مختلفة لخدمة احتياجات المحاكاة الخاصة بك، إلى جانب مجموعة من الدوال المساعدة والوظائف ذات الصلة.
emulateRange – تُستخدم هذه الواجهة لمحاكاة نطاق من التعليمات، أو دالة، ضمن سياق يحدده المستخدم. توفر خيارات لخطافات يحددها المستخدم لكل من التعليمات الفردية وعند مواجهة تعليمات "call". يمكن للمستخدم أن يقرر ما إذا كان المحاكي سيتجاوز استدعاءات الدوال أو يدخل إليها. تتيح هذه الواجهة طريقة سهلة للمستخدم لتحديد قيم لسجلات معينة ومعاملات المكدس. إذا تم تحديد سلسلة بايتات، فسيتم كتابتها إلى ذاكرة المحاكي ويتم كتابة المؤشر إلى السجل أو المتغير المكدسي. بعد المحاكاة، يمكن للمستخدم استخدام دوال الأداة المساعدة لـ flare-emu لقراءة البيانات من الذاكرة أو السجلات المحاكاة، أو استخدام كائن محاكاة Unicorn الذي يتم إرجاعه للاستعلام المباشر. هناك دالة غلاف صغيرة لـ emulateRange تُسمى emulateSelection، يمكن استخدامها لمحاكاة نطاق التعليمات المظللة حاليًا في IDA Pro.
iterate - تُستخدم هذه الواجهة لفرض المحاكاة على طول فروع محددة داخل دالة للوصول إلى هدف معين. يمكن للمستخدم تحديد قائمة بعناوين الأهداف، أو عنوان دالة يتم استخدام قائمة المراجع المتقاطعة لها كأهداف، إلى جانب دالة رد اتصال عند الوصول إلى الهدف. سيتم الوصول إلى الأهداف بغض النظر عن الظروف أثناء المحاكاة التي قد تكون تسببت في اتخاذ فروع مختلفة. كما هو الحال مع واجهة emulateRange، يتم توفير خيارات لخطافات يحددها المستخدم لكل من التعليمات الفردية وعند مواجهة تعليمات "call". مثال على استخدام واجهة iterate هو تحقيق شيء مشابه لما تفعله أداة argtracker الخاصة بنا.
iterateAllPaths - تشبه هذه الواجهة كثيرًا iterate، باستثناء أنه بدلاً من توفير عنوان هدف أو عناوين، فإنك تقدم دالة هدف سيحاول الوصول إلى جميع المسارات من خلالها ومحاكاتها. هذا مفيد عندما تقوم بتحليل شيفرة ترغب في الوصول إلى كل كتلة أساسية في دالة.
emulateBytes – توفر هذه الواجهة طريقة لمحاكاة كتلة من شيفرة شل خارجية ببساطة. لا تتم إضافة البايتات المقدمة إلى قاعدة بيانات IDA ويتم محاكاتها كما هي. يمكن أن يكون هذا مفيدًا لإعداد بيئة المحاكاة. على سبيل المثال، تستخدم flare-emu نفسها هذه الواجهة للتلاعب بسجل نموذجي خاص (MSR) لوحدة المعالجة المركزية ARM64 الذي لا يعرضه Unicorn لتمكين تعليمات النقطة العائمة المتجهة (VFP) والوصول إلى السجلات. يتم إرجاع كائن محاكاة Unicorn لمزيد من الاستعلام من قبل المستخدم.
emulateFrom - تكون هذه الواجهة مفيدة في الحالات التي لا تكون فيها حدود الدالة محددة بوضوح كما هو الحال غالبًا مع الثنائيات المبهمة أو شيفرة شل. توفر عنوان بدء، وسيقوم بالمحاكاة حتى لا يتبقى شيء للمحاكاة أو تقوم بإيقاف المحاكاة في أحد خطافاتك. مع IDA Pro، يمكن استدعاء هذا مع تعيين المعامل strict إلى False لتمكين اكتشاف الشيفرة الديناميكي؛ سيقوم flare-emu بجعل IDA Pro ينشئ تعليمات أثناء مواجهتها أثناء المحاكاة.
لتثبيت flare-emu لـ IDA Pro، ما عليك سوى وضع flare_emu.py و flare_emu_ida.py و flare_emu_hooks.py في دليل python الخاص بـ IDA Pro واستيرادها كوحدة في نصوص 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، وهي غير متوافقة مع الإصدارات السابقة من 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__`، نبدأ بإنشاء نسخة من الفئة `EmuHelper` من `flare-emu`. هذه هي الفئة التي نستخدمها لفعل كل شيء باستخدام `flare-emu`. بعد ذلك، نستخدم واجهة `iterate`، مع تمرير عنوان دالة `decryptString` الخاصة بنا واسم دالة الاستدعاء التي ستستدعيها `EmuHelper` لكل مرجع متقاطع يتم محاكاته حتى.
تستقبل دالة `iterateCallback` نسخة `EmuHelper` المسماة `eh` هنا، بالإضافة إلى عنوان المرجع المتقاطع، والوسائط الممررة لهذه الاستدعاء المحدد، وقاموسًا خاصًا مسمى `userData` هنا. لا يُستخدم `userData` في هذا المثال البسيط، لكن اعتبره سياقًا مستمرًا للمحاكي حيث يمكنك تخزين بياناتك المخصصة. لكن كن حذرًا، لأن `flare-emu` نفسها تستخدم هذا القاموس أيضًا لتخزين معلومات حاسمة تحتاجها لأداء مهامها. إحدى هذه البيانات هي نسخة `EmuHelper` نفسها، المخزنة في المفتاح `"EmuHelper"`. إذا كنت مهتمًا، ابحث في الكود المصدري لمعرفة المزيد عن هذا القاموس. تقوم دالة الاستدعاء هذه ببساطة باستدعاء وظيفة `decrypt`، وطباعة السلسلة المفكوكة، وإنشاء تعليق لها عند عنوان تلك الاستدعاء لـ `decryptString`.