Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find argc and argv from a library

How do I find a program's argc and argv from a shared object? I am writing a library in C that will be loaded via LD_PRELOAD. I've been able to find the stack two different ways:

  1. Read rsp via inline __asm__ call.
  2. Read /proc/<pid>/maps and parse the entry for stack.

I can then create a pointer, point it at the stack segment, then iterate through looking for data. The problem is I can't figure out an efficient way to determine what bytes are argc and the pointer to the pointer to the argv strings.

I know that /proc/<pid>/cmdline also contains the arguments, each separated by 0x00, but I'm interested in finding everything in memory.

In gdb I see a DWORD for argc followed by a QWORD which is the first pointer. 20 bytes before the address of argc is a pointer that points back into the main program's code segment. But that's not a deterministic way to identify argc and argv.

I've seen a few posts but no working code:

  • http://linux.derkeiler.com/Newsgroups/comp.os.linux.development.system/2005-07/0296.html
  • https://sourceware.org/ml/libc-help/2009-11/msg00010.html
like image 732
B-MO Avatar asked Jan 21 '16 05:01

B-MO


1 Answers

This response in your second link contains working source code which worked fine for me (Gnu/Linux elf-based system), including during LD_PRELOAD.

The code is very short; it consists of a function:

int foo(int argc, char **argv, char **env) {
   // Do something with argc, argv (and env, if desired)
}

and a pointer to that function in the .init_array section:

__attribute__((section(".init_array"))) static void *foo_constructor = &foo;

Putting that into a shared library and then LD_PRELOADing the shared library certainly triggered the call to foo when I tried it, and it was clearly called with the argc and argv which would later be passed to main (and also the value of environ).

like image 87
rici Avatar answered Oct 25 '22 08:10

rici