Intercepting system calls on Linux - Unix

This is a discussion on Intercepting system calls on Linux - Unix ; Hi Everybody, I want to intercept the open(), read(), write() and close() system calls on Linux. This can be done in 2 ways: 1. I write a Linux Kernel Module which intercepts these calls. Eg. http://85.147.245.113/mirrorbooks/ne...-7-SECT-2.html 2. I can also ...

+ Reply to Thread
Results 1 to 10 of 10

Thread: Intercepting system calls on Linux

  1. Intercepting system calls on Linux

    Hi Everybody,

    I want to intercept the open(), read(), write() and close() system
    calls on Linux. This can be done in 2 ways:

    1. I write a Linux Kernel Module which intercepts these calls.
    Eg. http://85.147.245.113/mirrorbooks/ne...-7-SECT-2.html
    2. I can also write a library and then link this library to the
    applications whose system calls I would like to intercept.
    Eg. http://developers.sun.com/solaris/ar...terposers.html

    My question is how do I write this library on Linux (steps to write
    and compile this library), since the only link which I found above is
    for Solaris.

    Could somebody please help me?

    I would really appreciate your help.

    Thanks and Regards,
    Christina.

  2. Re: Intercepting system calls on Linux

    On 28 Feb, 06:34, Christina wrote:
    >
    > I want to intercept the open(), read(), write() and close() system
    > calls on Linux. This can be done in 2 ways:
    >
    > 1. I write a Linux Kernel Module which intercepts these calls.
    > Eg.http://85.147.245.113/mirrorbooks/ne...0596007949/net...
    > 2. I can also write a library and then link this library to the
    > applications whose system calls I would like to intercept.
    > Eg.http://developers.sun.com/solaris/ar...terposers.html
    >
    > My question is how do I write this library on Linux (steps to write
    > and compile this library), since the only link which I found above is
    > for Solaris.


    Option 2 is called 'interpositioning'. Check out the brief
    description at http://safari.adobepress.com/0131774298/ch05lev1sec4
    which is an extract from the excellent _Expert C Programming: Deep C
    Secrets_ by Peter van den Linden.

    Be very careful, as mentioned in that extract...

  3. Re: Intercepting system calls on Linux

    Christina wrote:
    > My question is how do I write this library on Linux (steps to write
    > and compile this library), since the only link which I found above is
    > for Solaris.


    Solaris and Linux are very similar in this respect. Try the sample code,
    post problems with details.

    Rex

  4. Re: Intercepting system calls on Linux

    On Feb 28, 3:31*am, ke...@bytebrothers.co.uk wrote:
    > On 28 Feb, 06:34, Christina wrote:
    >
    >
    >
    > > I want to intercept the open(), read(), write() and close() system
    > > calls on Linux. This can be done in 2 ways:

    >
    > > 1. I write a Linux Kernel Module which intercepts these calls.
    > > Eg.http://85.147.245.113/mirrorbooks/ne...0596007949/net....
    > > 2. I can also write a library and then link this library to the
    > > applications whose system calls I would like to intercept.
    > > Eg.http://developers.sun.com/solaris/ar...terposers.html

    >
    > > My question is how do I write this library on Linux (steps to write
    > > and compile this library), since the only link which I found above is
    > > for Solaris.

    >
    > Option 2 is called 'interpositioning'. *Check out the brief
    > description athttp://safari.adobepress.com/0131774298/ch05lev1sec4
    > which is an extract from the excellent _Expert C Programming: Deep C
    > Secrets_ by Peter van den Linden.
    >
    > Be very careful, as mentioned in that extract...


    Thanks for the info. However, the book does not give me the steps for
    interposing calls on Linux. Do you know any article/webpage etc which
    will give me the instructions to do this on Linux?

    Regards,
    Christina.

  5. Re: Intercepting system calls on Linux

    On 28 Feb, 11:39, Christina wrote:
    > On Feb 28, 3:31 am, ke...@bytebrothers.co.uk wrote:
    >
    >
    >
    > > On 28 Feb, 06:34, Christina wrote:

    >
    > > > I want to intercept the open(), read(), write() and close() system
    > > > calls on Linux. This can be done in 2 ways:

    >
    > > > 1. I write a Linux Kernel Module which intercepts these calls.
    > > > Eg.http://85.147.245.113/mirrorbooks/ne...0596007949/net...
    > > > 2. I can also write a library and then link this library to the
    > > > applications whose system calls I would like to intercept.
    > > > Eg.http://developers.sun.com/solaris/ar...terposers.html

    >
    > > > My question is how do I write this library on Linux (steps to write
    > > > and compile this library), since the only link which I found above is
    > > > for Solaris.

    >
    > > Option 2 is called 'interpositioning'. Check out the brief
    > > description athttp://safari.adobepress.com/0131774298/ch05lev1sec4
    > > which is an extract from the excellent _Expert C Programming: Deep C
    > > Secrets_ by Peter van den Linden.

    >
    > > Be very careful, as mentioned in that extract...

    >
    > Thanks for the info. However, the book does not give me the steps for
    > interposing calls on Linux. Do you know any article/webpage etc which
    > will give me the instructions to do this on Linux?


    Huh? If you create an externally-visible function with the same name
    as a system function, _your_ function will be called _instead_of_ the
    original system function. It really is that simple. And that
    dangerous.

    #include
    #include
    #include

    FILE *fopen(const char *path, const char *mode)
    {
    printf("We're in my open function\n");
    return 0;
    }

    int main()
    {
    FILE* fp;

    if (NULL == (fp = fopen("filename", "r")))
    {
    fprintf(stderr, "Error %d\n", errno);
    }
    printf("All done!\n");
    exit(0);
    }

  6. Re: Intercepting system calls on Linux

    keith@bytebrothers.co.uk writes:

    >Huh? If you create an externally-visible function with the same name
    >as a system function, _your_ function will be called _instead_of_ the
    >original system function. It really is that simple. And that
    >dangerous.



    Keep in mind that the topic is about *sytem calls*, not user-level
    functions, such as fopen().
    Some readers may be interested in the jockey project and interceptor:

    http://home.gna.org/jockey/

    which assists with this.

    In some cases, GNU's libraries appear to know best, and do not call
    system calls by name, perhaps using syscall() ?
    This can create enormous challenges when attempting to replace/override
    the sytem calls.

    --
    Chris.

  7. Re: Intercepting system calls on Linux

    Christina wrote:
    > Hi Everybody,
    >
    > I want to intercept the open(), read(), write() and close() system
    > calls on Linux. This can be done in 2 ways:
    >
    > 1. I write a Linux Kernel Module which intercepts these calls.
    > Eg. http://85.147.245.113/mirrorbooks/ne...-7-SECT-2.html


    True.

    > 2. I can also write a library and then link this library to the
    > applications whose system calls I would like to intercept.
    > Eg. http://developers.sun.com/solaris/ar...terposers.html


    True, but you need to think carefully about whether you're intercepting
    the call to the library function or the actual syscall itself. There
    may be code that directly invokes the syscall. This may or may not
    matter depending on your application.

    A third option is the kernel facility provided to support the strace
    program, the ptrace function. See man 2 ptrace. I have never done
    this, but as I understand it basically you need to

    fork()

    in the child:
    PTRACE_TRACEME
    exec()

    in the parent:
    while (1) {
    waitpid(child)
    // child gets SIGTRACE, which is reported to wait
    use PTRACE_PEEKUSER to read the system call number and parameters
    ...your code here...
    use PTRACE_POKEUSER to write the replacement return value
    PTRACE_SYSCALL // child continues to next syscall
    }


    Or something very vaguely like that. As I say, I've never done this.

    You might like to look at the fakeroot program; you may be doing
    something similar to what it does. I'm not sure which technique it
    uses, probably (2).


    Phil.

  8. Re: Intercepting system calls on Linux

    On Feb 28, 11:53*am, Phil Endecott
    wrote:
    > Christina wrote:
    > > Hi Everybody,

    >
    > > I want to intercept the open(), read(), write() and close() system
    > > calls on Linux. This can be done in 2 ways:

    >
    > > 1. I write a Linux Kernel Module which intercepts these calls.
    > > Eg.http://85.147.245.113/mirrorbooks/ne...0596007949/net....

    >
    > True.
    >
    > > 2. I can also write a library and then link this library to the
    > > applications whose system calls I would like to intercept.
    > > Eg.http://developers.sun.com/solaris/ar...terposers.html

    >
    > True, but you need to think carefully about whether you're intercepting
    > the call to the library function or the actual syscall itself. *There
    > may be code that directly invokes the syscall. *This may or may not
    > matter depending on your application.
    >
    > A third option is the kernel facility provided to support the strace
    > program, the ptrace function. *See man 2 ptrace. *I have never done
    > this, but as I understand it basically you need to
    >
    > fork()
    >
    > in the child:
    > * *PTRACE_TRACEME
    > * *exec()
    >
    > in the parent:
    > * *while (1) {
    > * * *waitpid(child)
    > * * *// child gets SIGTRACE, which is reported to wait
    > * * *use PTRACE_PEEKUSER to read the system call number and parameters
    > * * *...your code here...
    > * * *use PTRACE_POKEUSER to write the replacement return value
    > * * *PTRACE_SYSCALL *// child continues to next syscall
    > * *}
    >
    > Or something very vaguely like that. *As I say, I've never done this.
    >
    > You might like to look at the fakeroot program; you may be doing
    > something similar to what it does. *I'm not sure which technique it
    > uses, probably (2).
    >
    > Phil.


    Thanks a lot for everybody's help.

    I really appreciate it,

    I was aware of the ptrace program, but didn't consider it an option
    then. It seems that ptrace is a better candidate for what I have in
    mind. I want to capture the open(), read(), write() and close() calls
    from specific processes and redirect them through a file cache that I
    create. I plan to post the question about the filecache as a new one
    since the two subjects can reflect the appropriate question.


    Regards,
    Christina.

  9. Re: Intercepting system calls on Linux

    On Feb 28, 1:56 pm, ke...@bytebrothers.co.uk wrote:
    > Huh? If you create an externally-visible function with the same name
    > as a system function, _your_ function will be called _instead_of_ the
    > original system function. It really is that simple. And that
    > dangerous.
    >
    > #include
    > #include
    > #include
    >
    > FILE *fopen(const char *path, const char *mode)
    > {
    > printf("We're in my open function\n");
    > return 0;
    >
    > }
    >
    > int main()
    > {
    > FILE* fp;
    >
    > if (NULL == (fp = fopen("filename", "r")))
    > {
    > fprintf(stderr, "Error %d\n", errno);
    > }
    > printf("All done!\n");
    > exit(0);
    >
    > }


    But consider:

    #define _GNU_SOURCE
    #include
    #include
    #include
    #include


    #define SIZE 128

    typedef FILE *(*open_func)( const char * path, const char * mode );

    FILE *
    fopen( const char * path, const char * mode )
    {
    open_func t;

    printf( "We're in my open function\n" );
    t = (open_func)dlsym( RTLD_NEXT, "fopen" );
    return t( path, mode );
    }

    int
    main( int argc, char **argv )
    {
    FILE * fp;
    char buf[ SIZE ];
    char * filename;
    int status;

    status = EXIT_SUCCESS;
    filename = argc > 1 ? argv[ 1 ] : "foo";
    if (NULL == (fp = fopen( filename, "r" ))) {
    perror( filename );
    status = EXIT_FAILURE;
    } else {
    fgets( buf, SIZE, fp );
    printf( "read: %s", buf );
    }

    printf( "All done!\n" );
    return status;
    }

  10. Re: Intercepting system calls on Linux

    On Feb 29, 12:47*pm, William Pursell wrote:
    > On Feb 28, 1:56 pm, ke...@bytebrothers.co.uk wrote:
    >
    >
    >
    >
    >
    > > Huh? *If you create an externally-visible function with the same name
    > > as a system function, _your_ function will be called _instead_of_ the
    > > original system function. It really is that simple. *And that
    > > dangerous.

    >
    > > #include
    > > #include
    > > #include

    >
    > > FILE *fopen(const char *path, const char *mode)
    > > {
    > > * * * * printf("We're in my open function\n");
    > > * * * * return 0;

    >
    > > }

    >
    > > int main()
    > > {
    > > * * * * FILE* fp;

    >
    > > * * * * if (NULL == (fp = fopen("filename", "r")))
    > > * * * * {
    > > * * * * * * * * fprintf(stderr, "Error %d\n", errno);
    > > * * * * }
    > > * * * * printf("All done!\n");
    > > * * * * exit(0);

    >
    > > }

    >
    > But consider:
    >
    > #define _GNU_SOURCE
    > #include
    > #include
    > #include
    > #include
    >
    > #define SIZE 128
    >
    > typedef FILE *(*open_func)( const char * path, const char * mode );
    >
    > FILE *
    > fopen( const char * path, const char * mode )
    > {
    > * * * * open_func t;
    >
    > * * * * printf( "We're in my open function\n" );
    > * * * * t = (open_func)dlsym( RTLD_NEXT, "fopen" );
    > * * * * return t( path, mode );
    >
    > }
    >
    > int
    > main( int argc, char **argv )
    > {
    > * * * * FILE * fp;
    > * * * * char * buf[ SIZE ];
    > * * * * char * filename;
    > * * * * int status;
    >
    > * * * * status = EXIT_SUCCESS;
    > * * * * filename = argc > 1 ? argv[ 1 ] : "foo";
    > * * * * if (NULL == (fp = fopen( filename, "r" ))) {
    > * * * * * * * * perror( filename );
    > * * * * * * * * status = EXIT_FAILURE;
    > * * * * } else {
    > * * * * * * * * fgets( buf, SIZE, fp );
    > * * * * * * * * printf( "read: %s", buf );
    > * * * * }
    >
    > * * * * printf( "All done!\n" );
    > * * * * return status;
    >
    >
    >
    > }- Hide quoted text -
    >
    > - Show quoted text -- Hide quoted text -
    >
    > - Show quoted text -


    Thanks a lot for the code. I just wrote a quick and dirty tutorial
    that migh help people who want to write library interposers. I have
    described all the steps required to write the library interposer on
    Linux below:
    http://www.cse.psu.edu/~patrick/Libr..._in_Linux.html

    Regards,
    Christina.

+ Reply to Thread