Is it possible to access the arguments to main
outside of main
(namely in a shared library constructor) on Linux other than by parsing /proc/self/cmdline
?
You can do this by putting the constructor in the .init_array
section. Functions in the .init_array
(unlike .init
) are called with the same arguments main
will be called with: argc
, argv
and env
.
Here's a simple example. I used LD_PRELOAD
simply to avoid complicating the example with code which actually links and uses a shared library, but it would work in a more normal scenario as well.
#include <stdio.h>
static int printargs(int argc, char** argv, char** env) {
puts("In printargs:");
for (int i = 0; i < argc; ++i)
printf(" Arg %d (%p) '%s'\n", i, (void*)argv[i], argv[i]);
return 0;
}
/* Put the function into the init_array */
__attribute__((section(".init_array"))) static void *ctr = &printargs;
(If you use -Wall
, you will see a warning, because ctr
is unused.)
$ gcc -o printargs.so -std=c11 -shared -fpic printargs.c
$ LD_PRELOAD=./printargs.so /bin/echo Hello, world.
In printargs:
Arg 0 (0x7ffc7617102f) '/bin/echo'
Arg 1 (0x7ffc76171039) 'Hello,'
Arg 2 (0x7ffc76171040) 'world.'
Hello, world.
This solution comes from a suggestion by Mike Frysinger in the libc-help mailing list and there is an even more laconic version of this answer here on SO.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With