strange behavior when intercepting read() with LD_PRELOAD

This is a discussion on strange behavior when intercepting read() with LD_PRELOAD within the Linux Programming forums, part of the Platform Specific Boards category; hi, ive been playing with LD_PRELOAD for a little while now (its so cool isnt it lol) and ive managed ...

  1. #1
    Registered User
    Join Date
    Jul 2006
    Posts
    63

    strange behavior when intercepting read() with LD_PRELOAD

    hi, ive been playing with LD_PRELOAD for a little while now (its so cool isnt it lol) and ive managed to do fun stuff like replace gettimeofday() with one that always returns 0 and run xclock. now i want to go a step further and intercept all calls to read(). I wrote a quick hackup of my library and this is what it looks like.

    Code:
    #include <dlfcn.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    ssize_t read (int __fd, void *__buf, size_t __nbytes) __wur
    {
        //printf ("start\n");
        ssize_t ret;
        void * handle;
        handle = dlopen ("/lib/libc.so.6", RTLD_LAZY);
        if (!handle) {
            fputs (dlerror (), stderr);
            exit (EXIT_FAILURE);
        }
        ssize_t (*orig_read)(int, void *, size_t);
        orig_read = dlsym (handle, "read");
        char * error;
        if ((error = dlerror()) != NULL) {
            fprintf (stderr, "%s\n", error);
            exit (EXIT_FAILURE);
        }
        ret = (*orig_read)(__fd, __buf, __nbytes);
        //printf ("%d bytes\n %s end\n", __nbytes, (char *)__buf);
        return ret;
    }
    i know that my library is being used because when the printfs are uncommented i get output, however programs that use this library always crash with annoying error codes, often times 0 (success).

    running xclock for example with strace gives
    Code:
    read(3, "Z\261\236\0\0\0`\3\377\377\37\0\0\1\0\0\24\0\377\377\1"..., 2220) = 2220
    select(4, [3], [3], NULL, NULL)         = 1 (out [3])
    writev(3, [{"7\0\5\0\0\0`\3;\1\0\0\10\0\0\0\377\377\377\0b\0\5\0\f\0"..., 40}], 1) = 40
    select(4, [3], [], NULL, NULL)          = 1 (in [3])
    read(3, "\1p\2\0\0\0\0\0\1\203\0\0\250\236\346\277\213\4\25\10<"..., 4096) = 32
    select(4, [3], [3], NULL, NULL)         = 1 (out [3])
    writev(3, [{"\203\0\1\0", 4}], 1)       = 4
    select(4, [3], [], NULL, NULL)          = 1 (in [3])
    read(3, "\1\10\3\0\0\0\0\0\377\377?\0\213\4\25\10<c \10\200\236"..., 4096) = 32
    select(4, [3], [3], NULL, NULL)         = 1 (out [3])
    writev(3, [{"\24\0\6\0;\1\0\0\27\0\0\0\37\0\0\0\0\0\0\0\0\341\365\5"..., 24}], 1) = 24
    select(4, [3], [], NULL, NULL)          = 1 (in [3])
    read(3, "\1\10\4\0\327\r\0\0\37\0\0\0\0\0\0\0\\7\0\0\213\4\25\10"..., 4096) = 4096
    read(3, "SelectionBox.foreground:\t#000000"..., 10108) = 10108
    read(3, 0x805ab64, 4096)                = -1 EAGAIN (Resource temporarily unavailable)
    open("/usr/share/locale/en_AU.UTF-8/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/usr/share/locale/en_AU.utf8/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/usr/share/locale/en_AU/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/usr/share/locale/en.UTF-8/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/usr/share/locale/en.utf8/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/usr/share/locale/en/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/usr/share/locale-langpack/en_AU.UTF-8/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/usr/share/locale-langpack/en_AU.utf8/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/usr/share/locale-langpack/en_AU/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/usr/share/locale-langpack/en.UTF-8/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/usr/share/locale-langpack/en.utf8/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
    open("/usr/share/locale-langpack/en/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
    write(2, "XIO:  fatal IO error 2 (No such "..., 71XIO:  fatal IO error 2 (No such file or directory) on X server ":0.0"
    ) = 71
    write(2, "      after 4 requests (0 known "..., 69      after 4 requests (0 known processed) with 0 events remaining.
    ) = 69
    exit_group(1)                           = ?
    Process 21745 detached
    now without ld_preload the same section looks like

    Code:
    read(3, "Z\261\236\0\0\0`\3\377\377\37\0\0\1\0\0\24\0\377\377\1"..., 2220) = 2220
    select(4, [3], [3], NULL, NULL)         = 1 (out [3])
    writev(3, [{"7\0\5\0\0\0`\3;\1\0\0\10\0\0\0\377\377\377\0b\0\5\0\f\0"..., 40}], 1) = 40
    select(4, [3], [], NULL, NULL)          = 1 (in [3])
    read(3, "\1p\2\0\0\0\0\0\1\203\0\0\250\236\346\277\213\4\25\10<"..., 4096) = 32
    select(4, [3], [3], NULL, NULL)         = 1 (out [3])
    writev(3, [{"\203\0\1\0", 4}], 1)       = 4
    select(4, [3], [], NULL, NULL)          = 1 (in [3])
    read(3, "\1`\3\0\0\0\0\0\377\377?\0\213\4\25\10<c \10\200\236\346"..., 4096) = 32
    select(4, [3], [3], NULL, NULL)         = 1 (out [3])
    writev(3, [{"\24\0\6\0;\1\0\0\27\0\0\0\37\0\0\0\0\0\0\0\0\341\365\5"..., 24}], 1) = 24
    select(4, [3], [], NULL, NULL)          = 1 (in [3])
    read(3, "\1\10\4\0\327\r\0\0\37\0\0\0\0\0\0\0\\7\0\0\213\4\25\10"..., 4096) = 4096
    read(3, "SelectionBox.foreground:\t#000000"..., 10108) = 10108
    read(3, 0x805ab64, 4096)                = -1 EAGAIN (Resource temporarily unavailable)
    select(4, [3], [3], NULL, NULL)         = 1 (out [3])
    writev(3, [{"b\0\5\0\t\0\0\0XKEYBOARD\0\0\0", 20}], 1) = 20
    select(4, [3], [], NULL, NULL)          = 1 (in [3])
    read(3, "\1s\5\0\0\0\0\0\1\226q\255\250\236\346\277\213\4\25\10"..., 4096) = 32
    read(3, 0x805ab64, 4096)                = -1 EAGAIN (Resource temporarily unavailable)
    select(4, [3], [3], NULL, NULL)         = 1 (out [3])
    writev(3, [{"\226\0\2\0\1\0\0\0", 8}], 1) = 8
    select(4, [3], [], NULL, NULL)          = 1 (in [3])
    read(3, "\1\1\6\0\0\0\0\0\1\0\0\0\250\236\346\277\rs\33\10\200`"..., 4096) = 32
    read(3, 0x805ab64, 4096)                = -1 EAGAIN (Resource temporarily unavailable)
    select(4, [3], [3], NULL, NULL)         = 1 (out [3])
    writev(3, [{"\20\0\5\0\v\0\0\0Custom Init\0", 20}], 1) = 20
    select(4, [3], [], NULL, NULL)          = 1 (in [3])
    read(3, "\1s\7\0\0\0\0\0G\2\0\0\250\236\346\277\213\4\25\10<c \10"..., 4096) = 32
    read(3, 0x805ab64, 4096)                = -1 EAGAIN (Resource temporarily unavailable)
    select(4, [3], [3], NULL, NULL)         = 1 (out [3])
    writev(3, [{"\20\0\5\0\v\0\0\0Custom Data\0", 20}], 1) = 20
    select(4, [3], [], NULL, NULL)          = 1 (in [3])
    read(3, "\1s\10\0\0\0\0\0H\2\0\0\250\236\346\277\213\4\25\10<c "..., 4096) = 32
    read(3, 0x805ab64, 4096)                = -1 EAGAIN (Resource temporarily unavailable)
    open("/usr/share/X11/locale/locale.alias", O_RDONLY) = 4
    fstat64(4, {st_mode=S_IFREG|0644, st_size=78744, ...}) = 0
    mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb79f6000
    read(4, "#\t$XdotOrg: lib/X11/nls/locale.a"..., 4096) = 4096
    read(4, "br_FR.iso88591\t\t\t\t\tbr_FR.ISO8859"..., 4096) = 4096
    read(4, "iso88597\t\t\t\t\tel_GR.ISO8859-7\nel_"..., 4096) = 4096
    read(4, "es_DO.ISO8859-1\nes_DO.utf8\t\t\t\t\te"..., 4096) = 4096
    these are only the sections relevant to the crash, ie they start to differ, but from just looking at these two you can see that read is acting differently in my implementation

    finally, i should point out that when the dynamic linker uses my read it seems to work, i can see many successful syscalls which look like this.

    Code:
    open("/usr/lib/libXaw.so.7", O_RDONLY)  = 3
    read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0@\330\0"..., 512) = 512
    any ideas
    thx in advance

  2. #2
    Captain Crash brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,230
    strace is not showing your hooked calls. It's showing the real ones.

  3. #3
    Registered User
    Join Date
    Jul 2006
    Posts
    63
    im not exactly sure how it works, i would assume that since it is my code which is actually making the call to read that the calls made would be my calls. Anyway, thats irrelevant, the point is that my read () is obviously acting differently from the real read, even tho as far as i can see its acting identically until it trys to read certain files, it seems to work reading the system libraries. Any ideas?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Strange results using dnsapi and windns
    By Niara in forum Networking/Device Communication
    Replies: 3
    Last Post: 08-13-2005, 10:21 AM
  2. Unknown Memory Leak in Init() Function
    By CodeHacker in forum Windows Programming
    Replies: 3
    Last Post: 07-09-2004, 09:54 AM
  3. Read Array pro!!Plz help!!
    By Supra in forum C Programming
    Replies: 2
    Last Post: 03-04-2002, 02:49 PM
  4. Serial Communications in C
    By ExDigit in forum Windows Programming
    Replies: 7
    Last Post: 01-09-2002, 09:52 AM
  5. Help! Can't read decimal number
    By Unregistered in forum C Programming
    Replies: 2
    Last Post: 09-07-2001, 02:09 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21