I would like to create a kernel module from scratch that latches to a user session and monitors each system call made by processes belonging to that user.
I know what everyone is thinking - "use strace" - but I'd like to have some of my own logging and analysis with the data I collect, and strace has some issues - an application could use "mmap" to write to a file without the file contents ever appearing as the arguments of an "open" system call, or an application without any write permission may create coredumps to copy sensitive data.
I want to be able to handle these special cases and do some of my own logging. I wonder though - how can I route all syscalls through my module? Is there any way to do that without touching the kernel code?
Thanks
For hijacking the syscall table and hook a syscall from it, requires write access to the table. The syscall table is a mapping between the syscall ID and the kernel address of its implementation. In order to modify the table, we will have to make write permission from read-only.
So a system call is a way to call kernel code. The called code is definitely part of the kernel. The calling code is in user space (obviously), and often part of a library (e.g. libc ).
You can try lsmod | grep <module name> to see all loaded kernel modules that are using a module. You can also try dmesg | grep <module name> to see if the kernel logs have any clues as to which processes may be using a module. You may be able to remove the module using rmmod --force <module_name> .
Wafer-Thin Wrapper In most applications, system calls are not made directly to the kernel. Virtually all programs link in the standard C library, which provides a thin but important wrapper around Linux system calls.
I don't have the exact answer to your question, but I red a paper a couple of days ago and it may be useful for you:
http://www.cse.iitk.ac.in/users/moona/students/Y2157230.pdf/
I have done something similar in the past by using a kernel module to patch the system call table. Each patched function did something like the following:
patchFunction(/*params*/)
{
// pre checks
ret = origFunction(/*params*/);
// post checks
return ret;
}
Note that when you start mucking around in the kernel data structures, your module becomes version dependent. The kernel module will probably have to be compiled for the specific kernel version you are installing on.
Also note, this is a technique employed by many rootkits so if you have security software installed it may try to prevent you from doing something like this.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With