I am working on a project in which I have to connect 80% -90% of the system call functions in OSX (10.10.5). I am doing this from a kernel extension. Since I have to (un) plug in many functions, I want to save the original kernel function into an array of function pointers so that I can quickly scan the array to restore the original function when unhooked.
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;
This works, the kern_open function is used to store the original kernel function called by the system call. mon_open is my connection function.
What I want to achieve is the following: so after uncoupling, I can just iterate over the KernSysCall array and restore the functions.
// 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;
Recovery: sysent[SYS_open].sy_call = KernSysCall[SYS_open];
However, saving the original kernel function inside an array of function pointers causes a kernel panic. I have not been able to connect lldb yet due to the error error: KDP_REATTACH failed . I hope someone knows what causes a kernel panic.
The following is a kernel panic log.
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 the request, the code for 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); }
Thank you in advance!