Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing main arguments outside of main on Linux

Tags:

c

linux

elf

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?

like image 286
PSkocik Avatar asked May 20 '16 23:05

PSkocik


1 Answers

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.

file: printargs.c

#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;

Build and use the shared library

(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.

like image 92
rici Avatar answered Oct 18 '22 13:10

rici