I thought we beat this to death in your other thread
First off, this --wrap thing ONLY works when you have the source code, and you're linking your program with a library. Since you say in your other thread that you have a statically linked executable with NO source code (actually, you say a lot of contradictory things as well), then this wrapping just isn't going to work.
Here is my test code.
Code:
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <poll.h>
#include <unistd.h>
void doit ( void ) {
while ( 1 ) {
struct pollfd p = { 0, POLLIN, 0 };
int result = poll(&p,1,0);
if ( result > 0 ) {
char buff[100];
int n = read(0,buff,sizeof(buff));
int ch = buff[0];
write(1,buff,n);
if ( ch == 'q' ) break;
if ( ch == 'c' ) {
int *dummy = 0;
*dummy = 0;
}
} else {
struct timeval now;
int r = gettimeofday(&now,NULL);
}
sleep(1);
}
}
int main ( ) {
doit();
return 0;
}
Now run it, and strace it.
Code:
$ # Normal run
$ ./a.out
hello
hello
quit
quit
$ strace ./a.out
execve("./a.out", ["./a.out"], [/* 40 vars */]) = 0
brk(0) = 0x1692000
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f07c7de1000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=145635, ...}) = 0
mmap(NULL, 145635, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f07c7dbd000
close(3) = 0
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 \24\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1685816, ...}) = 0
mmap(NULL, 3801960, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f07c7822000
mprotect(0x7f07c79b9000, 2093056, PROT_NONE) = 0
mmap(0x7f07c7bb8000, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x196000) = 0x7f07c7bb8000
mmap(0x7f07c7bbd000, 21352, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f07c7bbd000
close(3) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f07c7dbc000
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f07c7dba000
arch_prctl(ARCH_SET_FS, 0x7f07c7dba720) = 0
mprotect(0x7f07c7bb8000, 16384, PROT_READ) = 0
mprotect(0x600000, 4096, PROT_READ) = 0
mprotect(0x7f07c7de3000, 4096, PROT_READ) = 0
munmap(0x7f07c7dbd000, 145635) = 0
poll([{fd=0, events=POLLIN}], 1, 0) = 0 (Timeout)
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigaction(SIGCHLD, NULL, {SIG_DFL, [], 0}, 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
nanosleep({1, 0}, 0x7fff5c3977c0) = 0
poll([{fd=0, events=POLLIN}], 1, 0) = 0 (Timeout)
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigaction(SIGCHLD, NULL, {SIG_DFL, [], 0}, 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
nanosleep({1, 0}, quit
0x7fff5c3977c0) = 0
poll([{fd=0, events=POLLIN}], 1, 0) = 1 ([{fd=0, revents=POLLIN}])
read(0, "quit\n", 100) = 5
write(1, "quit\n", 5quit
) = 5
exit_group(0) = ?
Notice that the calls to poll have a zero timeout - as one would expect from looking at the code.
Now try some .so code injection using LD_PRELOAD.
This only works if the executable is dynamically linked, so that the dynamic link loader can patch things up as the program loads.
Again, a normal run and a strace.
Code:
$ LD_PRELOAD=`pwd`/libbar.so ./a.out
library loaded!
Libc found - poll=0x7f4fbff03420
trap poll called
hetrap poll called
llo
hello
trap poll called
qutrap poll called
it
trap poll called
quit
$ strace -ELD_PRELOAD=`pwd`/libbar.so ./a.out
execve("./a.out", ["./a.out"], [/* 41 vars */]) = 0
brk(0) = 0x9a4000
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fde35219000
open("/home/sc/Documents/libbar.so", O_RDONLY) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0`\6\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0775, st_size=8232, ...}) = 0
mmap(NULL, 2101328, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fde34df9000
mprotect(0x7fde34dfa000, 2093056, PROT_NONE) = 0
mmap(0x7fde34ff9000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0) = 0x7fde34ff9000
close(3) = 0
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=145635, ...}) = 0
mmap(NULL, 145635, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fde351f5000
close(3) = 0
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 \24\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1685816, ...}) = 0
mmap(NULL, 3801960, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fde34a58000
mprotect(0x7fde34bef000, 2093056, PROT_NONE) = 0
mmap(0x7fde34dee000, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x196000) = 0x7fde34dee000
mmap(0x7fde34df3000, 21352, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7fde34df3000
close(3) = 0
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/libdl.so.2", O_RDONLY) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\340\r\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=14768, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fde351f4000
mmap(NULL, 2109704, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fde34854000
mprotect(0x7fde34856000, 2097152, PROT_NONE) = 0
mmap(0x7fde34a56000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x2000) = 0x7fde34a56000
close(3) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fde351f2000
arch_prctl(ARCH_SET_FS, 0x7fde351f2720) = 0
mprotect(0x7fde34a56000, 4096, PROT_READ) = 0
mprotect(0x7fde34dee000, 16384, PROT_READ) = 0
mprotect(0x7fde34ff9000, 4096, PROT_READ) = 0
mprotect(0x600000, 4096, PROT_READ) = 0
mprotect(0x7fde3521b000, 4096, PROT_READ) = 0
munmap(0x7fde351f5000, 145635) = 0
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fde35218000
write(1, "library loaded!\n", 16library loaded!
) = 16
brk(0) = 0x9a4000
brk(0x9c5000) = 0x9c5000
write(1, "Libc found - poll=0x7fde34b2f420"..., 33Libc found - poll=0x7fde34b2f420
) = 33
write(1, "trap poll called\n", 17trap poll called
) = 17
poll([{fd=0, events=POLLIN}], 1, 1000) = 0 (Timeout)
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigaction(SIGCHLD, NULL, {SIG_DFL, [], 0}, 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
nanosleep({1, 0}, 0x7fff65ffdc10) = 0
write(1, "trap poll called\n", 17trap poll called
) = 17
poll([{fd=0, events=POLLIN}], 1, 1000quit) = 0 (Timeout)
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigaction(SIGCHLD, NULL, {SIG_DFL, [], 0}, 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
nanosleep({1, 0},
0x7fff65ffdc10) = 0
write(1, "trap poll called\n", 17trap poll called
) = 17
poll([{fd=0, events=POLLIN}], 1, 1000) = 1 ([{fd=0, revents=POLLIN}])
read(0, "quit\n", 100) = 5
write(1, "quit\n", 5quit
) = 5
exit_group(0) = ?
Notice this time that poll() is being called with a timeout of 1000
Here is my patch code, and how I built it.
Code:
#include <poll.h>
#include <stdio.h>
#include <unistd.h>
#include <dlfcn.h>
typedef int (*pfn)(struct pollfd *, nfds_t, int);
static pfn realPoll = NULL;
__attribute__((constructor)) void init(void) {
printf("library loaded!\n");
void *p = dlopen("libc.so.6",RTLD_NOW);
if ( p ) {
realPoll = dlsym(p,"poll");
printf("Libc found - poll=%p\n", (void*)realPoll);
} else {
printf("Err=%s\n", dlerror() );
}
}
int poll( struct pollfd *fds, nfds_t nfds, int timeout ) {
int result = 0;
printf("trap poll called\n");
if ( realPoll ) {
if ( timeout == 0 ) timeout = 1000;
result = realPoll(fds,nfds,timeout);
}
return result;
}
$ gcc -fPIC -c bar.c -ldl ; gcc -shared -o libbar.so bar.o -ldl
$ gcc foo.c -ldl
Finally, compile the main program statically, with
Code:
$ gcc -static foo.c -ldl
$ LD_PRELOAD=`pwd`/libbar.so ./a.out
hello
hello
quit
quit
$ strace -ELD_PRELOAD=`pwd`/libbar.so ./a.out
execve("./a.out", ["./a.out"], [/* 41 vars */]) = 0
uname({sys="Linux", node="OAK", ...}) = 0
brk(0) = 0x1ad0000
brk(0x1ad11a0) = 0x1ad11a0
arch_prctl(ARCH_SET_FS, 0x1ad0880) = 0
brk(0x1af21a0) = 0x1af21a0
brk(0x1af3000) = 0x1af3000
poll([{fd=0, events=POLLIN}], 1, 0) = 0 (Timeout)
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigaction(SIGCHLD, NULL, {SIG_DFL, [], 0}, 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
nanosleep({1, 0}, 0x7fff487e66f0) = 0
poll([{fd=0, events=POLLIN}], 1, 0) = 0 (Timeout)
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigaction(SIGCHLD, NULL, {SIG_DFL, [], 0}, 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
nanosleep({1, 0}, 0x7fff487e66f0) = 0
poll([{fd=0, events=POLLIN}], 1, 0) = 0 (Timeout)
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigaction(SIGCHLD, NULL, {SIG_DFL, [], 0}, 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
nanosleep({1, 0}, quit
0x7fff487e66f0) = 0
poll([{fd=0, events=POLLIN}], 1, 0) = 1 ([{fd=0, revents=POLLIN}])
read(0, "quit\n", 100) = 5
write(1, "quit\n", 5quit
) = 5
exit_group(0) = ?
And we're back to where we started.
The LD_PRELOAD has no effect, it does NOT get initialised, and poll is back to being called with ZERO timeout.
Then there is this
Code:
$ file ./a.out
./a.out: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, for GNU/Linux 2.6.15, not stripped
$ strip a.out
$ file ./a.out
./a.out: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, for GNU/Linux 2.6.15, stripped
If you have a statically linked executable that has been stripped of symbols, you are basically screwed.
C guru help needed URGENT
--- SIGSEGV (Segmentation fault) @ 0 (0) ---
+++ killed by SIGSEGV (core dumped) +++
C guru help needed URGENT
But as I've said already, the program is crashing because it is trying to dereference a NULL pointer - that's what the "SIGSEGV (Segmentation fault) @ 0 (0)" means. It almost certainly has nothing to do with recv or poll or any other system call. You might mess around with them (say changing timeout), and that just might sweep the problem under the carpet for a while, but it is no solution.
I'm going to wait for you to confirm a few FACTS about the situation you're facing before trying to figure out any possible work-around.