
ein iOS-Kernel-Funktions-Hooking-Framework für checkra1n-fähige Geräte

Ausgabe aus dem Kernel-Log nach dem Kompilieren und Ausführen von example/open1_hook.c
xnuspy ist ein pongoOS-Modul, das einen neuen Systemaufruf, xnuspy_ctl, installiert, mit dem Sie Kernel-Funktionen aus dem Userspace hooken können. Es unterstützt iOS 13.x, iOS 14.x und iOS 15.x auf checkra1n 0.12.2 und höher. 4K-Geräte werden nicht unterstützt.
Dieses Modul macht KTRR/KPP vollständig unwirksam und ermöglicht es, RWX-Speicher innerhalb von EL1 zu erstellen. Verwenden Sie dies nicht auf Ihrem Hauptgerät.
Erfordert libusb: brew install libusb
Führen Sie make im obersten Verzeichnis aus. Es wird den Loader und das Modul bauen.
Fügen Sie diese vor make hinzu.
XNUSPY_DEBUG=1
kprintf).XNUSPY_SERIAL=1
IOLog senden.XNUSPY_LEAKED_PAGE_LIMIT=n
64. Weitere Informationen finden Sie unter Debugging von Kernel-Panics.XNUSPY_TRAMP_PAGES=n
XNUSPY_DEBUG und XNUSPY_SERIAL sind voneinander unabhängig.
Nachdem Sie alles gebaut haben, lassen Sie checkra1n Ihr Gerät in eine pongo-Shell booten: /Applications/checkra1n.app/Contents/MacOS/checkra1n -p
Führen Sie im selben Verzeichnis, in dem Sie den Loader und das Modul gebaut haben, loader/loader module/xnuspy aus. Danach wird xnuspy seine Arbeit verrichten und in einigen Sekunden wird Ihr Gerät booten. Der loader wartet nach dem Senden von xnuspy-getkernelv noch ein paar Sekunden, falls SEPROM ausgenutzt werden muss.
Manchmal bleiben ein paar meiner Telefone nach dem Ausführen von checkra1ns KPF bei "Booting" hängen. Ich habe noch nicht herausgefunden, was das verursacht, aber falls es passiert, versuchen Sie es erneut. Wenn das Gerät nach bootx hängt, versuchen Sie es ebenfalls erneut. Schließlich ist das Markieren des kompilierten xnuspy_ctl-Codes als ausführbar auf meinem iPhone X mit iOS 13.3.1 etwas unzuverlässig, funktioniert aber auf meinen anderen Telefonen zu 100%. Wenn Sie beim Ausführen Ihres Hook-Programms einen Kernel Instruction Fetch Absturz haben, versuchen Sie es erneut.
xnuspy wird einen enosys-Systemaufruf patchen, sodass er auf xnuspy_ctl_tramp verweist. Dies ist ein kleines Trampolin, das den kompilierten xnuspy_ctl-Code als ausführbar markiert und zu ihm springt. Sie finden die Implementierung von xnuspy_ctl unter module/el1/xnuspy_ctl/xnuspy_ctl.c und Beispiele im example-Verzeichnis.
In include/xnuspy/ befindet sich xnuspy_ctl.h, ein Header, der Konstanten für xnuspy_ctl definiert. Er soll in alle Programme eingebunden werden, die Kernel-Funktionen hooken.
Sie können sysctlbyname verwenden, um herauszufinden, welcher Systemaufruf gepatcht wurde:```
size_t oldlen = sizeof(long);
long SYS_xnuspy_ctl = 0;
sysctlbyname("kern.xnuspy_ctl_callnum", &SYS_xnuspy_ctl, &oldlen, NULL, 0);
Dieser Systemaufruf hat vier Argumente: `flavor`, `arg1`, `arg2` und `arg3`.
Der `flavor` kann entweder `XNUSPY_CHECK_IF_PATCHED`, `XNUSPY_INSTALL_HOOK`,
`XNUSPY_REGISTER_DEATH_CALLBACK`, `XNUSPY_CALL_HOOKME`, `XNUSPY_CACHE_READ`,
`XNUSPY_KREAD`, `XNUSPY_KWRITE` oder `XNUSPY_GET_CURRENT_THREAD` sein.
Die Bedeutung der drei folgenden Argumente hängt vom `flavor` ab.
## `XNUSPY_CHECK_IF_PATCHED`
Dies existiert, damit Sie überprüfen können, ob `xnuspy_ctl` vorhanden ist. Die Verwendung mit diesem `flavor` führt zur Rückgabe von `999`. Die Werte der anderen Argumente werden ignoriert.
## `XNUSPY_INSTALL_HOOK`
Ich habe diesen `flavor` so entworfen, dass er der API von [`MSHookFunction`](http://www.cydiasubstrate.com/api/c/MSHookFunction/) entspricht.
`arg1` ist die *UNVERSCHOBENE* Adresse der Kernel-Funktion, die Sie hooken möchten. Wenn Sie eine verschobene Adresse angeben, wird es höchstwahrscheinlich zu einem Kernel-Panic kommen. `arg2` ist ein Zeiger auf Ihre ABI-kompatible Ersatzfunktion. `arg3` ist ein Zeiger für `xnuspy_ctl`, um die Adresse eines Trampolins, das die ursprüngliche Kernel-Funktion darstellt, mittels `copyout` auszugeben. Dies kann `NULL` sein, wenn Sie nicht beabsichtigen, das Original aufzurufen.
## `XNUSPY_REGISTER_DEATH_CALLBACK`
Dieser `flavor` ermöglicht es Ihnen, einen optionalen "Death-Callback" zu registrieren, eine Funktion, die xnuspy aufruft, wenn Ihr Hook-Programm beendet wird. Er gibt Ihnen die Möglichkeit, alles zu bereinigen, was Sie mit Ihren Kernel-Hooks erstellt haben. Falls Sie Kernel-Threads erstellt haben, teilen Sie ihnen in dieser Funktion mit, dass sie sich beenden sollen.
Ihr Callback wird nicht asynchron aufgerufen. Wenn Sie also blockieren, verhindern Sie die Ausführung des Garbage-Collection-Threads von xnuspy.
`arg1` ist ein Zeiger auf Ihre Callback-Funktion. Die Werte der anderen Argumente werden ignoriert.
## `XNUSPY_CALL_HOOKME`
`hookme` ist ein kleiner Assembly-Stub, den xnuspy über den xnuspy-Cache exportiert, damit Sie ihn hooken können. Der Aufruf von `xnuspy_ctl` mit diesem `flavor` führt dazu, dass `hookme` aufgerufen wird. Dies bietet eine Möglichkeit, einfach Kernel-Code auszuführen, ohne eine tatsächliche Kernel-Funktion hooken zu müssen.
`arg1` ist ein Argument, das beim Aufruf an `hookme` übergeben wird.
Dies kann `NULL` sein.
## `XNUSPY_CACHE_READ`
Dieser `flavor` gibt Ihnen eine Möglichkeit, aus dem xnuspy-Cache zu lesen. Er enthält viele nützliche Dinge wie `kprintf`, `current_proc`, `kernel_thread_start`, einige libc-Funktionen und den Kernel-Slide, sodass Sie sie nicht selbst finden müssen. Eine vollständige Liste der Cache-IDs finden Sie in `example/xnuspy_ctl.h`.
`arg1` ist eine der in `xnuspy_ctl.h` definierten Cache-IDs und `arg2` ist ein Zeiger für `xnuspy_ctl`, um die Adresse oder den Wert des Angeforderten mittels `copyout` auszugeben. Die Werte der anderen Argumente werden ignoriert.
## `XNUSPY_KREAD`
Dieser `flavor` bietet eine einfache Möglichkeit, aus dem Userspace Kernel-Speicher zu lesen, ohne tfp0.
`arg1` ist eine virtuelle Kernel-Adresse, `arg2` die Adresse eines Userspace-Puffers und `arg3` die Größe dieses Userspace-Puffers. Es werden `arg3` Bytes von `arg1` nach `arg2` geschrieben.
## `XNUSPY_KWRITE`
Dieser `flavor` bietet eine einfache Möglichkeit, aus dem Userspace in den Kernel-Speicher zu schreiben, ohne tfp0.
`arg1` ist eine virtuelle Kernel-Adresse, `arg2` die Adresse eines Userspace-Puffers und `arg3` die Größe dieses Userspace-Puffers. Es werden `arg3` Bytes von `arg2` nach `arg1` geschrieben.
## `XNUSPY_GET_CURRENT_THREAD`
Dieser `flavor` stellt dem Userspace die Kernel-Adresse des aufrufenden Threads zur Verfügung.
`arg1` ist ein Zeiger für `xnuspy_ctl`, um den Rückgabewert von `current_thread` mittels `copyout` auszugeben. Die Werte der anderen Argumente werden ignoriert.
### Fehler
Für alle `flavor` außer `XNUSPY_CHECK_IF_PATCHED` wird bei Erfolg `0` zurückgegeben. Bei einem Fehler wird `-1` zurückgegeben und `errno` gesetzt. `XNUSPY_CHECK_IF_PATCHED` gibt keine Fehler zurück. XNU's `mach_to_bsd_errno` wird verwendet, um einen `kern_return_t` in das entsprechende `errno` zu konvertieren.