What are the possible ways of intercepting system calls on unix environments? I'm looking to do in AIX.
Thanks
What are the possible ways of intercepting system calls on unix environments? I'm looking to do in AIX.
Thanks
Not familiar with AIX, but the following works on Linux and Solaris. You can use the LD_PRELOAD environment variable, which tells ld.so to load a shared library before libc and then write your own version of the system call, and optionally call the original. man ld.so
for more information. Something along the lines of
#include <dlfcn.h>
typedef int (*ioctl_fn)(int, int, void*);
static
int
my_ioctl(int fildes,
int request,
void* argp,
ioctl_fn fn_ptr)
{
int result = 0;
/* call original or do my stuff */
if (request == INTERESTED)
{
result = 0;
}
else
{
result = (*fn_ptr)(fildes, request, argp);
}
return result;
}
/*
* override ioctl() - on first call get a pointer to the "real" one
* and then pass it onto our version of the function
*/
int
ioctl(int fildes,
int request,
void* argp)
{
static ioctl_fn S_fn_ptr = 0;
if (S_fn_ptr == 0)
{
S_fn_ptr = (ioctl_fn)dlsym(RTLD_NEXT, "ioctl");
}
return my_ioctl(fildes, request, argp, S_fn_ptr);
}
Carved this out of some code I had lying around, apologies if I have made it incorrect.
I'm not sure about AIX, but I've done it on Linux.
On Linux, the system call table is contained in the sys_call_table
array.
We need to first find out the address of this table. Now, this is a tricky thing and there are multiple ways to do it.
We can find its address by looking at sysmap file:
punb200m2labs08vm1:/ # cat /boot/System.map-4.4.21-69-default | grep sys_call_table
ffffffff81600180 R sys_call_table
Hence, ffffffff81600180
is the address of sys_call_table
on my machine.
In your kernel module, you can just change the default function corresponding to certain system call number (that you're changing) and assign it to your own function.
e.g. Suppose you want to intercept 'open' system call whose number is __NR_open
on Linux. After you get the sys_call_table address from above, just assign your function to index __NR_open
of sys_call_table
:
sys_call_table[__NR_open] = your_function;
where your_function
is implemented by you to intercept 'open' system call.
From now on, every open system call will go through this function.
The details would differ on AIX, but the overall idea would be similar, I guess. You just need to find out AIX specific procedure to achieve this.