03-31-05 11:21 PM
Paul,
Thank you for the reply. I reexamined my code and found an bug Now
both listen and accept can be intercepted. But they are reported twice.
I can understand why LOAD message is printed twice, but I couldn't
understand why listen and accept are reported twice.
I was using Sun JDK 1.5 Update 2 on Red Hat Linux 9. The source code
for the dummy mylib.so is:
#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
void init(void) __attribute__((constructor));
void cleanup(void) __attribute__((destructor));
void init(void)
{
fprintf(stderr, "initialize libcSubstitute\n");
}
void cleanup(void)
{
fprintf(stderr, "libcSubstitute cleanup\n");
}
int write(int fd, const void *buf, size_t count)
{ static int (*real_write)(int, const void*, size_t) = NULL;
int ret;
if (real_write == NULL){
real_write = dlsym(RTLD_NEXT, "write");
}
if (!real_write){
fprintf(stderr, "cannot find write\n");
return -1;
}
fprintf(stderr, "intercept write from process %d\n", getpid());
ret = (*real_write)(fd, buf, count);
return ret;
}
int listen(int fd, int backlog)
{ static int (*real_listen)(int,int) = NULL;
if (real_listen == NULL) real_listen = dlsym(RTLD_NEXT,
"listen");
if (!real_listen){
fprintf(stderr, "cannot resolve listen()\n");
return -1;
}
fprintf(stderr, "intercept listen from process %d\n",
getpid());
return (*real_listen)(fd, backlog);
}
int accept(int fd, struct sockaddr *addr, socklen_t *addrlen)
{ static int (*real_accept)(int,struct sockaddr*,socklen_t*) =
NULL;
if (real_accept == NULL) real_accept = dlsym(RTLD_NEXT,
"accept");
if (!real_accept){
fprintf(stderr, "cannot resolve accept()\n");
return -1;
}
fprintf(stderr, "intercept accept from process %d\n",
getpid());
return (*real_accept)(fd, addr, addrlen);
}
I used the following command to compile it
gcc -g -fPIC -Wall -I. -c -o lib.o lib.c
gcc -shared -o libcsubst.so lib.o -ldl
The code for the Java echo server is:
import java.io.*;
import java.net.*;
public class echo{
public static void main(String args[]) {
ServerSocket echoServer = null;
String line;
DataInputStream is;
PrintStream os;
Socket clientSocket = null;
try {
echoServer = new ServerSocket(9999);
}
catch (IOException e) {
System.out.println(e);
}
System.out.print("listening\n");
try {
clientSocket = echoServer.accept();
is = new
DataInputStream(clientSocket.getInputStream());
os = new
PrintStream(clientSocket.getOutputStream());
while (true) {
line = is.readLine();
os.println(line);
}
}
catch (IOException e) {
System.out.println(e);
}
}
}
I used the command LD_PRELOAD=libcsubst.so Java echo, and observed the
following output:
initialize libcSubstitute
initialize libcSubstitute
intercept listen from process 32211
intercept accept from process 32211
intercept listen from process 32211
intercept write from process 32211
listening
intercept accept from process 32211
libcSubstitute cleanup
[ Post a follow-up to this message ]
|