PDA

View Full Version : Function Interposition in Linux



chercheur
06-25-2012, 03:01 AM
Hello,

Please I try to apply the mechanism Interposition Function in Linux on the function write (write a socket) as follows:


# include <sys/types.h>
# include <sys/socket.h>
# include <netinet/in.h>
# include <arpa/inet.h>
# include <netdb.h>
# include <stdio.h>
# include <string.h>
int write (int n, char buffer [32], int sb)
{


int nb = write (so, "Ceci est un exemple de socket!!!", 32);
}



​I also have the server code and client code, when the client connects to the server, the server sends a message to the client but when running I got the following error:

Erreur de segmentation
Have you an idea please ?

Thank you so much

Salem
06-25-2012, 03:55 AM
Post your whole code.

Two lines, which don't compile, are insufficient to track down a segmentation fault.

chercheur
06-25-2012, 04:53 AM
Post your whole code.

Two lines, which don't compile, are insufficient to track down a segmentation fault.
test.c

#include <sys/types.h> #include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


int write(int so, char buffer[32], int sb)
{
int nb=write(so, "Ceci est un exemple de Socket!!!", sb);


return nb;
}
server.c

//Socket Serveur#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFFER_TAILLE 32






int creer_socket_serveur(int port)


//Fonction qui attache une socket a un port, l'ecoute et renvoie le descripteur de la socket


{
int listen_fd;
struct sockaddr_in sin;


//Creation de la socket
if ((listen_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) exit(1);

//Definition de la socket
sin.sin_family = AF_INET;
sin.sin_port = htons(port);
sin.sin_addr.s_addr = INADDR_ANY;

//Attachement de la socket au port
if (bind(listen_fd, (struct sockaddr *)&sin, sizeof (sin)) == -1) exit(1);

//Socket en mode ecoute
listen(listen_fd, 5);

return (listen_fd);
}






main (int argc, char *argv[])
{
int port, so, client_sin_len, nb, socketserveur;
struct sockaddr_in client_sin;
char buffer[BUFFER_TAILLE]="Ceci est un exemple de socket!!!";


printf("Entrez le port du serveur : "); //Demande port
scanf("%d", &port);


socketserveur = creer_socket_serveur(port); //Creation du serveur et socket
printf("Serveur pret ... En attente de requetes ...\n");


client_sin_len = sizeof (client_sin);
so = accept(socketserveur, (struct sockaddr *)&client_sin, &client_sin_len);
if (so == -1)
{
printf ("Probleme de creation d'une socket de traitement\n");
exit (1);
}

nb = write(so, buffer, sizeof (buffer));
printf("Transmission effectuee. Nombre de caracteres transmis = %d\n", nb);
close (so);
close(socketserveur);
exit (0);
}

client.c

//Socket Client
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>

#define BUFFER_TAILLE 32

int main (int argc, char *argv[]) {

int socketclient,rc;
int port, retour;
struct sockaddr_in localAddr, servAddr;
struct hostent *h;
char adresseserveurip[32];
char buffer[BUFFER_TAILLE];

//Demande le serveur et no de port
printf("Entrez l'adresse IP ou le nom du serveur :");
scanf("%s", adresseserveurip);
printf("Entrez le port d'ecoute du serveur :");
scanf("%d", &port);

//Chercher serveur IP
h = gethostbyname(adresseserveurip);
if(h==NULL) {
printf("%s: serveur inconnu '%s'\n",argv[0],adresseserveurip);
exit(1);
}

//Creation socket
servAddr.sin_family = h->h_addrtype;
memcpy((char *) &servAddr.sin_addr.s_addr, h->h_addr_list[0], h->h_length);
servAddr.sin_port = htons(port);


//Creation de la socket
socketclient = socket(AF_INET, SOCK_STREAM, 0);
if(socketclient<0) {
perror("Probleme de creation de socket\n ");
exit(1);
}
//Connexion au serveur
rc = connect(socketclient, (struct sockaddr *) &servAddr, sizeof(servAddr));
if(rc < 0)
{
printf("Probleme de connexion\n");
exit(1);
}
retour = read (socketclient, buffer, 32);
buffer[32] = '\0';
printf("\nMessage :%s. Nombre de caracteres lus = %d\n", buffer, retour);
close (socketclient); // Fermeture de la socket
return 0;
}

I proceeded as follows:
gcc -shared -ldl -fPIC test.c -o test.so
i run the server like that:
LD_PRELOAD="/home/test.so" /home/server
i run the client like that: ./client
when the client connects to server the server sends a message ,
i have this error:
Erreur de segmentation



Thank you for help

grumpy
06-25-2012, 05:09 AM
Your write() function is infinitely recursive. That would explain the segmentation fault, when the server attempts to send a message.

phantomotap
06-25-2012, 12:37 PM
O_o

grumpy is right.

If you are trying to wrap an exported function, as you say, you can't just call the same named function with the same function signature.

If you need to call the wrapped function you must jump through some hoops.

Ultimately, just stop trying to "wing it" after hearing the phrase "Interposition Function".

Search for tutorials on doing this and you'll discover how to do what you want without the infinite recursion.

Soma

chercheur
06-25-2012, 04:08 PM
O_o

grumpy is right.

If you are trying to wrap an exported function, as you say, you can't just call the same named function with the same function signature.


i have modified the function like that


size_t write(int fd, const void *buf, size_t count)
{
static size_t (*write_func)(int, const void *, size_t) = NULL;


/* get reference to original (libc provided) write */
if (!write_func)
{
write_func = (size_t(*)(int, const void *, size_t)) dlsym(RTLD_NEXT, "write");
}
return write_func(fd, buffer, sizeof (buffer));
}


I have a question please :how canget the buffer "const void *buf" because I want to change it before sending ?


Thank you so much for help