Kernels lower than 4.6 use assembly stubs to harden the hooking of critical system calls like fork, clone, exec etc. Particularly speaking for execve, the following snippet from Kernel-4.5 shows entry stub of execve:
ENTRY(stub_execve) call sys_execve return_from_execve: ... END(stub_execve)
System call table contains this stub's address and this stub further calls original execve. So, to hook execve in this environment we need to patch
call sys_execve in stub with our hooking routine and after doing our desired things call the original execve. This all can be seen in action in execmon, a process execution monitoring utility for linux. I'd tested execmon successfully working in Ubuntu 16.04 with kernel 4.4.
Starting from kernel 4.6, upper scheme for critical calls protection had been changed. Now the stub looks like:
ENTRY(ptregs_\func) leaq \func(%rip), %rax jmp stub_ptregs_64 END(ptregs_\func)
\func will expand to
sys_execve for execve calls. Again, system call table contains this stub and this stub calls original execve, but now in a more secured manner instead of just doing
This newer stub, stores called function's address in
RAX register and jumps to another stub shown below (comments removed):
ENTRY(stub_ptregs_64) cmpq $.Lentry_SYSCALL_64_after_fastpath_call, (%rsp) jne 1f DISABLE_INTERRUPTS(CLBR_NONE) TRACE_IRQS_OFF popq %rax jmp entry_SYSCALL64_slow_path 1: jmp *%rax /* called from C */ END(stub_ptregs_64)
Please have a look on this to see comments and other referenced labels in this stub.
I'd tried hard to come up with some logic to overcome this protection and patch original calls with hooking functions, but no success yet. Would someone like to join me and help to get out of it.