Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
xnuspy — un framework de hooking de fonctions du noyau iOS pour les appareils compatibles checkra1n | Kitploit
Outils/GitHubGitHub/jsherman212/xnuspy
Sécurité iOSExploitationDébogueursAnalyse de Binaires
GitHubjsherman212/xnuspy

xnuspy

un framework de hooking de fonctions du noyau iOS pour les appareils compatibles checkra1n

Voir le dépôt
595112il y a 4 ansVérifié par Kitploit

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

xnuspy

alt text

Sortie du journal du noyau après compilation et exécution de example/open1_hook.c

xnuspy est un module pongoOS qui installe un nouvel appel système, xnuspy_ctl, permettant de hooker des fonctions du noyau depuis l'espace utilisateur. Il supporte iOS 13.x, iOS 14.x et iOS 15.x sur checkra1n 0.12.2 et ultérieur. Les appareils 4K ne sont pas supportés.

Ce module neutralise complètement KTRR/KPP et permet de créer de la mémoire RWX dans EL1. Ne l'utilisez pas sur votre appareil principal.

Nécessite libusb : brew install libusb

Construction

Exécutez make dans le répertoire racine. Cela compilera le chargeur et le module.

Options de construction

Ajoutez-les avant make.

  • XNUSPY_DEBUG=1
    • Envoie les sorties de débogage de xnuspy vers le journal du noyau (kprintf).
  • XNUSPY_SERIAL=1
    • Envoie les sorties de débogage de xnuspy vers IOLog.
  • XNUSPY_LEAKED_PAGE_LIMIT=n
    • Définit le nombre de pages que xnuspy peut fuir avant que son thread de collecte des ordures ne commence à les désallouer. La valeur par défaut est 64. Plus d'informations se trouvent sous Débogage des paniques du noyau.
  • XNUSPY_TRAMP_PAGES=n
    • Définit le nombre de pages que xnuspy réserve pour ses structures de trampoline. La valeur par défaut est 1. Plus d'informations se trouvent sous Limites.

XNUSPY_DEBUG et XNUSPY_SERIAL ne dépendent pas l'un de l'autre.

Utilisation

Après avoir tout construit, faites démarrer votre appareil par checkra1n dans un shell pongo : /Applications/checkra1n.app/Contents/MacOS/checkra1n -p

Dans le même répertoire où vous avez construit le chargeur et le module, faites loader/loader module/xnuspy. Après cela, xnuspy fera son travail et dans quelques secondes votre appareil démarrera. loader attendra quelques secondes supplémentaires après avoir émis xnuspy-getkernelv au cas où SEPROM doit être exploitée.

Problèmes connus

Parfois, certains de mes téléphones restaient bloqués sur « Booting » après l'exécution du KPF de checkra1n. Je n'ai pas encore compris ce qui cause cela, mais si cela arrive, réessayez. De plus, si l'appareil se bloque après bootx, réessayez. Enfin, marquer le code compilé xnuspy_ctl comme exécutable sur mon iPhone X sous iOS 13.3.1 est un peu capricieux, mais réussit 100% du temps sur mes autres téléphones. Si vous paniquez avec un abandon de récupération d'instruction du noyau lorsque vous exécutez votre programme de hook, réessayez.

xnuspy_ctl

xnuspy va patcher un appel système enosys pour pointer vers xnuspy_ctl_tramp. C'est un petit trampoline qui marque le code compilé xnuspy_ctl comme exécutable et saute vers lui. Vous trouverez l'implémentation de xnuspy_ctl dans module/el1/xnuspy_ctl/xnuspy_ctl.c et des exemples dans le répertoire example.

À l'intérieur de include/xnuspy/ se trouve xnuspy_ctl.h, un en-tête qui définit des constantes pour xnuspy_ctl. Il est destiné à être inclus dans tous les programmes qui hookent des fonctions du noyau.

