Ich arbeite an einem Projekt, bei dem ich 80% -90% der Systemaufruffunktionen auf OSX (10.10.5) haken muss. Ich mache das von einer Kernel-Erweiterung. Da ich viele Funktionen haken muss, möchte ich die ursprüngliche Kernelfunktion in einem Array von Funktionszeigern speichern, damit ich das Array schnell durchsuchen kann, um die ursprüngliche Funktion beim Abhaken wiederherzustellen.Speichern von SYSCALL-Funktionen im Array von Funktionszeigern
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;
Dies funktioniert, wird die kern_open Funktion verwendet, um die ursprüngliche Kernfunktion zu speichern, die auf einen Systemaufruf s genannt. mon_open ist meine hooking-Funktion.
Was ich erreichen möchte, ist das Folgende; damit ich beim Abhaken einfach durch das KernSysCall-Array iterieren und die Funktionen wiederherstellen kann.
// 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;
Wiederherstellen: sysent[SYS_open].sy_call = KernSysCall[SYS_open];
jedoch die ursprüngliche Kernfunktion innerhalb der Anordnung von Funktionszeiger speichert, wird eine Kernel-Panik verursacht. Ich konnte die lldb noch nicht anhängen, aufgrund eines error: KDP_REATTACH failed
Fehlers. Ich hoffe, dass jemand weiß, was die Kernel-Panik verursacht.
Unten ist ein Protokoll der Kernel Panic.
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]
In Wunsch der Code für 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);
}
Vielen Dank im Voraus!
Eine einigermaßen gut geschriebene Frage! Sind Sie sicher, dass es die Zeile 'KernSysCall [SYS_open] = sysent [SYS_open] .sy_call;' ist, die die Panik verursacht? (Ich nehme an, '[SYS_open]' in der Frage sollte 'sysent [SYS_open]') sein. – immibis
Danke. Das ist richtig. Ich bin mir fast 100% sicher. Die Deklaration des statischen Arrays verursacht keine Panik. Doing das gleiche Array-Ding mit Primitiven (e.x. int) verursacht keine Panik. Nur wenn ich 'KernSysCall [SYS_open] = sysent [SYS_open] .sy_call;' zuweiße. Der Rest ist so ziemlich wie die hässliche "array-less" -Lösung. – Joseph
Beachten Sie, dass DTrace auch den sy_call verschiedener sysent-Einträge ändert. Wenn also irgendetwas in Ihrem System DTrace verwendet, können Sie und Ihr Hook sich gegenseitig auf die Füße treten. Stürzt es auf * Entladen * Ihres Kext, oder haken Sie ab, ohne zu entladen? Hast du deine Kernel-Panik symbolisiert, um genau zu sehen, was passiert? (Mit einem Kernel-Argument von 'keepyms = 1' wird der Kernel den Absturz für Sie symbolisieren) Um Ihnen zu helfen, Ihren LLDB-Fehler zu diagnostizieren, müssen Sie uns ein bisschen mehr Informationen über Ihre Einrichtung geben. – pmdj