
बाइनरी-ओनली फर्मवेयर हिस्टोरियन जो कच्चे बाइनरी में फंक्शन का पता लगाने के लिए समान बाइनरी से ज्ञात फंक्शन निकालकर सीखता है, जिससे एम्बेडेड फर्मवेयर विश्लेषण के लिए डिसअसेंबली के बिना तेज़ फंक्शन मिलान संभव होता है।
Polypyus समान बाइनरी से ज्ञात फ़ंक्शन निकालकर कच्ची बाइनरी में फ़ंक्शन का पता लगाना सीखता है। इस प्रकार, यह एक फर्मवेयर इतिहासकार है। Polypyus इन बाइनरी को डिसअसेंबल किए बिना काम करता है, जो उन बाइनरी के लिए एक लाभ है जिन्हें डिसअसेंबल करना जटिल है और जहाँ सामान्य उपकरण फ़ंक्शन को चूक जाते हैं। इसके अलावा, केवल बाइनरी दृष्टिकोण इसे बहुत तेज़ बनाता है और कुछ सेकंड में चलता है। हालाँकि, इस दृष्टिकोण के लिए आवश्यक है कि बाइनरी एक ही आर्किटेक्चर के लिए हों और समान कंपाइलर विकल्प हों।
Polypyus Ghidra, IDA, BinDiff, और Diaphora जैसे मौजूदा उपकरणों के वर्कफ़्लो में एकीकृत होता है। उदाहरण के लिए, यह पहले से एनोटेट किए गए फ़ंक्शन आयात कर सकता है और उनसे सीख सकता है, और पाए गए फ़ंक्शन को IDA में आयात करने के लिए निर्यात भी कर सकता है। चूँकि Polypyus काफी सख्त थ्रेशोल्ड का उपयोग करता है, इसने हमारे प्रयोगों में केवल सही मिलान पाए। जबकि इससे मौजूदा उपकरणों की तुलना में कम परिणाम मिलते हैं, फिर भी यह इन मिलानों को IDA में लोड करने के लिए एक अच्छा प्रवेश बिंदु है ताकि इसके ऑटो विश्लेषण परिणामों में सुधार हो और फिर शीर्ष पर BinDiff चलाया जा सके।
कच्ची फर्मवेयर बाइनरी, विशेष रूप से विभिन्न Broadcom और Cypress ब्लूटूथ फर्मवेयर संस्करणों पर काम करते समय, हमने पाया कि IDA ऑटो विश्लेषण अक्सर फ़ंक्शन प्रारंभ को गलत तरीके से पहचानता है। IDA Pro 6.8 में ऑटो विश्लेषण थोड़ा अधिक आक्रामक है, जिससे अधिक परिणाम मिलते हैं लेकिन अधिक गलत सकारात्मक भी। कुल मिलाकर, अधिक निराशावादी था, लेकिन बहुत सारे फ़ंक्शन चूक गया। इसके परिणामस्वरूप हमारे फर्मवेयर के बीच में केवल कुछ मिलान हुए और में कोई उपयोगी मिलान नहीं मिला।
दिलचस्प बात यह है कि 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 मोड में काम करते समय आने वाली समस्याओं और वैकल्पिक केवल-बाइनरी दृष्टिकोण कैसे काम करता है, को कवर करता है।
patch.elf या .symdefs प्रारूप में लीक हुए प्रतीकों में केवल फ़ंक्शन और
ग्लोबल वेरिएबल नाम होते हैं। हालाँकि, WICED Studio 6.2 और 6.4 में कुछ .pdom Eclipse प्रोजेक्ट फ़ाइलें भी हैं। इनमें अतिरिक्त प्रकार की जानकारी होती है। Eclipse इनका उपयोग आंतरिक रूप से ऑटो पूर्णता, फ़ंक्शन खोज आदि के लिए करता है, और हम प्रकार जानकारी जोड़ने के लिए रिवर्स में इनका उपयोग कर सकते हैं। चूँकि .pdom फ़ाइलों में केवल आंशिक, कैश की गई जानकारी होती है, कई को संयोजित करना सहायक हो सकता है।
पहले चरण में, हम .pdom प्रकार जानकारी को SQLite डेटाबेस में निर्यात करते हैं। निर्यात
में थोड़ा समय लगता है, लेकिन इसे रोका भी जा सकता है और बाद में जारी रखा जा सकता है। निर्यात इस प्रकार काम करता है:
java -jar pdom/export/export.jar -P BCM20739-B0.1462220149391.pdom
PDOM आयात IDA डेटाबेस में फ़ंक्शन नामों की खोज करता है, प्रकार जानकारी खोजने के लिए उन्हें PDOM में देखता है, और फिर उस प्रकार जानकारी को IDA डेटाबेस में लागू करता है। इस प्रकार, IDA डेटाबेस में पहले से सही फ़ंक्शन नाम होने चाहिए। सिद्धांत रूप में, ये Polypyus के import_export स्क्रिप्ट से बनाए जा सकते हैं। हालाँकि, कुछ अधिक उन्नत स्क्रिप्ट जो PDOM आयात का समर्थन करती हैं, वे patch.elf अनुभागों को भी संभाल सकती हैं। इम्पोर्टर को इस प्रकार चलाएँ:
T=0x1 (Alt-g) पर सेट करें।patch.elf फ़ाइल चुनें (Select file)।20739mapb0.h भी आयात कर सकते हैं ताकि हार्डवेयर रजिस्टरों को नाम दिया जा सके (Import map.h)।इस स्क्रिप्ट का परीक्षण IDA Pro 7.4 और 7.5 पर किया गया था।
कुछ आंतरिक परीक्षण के बाद, हम IDA Pro और Polypyus के साथ काम करते समय निम्नलिखित वर्कफ़्लो की अनुशंसा कर सकते हैं:
Alt-g, T=0x1)।0x0 पर rx के साथ, RAM 0x200000 पर rwx के साथ (कम से कम ब्लूटूथ फर्मवेयर के लिए)।0x4 पर एक 4-बाइट ऑफ़सेट (o) है।
CYW20735 फर्मवेयर पर यह 0x3bc+1 की ओर इंगित करता है। एक बाइट पीछे जाएँ और एक फ़ंक्शन बनाएँ (p)।...अब आपका IDA डेटाबेस कुछ हद तक उपयोगी हो सकता है :) ARM Thumb2 के भीतर डिसअसेंबलर अभी भी बहुत सी चीजों में विफल रहता है, लेकिन IDA अपने आप जो कुछ भी करता है, उससे कहीं बेहतर है।
firmware फ़ोल्डर में प्रतीकों के साथ और बिना विभिन्न फर्मवेयर हैं।
इतिहास में सब कुछ प्रतीकों के साथ है, लक्ष्य में सब कुछ प्रतीकों के बिना है।
| चिप | डिवाइस | निर्माण तिथि | प्रतीक |
|---|---|---|---|
| BCM20703A2 | MacBook/iMac 2016-2017 | Oct 22 2015 | ✔ |
| CYW20719B1 | Evaluation board | Jan 17 2017 | ✔ |
| CYW20735B1 | Evaluation board | Jan 18 2018 | ✔ |
| CYW20819A1 | Evaluation board | May 22 2018 | ✔ |
| चिप | डिवाइस | निर्माण तिथि | प्रतीक |
|---|---|---|---|
| BCM2046A2 | iMac Late 2009 | 2007? | - |
| BCM2070B0 | MacBook 2011, Thinkpad T420 | Jul 9 2008 | - |
| BCM20702A1 | Asus USB Dongle | Feb (?) 2010 | - |
| BCM4345B0 | iPhone 6 | Jul 15 2013 | - |
| BCM4335C0 | Google Nexus 5 | Dec 11 2012 | - |
| BCM4345B0 | Google Nexus 6P / Galaxy S6 | Oct 23 2014 | - |
| BCM43430A1 | Raspberry Pi 3 and Zero W | Jun 2 2014 | - |
| BCM4345C0 | Raspberry Pi 3+ and 4 | Aug 19 2014 | - |
| BCM4347B0 | Samsung Galaxy S8 series | Jun 3 2016 | - |
| BCM4375B1 | Samsung Galaxy S10/20 series | Apr 13 2018 | - |
| BCM4378B1 | iPhone 11/SE2 | Oct 25 2018 | स्ट्रिंग्स |
Samsung श्रृंखला के लिए, S8 में Note 8 और S8+ आदि भी शामिल हैं, और S10/S20 में S10e से लेकर Note 20 5G तक सब कुछ शामिल है।
डंप गुणवत्ता भिन्न हो सकती है, कुछ RAM के साथ हैं और कुछ केवल ROM हैं। हमारे पास इस सूची में अधिकांश उपकरणों तक पहुँच है। यदि आपको सबसे हाल के पैच स्तरों और RAM सहित डंप की आवश्यकता है, तो हमसे संपर्क करने में संकोच न करें।
पेपर में उल्लिखित कुछ उपकरण यहाँ शामिल नहीं हैं, क्योंकि ये केवल शोध उपकरण नहीं हो सकते हैं, आदि। कुछ iPhones और MacBooks भी गायब हैं, क्योंकि हमारे पास वे केवल शोध उपकरणों के रूप में हैं, लेकिन मूल डंप ऐसा नहीं था। ये उपकरण जल्द ही जोड़े जाएँगे :)
इस रिपॉजिटरी में एक .editorconfig फ़ाइल है। यह इंडेंशन शैली, वर्णसेट और पंक्ति विभाजकों को कॉन्फ़िगर करती है। योगदान करते समय इस कॉन्फ़िगरेशन का पालन करें, जो .editorconfig के लिए IDE प्लगइन का उपयोग करने पर आसान हो सकता है।
परीक्षण निर्भरताएँ स्थापित करने के लिए निष्पादित करें
pip install '.[test]'
यह केवल परीक्षण मामलों को निष्पादित करने के लिए आवश्यक पैकेज स्थापित करेगा।
विकास निर्भरताएँ, उदाहरण के लिए पैकेज प्रकारों के लिए स्टब प्रदान करती हैं। उन्हें स्थापित करने के लिए चलाएँ
pip install '.[development]'
pytest सभी परीक्षण चलाएगा।
प्रोजेक्ट Python के विभिन्न संस्करणों के विरुद्ध स्थानीय रूप से परीक्षण चलाने के लिए tox का उपयोग करता है। Tox को संस्करण 3.6, 3.7, 3.8 और 3.9 के विरुद्ध परीक्षण करने के लिए सेट किया गया है। Tox चलाने के लिए परीक्षण निर्भरताएँ स्थापित करें और Python के इन 4 उल्लिखित संस्करणों को स्थापित करें। Python के कई संस्करणों को स्थापित और प्रबंधित करने का हमारा अनुशंसित तरीका pyenv है।
चरण:
pyenv install 3.9.1
pyenv install 3.8.6
pyenv install 3.7.9
pyenv install 3.6.12
pyenv virtualenv 3.9.1 polypyus
pyenv local polypyus 3.8.6 3.7.9 3.6.12
pip install '.[test]'
pip install '.[development]'
tox चलाएँ।Polypyus स्वचालित परीक्षण रन और कुछ लिंटिंग के लिए GitHub Actions का उपयोग करता है। यदि आप चाहते हैं, तो आप प्री-कमिट गिट हुक पर लिंटिंग चरणों को स्थानीय रूप से चला सकते हैं।
हर बार एक नया कमिट बनाने से पहले यह लिंटिंग को ट्रिगर करेगा और उन समस्याओं को दिखाएगा जो इस कोड को GitHub Actions लिंटिंग चरण में सफल होने से रोकेंगी। यह बदली हुई फ़ाइलों को black के साथ भी फ़ॉर्मेट करेगा।
pip install '.[development]'
pre-commit install
हम Polypyus लोगो बनाने के लिए Anna Stichling को धन्यवाद देते हैं। हम उनकी प्रतिक्रिया के लिए Christian Blichmann और Joxean Koret को भी धन्यवाद देते हैं।
Polypyus ओपन-सोर्स है और GPLv3 के तहत लाइसेंस प्राप्त है।