Vous pouvez utiliser sysctlbyname pour savoir quel appel système a été patché :``` size_t oldlen = sizeof(long); long SYS_xnuspy_ctl = 0; sysctlbyname("kern.xnuspy_ctl_callnum", &SYS_xnuspy_ctl, &oldlen, NULL, 0);

root@kitploit:~
Cet appel système prend quatre arguments : `flavor`, `arg1`, `arg2` et `arg3`.
Les saveurs possibles sont `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`.
La signification des trois arguments suivants dépend de la saveur.

## `XNUSPY_CHECK_IF_PATCHED`
Cette saveur existe pour que vous puissiez vérifier si `xnuspy_ctl` est présent. L'invoquer avec cette saveur lui fera retourner `999`. Les valeurs des autres arguments sont ignorées.

## `XNUSPY_INSTALL_HOOK`
J'ai conçu cette saveur pour correspondre à l'API de [`MSHookFunction`](http://www.cydiasubstrate.com/api/c/MSHookFunction/).
`arg1` est l'adresse *NON GLISSÉE* de la fonction du noyau que vous souhaitez hooker. Si vous fournissez une adresse glissée, vous provoquerez très probablement un kernel panic. `arg2` est un pointeur vers votre fonction de remplacement compatible ABI. `arg3` est un pointeur pour que `xnuspy_ctl` fasse `copyout` de l'adresse d'un trampoline qui représente la fonction originale du noyau. Cela peut être `NULL` si vous n'avez pas l'intention d'appeler l'originale.

## `XNUSPY_REGISTER_DEATH_CALLBACK`
Cette saveur vous permet d'enregistrer un « callback de fin de vie » optionnel, une fonction que xnuspy appellera lorsque votre programme de hook se termine. Cela vous donne la possibilité de nettoyer tout ce que vous avez créé à partir de vos hooks du noyau. Si vous avez créé des threads noyau, vous leur demanderiez de se terminer dans cette fonction.

Votre callback n'est pas invoqué de manière asynchrone, donc si vous bloquez, vous empêchez le thread de garbage collection de xnuspy de s'exécuter.

`arg1` est un pointeur vers votre fonction callback. Les valeurs des autres arguments sont ignorées.

## `XNUSPY_CALL_HOOKME`
`hookme` est un petit stub assembleur que xnuspy exporte via le cache xnuspy pour que vous puissiez le hooker. Invoquer `xnuspy_ctl` avec cette saveur entraînera l'appel de `hookme`, offrant un moyen d'obtenir facilement une exécution de code noyau sans avoir à hooker une fonction noyau réelle.

`arg1` est un argument qui sera passé à `hookme` lors de son invocation. Cela peut être `NULL`.

## `XNUSPY_CACHE_READ`
Cette saveur vous offre un moyen de lire depuis le cache xnuspy. Il contient de nombreuses choses utiles comme `kprintf`, `current_proc`, `kernel_thread_start`, certaines fonctions libc, et le slide du noyau afin que vous n'ayez pas à les trouver vous-même. Pour une liste complète des identifiants de cache, consultez `example/xnuspy_ctl.h`. 

`arg1` est l'un des identifiants de cache définis dans `xnuspy_ctl.h` et `arg2` est un pointeur pour que `xnuspy_ctl` fasse `copyout` de l'adresse ou de la valeur de ce que vous avez demandé. Les valeurs des autres arguments sont ignorées.

## `XNUSPY_KREAD`
Cette saveur vous offre un moyen simple de lire la mémoire du noyau depuis l'espace utilisateur sans tfp0.

`arg1` est une adresse virtuelle noyau, `arg2` est l'adresse d'un tampon espace utilisateur, et `arg3` est la taille de ce tampon espace utilisateur. `arg3` octets seront écrits de `arg1` vers `arg2`.

## `XNUSPY_KWRITE`
Cette saveur vous offre un moyen simple d'écrire dans la mémoire du noyau depuis l'espace utilisateur sans tfp0.

`arg1` est une adresse virtuelle noyau, `arg2` est l'adresse d'un tampon espace utilisateur, et `arg3` est la taille de ce tampon espace utilisateur. `arg3` octets seront écrits de `arg2` vers `arg1`.

## `XNUSPY_GET_CURRENT_THREAD`
Cette saveur fournit à l'espace utilisateur l'adresse noyau du thread appelant.

`arg1` est un pointeur pour que `xnuspy_ctl` fasse `copyout` de la valeur de retour de `current_thread`. Les valeurs des autres arguments sont ignorées.

### Errors
Pour toutes les saveurs sauf `XNUSPY_CHECK_IF_PATCHED`, `0` est retourné en cas de succès. En cas d'erreur, `-1` est retourné et `errno` est défini. `XNUSPY_CHECK_IF_PATCHED` ne retourne aucune erreur. La fonction `mach_to_bsd_errno` de XNU est utilisée pour convertir un `kern_return_t` en `errno` approprié.

#### Erreurs liées à `XNUSPY_INSTALL_HOOK`
`errno` est défini sur...
- `EEXIST` si :
  - Un hook existe déjà pour la fonction noyau non glissée désignée par `arg1`.
- `ENOMEM` si :
  - `unified_kalloc` a retourné `NULL`.
- `ENOSPC` si :
  - Il n'y a plus de structures `xnuspy_tramp` libres, une structure de données interne à xnuspy. Cela ne devrait pas se produire sauf si vous hookez des centaines de fonctions noyau *en même temps*. Si vous avez besoin de plus de hooks de fonctions, consultez [Limites](#limits).
- `ENOTSUP` si :
  - L'appelant ne provient pas d'un exécutable Mach-O ou d'une bibliothèque dynamique.
- `ENOENT` si :
  - `mh_for_addr` n'a pas pu déterminer l'en-tête Mach-O correspondant à `arg2` dans l'espace d'adressage de l'appelant.
- `EFAULT` si :
  - L'en-tête Mach-O déterminé n'est pas réellement un en-tête Mach-O. Cela n'arrivera probablement jamais.
- `EIO` si :
  - `mach_make_memory_entry_64` n'a pas retourné d'entrée mémoire pour l'intégralité des segments `__TEXT` et `__DATA` de l'en-tête Mach-O déterminé.

`errno` dépend également de la valeur de retour de `vm_map_wire_external`, `mach_vm_map_external`, `mach_make_memory_entry_64`, `copyin`, `copyout`, et, le cas échéant, de la fonction d'initialisation unique.

Si cette saveur retourne une erreur, la fonction noyau cible n'a pas été hookée. Si vous avez passé un pointeur non `NULL` pour `arg3`, il peut ou non avoir été initialisé. Il est dangereux de l'utiliser s'il l'a été.

#### Erreurs liées à `XNUSPY_REGISTER_DEATH_CALLBACK`
`errno` est défini sur...
- `ENOENT` si :
  - Le processus appelant n'a hooké aucune fonction noyau.

Si cette saveur retourne une erreur, votre callback de fin de vie n'a pas été enregistré.

#### Erreurs liées à `XNUSPY_CALL_HOOKME`
`errno` est défini sur...
- `ENOTSUP` si :
  - `hookme` est trop éloigné de la mémoire contenant les structures `xnuspy_tramp`. Ceci est déterminé à l'intérieur de pongoOS, et ne peut se produire que si xnuspy a dû se replier sur du code inutilisé déjà présent dans le kernelcache. Dans ce cas, appeler `hookme` provoquerait presque certainement un kernel panic, et vous devrez trouver une autre fonction noyau à hooker.

Si cette saveur retourne une erreur, `hookme` n'a pas été appelé.

#### Erreurs liées à `XNUSPY_CACHE_READ`
`errno` est défini sur...
- `EINVAL` si :
  - La constante désignée par `arg1` ne représente rien dans le cache.
  - `arg1` était `IO_LOCK`, mais le noyau est iOS 14.4.2 ou inférieur ou iOS 15.x.
  - `arg1` était `IPC_OBJECT_LOCK`, mais le noyau est iOS 15.x.
  - `arg1` était `IPC_PORT_RELEASE_SEND`, mais le noyau est iOS 14.5 ou supérieur.
  - `arg1` était `IPC_PORT_RELEASE_SEND_AND_UNLOCK`, mais le noyau est iOS 14.4.2 ou inférieur.
  - `arg1` était `KALLOC_CANBLOCK`, mais le noyau est iOS 14.x ou supérieur.
  - `arg1` était `KALLOC_EXTERNAL`, mais le noyau est iOS 13.x.
  - `arg1` était `KFREE_ADDR`, mais le noyau est iOS 14.x ou supérieur.
  - `arg1` était `KFREE_EXT`, mais le noyau est iOS 13.x.
  - `arg1` était `PROC_REF`, mais le noyau est iOS 14.8 ou inférieur.
  - `arg1` était `PROC_REF_LOCKED`, mais le noyau est iOS 15.x.
  - `arg1` était `PROC_RELE`, mais le noyau est iOS 14.8 ou inférieur.
  - `arg1` était `PROC_RELE_LOCKED`, mais le noyau est iOS 15.x.
  - `arg1` était `VM_MAP_UNWIRE`, mais le noyau est iOS 15.x.
  - `arg1` était `VM_MAP_UNWIRE_NESTED`, mais le noyau est iOS 14.8 ou inférieur.

`errno` dépend également de la valeur de retour de `copyout` et, le cas échéant, de la valeur de retour de la fonction d'initialisation unique.

Si cette saveur retourne une erreur, le pointeur que vous avez passé pour `arg2` n'a pas été initialisé.

#### Erreurs liées à `XNUSPY_KREAD` et `XNUSPY_KWRITE`
`errno` est défini sur...
- `EFAULT` si :
  - La traduction d'adresse a échoué pour `arg1` ou `arg2`. Si vous avez compilé avec `XNUSPY_DEBUG=1`, un message à ce sujet est imprimé dans le journal du noyau.

Si cette saveur retourne une erreur, la mémoire noyau n'a pas été lue/écrite.

#### Erreurs liées à `XNUSPY_GET_CURRENT_THREAD`
Si `copyout` échoue, `errno` est défini sur sa valeur de retour.

# Informations importantes

### Pièges courants
Lors de l'écriture de fonctions de remplacement, il était facile d'oublier que j'écrivais du code noyau. Voici quelques points à garder à l'esprit lorsque vous écrivez des hooks :

- *Vous ne pouvez exécuter aucun code espace utilisateur qui se trouve en dehors du segment `__TEXT` de votre programme*. Vous provoquerez un kernel panic si, par exemple, vous appelez accidentellement `printf` au lieu de `kprintf`. Vous devez réimplémenter toute fonction libc que vous souhaitez appeler si cette fonction n'est pas déjà disponible via `XNUSPY_CACHE_READ`. Vous pouvez cependant créer des pointeurs de fonction vers d'autres fonctions noyau et les appeler.
- *De nombreuses macros couramment utilisées dans le code espace utilisateur sont dangereuses pour le noyau.* Par exemple, `PAGE_SIZE` se développe en `vm_page_size`, pas en une constante. Vous devez désactiver PAN (sur A10+, ce que je ne recommande pas non plus) avant de lire cette variable ou vous provoquerez un kernel panic.
- *Assurez-vous de compiler votre code avec `-fno-stack-protector` et `-D_FORTIFY_SOURCE=0`* Dans certains cas, l'appareil devra lire `___stack_chk_guard` en déréférençant un autre pointeur espace utilisateur, ce qui provoquera un kernel panic sur A10+.
- *Pour être sûr, ne compilez pas vos programmes de hook avec des optimisations du compilateur.*

Il est également recommandé de parcourir https://developer.apple.com/library/archive/documentation/Darwin/Conceptual/KernelProgramming/style/style.html.

### Débogage des kernel panics
Les bogues sont inévitables lors de l'écriture de code, donc vous allez éventuellement provoquer un kernel panic. Un kernel panic ne signifie pas nécessairement qu'il y a un bogue dans xnuspy, donc avant d'ouvrir un ticket, veuillez vous assurer que vous obtenez toujours un kernel panic lorsque vous ne faites rien d'autre que d'appeler la fonction originale et de retourner sa valeur (si nécessaire). Si vous obtenez toujours un kernel panic, il s'agit probablement d'un bogue de xnuspy (et veuillez ouvrir un ticket), mais sinon, il y a un problème avec votre remplacement.

Puisque xnuspy ne redirige pas réellement l'exécution vers des pages EL0, déboguer un kernel panic n'est pas aussi simple. Ouvrez `module/el1/xnuspy_ctl/xnuspy_ctl.c`, et juste avant le seul appel à `kwrite_instr` dans `xnuspy_install_hook`, ajoutez un appel à `IOSleep` de quelques secondes. Cela permet de s'assurer qu'il y a suffisamment de temps avant que l'appareil ne panique pour que les journaux se propagent. Recompilez xnuspy avec `XNUSPY_DEBUG=1 make -B` et rechargez le module. Après avoir chargé le module, si ce n'est pas déjà fait, compilez `klog` depuis `klog/`. Transférez-le sur votre appareil et exécutez `stdbuf -o0 ./klog | grep shared_mapping_kva`. Relancez votre programme de hook et surveillez une ligne de `klog` qui ressemble à ceci :

`shared_mapping_kva: dist 0x7af4 uaddr 0x104797af4 umh 0x104790000 kmh 0xfffffff00c90c000`

Si vous installez plus d'un hook, il y aura plus d'une occurrence. Dans ce cas, `dist` et `uaddr` varieront, mais `umh` et `kmh` non. `kmh` pointe vers le début du mappage noyau du segment `__TEXT` de votre programme. Jetez votre programme de hook dans votre désassembleur préféré et rebasez-le de sorte que son en-tête Mach-O soit à l'adresse de `kmh`. Pour IDA Pro, c'est `Edit -> Segments -> Rebase program...` avec `Image base` activé. Après que votre appareil a paniqué et redémarré à nouveau, s'il y a des adresses dans le journal de kernel panic qui correspondent au mappage noyau de votre remplacement, elles correspondront au désassemblage. S'il n'y en a pas, vous avez probablement une corruption mémoire subtile à l'intérieur de votre remplacement.

xnuspy n'a également aucun moyen de savoir si un thread noyau est toujours en cours d'exécution (ou va s'exécuter) sur le mappage noyau du segment `__TEXT` de votre programme après la désinstallation de vos hooks. L'une des choses que xnuspy fait pour gérer cela est de ne pas désallouer ce mappage immédiatement après la mort de votre programme de hook. Au lieu de cela, il est ajouté à la fin d'une file d'attente. Une fois que le thread de garbage collection de xnuspy remarque qu'une limite définie a été dépassée concernant le nombre de pages de mappages détenues dans cette file d'attente, il commencera à désallouer depuis le début de la file d'attente et continuera jusqu'à ce que cette limite ne soit plus dépassée. Par défaut, cette limite est de 1 Mo, soit 64 pages.

Cela aide énormément, mais plus les segments `__TEXT` et `__DATA` de votre programme de hook deviennent grands, moins xnuspy a de chances de gagner cette course. Si vous paniquez régulièrement et que votre programme de hook est relativement gros, essayez d'augmenter cette limite en ajoutant `XNUSPY_LEAKED_PAGE_LIMIT=n` avant `make`. Cela fixera cette limite à `n` pages au lieu de 64.

### Limites
xnuspy réserve une page de mémoire statique du noyau avant le démarrage de XNU pour ses structures `xnuspy_tramp`, vous permettant de hooker simultanément environ 225 fonctions noyau. Si vous en voulez plus, vous pouvez ajouter `XNUSPY_TRAMP_PAGES=n` avant `make`. Cela indiquera à xnuspy de réserver `n` pages de mémoire statique pour les structures `xnuspy_tramp`. Cependant, si xnuspy doit se replier sur du code inutilisé déjà présent dans le kernelcache, cela est ignoré. Quand cela se produit est détaillé dans [Fonctionnement](#how-it-works).

### Journalisation
Pour une raison inconnue, les journaux de `os_log_with_args` n'apparaissent pas dans le flux produit par l'outil en ligne de commande `oslog`. Les journaux de `kprintf` n'y parviennent pas non plus, mais ils *peuvent* être vus avec `dmesg`. Cependant, `dmesg` n'est pas un flux en direct, j'ai donc écrit `klog`, un outil qui affiche les journaux `kprintf` en temps réel. Vous le trouverez dans `klog/`. Je recommande vivement de l'utiliser plutôt que de spammer `dmesg` pour vos messages `kprintf`.

Si vous obtenez `open: Resource busy` après avoir exécuté `klog`, exécutez cette commande : `launchctl unload /System/Library/LaunchDaemons/com.apple.syslogd.plist` et réessayez.

Malheureusement, vous ne pourrez pas voir les `NSLog` si `atm_diagnostic_config=0x20000000` est défini dans les bootargs de XNU. `klog` dépend de la présence de ce boot argument. Si vous voulez retrouver `NSLog`, supprimez ce boot argument de `pongo_send_command` dans `loader.c`.

### Désinstallation des hooks
xnuspy gérera cela pour vous. Une fois qu'un processus se termine, tous les hooks noyau qui ont été installés par ce processus sont désinstallés en une seconde environ.

### Fonctions noyau hookables
La plupart des frameworks de hook de fonctions ont une longueur minimale qui rend une fonction hookable. xnuspy a cette limite *uniquement* si vous prévoyez d'appeler la fonction originale *et* que la première instruction de la fonction hookée n'est pas `B`. Dans ce cas, la longueur minimale est de huit octets. Sinon, il n'y a pas de longueur minimale.

xnuspy utilise `X16` et `X17` pour ses trampolines, donc les fonctions noyau qui s'attendent à ce que ceux-ci persistent entre les appels de fonction ne peuvent pas être hookées (il n'y en a pas beaucoup qui s'attendent à cela). Si la fonction que vous souhaitez hooker commence par `BL`, et que vous avez l'intention d'appeler l'originale, vous ne pouvez le faire que si l'exécution de la fonction originale ne modifie pas `X17`.

### Sécurité des threads
`xnuspy_ctl` effectuera une initialisation unique la première fois qu'il est appelé après un démarrage à froid. C'est la seule partie de xnuspy qui est sujette aux conditions de concurrence car je ne peux pas initialiser statiquement le verrou de lecture/écriture que j'utilise. Une fois que le premier appel revient, tous les appels futurs sont garantis thread-safe.

# Fonctionnement
Ceci est simplifié, mais cela capture bien l'idée principale. Un hook de fonction dans xnuspy est une structure qui réside sur une mémoire du noyau accessible en écriture et exécutable. Dans la plupart des cas, il s'agit de la mémoire retournée par `alloc_static` dans pongoOS. Cela peut se résumer à ceci :```
struct {
	uint64_t replacement;
	uint32_t tramp[2];
	uint32_t orig[10];
};

