
um framework de hooking de funções do kernel iOS para dispositivos compatíveis com checkra1n

Saída do log do kernel após compilar e executar example/open1_hook.c
xnuspy é um módulo do pongoOS que instala uma nova chamada de sistema, xnuspy_ctl,
que permite interceptar funções do kernel a partir do espaço do usuário. Suporta iOS 13.x,
iOS 14.x e iOS 15.x no checkra1n 0.12.2 e superiores. Dispositivos 4K não são suportados.
Este módulo neutraliza completamente o KTRR/KPP e torna possível criar memória RWX dentro do EL1. Não use isso no seu dispositivo principal.
Requer libusb: brew install libusb
Execute make no diretório raiz. Ele compilará o carregador e o módulo.
Adicione estas antes de make.
XNUSPY_DEBUG=1
kprintf).XNUSPY_SERIAL=1
IOLog.XNUSPY_LEAKED_PAGE_LIMIT=n
64. Mais informações podem ser encontradas em Depuração de panics do kernel.XNUSPY_TRAMP_PAGES=n
XNUSPY_DEBUG e XNUSPY_SERIAL não dependem um do outro.
Depois de compilar tudo, faça o checkra1n iniciar seu dispositivo em um shell pongo:
/Applications/checkra1n.app/Contents/MacOS/checkra1n -p
No mesmo diretório onde você compilou o carregador e o módulo, execute
loader/loader module/xnuspy. Após isso, o xnuspy fará sua parte e
em alguns segundos seu dispositivo será iniciado. O loader aguardará mais alguns
segundos após emitir xnuspy-getkernelv caso o SEPROM precise ser explorado.
Às vezes, alguns dos meus telefones travavam em "Booting" após a execução do KPF do checkra1n. Ainda não descobri o que causa isso, mas se acontecer, tente novamente. Além disso, se o dispositivo travar após bootx, tente novamente. Por fim, marcar o código compilado de xnuspy_ctl como executável no meu iPhone X rodando iOS 13.3.1 é um pouco instável, mas funciona 100% das vezes nos meus outros telefones. Se você tiver um panic com um aborto de busca de instrução do kernel ao executar seu programa de hook, tente novamente.
O xnuspy irá corrigir uma chamada de sistema enosys para apontar para xnuspy_ctl_tramp. Este é um pequeno trampolim que marca o código compilado de xnuspy_ctl como executável e desvia para ele. Você pode encontrar a implementação de xnuspy_ctl em module/el1/xnuspy_ctl/xnuspy_ctl.c e exemplos no diretório example.
Dentro de include/xnuspy/ está xnuspy_ctl.h, um cabeçalho que define constantes para xnuspy_ctl. Ele deve ser incluído em todos os programas que interceptam funções do kernel.
Você pode usar sysctlbyname para descobrir qual chamada de sistema foi corrigida:```
size_t oldlen = sizeof(long);
long SYS_xnuspy_ctl = 0;
sysctlbyname("kern.xnuspy_ctl_callnum", &SYS_xnuspy_ctl, &oldlen, NULL, 0);
Esta chamada de sistema recebe quatro argumentos, `flavor`, `arg1`, `arg2` e `arg3`.
O flavor pode ser `XNUSPY_CHECK_IF_PATCHED`, `XNUSPY_INSTALL_HOOK`,
`XNUSPY_REGISTER_DEATH_CALLBACK`, `XNUSPY_CALL_HOOKME`, `XNUSPY_CACHE_READ`,
`XNUSPY_KREAD`, `XNUSPY_KWRITE` ou `XNUSPY_GET_CURRENT_THREAD`.
O significado dos próximos três argumentos depende do flavor.
## `XNUSPY_CHECK_IF_PATCHED`
Isto existe para que você possa verificar se `xnuspy_ctl` está presente. Invocá-lo com este
flavor fará com que retorne `999`. Os valores dos outros argumentos são
ignorados.
## `XNUSPY_INSTALL_HOOK`
Projetei este flavor para corresponder à API do [`MSHookFunction`](http://www.cydiasubstrate.com/api/c/MSHookFunction/).
`arg1` é o endereço *NÃO DESLIZADO* da função do kernel que você deseja hookear. Se você
fornecer um endereço deslizado, muito provavelmente causará um pânico. `arg2` é um ponteiro para sua
função de substituição compatível com ABI. `arg3` é um ponteiro para `xnuspy_ctl`
`copyout` o endereço de um trampolim que representa a função original do
kernel. Isto pode ser `NULL` se você não pretende chamar a original.
## `XNUSPY_REGISTER_DEATH_CALLBACK`
Este flavor permite registrar um "callback de morte" opcional, uma função que xnuspy
chamará quando seu programa de hook for encerrado. Ele dá a você uma chance de limpar qualquer coisa
que você criou a partir dos seus hooks do kernel. Se você criou quaisquer threads do kernel, você deve
dizer a elas para terminarem nesta função.
Seu callback não é invocado de forma assíncrona, portanto, se você bloquear, estará impedindo
a thread de coleta de lixo do xnuspy de executar.
`arg1` é um ponteiro para sua função de callback. Os valores dos outros argumentos
são ignorados.
## `XNUSPY_CALL_HOOKME`
`hookme` é um pequeno stub de montagem que xnuspy exporta através do cache xnuspy
para você hookear. Invocar `xnuspy_ctl` com este flavor fará com que `hookme` seja
chamado, fornecendo uma maneira de você obter facilmente execução de código no kernel sem
precisar hookear uma função real do kernel.
`arg1` é um argumento que será passado para `hookme` quando for invocado.
Isto pode ser `NULL`.
## `XNUSPY_CACHE_READ`
Este flavor oferece uma maneira de ler do cache xnuspy. Ele contém muitas coisas
úteis como `kprintf`, `current_proc`, `kernel_thread_start`, algumas funções libc,
e o slide do kernel para que você não precise encontrá-los por conta própria. Para uma lista completa
de IDs do cache, confira `example/xnuspy_ctl.h`.
`arg1` é um dos IDs de cache definidos em `xnuspy_ctl.h` e `arg2` é um
ponteiro para `xnuspy_ctl` `copyout` o endereço ou valor do que você solicitou.
Os valores dos outros argumentos são ignorados.
## `XNUSPY_KREAD`
Este flavor oferece uma maneira fácil de ler memória do kernel do userspace sem
tfp0.
`arg1` é um endereço virtual do kernel, `arg2` é o endereço de um buffer no userspace,
e `arg3` é o tamanho desse buffer no userspace. `arg3` bytes serão escritos
de `arg1` para `arg2`.
## `XNUSPY_KWRITE`
Este flavor oferece uma maneira fácil de escrever na memória do kernel a partir do userspace sem
tfp0.
`arg1` é um endereço virtual do kernel, `arg2` é o endereço de um buffer no userspace,
e `arg3` é o tamanho desse buffer no userspace. `arg3` bytes serão escritos
de `arg2` para `arg1`.
## `XNUSPY_GET_CURRENT_THREAD`
Este flavor fornece ao userspace o endereço do kernel da thread chamadora.
`arg1` é um ponteiro para `xnuspy_ctl` `copyout` o valor de retorno de
`current_thread`. Os valores dos outros argumentos são ignorados.
### Erros
Para todos os flavors exceto `XNUSPY_CHECK_IF_PATCHED`, `0` é retornado em caso de sucesso.
Em caso de erro, `-1` é retornado e `errno` é definido. `XNUSPY_CHECK_IF_PATCHED`
não retorna nenhum erro. O `mach_to_bsd_errno` do XNU é usado para converter um
`kern_return_t` no `errno` apropriado.