Saving SYSCALL functions in an array of function pointers

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!

+7
c module kernel macos kernel-extension
source share
2 answers

Surprisingly stupid, I forgot to point kern_open (the return value of mon_open ) to the function pointer in the array. kern_open was NULL , so this threw a NULL -interinter exception. Now the array of function pointers works correctly.

@pmdj, thanks a lot for your help.

0
source share

The line 0x0 in the panic log indicates that either the NULL function pointer is called (more likely, in this case), or you broke the stack and overwrite the return pointer with NULL. Are you sure that you are not โ€œrestoringโ€ system calls that you never hooked in the first place?

To get lldb working with virtual machines, the requirements depend on different virtualization environments. It should work with VMWare Fusion, assuming you are using "host only network" or bridge mode. With VirtualBox, he only worked with a Virtio network device the last time I tried, and I couldn't get it to work at all on Parallels, but that was a few years ago.

Please note that if you add a serial port to your virtual machine by writing to a text file, you can enter it using kprintf() - this can help you here, since you can print your pointer values โ€‹โ€‹when connecting and disconnecting.

0
source share

All Articles