
iOS kernelcaches का विश्लेषण करने के लिए एक IDA टूलकिट।
यह फ़ोर्क IDA 9.x / Python 3 / iOS 27.0 beta 1 पर काम करने के लिए अपडेट किया गया था
ida_kernelcache, IDA Pro के लिए एक IDAPython मॉड्यूल है जो iOS कर्नेलकैश के साथ काम करना आसान बनाता है। मॉड्यूल निम्नलिखित कार्य प्रदान करता है:
__PRELINK_INFO सेगमेंट को Python डिक्शनरी में पार्स करें।__got सेक्शन में ऑफ़सेट और __stubs सेक्शन में स्टब फ़ंक्शंस को सिंबलिकेट करें।मुख्य प्रोसेसिंग फ़ंक्शन को किसी भी मैन्युअल विश्लेषण या रिवर्स इंजीनियरिंग से पहले चलाने के लिए डिज़ाइन किया गया है। डिफ़ॉल्ट सेटिंग्स के साथ, IDA कर्नेलकैश में बहुत सारी उपयोगी जानकारी को मिस कर देता है। ये स्क्रिप्ट्स कर्नेलकैश की ज्ञात संरचना का लाभ उठाकर उपयोगी जानकारी को स्वचालित रूप से प्रसारित करने में IDA की मदद करती हैं।
मॉड्यूल में मौजूद मानक कार्यक्षमता के अलावा, ida_kernelcache में iOS कर्नेलकैश का विश्लेषण करना आसान बनाने के लिए कई स्क्रिप्ट्स शामिल हैं। उदाहरण के लिए, आप किसी फ़ंक्शन द्वारा उपयोग किए जाने वाले C स्ट्रक्ट्स को स्वचालित रूप से उत्पन्न करने के लिए स्क्रिप्ट्स का उपयोग कर सकते हैं।
ida_kernelcache में उपयोग की जाने वाली कई तकनीकें memctl के लिए विकसित की गई थीं और सीधे उससे उधार ली गई हैं।
ida_kernelcache का परीक्षण IDA Pro 6.95 के साथ iOS संस्करणों 10.1.1, 11.0, 11.2, 11.3.1 और 12.0 बीटा के कर्नेलकैश पर किया गया है। वर्तमान में केवल iOS 10 और उसके बाद के Arm64 कर्नेलकैश समर्थित हैं।
आपके पास पहले से ही IDA में एक डीकंप्रेस्ड कर्नेलकैश फ़ाइल लोड होनी चाहिए। आप ऑनलाइन Apple से किसी विशेष IPSW को डाउनलोड करने का URL पा सकते हैं, और कर्नेलकैश को डीकंप्रेस करने में सक्षम कई सार्वजनिक उपकरण (memctl सहित) मौजूद हैं।
IDA में, मेन्यू बार से "File" -> "Script file..." चुनें, फिर मुख्य निर्देशिका में ida_kernelcache.py स्क्रिप्ट चुनें। यह ida_kernelcache मॉड्यूल को IDAPython इंटरप्रेटर में ida_kernelcache और kc नामों से लोड करेगा। IDAPython प्रॉम्प्ट पर, kc.kernelcache_process() टाइप करें और कर्नेलकैश का विश्लेषण शुरू करने के लिए Enter दबाएं। यह फ़ंक्शन ida_kernelcache द्वारा समर्थित सभी प्रमुख विश्लेषण करता है। फ़ंक्शन कई मिनट तक चलेगा क्योंकि IDA नए फ़ंक्शंस की पहचान और विश्लेषण करता है।
ida_kernelcache पतों के लिए उपयोगकर्ता नामों को अधिलेखित न करने का प्रयास करेगा। इसका मतलब है कि यदि kernelcache_process के साथ आरंभीकरण से पहले कर्नेलकैश का मैन्युअल रूप से विश्लेषण किया गया है, तो परिणाम उतने गहन नहीं हो सकते क्योंकि उपयोगकर्ता-निर्दिष्ट नाम स्वचालित नाम प्रसार को अवरुद्ध कर सकते हैं। हालांकि, इसकी भी कोई गारंटी नहीं है कि ida_kernelcache पिछले विश्लेषण को खराब नहीं करेगा, इसलिए यदि आप पहले से विश्लेषण की गई कर्नेलकैश फ़ाइल पर kernelcache_process चलाने का निर्णय लेते हैं, तो पहले बैकअप बना लें।
ida_kernelcache को ida_kernelcache.py के माध्यम से लोड करने का इरादा है; ida_kernelcache निर्देशिका में उपमॉड्यूल को सीधे लोड करने का इरादा नहीं है। हालांकि, ida_kernelcache इनमें से कई उपमॉड्यूल की कार्यक्षमता को उजागर करता है। यहाँ बताया गया है कि उनमें से प्रत्येक क्या करता है:
ida_utilities:
यह मॉड्यूल IDA के कुछ फ़ंक्शंस को लपेटता है ताकि उपयोग में आसान API प्रदान किया जा सके। विशेष रूप से उपयोगी हैं is_mapped, read_word, read_struct, force_function, और ReadWords। is_mapped जाँचता है कि कोई पता मैप किया गया है या नहीं, और वैकल्पिक रूप से इसमें कोई ज्ञात मान है या नहीं। read_word किसी पते से एक चर-आकार का शब्द पढ़ता है। read_struct एक संरचना प्रकार को Python डिक्शनरी या Python एक्सेसर ऑब्जेक्ट में पढ़ता है, जो डेटा संरचनाओं को पार्स करना बहुत आसान बनाता है। force_function किसी पते को IDA में किसी फ़ंक्शन की शुरुआत में बदलने के लिए कई तरकीबें आज़माता है। ReadWords एक जनरेटर है जो एक श्रेणी में डेटा शब्दों और उनके पतों पर पुनरावृति करता है।
build_struct: इस आंतरिक मॉड्यूल में संरचना पर एक्सेस के अनुक्रम के आधार पर स्वचालित रूप से IDA संरचना को पॉप्युलेट करने के लिए उपयोगिताएँ हैं।
class_struct:
यह मॉड्यूल C++ वर्चुअल मेथड टेबल्स और क्लासेस का प्रतिनिधित्व करने वाली IDA संरचनाएँ उत्पन्न करने के लिए फ़ंक्शन प्रदान करता है। initialize_vtable_structs (सिंबलिकेटेड) वर्चुअल मेथड टेबल्स को स्कैन करता है और वर्चुअल मेथड पॉइंटर्स को होल्ड करने के लिए IDA संरचनाएँ बनाता है। initialize_class_structs प्रत्येक क्लास के फ़ील्ड तक पहुँच की पहचान करने के लिए वर्चुअल मेथड्स पर डेटा प्रवाह विश्लेषण करता है, फिर क्लासेस का प्रतिनिधित्व करने के लिए IDA संरचनाएँ बनाता है। वे निर्देश जो किसी फ़ील्ड को संदर्भित करते प्रतीत होते हैं, उन्हें संरचना ऑफ़सेट संदर्भों में भी बदल दिया जाता है। अधिक विवरण के लिए मॉड्यूल डॉकस्ट्रिंग देखें।
classes:
यह मॉड्यूल ClassInfo प्रकार को परिभाषित करता है जो कर्नेलकैश में C++ क्लासेस के बारे में जानकारी रखता है और कर्नेलकैश को स्कैन करके क्लासेस का पता लगाने और क्लास नामों से ClassInfo ऑब्जेक्ट्स के मानचित्रण के साथ वैश्विक class_info शब्दकोश को पॉप्युलेट करने के लिए collect_class_info फ़ंक्शन प्रदान करता है। ClassInfo प्रकार प्रत्येक C++ क्लास के लिए क्लास का नाम, OSMetaClass इंस्टेंस, वर्चुअल मेथड टेबल और सुपरक्लास का नाम रिकॉर्ड करता है। इसके अतिरिक्त, प्रत्येक ClassInfo ऑब्जेक्ट सुपरक्लास के ClassInfo और सभी प्रत्यक्ष उपवर्गों के ClassInfo के संदर्भों को संग्रहीत करता है, जिससे क्लास पदानुक्रम की जाँच करना और उसे पार करना आसान हो जाता है। collect_class_info वैश्विक vtables सेट में सभी वर्चुअल मेथड टेबल्स का सेट भी संग्रहीत करता है।
data_flow: इस आंतरिक मॉड्यूल में डेटा प्रवाह संचालन शामिल हैं जिनका उपयोग ida_kernelcache के शेष भाग द्वारा किया जाता है।
kernel:
यह मॉड्यूल base और prelink_info वैश्विक चर प्रदान करता है। base कर्नेल इमेज का आधार पता है (कर्नेल के Mach-O हेडर की शुरुआत)। prelink_info पार्स किया गया __PRELINK_INFO शब्दकोश है।
kplist:
यह मॉड्यूल कर्नेल-शैली plist को पार्स करने के लिए kplist_parse फ़ंक्शन प्रदान करता है।
metaclass:
यह मॉड्यूल initialize_metaclass_symbols फ़ंक्शन प्रदान करता है जो प्रत्येक ज्ञात OSMetaClass इंस्टेंस के लिए एक प्रतीक जोड़ता है।
offset:
यह मॉड्यूल initialize_data_offsets और initialize_offset_symbols फ़ंक्शन प्रदान करता है। पहला उन पॉइंटर्स की तलाश में सेगमेंट को स्कैन करता है जिन्हें ऑफ़सेट में परिवर्तित किया जा सकता है। दूसरा प्रत्येक kext के __got सेक्शन में ऑफ़सेट को सिंबलिकेट करता है यदि ऑफ़सेट के लक्ष्य में कोई प्रतीक है।
segment:
यह मॉड्यूल IDA के सेगमेंट को अधिक उपयोगी बनाने के लिए उनका नाम बदलने के लिए initialize_segments फ़ंक्शन प्रदान करता है। डिफ़ॉल्ट रूप से, IDA बंडल पहचानकर्ता के अनुमान को क्षेत्र का वर्णन करने वाले Mach-O सेक्शन के साथ जोड़कर सेगमेंट नाम बनाता प्रतीत होता है। initialize_segments __PRELINK_INFO शब्दकोश से वास्तविक बंडल पहचानकर्ता निकालता है और प्रत्येक सेगमेंट का नाम बदलकर उसमें बंडल पहचानकर्ता, Mach-O सेगमेंट और Mach-O सेक्शन शामिल करता है। इससे, उदाहरण के लिए, __TEXT.__const और __DATA_CONST.__const के बीच अंतर करना संभव हो जाता है। यह मॉड्यूल kernelcache_kext फ़ंक्शन (शीर्ष स्तर पर पुनः निर्यात) भी प्रदान करता है ताकि निर्दिष्ट पते वाले kext का निर्धारण किया जा सके (केवल पुराने iOS 11 स्प्लिट-kext कर्नेलकैश प्रारूप पर)।