# Intercepting system calls



## reoknite (Jun 21, 2012)

I am trying to intercept the system calls and print out the value of the arguments, as well as which system call was called. I am thinking to do it by modifying libc code and creating wrappers around the system calls, but I am lost on tracking how the systems called are actually executed and which level to cut in. (e.g. The open.S file generated seems to be defining __sys_open function. How is the open call converted to __sys_open?)

I would like to know if this approach is possible, and some pointers on how I should do it.

P.S. I know about ktrace but it is not exactly what I need. I want to capture the output from user programs in the trace too.

Thanks.


----------



## t1066 (Jun 22, 2012)

Maybe you can try DTrace?


```
# dtrace -qn 'syscall:::entry { @[execname, probefunc] = count(); } tick-1s { trunc(@,10); printa(@); exit(0); }'

  transmission-qt                             fstat                                                    94
  transmission-qt                             pread                                                    94
  transmission-qt                             sendto                                                  115
  transmission-qt                             kevent                                                  488
  transmission-qt                             writev                                                  560
  transmission-qt                             clock_gettime                                           998
  Xorg                                        gettimeofday                                           1045
  transmission-qt                             ioctl                                                  1284
  transmission-qt                             readv                                                  1284
  transmission-qt                             gettimeofday                                           6420
```


----------



## anomie (Jun 22, 2012)

Also, see if truss(1) meets your needs. (Don't totally understand your requirements, so just offering an additional, general suggestion.)


----------



## fluca1978 (Jun 25, 2012)

Why not wrapping a system call with your own system call that will trace and invoke the original call? This will solve to a loadable module that is not going to affect the libc. Otherwise I would use truss or dtrace as already suggested.


----------



## jianmoto (May 14, 2015)

Hello reoknite,
I want to intercept some system call of freebsd FreeBSD 9.3 today. But I don't know how to do this.There is an example that I found from network.


```
#include <sys/types.h>
#include <sys/param.h>
#include <sys/proc.h>
#include <sys/module.h>
#include <sys/sysent.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/linker.h>
#include <sys/sysproto.h>
#include <sys/sysent.h>
#include <sys/proc.h>
#include <sys/syscall.h>
static int hacked_mkdir (struct proc *p, struct mkdir_args *ua) {
     printf("MKDIR SYSCALL : %s\n", ua->path);
     return mkdir(p, ua);
}
static struct sysent hacked_mkdir_mkdir_sysent = {
1,
hacked_mkdir
};
static int dummy_handler (struct module *module, int cmd, void *arg) {
    int error = 0;
    switch (cmd) {
          case MOD_LOAD :
          sysent[SYS_mkdir]=hacked_mkdir_mkdir_sysent;
          break;
          case MOD_UNLOAD :
         sysent[SYS_mkdir].sy_call=(sy_call_t*)mkdir;
         break;
         default :
         error = EINVAL;
         break;
      }
      return error;
}
static moduledata_t syscall_mod = {
"Intercept",
dummy_handler,
NULL
};
DECLARE_MODULE(syscall, syscall_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE);
```
But this code was out of date. Can you tell me how to intercept the system calls of freebsd FreeBSD 9.3?


----------

