
iOS kernelcache रिवर्स इंजीनियरिंग के लिए एक Ghidra फ्रेमवर्क
यह फ्रेमवर्क Kernelcache रिवर्स इंजीनियरिंग में मेरे अनुभव का अंतिम उत्पाद है, मैं आमतौर पर कर्नेल और इसके एक्सटेंशन की मैन्युअल ऑडिट करके कमजोरियों की तलाश करता हूं और Ghidra में अधिकांश चीजों को स्वचालित कर दिया है जिन्हें मैं वास्तव में रिवर्सिंग की प्रक्रिया को तेज करने के लिए देखना चाहता था, और यह प्रभावी साबित हुआ है और बहुत समय बचाता है। यह फ्रेमवर्क iOS 12/13/14/15 और macOS 11/12 (दोनों kernelcache और एकल KEXT) पर काम करता है और इसे जनता के लिए इस इरादे से बनाया गया है कि लोग अपने स्वयं के वातावरण को तैयार करने के संघर्ष के बिना iOS कर्नेल पर शोध शुरू कर सकें। जैसा कि मेरा मानना है, यह फ्रेमवर्क (इसमें प्रदान किए गए टूलसेट और IOKit के कुछ बुनियादी ज्ञान के साथ) Kernelcache में हैकिंग शुरू करने के लिए पर्याप्त है।
यह फ्रेमवर्क पूरी तरह से Python में लिखा गया है, और इसे अन्य टूल बनाने के लिए बढ़ाया जा सकता है, यह कुछ बुनियादी API प्रदान करता है जिनका उपयोग आप लगभग किसी भी प्रोजेक्ट में कर सकते हैं और लंबे मैनुअल को पढ़ने से समय बचा सकते हैं, आपका utils/ निर्देशिका में मुख्य कार्यक्षमताओं को पढ़ने के लिए स्वागत है।
Ghidra Kernelcache का विश्लेषण करने में अच्छा है, लेकिन अन्य RE टूल की तरह, इसे कुछ मैन्युअल काम की आवश्यकता होती है, ghidra_kernelcache शुरुआत में और रिवर्स इंजीनियरिंग करते समय भी चीजों को ठीक करने के लिए एक अच्छा प्रवेश बिंदु प्रदान करता है, जिससे एक अच्छा डीकंपाइलर आउटपुट मिलता है।
@_bazad द्वारा IDAPro में एक समान प्रोजेक्ट है जिसे ida_kernelcache कहा जाता है जो IDA में कर्नेल इमेज के साथ काम करने वाले शोधकर्ताओं के लिए एक अच्छा प्रवेश बिंदु प्रदान करता है, मेरा फ्रेमवर्क Brandon के काम के समान दिखता है, और kernelcache के साथ काम करने की प्रक्रिया को कम दर्दनाक बनाने के लिए और अधिक सुविधाएं प्रदान करके आगे बढ़ता है।
::externalMethod() और ::getTargetAndMethodForIndex() दोनों के लिए बाहरी मेथड की डिस्पैच टेबल का ऑटो फिक्सिंग.ये सुविधाएं अलग-अलग टूल के रूप में बनाई गई हैं जिन्हें की शॉर्टकट द्वारा या टूलबार में उनके आइकन पर क्लिक करके निष्पादित किया जा सकता है।
रिपॉजिटरी को क्लोन करें :```sh git clone https://github.com/0x36/ghidra_kernelcache.git
**महत्वपूर्ण नोट**: यह प्रोजेक्ट Ghidra 10.1_PUBLIC और 10.2_DEV पर परीक्षित किया गया है और पिछले संस्करणों के साथ संगत नहीं है।
*`Windows → Script Manager`* पर जाएँ, *`script Directory`* पर क्लिक करें, फिर *`ghidra_kernelcache`* को निर्देशिका पथ सूची में जोड़ें।
*`Windows → Script Manager`* पर जाएँ, *scripts* सूची में, *`iOS→kernel`* श्रेणी पर जाएँ और वहाँ देखे गए प्लगइन्स को चेक करें, वे GHIDRA टूलबार में दिखाई देंगे।
[logos/](https://github.com/0x36/ghidra_kernelcache/tree/master/logos) निर्देशिका में, आप प्रत्येक टूल के लिए अपने स्वयं के लोगो रख सकते हैं।
## iOS kernelcache प्रतीकीकरण
`ghidra_kernelcache` को पहले चरण में [iometa](https://github.com/Siguza/iometa/) (जिसे [@s1guza](https://twitter.com/s1guza) ने बनाया है) की आवश्यकता होती है, जो कर्नेल बाइनरी में C++ क्लास जानकारी प्रदान करने वाला एक शक्तिशाली उपकरण है। सबसे अच्छी बात यह है कि यह एक स्वतंत्र बाइनरी के रूप में काम करता है, इसलिए आउटपुट को आपके पसंदीदा RE फ्रेमवर्क में केवल पार्स करके आयात किया जा सकता है। मेरा फ्रेमवर्क iometa के आउटपुट को लेता है और प्रतीकीकरण और वर्चुअल तालिकाओं को ठीक करने के लिए पार्स करता है।
### उपयोग
कर्नेल को डीकंप्रेस करने के बाद, निम्नलिखित कमांड चलाएँ:```sh
$ iometa -n -A /tmp/kernel A10-legacy.txt > /tmp/kernel.txt
# if you want also to symbolicate using jtool2
$ jtool2 --analyze /tmp/kernel
Ghidra में kernelcache लोड करें, बैच आयात का उपयोग न करें, इसे Mach-O इमेज के रूप में लोड करें।
Kernelcache के लोड और स्वचालित विश्लेषण के बाद, टूलबार में दिखाए गए आइकन पर क्लिक करें या बस Meta-Shift-K दबाएँ, फिर iometa आउटपुट का पूरा पथ डालें जो हमारे मामले में /tmp/kernel.txt है।
यदि आप jtool2 प्रतीकों का उपयोग करना चाहते हैं, तो आप iOS→kernel श्रेणी में स्थित jsymbol.py का भी उपयोग कर सकते हैं।
पूर्ण API उदाहरण ghidra_kernelcache/kc.py में हैं।
→ यहाँ क्लास ऑब्जेक्ट्स के हेरफेर के कुछ उदाहरण हैं:```py from utils.helpers import * from utils.class import * from utils.iometa import ParseIOMeta
ff = "/Users/mg/ghidra_ios/kernel.txt" iom = ParseIOMeta(ff) Obj = iom.getObjects() kc = kernelCache(Obj)
kc.process_all_classes()
kc.process_classes_for_bundle("com.apple.iokit.IOSurface")
kc.process_classes_for_bundle("kernel")
kc.process_class("IOGraphicsAccelerator2")
kc.clear_class_structures()
kc.update_classes_vtable()
kc.explore_pac()
जैसा कि आप देख सकते हैं, आप kernelcache को पूरी तरह या आंशिक रूप से प्रतीकीकृत (symbolicate) कर सकते हैं, यदि आंशिक प्रतीकीकरण चुना गया है, तो `ghidra_kernelcache` आगे बढ़ने से पहले स्वचालित रूप से सभी वर्ग निर्भरताओं का निर्माण करेगा।
यदि आप पूरे kernelcache (पूर्ण प्रतीकीकरण) के विरुद्ध स्क्रिप्ट चलाते हैं, तो `ghidra_kernelcache` को कर्नेल इमेज का विश्लेषण करने में कई मिनट लगेंगे।
एक बार समाप्त होने पर, Ghidra निम्नलिखित प्रदान करेगा:
→ बुकमार्क फ़िल्टर में "iOS" नामक एक नई श्रेणी जोड़ी गई है:
<img src="https://raw.githubusercontent.com/0x36/ghidra_kernelcache/master/screenshots/image1.png" alt="image1" width="200"/>
→ IOKit वर्ग वर्चुअल टेबल्स को बेहतर और तेज़ वर्चुअल टेबल खोज के लिए 'iOS' बुकमार्क में जोड़ा जाता है, आप केवल सर्च बार में अक्षर, शब्द या kext बंडल प्रदान करके kext या वर्ग खोज सकते हैं।
<img src="https://raw.githubusercontent.com/0x36/ghidra_kernelcache/master/screenshots/image2.png" alt="image2"/>
→ वर्चुअल टेबल को ठीक करना: अज्ञात कोड को डिसएसेंबल/कंपाइल करना, नेमस्पेस ठीक करना, वर्ग विधियों को पुनः प्रतीकीकृत करना और प्रत्येक विधि पर फंक्शन डेफिनिशन लागू करना:
<img src="https://raw.githubusercontent.com/0x36/ghidra_kernelcache/master/screenshots/image3.png" alt="image3"/>
→ वर्ग नेमस्पेस का निर्माण और प्रत्येक विधि को उसके संगत नेमस्पेस में रखना:
<img src="https://raw.githubusercontent.com/0x36/ghidra_kernelcache/master/screenshots/image4.png" alt="image4"/>
→ वर्ग पदानुक्रम के सम्मान के साथ वर्ग संरचना बनाना:
<img src="https://raw.githubusercontent.com/0x36/ghidra_kernelcache/master/screenshots/image5.png" alt="image5"/>
→ वर्ग vtable बनाना, और प्रत्येक विधि की अपनी विधि परिभाषा होती है जिससे डीकंपाइलेशन आउटपुट बेहतर होता है:
<img src="https://raw.githubusercontent.com/0x36/ghidra_kernelcache/master/screenshots/image6.png" alt="image6"/>
पूर्ण कार्यान्वयन [`utils/class.py.`](https://github.com/0x36/ghidra_kernelcache/blob/master/utils/class.py) में पाया जा सकता है।
यहाँ `ghidra_kernelcache` का उपयोग करके प्रतीकीकरण से पहले/बाद के कुछ स्क्रीनशॉट हैं:
<img src="https://raw.githubusercontent.com/0x36/ghidra_kernelcache/master/screenshots/image7.png" alt="image7"/>
<img src="https://raw.githubusercontent.com/0x36/ghidra_kernelcache/master/screenshots/image8.png" alt="image8"/>
## macOS Kext प्रतीकीकरण
---
`ghidra_kernelcache` macOS समर्थन ARM64e और x86_64 आर्किटेक्चर के लिए kernelcache और एकल KEXT प्रतीकीकरण दोनों के लिए है।
**महत्वपूर्ण:** इस लेखन के समय Ghidra पूरे macOS kernelcache को पार्स करने में असमर्थ है, लेकिन प्रारंभिक विश्लेषण के लिए इसे IDA में लोड करना और फिर बाद में डेटाबेस (idb से xml) को Ghidra में आयात करना संभव है, लेकिन यह दायरे से बाहर है। यदि आप ऐसा करने में सफल होते हैं, तो `ghidra_kernelcache` बाकी का ध्यान रखेगा।
किसी भी macOS कर्नेल एक्सटेंशन का प्रतीकीकरण करने से पहले कुछ कदम उठाने होते हैं, क्योंकि `ghidra_kernelcache` का मुख्य उद्देश्य वर्ग पदानुक्रम को पुनर्निर्मित करना और सभी वर्ग संरचनाओं को एक एकल डेटाबेस में प्रबंधित करना है, एक कर्नेल एक्सटेंशन उन आवश्यकताओं को पूरा नहीं करता है, जिसका अर्थ है कि एकल KEXT के प्रतीकीकरण के लिए कर्नेल और संभवतः अन्य कर्नेल एक्सटेंशन जिन पर यह निर्भर करता है, के प्रतीकीकरण की आवश्यकता होती है, इसलिए यहाँ कुछ अतिरिक्त कार्य करने की आवश्यकता है।
`ghidra_kernelcache` अब Ghidra के शक्तिशाली *DataType Project Archive* के माध्यम से वर्ग संरचनाओं और वर्चुअल विधि परिभाषाओं का प्रबंधन और साझाकरण करके कर्नेल सहित कर्नेल एक्सटेंशन को प्रतीकीकृत करने का एक शक्तिशाली तरीका प्रदान करता है।
### कर्नेल एक्सटेंशन को प्रतीकीकृत करने के चरण
- अपने Ghidra प्रोजेक्ट में एक नया फोल्डर बनाएं, फिर ` /System/Library/Kernels/kernel.release.XXXXX` को उस फोल्डर में लोड करें और Ghidra को इसका विश्लेषण करने दें।
- एक नया *Project Archive* बनाएं: `DataType Provider` पर जाएं → विंडो के ऊपर दाएं कोने में तीर पर क्लिक करें → `New Project Archive` → इसे नवनिर्मित फोल्डर के अंदर रखें → इसे कुछ नाम दें (जैसे macOS_12.1)।
- अब `ghidra_kernelcache` का उपयोग करके कर्नेल को प्रतीकीकृत करें, यह प्रक्रिया iOS *kernelcache* प्रतीकीकरण के समान है।```bash
$ iometa -n -A /System/Library/Kernels/kernel.release.t8101 > /tmp/kernel.txt
KM.py स्क्रिप्ट में पूर्ण स्क्रिप्ट कार्यान्वयन पा सकते हैं :```pyfrom utils.helpers import * from utils.kext import * iom = ParseIOMeta("/tmp/kernel.txt") Obj = iom.getObjects() kc = Kext(Obj,shared_p="macOS_12.1") kc.process_kernel_kext()
- एक बार समाप्त होने पर, कर्नेल के आर्काइव और `macOS_12.1` आर्काइव के बीच एक डेटाबेस संबंध बन गया है। अब, `kernel.release.t8001` पर राइट क्लिक करें → `Commit DataTypes To` → `macOS_12.1` पर क्लिक करें।
- फिर `राइट क्लिक` करें →`सभी चुनें` → `Commit` करें।
- प्रोजेक्ट आर्काइव को सेव करें : `राइट क्लिक` → `Save Archive`।
हमने अभी एक प्रोजेक्ट आर्काइव बनाया है जिसे सभी कर्नेल एक्सटेंशन में साझा किया जा सकता है।
आइए Apple Silicon के लिए `IOSurface` Kext का एक उदाहरण लें :```bash
$ lipo /System/Library/Extensions/IOSurface.kext/Contents/MacOS/IOSurface -thin arm64e -output /tmp/iosurface.arm64e
$ iometa -n -A /tmp/iosurface.arm64e > /tmp/iosurface.txt
macOS_12.1 को लोड करें: Data Type Manager → Open Project Archive पर जाएँ, फिर macOS_12.1 चुनेंKM.py में मिल सकती है:```python
from utils.helpers import *
from utils.kext import *kc = Kext(Obj,shared_p="macOS_12.1")
kc.depac()
kc.process_kernel_kext()
**महत्वपूर्ण नोट** : कभी-कभी `kc.process_kernel_kext()` विफल हो जाता है क्योंकि Ghidra कुछ C++ प्रतीकों को डिमैंगल नहीं कर पाता। इसे ठीक करने के लिए, स्क्रिप्ट मैनेजर पर जाएँ और `DemangleAllScript.java` स्क्रिप्ट चलाएँ, फिर `kc.process_kernel_kext()` को पुनः प्रारंभ करें।
### कस्टम कक्षाएँ
कुछ मामले ऐसे हैं जहाँ कुछ C++ कक्षाएँ, जिन्हें `ghidra_kernelcache` और `iometa` प्रतीकीकृत नहीं कर सकते, इसलिए इसे संभालने के लिए एक नई सुविधा जोड़ी गई है।
`Custom()` वर्ग पुनर्निर्माण सभी `::vtable` प्रतीकों के माध्यम से पुनरावृत्त करता है और जाँचता है कि क्या वर्ग पहले से परिभाषित है या नहीं, यदि नहीं, तो यह स्वचालित रूप से एक वर्ग संरचना, प्रत्येक पहचाने गए वर्ग विधि के लिए फ़ंक्शन परिभाषाएँ, एक नामस्थान और प्रत्येक वर्ग के लिए एक आभासी तालिका बनाता है।
कस्टम वर्ग निर्माण फिलहाल केवल macOS पर समर्थित है।```bash
$ iometa -n -A /System/Library/Kernels/kernel.release.t8101 > /tmp/kernel.txt
$ iometa -n -A <kext_path> >> /tmp/kernel.txt
check_policies.sh के रूप में सहेजें।chmod +x check_policies.sh।./check_policies.sh।```pyfrom utils.helpers import * from utils.custom_kc import *
if name == "main": default = "/tmp/kernel.txt" ff = askString("iometa symbol file","Symbol file: ",default) iom = ParseIOMeta(ff) Obj = iom.getObjects()
kc = Custom(Obj)
kc.process_all_classes()
kc.explore_pac()
## Miscellaneous scripts
---
### KDK के Dwarf4 को आयात करना
Ghidra किसी कारण से संबंधित `.dsym` निर्देशिका को लोड करने में विफल रहता है, मैंने इसे ठीक करने के लिए एक छोटी स्क्रिप्ट बनाई है। यह [यहाँ](https://github.com/0x36/ghidra_kernelcache/blob/master/dwarf4_fix.py) पाई जा सकती है।
**उपयोग** : अपने KDK पथ से कर्नेल लोड करें, Ghidra को विश्लेषण पूरा करने दें, फिर `dwarf_fix.py` चलाएँ, यह प्रतीकों को लोड करेगा और प्रक्रिया में कुछ मिनट लग सकते हैं।
<img src="https://raw.githubusercontent.com/0x36/ghidra_kernelcache/master/screenshots/image12.png" alt="image12"/>
### वर्चुअल विधि कॉल संदर्भों को हल करना
`ghidra_kernelcache` वर्चुअल कॉल को हल करने के लिए दो तरीके प्रदान करता है: `kernelCache.explore_pac` या `fix_extra_refs`
**kernelCache.explore_pac()**
यदि आप arm64e बाइनरी पर काम कर रहे हैं, तो `ghidra_kernelcache` `Pointer Authentication Code` मान की तलाश करके वर्चुअल विधि कॉल को पहचान सकता है। प्रक्रिया सीधी है और `fix_extra_refs()` के विपरीत, `kernelCache.explore_pac` `Pcode` या `varnode` पहचान पर निर्भर नहीं करता है, यह बस प्रोग्राम में सभी निर्देशों के माध्यम से पुनरावृत्ति करता है, `MOVK` निर्देशों की खोज करता है, दूसरे ऑपरेंड को लाता है और डेटाबेस में उसके संबंधित मान को देखता है।
उपयोग :
**kernelCache**, **Kext** या **Custom** के माध्यम से एक *KernelCache* इंस्टेंस बनाएँ, फिर `explore_pac()` विधि को कॉल करें।```py
from utils.helpers import *
from utils.kext import *
if __name__ == "__main__":
default = "/tmp/kernel.txt"
ff = askString("iometa symbol file","Symbol file: ",default)
iom = ParseIOMeta(ff)
Obj = iom.getObjects()
kc = Kext(Obj)
kc.explore_pac()
fix_extra_refs() यह फ़ंक्शन एक बुनियादी डेटा प्रवाह विश्लेषण पर आधारित है, जो सभी वर्चुअल कॉल विधियों को खोजने और उनके कार्यान्वयनों को स्वचालित रूप से हल करने के लिए है, यह सभी आर्किटेक्चर पर काम करता है और डीकंपाइलर आउटपुट से स्रोत डेटा प्रकार को पहचानने की क्षमता रखता है तथा फ़ंक्शन के अंदर सभी वर्चुअल कॉल संदर्भों को हल करता है, जिससे उपयोगकर्ता मैन्युअल रूप से देखे बिना सीधे कार्यान्वयन तक आगे/पीछे जा सकता है।
fix_extra_refs द्वारा प्रदान की गई सबसे उपयोगी सुविधा यह है कि यह प्रत्येक निष्पादन पर संदर्भों को सिंक्रोनाइज़ रखता है। उदाहरण के लिए, आपने एक वेरिएबल डेटा प्रकार को क्लास डेटा प्रकार में बदल दिया, fix_extra_refs स्वचालित रूप से परिवर्तन को पहचान लेगा, और सभी कॉल साइटों पर पुनरावर्ती रूप से जाकर उनके संदर्भों को हल करेगा, और यह तभी रुकेगा जब कॉल साइट कतार खाली हो जाएगी।
fix_extra_refs द्वारा प्रदान की गई कुछ अन्य सुविधाएँ इस प्रकार हैं:
_ptmf2ptf() कॉल का पता लगाता है और ऑफ़सेट और पूर्ण फ़ंक्शन पते दोनों के लिए उनकी कॉल विधि को हल करता हैआप कार्यान्वयन utils/references.py, में पा सकते हैं, fix_extra_refs pcode संचालनों को पार्स करता है और CALLIND और CALL ऑपकोड की खोज करता है, फिर संचालन में शामिल सभी varnodes को प्राप्त करता है, जब एक Varnode परिभाषा की पहचान हो जाती है, तो यह क्लास ऑब्जेक्ट प्रकार की पहचान करने के लिए उसका HighVariable प्राप्त करता है, यदि प्रकार अज्ञात है (अर्थात क्लास संरचना प्रतीत नहीं होता) तो यह इसे अनदेखा कर देता है, अन्यथा यह क्लास का नाम लेगा, उसकी वर्चुअल कॉल टेबल को देखेगा, Varnode द्वारा प्रदान किए गए ऑफ़सेट का उपयोग करके सही वर्चुअल मेथड कॉल को प्राप्त कर सकता है और कॉल इंस्ट्रक्शन पर एक संदर्भ रखता है।```py
fix_extra_refs(toAddr(address))
`fix_extra_refs` का उपयोग करके आउटपुट का एक उदाहरण यहाँ दिया गया है:
<img src="https://raw.githubusercontent.com/0x36/ghidra_kernelcache/master/screenshots/image9.png" alt="image9"/>
ध्यान दें कि इसने बिना किसी मैनुअल संशोधन के **IOService::isOpen()**, **OSArray::getNextIndexOfObject()** और **IOStream::removeBuffer()** वर्चुअल कॉल्स को सफलतापूर्वक हल कर दिया है।
इसके बाद, `fix_extra_refs` **IOStream::removeBuffer()** को डीकंपाइल करेगा, इस विधि के सभी HighVariables प्राप्त करेगा, फिर पिछली विधि की तरह उनके संदर्भों को हल करेगा... और इसी प्रकार आगे बढ़ेगा।
<img src="https://raw.githubusercontent.com/0x36/ghidra_kernelcache/master/screenshots/image10.png" alt="image10"/>
### बाहरी विधि तालिकाओं को स्वचालित रूप से ठीक करना
मेरा मानना है कि हर शोधकर्ता के पास इस भाग से निपटने के लिए कुछ स्क्रिप्ट होती है, क्योंकि यह IOKit का मुख्य हमला सतह है, इसे मैन्युअल रूप से करना बोझिल है, और इसे इस तरह से स्वचालित किया जाना चाहिए जिससे शोधकर्ता कई बाहरी विधि तालिकाओं में गहराई से जाना चाहे।
`ghidra_kernelcache` द्वारा दो स्क्रिप्ट प्रदान की गई हैं: **fix_methodForIndex.py** और **fix_extMethod.py**। आप उन्हें ऊपर दिखाए गए अन्य स्क्रिप्ट की तरह सक्षम कर सकते हैं।
***उपयोग***: कर्सर को बाहरी डिस्पैच तालिका की शुरुआत में रखें, स्क्रिप्ट चलाएँ: लक्ष्य और चयनकर्ताओं की संख्या प्रदान करें।
`IOStreamUserClient::getTargetAndMethodForIndex()` के लिए उदाहरण:
<img src="https://raw.githubusercontent.com/0x36/ghidra_kernelcache/master/screenshots/image11.png" alt="image11"/>
### namespace.py: विधि नामस्थान ठीक करें...
यह एक उपयोगी स्क्रिप्ट है जो सभी सामने आई विधियों में क्लास प्रकार को जनसंख्या देती है, और यह `extra_refs.py` स्क्रिप्ट के लिए एक निर्भरता है ताकि कैली फंक्शन्स का पुनरावर्ती अन्वेषण किया जा सके और उनके संदर्भों को हल किया जा सके।
***उपयोग***: कर्सर को वांछित फंक्शन के डीकंपाइलर आउटपुट में रखें, टूलबार से स्क्रिप्ट चलाएँ या **Meta-Shift-N** दबाएँ।
### प्रतीक नाम और प्रकार प्रसार
`ghidra_kernelcache` बुनियादी Pcode संचालन के लिए प्रकार प्रसार समर्थन प्रदान करता है, लेकिन यह संभवतः उन चरों के लिए विफल होगा जो जटिल कास्टिंग का उपयोग कर रहे हैं।
यदि कोई सहायता करना चाहता है, या Ghidra में निम्न-स्तरीय चीजों के साथ काम शुरू करना चाहता है, तो यह अवसर है।
कार्यान्वयन [ghidra_kernelcache/propagate.py](https://github.com/0x36/ghidra_kernelcache/blob/master/propagate.py) में पाया जा सकता है।
### फंक्शन हस्ताक्षर लोड करना
Ghidra में C++ हेडर फ़ाइलों को पार्स करना संभव नहीं है, और kernelcache में कर्नेल फंक्शन हस्ताक्षर होने से डीकंपाइलर आउटपुट में कई चीजों में सुधार हो सकता है।
उदाहरण के लिए, मान लें कि हमने `virtual IOMemoryMap * map(IOOptionBits options = 0);` जोड़ दिया है, Ghidra स्वचालित रूप से फंक्शन परिभाषा और फंक्शन हस्ताक्षर दोनों के लिए रिटर्न वैल्यू को `IOMemoryMap` पॉइंटर में बदल देगा।
आप किसी भी C++ प्रतीक को **signatures/** निर्देशिका में सिंटैक्स के सम्मान के साथ जोड़ सकते हैं और इस निर्देशिका में परिभाषित फंक्शन हस्ताक्षर पा सकते हैं।```c++
// Defining an instance class method
IOMemoryDescriptor * withPersistentMemoryDescriptor(IOMemoryDescriptor *originalMD);
// Defining a virtual method, it must start with "virtual" keyword
virtual IOMemoryMap * createMappingInTask(task_t intoTask, mach_vm_address_t atAddress, IOOptionBits options, mach_vm_size_t offset = 0, mach_vm_size_t length = 0);
// Defining a structure
struct task_t;
// typedef'ing a type
typedef typedef uint IOOptionBits;
// Lines begining with '//' are ignored
उपयोग: कर्नेल को प्रतीकीकृत करने के बाद, सभी उपलब्ध फ़ंक्शन हस्ताक्षर लोड करने के लिए स्क्रिप्ट load_sigatnures.py चलाने की अत्यधिक अनुशंसा की जाती है। पिछले अधिकांश टूल्स की तरह, इस स्क्रिप्ट को टूलबार में जोड़कर या प्लगइन मैनेजर से चलाएं, या बस Meta-Shift-S दबाएं।
यह स्क्रिप्ट सीधी-सादी है, यह एक पुराने प्रोजेक्ट से SourceType.USER_DEFINED के साथ सभी संरचनाएं, क्लासेस, टाइपडेफ़, और फ़ंक्शन परिभाषाएं आयात करके एक नए प्रोजेक्ट में डालती है।
उपयोग: पुराने और नए Ghidra प्रोजेक्ट को एक ही टूल पर खोलें, load_structs.py स्क्रिप्ट पर जाएं, पुराने प्रोग्राम का नाम src_prog_string वेरिएबल में डालें, और नए का नाम dst_prog_string वेरिएबल में डालें, फिर स्क्रिप्ट चलाएं।
यदि आपको यह प्रोजेक्ट रोचक लगता है और आप योगदान देना चाहते हैं, तो बस एक PR करें और मैं इसकी समीक्षा करूंगा, इस बीच, मैं निम्नलिखित क्षेत्रों में कुछ योगदान देखना चाहूंगा:
मैं @s1guza को उनके शानदार iometa के लिए धन्यवाद देना चाहूंगा, जिस पर ghidra_kernelcache निर्भर है।