Je travaille sur un projet dans lequel je dois raccorder 80% -90% des fonctions d'appel système sur OSX (10.10.5). Je fais ceci à partir d'une extension de noyau. Comme je dois (dé) hooker beaucoup de fonctions, je veux stocker la fonction originale du noyau dans un tableau de pointeurs de fonction, pour que je puisse faire une recherche rapide dans le tableau afin de restaurer la fonction d'origine lors du décrochage.Stockage des fonctions SYSCALL dans un tableau de pointeurs de fonction
int (*kern_open)(struct proc *, struct open_args *, int *);
int mon_open(struct proc *p, struct open_args *uap, int *retval) {
kern_open = sysent[SYS_open].sy_call;
sysent[SYS_open].sy_call = mon_open;
Cela fonctionne, la fonction kern_open est utilisée pour stocker la fonction du noyau original qui s fait appel à un appel système. mon_open est ma fonction d'accrochage.
Ce que je veux réaliser est le suivant; de sorte que lors du décrochage, je peux juste itérer à travers le tableau KernSysCall et restaurer les fonctions.
// global array of function pointers that all have the same func def.
static int (*KernSysCall[SYS_MAXSYSCALL])(struct proc *, struct args *, int *);
KernSysCall[SYS_open] = sysent[SYS_open].sy_call;
sysent[SYS_open].sy_call = mon_open;
Restauration: sysent[SYS_open].sy_call = KernSysCall[SYS_open];
Cependant, le stockage de la fonction de noyau d'origine à l'intérieur de la matrice de pointeurs de fonctions est à l'origine d'une panique du noyau. Je n'ai pas encore pu attacher le lldb, en raison d'une erreur error: KDP_REATTACH failed
. J'espère que quelqu'un sait ce qui cause la panique du noyau.
Vous trouverez ci-dessous un journal de la panique du noyau.
Anonymous UUID: 052D64D2-A43C-99F8-D221-B591991E54AF
Wed Nov 11 12:55:06 2015
*** Panic Report ***
panic(cpu 0 caller 0xffffff80093f0024): Kernel trap at 0x0000000000000000, type 14=page fault, registers:
CR0: 0x0000000080010033, CR2: 0x0000000000000000, CR3: 0x00000000769bb018, CR4: 0x00000000001606e0
RAX: 0x0000000000000000, RBX: 0xffffff80115e3fc0, RCX: 0x0000000000000001, RDX: 0xffffff80115e3fc0
RSP: 0xffffff8068dabaf8, RBP: 0xffffff8068dabf50, RSI: 0xffffff80115e3f80, RDI: 0xffffff8010059cf0
R8: 0xffffff7f8afaccdf, R9: 0xffffff8009ae2a18, R10: 0xffffff8009939740, R11: 0x0000000000000000
R12: 0xffffff8010059cf0, R13: 0x0000000000000005, R14: 0xffffff80115e3f80, R15: 0xffffff801188b480
RFL: 0x0000000000010282, RIP: 0x0000000000000000, CS: 0x0000000000000008, SS: 0x0000000000000010
Fault CR2: 0x0000000000000000, Error code: 0x0000000000000010, Fault CPU: 0x0 VMM
Backtrace (CPU 0), Frame : Return Address
0xffffff8068dab790 : 0xffffff80092e4ed1 mach_kernel : _panic + 0xd1
0xffffff8068dab810 : 0xffffff80093f0024 mach_kernel : _kernel_trap + 0x664
0xffffff8068dab9e0 : 0xffffff800940de53 mach_kernel : trap_from_kernel + 0x26
0xffffff8068daba00 : 0x0
0xffffff8068dabf50 : 0xffffff800982c0c1 mach_kernel : _unix_syscall64 + 0x2f1
0xffffff8068dabfb0 : 0xffffff800940e656 mach_kernel : _hndl_unix_scall64 + 0x16
BSD process name corresponding to current thread: xpcproxy
Boot args: debug=0x14e kext-dev-mode=1 -v keepsyms=1 kmem=1
Mac OS version:
14F27
Kernel version:
Darwin Kernel Version 14.5.0: Wed Jul 29 02:26:53 PDT 2015; root:xnu-2782.40.9~1/DEVELOPMENT_X86_64
Kernel UUID: C75BDFDD-9F27-3694-BB80-73CF991C13D8
Kernel slide: 0x0000000009000000
Kernel text base: 0xffffff8009200000
__HIB text base: 0xffffff8009100000
System model name: VMware7,1 (Mac-66F35F19FE2A0D05)
System uptime in nanoseconds: 251264993940
last loaded kext at 249789197520: my.kext 1 (addr 0xffffff7f8afa9000, size 57344)
last unloaded kext at 116769666233: com.apple.driver.AppleFileSystemDriver 3.0.1 (addr 0xffffff7f8aed3000, size 16384)
loaded kexts:
my.kext 1
[more kexts here]
Dans la demande, le code de mon_open():
int
mon_open(struct proc *p, struct open_args *uap, int *r) {
int error;
char processname[MAXCOMLEN+1];
char intercepted_path[MAXPATHLEN];
pid_t pid = proc_pid(p);
proc_name(pid, processname, sizeof(processname));
size_t dummy = 0;
error = copyinstr((void *)uap->path, (void *)intercepted_path, MAXPATHLEN, &dummy);
if (!error) {
printf("[MYKEXT] open called with path: %s, PID: %d, processname: %s\n", intercepted_path, pid, processname);
}
return kern_open(p, uap, r);
}
Merci beaucoup à l'avance!
Une question raisonnablement bien écrite! Êtes-vous sûr que c'est la ligne 'KernSysCall [SYS_open] = sysent [SYS_open] .sy_call;' qui provoque la panique? (Je suppose que '[SYS_open]' dans la question devait être 'sysent [SYS_open]') – immibis
Merci. C'est correct Je suis presque sûr à 100%. Déclarer le tableau statique ne provoque pas la panique. Faire la même chose avec des primitives (e.x. int) ne provoque pas de panique. Seulement quand j'attribue 'KernSysCall [SYS_open] = sysent [SYS_open] .sy_call;' Le reste est à peu près le même que l'horrible "sans tableau" solution. – Joseph
Notez que DTrace modifie également le sy_call des différentes entrées sysent, donc si quelque chose dans votre système utilise DTrace, lui et votre hook peuvent marcher sur les orteils des autres. Est-ce qu'il plante sur * décharger * votre kext, ou décrochez-vous sans décharger? Avez-vous symbolisé la panique de votre noyau pour vérifier exactement ce qui se passe? (avec un argument noyau de 'keepsyms = 1' le noyau symbolisera le crash pour vous) Pour vous aider à diagnostiquer votre échec LLDB, vous allez devoir nous donner un peu plus d'informations sur votre configuration. – pmdj