i am using LD_PRELOAD to capture write() system call in linux .
I am successfully able to do this for write system call and make it work.
But when i call printf() that time it does not work. If we observe printf stack trace using strace i found that, at the end printf calls write() system call to write to console, but at that time my write() system call is not called before actually calling the the write() system call.
Anybody have any idea why is this happening ?
Function calls made from one library to another or from the executable to a dynamically loaded library go through the PLT (Procedure Linkage Table) and are able to be redirected by the use of LD_PRELOAD. However, function calls within a library can be resolved at compile time and do not go through the PLT. Therefore they are unable to be redirected by LD_PRELOAD. Since printf and write are both compiled into libc.so.6, the call to write from printf never goes through the PLT to look for a possible redirection, but when you call write directly from your application (or from another shared library) it does.
Related
I'd like to be able to intercept filenames with a certain prefix from any of my child processes that I launch. This would be names like "pipe://pipe_name". I think wrapping the open() system call would be a good way to do this for my application, but I'd like to do it without having to compile a separate shared library and hooking it with the LD_PRELOAD trick (or using FUSE and having to have a mounted directory)
I'll be forking the processes myself, is there a way to redirect open() to my own function before forking and have it persist in the child after an exec()?
Edit: The thought behind this is that I want to implement multi-reader pipes by having an intermediate process tee() the data from one pipe into all the others. I'd like this to be transparent to my child processes, so that they can take a filename and open() it, and, if it's a pipe, I'll return the file descriptor for it, while if it's a normal file, I'll just pass that to the regular open() function. Any alternative way to do this that makes it transparent to the child processes would interesting to hear. I'd like to not have to compile a separate library that has to be pre-linked though.
I believe the answer here is no, it's not possible. To my knowledge, there's only three ways to achieve this:
LD_PRELOAD trick, compile a .so that's pre-loaded to override the system call
Implement a FUSE filesystem and pass a path into it to the client program, intercept calls.
Use PTRACE to intercept system calls, and fix them up as needed.
2 and 3 will be very slow as they'll have to intercept every I/O call and swap back to user space to handle it. Probably 500% slower than normal. 1 requires building and maintaining an external shared library to link in.
For my application, where I'm just wanting to be able to pass in a path to a pipe, I realized I can open both ends in my process (via pipe()), then go grab the path to the read end in /proc//fd and pass that path to the client program, which gives me everything I need I think.
I have a program with no source code.
When I run it, I have a "Can't open file..." error in the logs.
I called strace to trace the open calls on the kernel, in that way:
strace -e trace=open,close,read,write,connect,accept your-command-here
However, it seems there is none of the open calls I am expecting (that shall happen before that the log says "Can't open file...")
The executable indeed delegated the open call to a tierce library.
It seems that strace only trace the calls from the executable on the kernel, not those of the libraries depencies.
I tried to use ltrace to trace what happens in the subsequent libraries, but it doesnt display the same informations as strace, only the function calls (which are not human-readable).
Is there a way to run strace on the executable and the libraires in the same time ?
strace should be showing all of the open calls. However:
Perhaps your application calls a subprocess to do work. For that case, you can add a -f option.
On the other hand, it may be doing the work by opening a socket (or similar) connection to another process. For that case, you will not see any trace. Likewise, if you are using the syslog interface, then the actual work may be done outside your process, potentially in the kernel where you cannot trace with this tool.
When called with no argument other than the program to run, ltrace seems to display only the calls made by the program into shared libraries, and not the inter-library calls.
I'd like to filter down these results by selecting the library the calls are made into. The -l option filters the library, but the inter-library calls are shown also. Adding -e '#my_program does not do any difference.
ltrace's man page states that inter-library calls are removed by linking the program with -Dsymbolic.
Is there a way to get rid of the inter-library calls without recompiling the program?
Thanks
I am interested in replacing a system call with a custom that I will implement in linux kernel 3.
I read that the sys call table is no longer exposed.
Any ideas?
any reference to this http://www.linuxtopia.org/online_books/linux_kernel/linux_kernel_module_programming_2.6/x978.html example but for kernel 3 will be appreciated :)
Thank you!
I would recommend using kprobes for this kind of job, you can easily break on any kernel address (or symbol...) and alter the execution path, all of this at runtime, with a kernel module if you need to :)
Kprobes work by dynamically replacing an instruction (e.g. first instruction of your syscall entry) by a break (e.g. int3 on x86). Inside the do_int3 handler, a notifier notifies kprobes, which in turn passes the execution to your registered function, from which point you can do almost anything.
A very good documentation is given in Documentation/kprobes.txt so as a tiny example in samples/kprobes/kprobes_example.c (in this example they break on do_fork to log each fork on the system). It has a very simple API and is very portable nowdays.
Warning: If you need to alter the execution path, make sure your kprobes are not optimized (i.e. a jmp instruction to your handler replaces the instruction you break onto instead of an int3) otherwize you won't be able to really alter the execution easily (after the ret of your function, the syscall function will still be executed as usual). If you are only interested in tracing, then this is fine and you can safely ignore this issue.
Write a LKM that would be better optio.What do you mean by replace,do you want to add a new one.
Is there (in glibc-2.5 and newer) a way to define a hook for pthread_create?
There is a lot of binary applications and I want to write a dynamic lib to be loaded via LD_PRELOAD
I can add hook on entry to main (''attributte constructor''), but how can I force my code to be executed in every thread just before the thread's function will run.
This answer shows how to interpose pthread_create. (Beware: it will work correctly in 64-bit, but not 32-bit programs.)
Once you interpose pthread_create, you can make it call your own function, which will do whatever you want, and then call the original function the user passed to pthread_create.