Où replacement est l'adresse virtuelle du noyau (détaillée plus tard) de la fonction de remplacement, tramp est un petit trampoline qui redirige l'exécution vers replacement, et orig est un trampoline plus grand et plus complexe qui représente la fonction originale.

L'une des premières choses que fait xnuspy est de déterminer où se trouve le remplacement EL0 dans l'espace d'adressage du processus appelant. Cela est fait pour que les fonctions du noyau puissent être hookées depuis des bibliothèques dynamiques. L'en-tête Mach-O qui correspond à l'adresse de ce remplacement est sauvegardé.

Ensuite, un mappage partagé utilisateur-noyau des segments __TEXT et __DATA de cet en-tête (ainsi que tout segment entre eux, le cas échéant) est créé. __TEXT est partagé afin que vous puissiez appeler d'autres fonctions depuis vos hooks. __DATA est partagé afin que les modifications des variables globales soient visibles à la fois par EL1 et EL0.

Comme ce mappage est une copie un-à-un de __TEXT et __DATA, il est facile de déterminer l'adresse de la fonction de remplacement de l'utilisateur dessus. Étant donné l'adresse de l'en-tête Mach-O du processus appelant u, l'adresse du début du mappage partagé k, et l'adresse de la fonction de remplacement de l'utilisateur r, nous appliquons la formule suivante : replacement = k + (r - u)

Après cela, replacement est l'adresse virtuelle du noyau de la fonction de remplacement de l'utilisateur sur le mappage partagé et est écrite dans la structure de hook de fonction. xnuspy ne redirige pas l'exécution vers l'adresse EL0 de la fonction de remplacement car c'est extrêmement dangereux : non seulement cela nous met à la merci de l'ordonnanceur, mais cela ne nous donne aucun contrôle sur le scénario où un processus avec un hook noyau meurt pendant qu'un thread du noyau exécute encore le remplacement.

Enfin, le mappage partagé est marqué comme exécutable et un branchement immédiat inconditionnel (B) est assemblé. Il dirige l'exécution vers le début de tramp, et c'est ce qui remplace la première instruction de la fonction noyau maintenant hookée. Malheureusement, cela nous limite à brancher vers des structures de hook à moins de 128 Mo d'une fonction noyau donnée. xnuspy vérifie ce scénario avant le démarrage et se rabat sur du code inutilisé déjà dans le kernelcache pour les structures de hook si nécessaire.

Autres notes

Je fais de mon mieux pour m'assurer que les patchfinders fonctionnent, donc si quelque chose ne fonctionne pas, veuillez ouvrir un issue.

Télécharger l’outil