samedi 18 avril 2015

How to change interpreter path and pass command line arguments to an "executable" shared library on Linux?

Here is a minimal example for an "executable" shared library (assumed file name: mini.c):



// Interpreter path is different on some systems
//+definitely different for 32-Bit machines

const char my_interp[] __attribute__((section(".interp")))
= "/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2";

#include <stdio.h>
#include <stdlib.h>

int entry() {
printf("WooFoo!\n");
exit (0);
}


If one compiles it with e.g.: gcc -fPIC -o mini.so -shared -Wl,-e,entry mini.c. "Running" the resulting .so will look like this:



confus@confusion:~$ ./mini.so
WooFoo!


My question is now:

How do I have to change the above program to pass command line arguments to a call of the .so-file? An example shell session after the change might e.g. look like this:



confus@confusion:~$ ./mini.so 2 bar
1: WooFoo! bar!
2: WooFoo! bar!
confus@confusion:~$ ./mini.so 3 bla
1: WooFoo! bla!
2: WooFoo! bla!
3: WooFoo! bla!
5: WooFoo! Bar!


It would also be nice to detect on compile time, wheter the target is a 32-Bit or 64-Bit binary to change the interpreter string accordingly. Otherwise one gets a "Accessing a corrupted shared library" warning. Something like:



#ifdef SIXTY_FOUR_BIT
const char my_interp[] __attribute__((section(".interp"))) = "/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2";
#else
const char my_interp[] __attribute__((section(".interp"))) = "/lib/ld-linux.so.2";
#endif


Or even better, to detect the appropriate path fully automatically to ensure it is right for the system the library is compiled on.


Aucun commentaire:

Enregistrer un commentaire