systr_init_library, systr_cleanup_library, systr_run, systr_stop, systr_trace_syscall, systr_untrace_syscall, systr_get_pid, systr_get_param, systr_set_params, systr_is_entry, systr_pmem_read, systr_pmem_write, systr_pszmem_read - System Call Tracing Library support functions
#include <sysctr.h> int systr_init_library(void); void systr_cleanup_library(void); int systr_run(char **av); int systr_stop(void); int systr_trace_syscall(int syscall, int (*scfunc)(void *, trsyscall_t), void *priv); int systr_untrace_syscall(int syscall); int systr_get_pid(trsyscall_t tsc, unsigned long *pid); int systr_get_param(trsyscall_t tsc, int param, unsigned long *pparam); int systr_set_params(trsyscall_t tsc, ...); int systr_is_entry(trsyscall_t tsc); int systr_pmem_read(trsyscall_t tsc, int where, unsigned long addr, char *buf, int size); int systr_pmem_write(trsyscall_t tsc, int where, unsigned long addr, char *buf, int size); int systr_pszmem_read(trsyscall_t tsc, int where, unsigned long addr, char *buf, int bmax);
Initialize the library and makes it ready to accept other calls to library functions. It should be called only once at the beginning of the program. It returns 0 in case of success, and a value <0 in case of error.
Undo the operations done with the systr_init_library() call. It stop the monitoring process and kills all the processes spawned by the systr_run() call. It should be called after the return of the systr_run(), when the user has done using the LibSysCTr library.
It starts the monitoring activity on the system calls registered with systr_trace_syscall(). The av parameter is an arrary of character pointers that specify the process binary to be monitored. The av[0] array element is the path (or name) of the binary file to be executed, while the following elements are the parameters supplied to the binary. The av array is terminated by a NULL pointer. The function returns when no more monitored processes are available, or when a call to systr_stop() is done by the caller. In case of success the function returns 0, while in case errors happened during the process, a value <0 is returned.
The function stops the internal monitor loop triggered by a call to systr_run() and makes the function systr_run() to return soon. It is usually called from inside a user callback to stop the library event processing. It returns 0 in case of success, and a value <0 in case of error.
The function lets the user to register the system call syscall to be traced by the LibSysCTr library. The parameter scfunc specify a pointer to a callback function that will be invoked at every entry and exit from the syscall system call. The callback function template will look like:
int scfunc(void *priv, trsyscall_t tsc) { ... }The priv parameter will be passed back to the callback function, and it is treated transparently by the LibSysCTr library. The tsc parameter that the callback will receive, is a system call context handle that can be used to call other LibSysCTr utility functions. The callback function will return SYSTR_RET_CONTINUE if it wants to continue tracing the current process, or SYSTR_RET_DETACH if it does not want to receive any more notification from the process associated with the tsc context. The systr_trace_syscall() returns 0 in case of success, and a value <0 in case of error.
Undo the effects of a systr_trace_syscall() function call, by unregistering the syscall from the list of the ones monitored by the LibSysCTr library. it returns 0 in case of success, and a value <0 in case of error.
The function will be used to retrieve the process ID (pid) associated with the current system call context tsc. The process ID value will be stored in the location pointed by pid. The systr_get_pid() function returns 0 in case of success, and a value <0 in case of error.
The function lets the caller to retrieve system call parameters (or registers) associated
with the context
tsc.
The
param
value specify the system call parameter to be retrieved, and it can be one of the following
values:
The retrieved system call parameter will be stored in the location pointed by pparam. The function returns 0 in case of success, or a value <0 in case of error.
The function lets the caller to set system call parameters (or registers) associated with the context tsc. To optimize the process context writing, the systr_set_params() accepts multiple parameter-value cuples to be set at the same time. So, following the tsc parameter, there will be a list of parameter,value couples, terminated with a last parameter equal to -1. Example:
unsigned long param1, param2; systr_set_params(tsc, SYSTR_PARAM_1, ¶m1, SYSTR_PARAM_2, ¶m2, -1);The systr_set_params() function will return 0 in case of success, or a value <0 in case of error.
The LibSysCTr system call interception will trigger two callback invocations per each system call. One on system call entry, and one on exit. The systr_is_entry() function can be used to distinguish between the entry and the exit from the system call. It returns a value different from 0 in case it is an entry call, or 0 in case it is an exit.
The function lets the caller to read the memory of the process associated
with the context
tsc.
The
where
parameter is either:
The addr parameter specify the address, in the traced process address space, from where to start the read operation, and the size parameter specifies the size in bytes of the block to be read. The read data will be stored in the buffer pointed by buf. The function return the number of bytes read (usually size), or a number lower than size in case errors happened.
The function lets the caller to write the memory of the process associated
with the context
tsc.
The
where
parameter is either:
The addr parameter specify the address, in the traced process address space, from where to start the write operation, and the size parameter specifies the size in bytes of the block to be written. The data will be read from the user buffer pointed by buf. The function return the number of bytes written (usually size), or a number lower than size in case errors happened.
The function lets the caller to read the memory of the process associated
with the context
tsc.
The data will be read as zero-terminated string, up to
bmax
bytes. The
where
parameter is either:
The addr parameter specify the address, in the traced process address space, from where to start the read operation. The read data will be stored in the buffer pointed by buf. The function return the number of bytes read, or -1 in case of error.
#include <stdio.h> #include <stdlib.h> #include <signal.h> #include <unistd.h> #include <errno.h> #include <string.h> #include <linux/unistd.h> #include <sysctr.h> static int open_scfunc(void *priv, trsyscall_t tsc) { int entry; unsigned long pid, param, rcode; char buf[512]; systr_get_pid(tsc, &pid); entry = systr_is_entry(tsc); systr_get_param(tsc, SYSTR_PARAM_1, ¶m); if (!entry) systr_get_param(tsc, SYSTR_PARAM_RCODE, &rcode); buf[0] = 0; systr_pszmem_read(tsc, SYSTR_DATA_SECT, param, buf, sizeof(buf) - 1); fprintf(stderr, "[%lu] %s open(%s)", pid, entry ? "E": "X", buf); if (entry) fprintf(stderr, " = ?); else fprintf(stderr, " = %lu, rcode); return SYSTR_RET_CONTINUE; } static int close_scfunc(void *priv, trsyscall_t tsc) { int entry; unsigned long pid, param; systr_get_pid(tsc, &pid); entry = systr_is_entry(tsc); systr_get_param(tsc, SYSTR_PARAM_1, ¶m); fprintf(stderr, "[%lu] %s close(%d), pid, entry ? "E": "X", param); return SYSTR_RET_CONTINUE; } static int exec_scfunc(void *priv, trsyscall_t tsc) { int entry; unsigned long pid, param; char buf[512]; systr_get_pid(tsc, &pid); entry = systr_is_entry(tsc); systr_get_param(tsc, SYSTR_PARAM_1, ¶m); buf[0] = 0; if (entry) systr_pszmem_read(tsc, SYSTR_DATA_SECT, param, buf, sizeof(buf) - 1); fprintf(stderr, "[%lu] %s exec(%s), pid, entry ? "E": "X", buf); return SYSTR_RET_CONTINUE; } static int fork_scfunc(void *priv, trsyscall_t tsc) { int entry; unsigned long pid, cpid; systr_get_pid(tsc, &pid); entry = systr_is_entry(tsc); if (entry) fprintf(stderr, "[%lu] E fork(), pid); else { systr_get_param(tsc, SYSTR_PARAM_RCODE, &cpid); fprintf(stderr, "[%lu] X fork() -> %lu, pid, cpid); } return SYSTR_RET_CONTINUE; } static int wait_scfunc(void *priv, trsyscall_t tsc) { int entry; unsigned long pid, res, wpid, options; systr_get_pid(tsc, &pid); systr_get_param(tsc, SYSTR_PARAM_1, &wpid); systr_get_param(tsc, SYSTR_PARAM_3, &options); entry = systr_is_entry(tsc); if (entry) fprintf(stderr, "[%lu] E wait(%ld, %lu), pid, wpid, options); else { systr_get_param(tsc, SYSTR_PARAM_RCODE, &res); fprintf(stderr, "[%lu] X wait(%ld, %lu) = %ld, pid, wpid, options, res); } return SYSTR_RET_CONTINUE; } int main(int ac, char **av) { if (systr_init_library() < 0) return 1; systr_trace_syscall(__NR_execve, exec_scfunc, NULL); systr_trace_syscall(__NR_open, open_scfunc, NULL); systr_trace_syscall(__NR_close, close_scfunc, NULL); systr_trace_syscall(__NR_fork, fork_scfunc, NULL); systr_trace_syscall(__NR_vfork, fork_scfunc, NULL); systr_trace_syscall(__NR_clone, fork_scfunc, NULL); systr_trace_syscall(__NR_waitpid, wait_scfunc, NULL); systr_trace_syscall(__NR_wait4, wait_scfunc, NULL); systr_run(&av[i]); systr_cleanup_library(); return 0; }
http://www.gnu.org/copyleft/lesser.html
http://www.xmailserver.org/sysctr-lib.html