This is the mail archive of the mailing list for the glibc project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: How to access application arguments from shared library constructor

On Thursday 05 November 2009 18:30:45 Bharath Ramesh wrote:
> On Thu, Nov 05, 2009 at 06:52:48PM -0400, Mike Frysinger wrote:
> > On Thursday 05 November 2009 17:13:05 Carlos O'Donell wrote:
> > > On Wed, Nov 4, 2009 at 6:09 PM, Mike Frysinger wrote:
> > > > On Wednesday 04 November 2009 17:11:28 Bharath Ramesh wrote:
> > > >> I am trying to access the arguments passed to an application in the
> > > >> constructor of a shared library. My aim is to prepend the arguments
> > > >> with certain arguments that I can strip off just before my
> > > >> constructor exits. This requires that I have access to the argument
> > > >> list passed to the application in the constructor. I would
> > > >> appreciate any help on this. I am sorry if this an incorrect mailing
> > > >> list to ask this question. I thought this might be good place to
> > > >> start off. I would appreciate if I am copied in the reply as I am
> > > >> not subscribed to this list.
> > > >
> > > > $ cat test.c
> > > > #include <stdio.h>
> > > > extern char **environ;
> > > > foo(int argc, char **argv, char **env)
> > > > { printf("%i, %p, %s, %p, %p\n", argc, argv, *argv, env, environ); }
> > > > __attribute__((section(".init_array"))) static void *foo_constructor
> > > > = &foo; main(){}
> > > >
> > > > $ gcc test.c && ./a.out foo
> > > > 2, 0xbfd877f4, ./a.out, 0xbfd87800, 0xbfd87800
> > >
> > > AFAIK there is no portable way to modify the incoming argc, argv, env
> > > or environ. The position of each of these is target/ABI dependent, and
> > > may vary for each glibc port.
> >
> > i'm not sure what the ELF requirements are here -- are you guaranteed a
> > pointer to the argv/env storage ?  obviously modifying argc isnt possible
> > since that is always passed as an argument, but modifying the array of
> > argv/env pointers should "just work".
> Thanks for this info, I wrote a small test shared library and I am able
> to get access to argc, argv, env and enivron. I tried modifying the
> value of argc and contents of argv array. I am able to modify the
> contents of the argv array, but not argc. Now I understand, I can not
> modify the value of argc. This some what seems to break my use case as
> when finally main is called with argc and argv they can break the
> application if it checks for the value of argc and doesnt find any value
> in argv array. I probably need to find a better way to do initialize my
> library without affecting the applications default behavior.

i thought you just wanted (read-only) access to the arguments, not to modify 
them on the fly.  i dont believe it's possible to modify the argc as seen by 
main() as this value is passed as a function argument not just to your init 
func, but to all funcs.  since this depends on the function calling 
convention, it could be in a register, on the stack, or somewhere in between 
based on what gcc has decided to do.  and the value gets moved around a lot 
since it gets passed to multiple functions

things you could do instead:
 - call main() yourself from initializer
	- downside: you bypass arbitrary initializer functions (including internal 
libc code), so that probably will break

 - patch the main() entry code dynamically
	- downside: have to mark the .text writable, have to write arch-specific 
code, security settings have to allow this, etc...

off the top of my head, i dont how to get the storage location that glibc is 
using to access main().  if you could find that, you could set the pointer 
temporarily to your own function and call back to the real main() with 
modified arguments.

Attachment: signature.asc
Description: This is a digitally signed message part.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]