
un framework de hooking de funciones del kernel de iOS para dispositivos checkra1n'able

Salida del registro del kernel después de compilar y ejecutar example/open1_hook.c
xnuspy es un módulo de pongoOS que instala una nueva llamada al sistema, xnuspy_ctl, que permite enganchar funciones del kernel desde el espacio de usuario. Es compatible con iOS 13.x, iOS 14.x y iOS 15.x en checkra1n 0.12.2 y superiores. Los dispositivos 4K no son compatibles.
Este módulo neutraliza completamente KTRR/KPP y hace posible crear memoria RWX dentro de EL1. No lo uses en tu dispositivo principal.
Requiere libusb: brew install libusb
Ejecuta make en el directorio raíz. Esto compilará el cargador y el módulo.
Añade estos antes de make.
XNUSPY_DEBUG=1
kprintf).XNUSPY_SERIAL=1
IOLog.XNUSPY_LEAKED_PAGE_LIMIT=n
64. Más información se puede encontrar en Depuración de pánicos del kernel.XNUSPY_TRAMP_PAGES=n
XNUSPY_DEBUG y XNUSPY_SERIAL no dependen el uno del otro.
Después de haber construido todo, haz que checkra1n arranque tu dispositivo en un shell pongo: /Applications/checkra1n.app/Contents/MacOS/checkra1n -p
En el mismo directorio donde construiste el cargador y el módulo, ejecuta loader/loader module/xnuspy. Después de hacer eso, xnuspy hará lo suyo y en unos segundos tu dispositivo arrancará. loader esperará un par de segundos más después de emitir xnuspy-getkernelv en caso de que SEPROM necesite ser explotado.
A veces un par de mis teléfonos se quedaban atascados en "Booting" después de que se ejecuta el KPF de checkra1n. Aún no he descubierto qué causa esto, pero si sucede, inténtalo de nuevo. Además, si el dispositivo se cuelga después de bootx, inténtalo de nuevo. Finalmente, marcar el código compilado de xnuspy_ctl como ejecutable en mi iPhone X con iOS 13.3.1 es un poco irregular, pero tiene éxito el 100% de las veces en mis otros teléfonos. Si obtienes un pánico con una falla de recuperación de instrucción del kernel cuando ejecutas tu programa de enganche, inténtalo de nuevo.
xnuspy parcheará una llamada al sistema enosys para que apunte a xnuspy_ctl_tramp. Este es un pequeño trampolín que marca el código compilado de xnuspy_ctl como ejecutable y salta a él. Puedes encontrar la implementación de xnuspy_ctl en module/el1/xnuspy_ctl/xnuspy_ctl.c y ejemplos en el directorio example.
Dentro de include/xnuspy/ está xnuspy_ctl.h, un archivo de cabecera que define constantes para xnuspy_ctl. Está destinado a ser incluido en todos los programas que enganchan funciones del kernel.
Puedes usar sysctlbyname para averiguar qué llamada al sistema fue parcheada:```
size_t oldlen = sizeof(long);
long SYS_xnuspy_ctl = 0;
sysctlbyname("kern.xnuspy_ctl_callnum", &SYS_xnuspy_ctl, &oldlen, NULL, 0);
Esta llamada al sistema toma cuatro argumentos: `flavor`, `arg1`, `arg2` y `arg3`.
El `flavor` puede ser `XNUSPY_CHECK_IF_PATCHED`, `XNUSPY_INSTALL_HOOK`,
`XNUSPY_REGISTER_DEATH_CALLBACK`, `XNUSPY_CALL_HOOKME`, `XNUSPY_CACHE_READ`,
`XNUSPY_KREAD`, `XNUSPY_KWRITE` o `XNUSPY_GET_CURRENT_THREAD`.
El significado de los siguientes tres argumentos depende del `flavor`.
## `XNUSPY_CHECK_IF_PATCHED`
Esto existe para que puedas comprobar si `xnuspy_ctl` está presente. Invocarlo con este
`flavor` hará que devuelva `999`. Los valores de los otros argumentos se ignoran.
## `XNUSPY_INSTALL_HOOK`
Diseñé este `flavor` para que coincida con la API de [`MSHookFunction`](http://www.cydiasubstrate.com/api/c/MSHookFunction/).
`arg1` es la dirección *sin slide* de la función del kernel que deseas enganchar. Si
proporcionas una dirección con slide, lo más probable es que causes un pánico. `arg2` es un puntero a tu
función de reemplazo compatible con ABI. `arg3` es un puntero para que `xnuspy_ctl`
`copyout` la dirección de un trampolín que representa la función original del kernel.
Puede ser `NULL` si no tienes intención de llamar a la original.
## `XNUSPY_REGISTER_DEATH_CALLBACK`
Este `flavor` te permite registrar un "callback de muerte" opcional, una función que xnuspy
llamará cuando tu programa de hooks termine. Te da una oportunidad para limpiar cualquier cosa
que hayas creado desde tus hooks del kernel. Si creaste algún hilo del kernel, deberías
indicarles que terminen en esta función.
Tu callback no se invoca de forma asíncrona, así que si te bloqueas, estás impidiendo
que el hilo de recolección de basura de xnuspy se ejecute.
`arg1` es un puntero a tu función callback. Los valores de los otros argumentos
se ignoran.
## `XNUSPY_CALL_HOOKME`
`hookme` es un pequeño stub en ensamblador que xnuspy exporta a través de la caché de xnuspy
para que lo enganches. Invocar `xnuspy_ctl` con este `flavor` hará que se llame a `hookme`,
proporcionándote una forma de obtener fácilmente ejecución de código en el kernel sin
tener que enganchar una función real del kernel.
`arg1` es un argumento que se pasará a `hookme` cuando se invoque.
Puede ser `NULL`.
## `XNUSPY_CACHE_READ`
Este `flavor` te da una forma de leer desde la caché de xnuspy. Contiene muchas cosas
útiles como `kprintf`, `current_proc`, `kernel_thread_start`, algunas funciones de libc,
y el slide del kernel para que no tengas que encontrarlos tú mismo. Para una lista completa
de los IDs de caché, consulta `example/xnuspy_ctl.h`.
`arg1` es uno de los IDs de caché definidos en `xnuspy_ctl.h` y `arg2` es un
puntero para que `xnuspy_ctl` `copyout` la dirección o el valor de lo que solicitaste.
Los valores de los otros argumentos se ignoran.
## `XNUSPY_KREAD`
Este `flavor` te da una forma sencilla de leer memoria del kernel desde espacio de usuario sin
tfp0.
`arg1` es una dirección virtual del kernel, `arg2` es la dirección de un buffer de espacio de usuario,
y `arg3` es el tamaño de ese buffer de espacio de usuario. Se escribirán `arg3` bytes
desde `arg1` hasta `arg2`.
## `XNUSPY_KWRITE`
Este `flavor` te da una forma sencilla de escribir en la memoria del kernel desde espacio de usuario sin
tfp0.
`arg1` es una dirección virtual del kernel, `arg2` es la dirección de un buffer de espacio de usuario,
y `arg3` es el tamaño de ese buffer de espacio de usuario. Se escribirán `arg3` bytes
desde `arg2` hasta `arg1`.
## `XNUSPY_GET_CURRENT_THREAD`
Este `flavor` proporciona al espacio de usuario la dirección del kernel del hilo que realiza la llamada.
`arg1` es un puntero para que `xnuspy_ctl` `copyout` el valor de retorno de
`current_thread`. Los valores de los otros argumentos se ignoran.
### Errores
Para todos los `flavor` excepto `XNUSPY_CHECK_IF_PATCHED`, se devuelve `0` en caso de éxito.
Ante un error, se devuelve `-1` y se establece `errno`. `XNUSPY_CHECK_IF_PATCHED`
no devuelve ningún error. Se utiliza `mach_to_bsd_errno` de XNU para convertir un
`kern_return_t` al `errno` correspondiente.