
Ein Ghidra-Framework für iOS-Kernelcache-Reverse-Engineering
Dieses Framework ist das Endprodukt meiner Erfahrung im Reverse Engineering von Kernelcaches. Normalerweise suche ich nach Schwachstellen, indem ich den Kernel und seine Erweiterungen manuell auditiere, und habe die meisten Dinge automatisiert, die ich in Ghidra wirklich sehen wollte, um den Prozess des Reversings zu beschleunigen. Dies hat sich als effektiv erwiesen und spart viel Zeit. Das Framework funktioniert unter iOS 12/13/14/15 und macOS 11/12 (sowohl Kernelcache als auch einzelne KEXT) und wurde der Öffentlichkeit zur Verfügung gestellt, um Menschen den Einstieg in die iOS-Kernel-Forschung zu erleichtern, ohne die Mühe der eigenen Umgebungsvorbereitung. Wie ich glaube, ist dieses Framework (einschließlich des bereitgestellten Toolsets und mit grundlegenden IOKit-Kenntnissen) ausreichend, um mit dem Hacken des Kernelcaches zu beginnen.
Das Framework ist vollständig in Python geschrieben und kann erweitert werden, um andere Tools zu bauen. Es bietet einige grundlegende APIs, die Sie in fast jedem Projekt verwenden können und Zeit sparen, da Sie das ausführliche Handbuch nicht lesen müssen. Sie sind herzlich eingeladen, die Kernfunktionen im Verzeichnis utils/ zu lesen.
Ghidra ist gut bei der Analyse von Kernelcaches, aber wie andere RE-Tools erfordert es manuelle Arbeit. ghidra_kernelcache bietet einen guten Einstiegspunkt, um Dinge sowohl zu Beginn als auch während des Reverse Engineerings zu korrigieren und so eine ansprechende Decompiler-Ausgabe zu liefern.
Es gibt ein ähnliches Projekt von @_bazad in IDAPro namens ida_kernelcache, das einen guten Einstiegspunkt für Forscher bietet, die mit dem Kernel-Image in IDA arbeiten möchten. Mein Framework ähnelt Brandons Arbeit etwas, geht aber darüber hinaus, indem es viel mehr Funktionen bietet, um den Arbeitsprozess mit dem Kernelcache weniger schmerzhaft zu machen.
::externalMethod() und ::getTargetAndMethodForIndex().Diese Funktionen sind als separate Tools implementiert, die entweder über Tastenkombinationen oder durch Klicken auf ihre Symbole in der Symbolleiste ausgeführt werden können.
Klonen Sie das Repository :```sh git clone https://github.com/0x36/ghidra_kernelcache.git
**Wichtiger Hinweis**: Das Projekt wurde auf Ghidra 10.1_PUBLIC und 10.2_DEV getestet und ist nicht abwärtskompatibel.
Gehen Sie zu *`Windows → Script Manager`,* klicken Sie auf *`script Directory` ,* und fügen Sie dann *`ghidra_kernelcache`* zur Verzeichnispfadliste hinzu.
Gehen Sie zu *`Windows → Script Manager`,* gehen Sie in der *scripts*-Auflistung zur Kategorie *`iOS→kernel`* und aktivieren Sie die dort sichtbaren Plugins. Diese werden in der GHIDRA-Symbolleiste angezeigt .
Im Verzeichnis [logos/](https://github.com/0x36/ghidra_kernelcache/tree/master/logos) können Sie eigene Logos für jedes Tool ablegen.
## iOS kernelcache Symbolisierung
`ghidra_kernelcache` erfordert in der ersten Phase [iometa](https://github.com/Siguza/iometa/) (erstellt von [@s1guza](https://twitter.com/s1guza)), ein leistungsstarkes Tool, das C++-Klasseninformationen im Kernel-Binary bereitstellt. Das Tolle daran ist, dass es als eigenständige Binärdatei funktioniert, sodass die Ausgabe durch einfaches Parsen in Ihr bevorzugtes RE-Framework importiert werden kann. Mein Framework nimmt die Ausgabe von iometa und analysiert sie, um virtuelle Tabellen zu symbolisieren und zu reparieren.
### Verwendung
Nach dem Dekomprimieren des Kernels führen Sie die folgenden Befehle aus :
iometa kernelcache.release.xxx > output
$ iometa -n -A /tmp/kernel A10-legacy.txt > /tmp/kernel.txt
# if you want also to symbolicate using jtool2
$ jtool2 --analyze /tmp/kernel
```
Laden Sie den Kernelcache in Ghidra, ***NICHT DEN BATCH-IMPORT VERWENDEN***, laden Sie ihn als Mach-O-Image.
Nachdem der Kernelcache geladen und automatisch analysiert wurde, klicken Sie auf das in der Symbolleiste angezeigte Symbol oder drücken Sie einfach **Meta-Shift-K**, und geben Sie dann den vollständigen Pfad der iometa-Ausgabe ein, in unserem Fall `/tmp/kernel.txt`.
Wenn Sie `jtool2`-Symbole verwenden möchten, können Sie auch `jsymbol.py` aus der Kategorie `iOS→kernel` verwenden.
### iOS Kernelcache-API
Vollständige API-Beispiele finden Sie in [`ghidra_kernelcache/kc.py`](https://github.com/0x36/ghidra_kernelcache/blob/master/KC.py)
→ Hier einige Beispiele zur Manipulation von Klassenobjekten :```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)
# symbolicate the kernel
kc.process_all_classes()
# symbolicate the classes under com.apple.iokit.IOSurface bundle
kc.process_classes_for_bundle("com.apple.iokit.IOSurface")
# symbolicate the classes under __kernel__ bundle
kc.process_classes_for_bundle("__kernel__")
# Process one class (including its parents)
kc.process_class("IOGraphicsAccelerator2")
# Clears the content of the class structures (vtables are excluded)
kc.clear_class_structures()
# Overwrite the old vtable structure definition and resymbolicate it again
kc.update_classes_vtable()
# Reconstructing function call trees by enumerating all pac references and find their corresponding virtual method call
kc.explore_pac()
```
Wie Sie sehen, können Sie den Kernelcache vollständig oder teilweise symbolatisieren. Falls eine partielle Symbolatisierung gewählt wurde, erstellt `ghidra_kernelcache` automatisch alle Klassenabhängigkeiten, bevor es fortfährt.
Wenn Sie das Skript gegen den gesamten Kernelcache (vollständige Symbolatisierung) ausführen, benötigt `ghidra_kernelcache` einige Minuten, um das Kernel-Image zu analysieren.
Sobald der Vorgang abgeschlossen ist, stellt Ghidra Folgendes bereit:
→ Im Bookmark-Filter wurde eine neue Kategorie namens "iOS" hinzugefügt:
<img src="https://raw.githubusercontent.com/0x36/ghidra_kernelcache/master/screenshots/image1.png" alt="image1" width="200"/>
→ IOKit-Klassen-Virtual-Tables werden zum 'iOS'-Bookmark hinzugefügt, um eine bessere und schnellere Virtual-Table-Suche zu ermöglichen. Sie können einfach nach einem Kext oder einer Klasse suchen, indem Sie Buchstaben, Wörter oder die Kext-Bundle-ID in die Suchleiste eingeben.
<img src="https://raw.githubusercontent.com/0x36/ghidra_kernelcache/master/screenshots/image2.png" alt="image2"/>
→ Reparatur der Virtual-Table: Disassembliert/übersetzt unbekannten Code, korrigiert Namensräume, resymbolisiert die Klassenmethoden und wendet Funktionsdefinitionen auf jede Methode an:
<img src="https://raw.githubusercontent.com/0x36/ghidra_kernelcache/master/screenshots/image3.png" alt="image3"/>
→ Erstellung von Klassennamensräumen und Einordnung jeder Methode in ihren entsprechenden Namensraum:
<img src="https://raw.githubusercontent.com/0x36/ghidra_kernelcache/master/screenshots/image4.png" alt="image4"/>
→ Erstellung der Klassenstruktur unter Berücksichtigung der Klassenhierarchie:
<img src="https://raw.githubusercontent.com/0x36/ghidra_kernelcache/master/screenshots/image5.png" alt="image5"/>
```