
बाइनरी-ओनली फर्मवेयर हिस्टोरियन जो कच्चे बाइनरी में फंक्शन का पता लगाने के लिए समान बाइनरी से ज्ञात फंक्शन निकालकर सीखता है, जिससे एम्बेडेड फर्मवेयर विश्लेषण के लिए डिसअसेंबली के बिना तेज़ फंक्शन मिलान संभव होता है।
Polypyus समान बाइनरी से ज्ञात फ़ंक्शन निकालकर कच्ची बाइनरी में फ़ंक्शन का पता लगाना सीखता है। इस प्रकार, यह एक फर्मवेयर इतिहासकार है। Polypyus इन बाइनरी को डिसअसेंबल किए बिना काम करता है, जो उन बाइनरी के लिए एक लाभ है जिन्हें डिसअसेंबल करना जटिल है और जहाँ सामान्य उपकरण फ़ंक्शन को चूक जाते हैं। इसके अलावा, केवल बाइनरी दृष्टिकोण इसे बहुत तेज़ बनाता है और कुछ सेकंड में चलता है। हालाँकि, इस दृष्टिकोण के लिए आवश्यक है कि बाइनरी एक ही आर्किटेक्चर के लिए हों और समान कंपाइलर विकल्प हों।
Polypyus Ghidra, IDA, BinDiff, और Diaphora जैसे मौजूदा उपकरणों के वर्कफ़्लो में एकीकृत होता है। उदाहरण के लिए, यह पहले से एनोटेट किए गए फ़ंक्शन आयात कर सकता है और उनसे सीख सकता है, और पाए गए फ़ंक्शन को IDA में आयात करने के लिए निर्यात भी कर सकता है। चूँकि Polypyus काफी सख्त थ्रेशोल्ड का उपयोग करता है, इसने हमारे प्रयोगों में केवल सही मिलान पाए। जबकि इससे मौजूदा उपकरणों की तुलना में कम परिणाम मिलते हैं, फिर भी यह इन मिलानों को IDA में लोड करने के लिए एक अच्छा प्रवेश बिंदु है ताकि इसके ऑटो विश्लेषण परिणामों में सुधार हो और फिर शीर्ष पर BinDiff चलाया जा सके।
कच्ची फर्मवेयर बाइनरी, विशेष रूप से विभिन्न Broadcom और Cypress ब्लूटूथ फर्मवेयर संस्करणों पर काम करते समय, हमने पाया कि IDA ऑटो विश्लेषण अक्सर फ़ंक्शन प्रारंभ को गलत तरीके से पहचानता है। IDA Pro 6.8 में ऑटो विश्लेषण थोड़ा अधिक आक्रामक है, जिससे अधिक परिणाम मिलते हैं लेकिन अधिक गलत सकारात्मक भी। कुल मिलाकर, IDA Pro 7.2 अधिक निराशावादी था, लेकिन बहुत सारे फ़ंक्शन चूक गया। इसके परिणामस्वरूप हमारे फर्मवेयर के बीच IDA Pro 6.8 में केवल कुछ BinDiff मिलान हुए और IDA Pro 7.2 में कोई उपयोगी मिलान नहीं मिला।
दिलचस्प बात यह है कि BinDiff अक्सर उन फ़ंक्शन को पहचानने में विफल रहा जो शाखाओं को छोड़कर, बाइट-समान थे। ध्यान दें कि Polypyus इन बाइट-समान फ़ंक्शनों की तलाश करता है। हम मानते हैं कि BinDiff इन फ़ंक्शनों पर विफल रहता है क्योंकि लापता फ़ंक्शन और गलत सकारात्मक के कारण एक अलग कॉल ग्राफ़ उत्पन्न होता है। कभी-कभी, ये फ़ंक्शन पहले से ही IDA द्वारा पहचाने जाते थे, लेकिन अक्सर, IDA या तो इन्हें कोड के रूप में नहीं पहचानता था या फ़ंक्शन के रूप में चिह्नित नहीं करता था। ध्यान दें कि Diaphora में समान समस्याएँ हैं, क्योंकि यह आगे की प्रक्रिया से पहले IDA द्वारा पहचाने गए फ़ंक्शन निर्यात करता है। निम्नलिखित CYW20735B1 ब्लूटूथ फर्मवेयर बाइनरी पर एक बेंचमार्क दिखाता है जो विभिन्न डिसअसेंबलरों की तुलना करता है और कैसे डिसअसेंबलर विफलताओं के परिणामस्वरूप फ़ॉलो-अप डिफ़िंग समस्याएँ होती हैं।
इसके अलावा, जबकि हमने पाया कि Amnesia कई फ़ंक्शन ढूंढता है, यह कई गलत सकारात्मक भी ढूंढता है। हालाँकि, कई फ़ंक्शनों की शुरुआत में समान स्टैक फ्रेम सेटअप होता है। इस प्रकार, Polypyus के पास एनोटेट इनपुट बाइनरी से सामान्य फ़ंक्शन प्रारंभ सीखने और उनके नाम का मिलान किए बिना फ़ंक्शन की पहचान करने के लिए इसे अन्य बाइनरी पर लागू करने का विकल्प है। यह वैकल्पिक कदम केवल उन क्षेत्रों पर लागू होता है जहाँ पहले कोई फ़ंक्शन स्थित नहीं था, इस प्रकार सामान्य फ़ंक्शन प्रारंभ विधि और मुख्य फ़ंक्शन खोज में कोई विरोध नहीं होता।
चूँकि ये मैचर कच्ची बाइनरी पर काम करते हैं, वे डिसअसेंबलर पर निर्भर नहीं होते हैं। इसका एक महत्वपूर्ण नुकसान भी है: यदि अलग-अलग कंपाइलर विकल्प या एक अलग लक्ष्य आर्किटेक्चर था, तो Polypyus समान फ़ंक्शन का पता नहीं लगाएगा। इसके अलावा, जबकि पहचाने गए मिलान बहुत विश्वसनीय हैं, फ़ंक्शन प्रारंभ पहचान थोड़ी कम विश्वसनीय है, इसलिए बाद का उपयोग सावधानी से करें। निम्नलिखित में, आप देख सकते हैं कि Cypress मूल्यांकन किट एक-दूसरे से बहुत समान हैं, लेकिन MacBook फर्मवेयर बहुत अलग है।
Polypyus एनोटेट फर्मवेयर बाइनरी के संग्रह में सामान्य फ़ंक्शनों की तुलना करके फजी बाइनरी मैचर बनाता है।
वर्तमान में, निम्नलिखित एनोटेशन समर्थित हैं:
patch.elf फ़ाइल, जो एक विशेष ELF फ़ाइल है जिसमें केवल प्रतीक परिभाषाएँ होती हैं।.symdefs फ़ाइल जैसा कि अधिकांश ARM कंपाइलरों द्वारा निर्मित होता है।.csv फ़ाइल जिसका प्रारूप firmware फ़ोल्डर में प्रलेखित है।इन एनोटेशन में ज्ञात फ़ंक्शनों का पता, आकार और नाम होता है। इतिहास संग्रह में इनपुट बाइनरी में जितनी अधिक समानताएँ होंगी, Polypyus के प्रदर्शन और परिणामों के लिए उतना ही बेहतर होगा। कई थोड़े अलग-अलग फ़ंक्शन दिए जाने पर, Polypyus बहुत अच्छे मैचर बनाता है।
Polypyus के लिए Python 3 >= 3.6 आवश्यक है। हम निम्नलिखित स्थापना के लिए virtualenv के उपयोग की सलाह देते हैं। इस रिपॉजिटरी को क्लोन करें और इस फ़ोल्डर में चलाएँ:
pip install .
स्थापना के बाद निम्नलिखित कमांड उपलब्ध हैं:
polypyus-guipolypyus-cliPolypyus एक ग्राफिकल और कमांड-लाइन इंटरफ़ेस के माध्यम से उपलब्ध है।
GUI polypyus-gui और CLI polypyus-cli दोनों ही आह्वान के दौरान ये तर्क लेते हैं:
--verbose वर्बोसिटी स्तर है। डिफ़ॉल्ट रूप से, यह चेतावनियाँ दिखाता है -v जानकारी दिखाता है -vv डीबग जानकारी दिखाता है।
--project प्रोजेक्ट फ़ाइल का स्थान सेट करता है। यह या तो एक फ़ाइल पथ है या ":memory:"।
--help सहायता संदेश दिखाएँ।
प्रोजेक्ट विकल्प आपको विभिन्न संदर्भों के लिए अपने काम को विभिन्न फ़ाइलों में संग्रहीत करने और उन्हें फिर से खोलने की सुविधा प्रदान करता है।
सामान्य GUI वर्कफ़्लो विंडो के बाएँ से दाएँ जाता है।
पहले, इतिहास में बाइनरी जोड़ी जाती हैं। फिर, इतिहास में प्रविष्टियों के लिए प्रतीक एनोटेशन जोड़े जाते हैं।
उसके बाद, लक्ष्य बाइनरी जोड़ी जा सकती हैं।
मिलान के लिए, Create matchers from history पर क्लिक करें। एक बार मैचर बन जाने के बाद, एकल लक्ष्य
चुने जा सकते हैं, या batch match चुनकर सभी लक्ष्यों का मिलान किया जा सकता है।
अंत में, निष्कर्षों को .csv फ़ाइल में निर्यात किया जा सकता है।
निम्नलिखित में आप एक डेमो वीडियो देख सकते हैं जहाँ Polypyus को दो इनपुट बाइनरी से सीखने, उन्हें एनोटेट करने, मैचर बनाने और एक नई बाइनरी पर मिलान लागू करने में केवल कुछ सेकंड लगते हैं।
CLI का उपयोग करने का लाभ इसकी स्वचालित होने की क्षमता है। अभी के लिए, CLI का आउटपुट प्रारूप परिवर्तन के अधीन है। हालाँकि, यहाँ इसे कॉल करने का एक उदाहरण है:
polypyus-cli --history firmware/history/20819-A1.bin --annotation firmware/history/20819-A1_patch.elf --history firmware/history/20735B1.bin --annotation firmware/history/20735B1_patch.elf --project test.sqlite
polypyus-cli --target firmware/history/20739B1.bin --project test.sqlite
पहला कमांड test.sqlite को एक नई प्रोजेक्ट फ़ाइल के रूप में बनाता है और 20819-A1.bin और 20735B1.bin को उनके संबंधित patch.elf फ़ाइलों के साथ आयात करता है।
दूसरा आह्वान उसी प्रोजेक्ट फ़ाइल का पुन: उपयोग करता है और बाइनरी 20739B1.bin के विरुद्ध मिलान करता है।
प्रत्येक कमांड के लिए, --history और --annotation की संख्या का मिलान होना चाहिए।
इन दो कमांडों को पहले कमांड में --target तर्क जोड़कर एक में भी जोड़ा जा सकता है।
एक पेपर जो आंतरिक कार्यप्रणाली की व्याख्या करता है, Workshop on Binary Analysis Research (BAR) 2021 में Polypyus - The Firmware Historian शीर्षक से प्रकाशित हुआ था। कुछ और विवरण जान की मास्टर थीसिस अंतिम प्रस्तुति में भी शामिल हैं, जो पारंपरिक बाइनरी डिफ़िंग दृष्टिकोणों के साथ ARM Thumb2 मोड में काम करते समय आने वाली समस्याओं और वैकल्पिक केवल-बाइनरी दृष्टिकोण कैसे काम करता है, को कवर करता है।