Intercept system calls on Red Hat Linux

Hello, I am trying to intercept all the system calls on red hat linux,
I would like to see some example on how to doing it. Thanks.
yarockAsked:
Who is Participating?
 
NopiusCommented:
You can intercept system call with kernel modules, but only on linux 2.4.x kernel, on 2.6.x syscall_table is not exported (otherwise you should edit kernel tree directly).
1) Read Linox Device Drivers 3rd edition http://safari.oreilly.com/0596005903
2) Read till the end this thread http://www.gelato.unsw.edu.au/archives/linux-ia64/0501/12790.html there is an example for IA64 that becomes at least working.
0
 
Duncan RoeSoftware DeveloperCommented:
Simplest is strace. By default this prints all system calls, but with command-line args you can refine what it prints. Type "man strace" to read more.
Just prepend "strace " to an interactive command ("strace -f " if it spawns children).
To view the activity of a background process opr daemon, find its pid (e.g. with ps -afxu) then add "-p <pid>" to the strace command line instead of the interactive command
0
 
manish_regmiCommented:
If you are using Red hat 9 and have not updated to 2.6 kernel versions, You han hook your functions to every system calls.
1)Hook your function to the system call.
2)Do wahtever you like in your function and call the original system call function.
 
things are explained here
http://www.csee.umbc.edu/courses/undergraduate/CMSC421/fall02/burt/projects/howto_add_systemcall.html


regards
Manish Regmi

0
 
ravenplCommented:
There are two ways
- if You have sources for application You want to intercept the syscall(add new functionality) add following code to main executeable
- if You don't have it You can't intercept syscall(except in kernel module), but most applications calls glibc syscall wrappers rather than the syscall itself. Therefore You can compile following code to .so and preload it(so it's used instead of glibc one)

following example changes(binds) source IP for newly created connections to 192.168.8.1 (otherwise default would be used)

#define RTLD_NEXT       ((void *) -1l)
#define sip             (unsigned int)((192<<24) + (0<<168) + (110<<8) + (1<<0))
int connect(int  sockfd,  const  struct sockaddr *serv_addr, socklen_t addrlen) {
struct sockaddr_in      my_addr;
struct sockaddr_in      *s_addr;
int (*org)(int, const struct sockaddr *, socklen_t);

    s_addr = (struct sockaddr_in *)serv_addr;
    if (PF_INET == s_addr->sin_family) { /* this check may be not enought */
            bzero((char *) &my_addr, sizeof(my_addr));
            my_addr.sin_family      = AF_INET;
            my_addr.sin_addr.s_addr = htonl(sip);  /* bind to address */
            my_addr.sin_port        = htons(0); /* let the system choose */
            bind(sockfd, (struct sockaddr *) &my_addr, sizeof(my_addr)); /* ignore error */
    };
    org = dlsym(RTLD_NEXT, "connect");
    if (! org) { errno = ENOENT; return -1; };
    return (*org)(sockfd, serv_addr, addrlen);
};
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.