Exemple #1
0
static void
init (void)
{
  void *resume, *personality;
  void *handle;

  handle = __libc_dlopen (LIBGCC_S_SO);

  if (handle == NULL
      || (resume = __libc_dlsym (handle, "_Unwind_Resume")) == NULL
      || (personality = __libc_dlsym (handle, "__gcc_personality_v0")) == NULL)
    __libc_fatal (LIBGCC_S_SO " must be installed for pthread_cancel to work\n");

  libgcc_s_resume = resume;
  libgcc_s_personality = personality;
  atomic_write_barrier ();
  /* At the point at which any thread writes the handle
     to libgcc_s_handle, the initialization is complete.
     The writing of libgcc_s_handle is atomic. All other
     threads reading libgcc_s_handle do so atomically. Any
     thread that does not execute this function must issue
     a read barrier to ensure that all of the above has
     actually completed and that the values of the
     function pointers are correct.   */
  libgcc_s_handle = handle;
}
void
pthread_cancel_init (void)
{
  void *resume, *personality, *forcedunwind, *getcfa;
  void *handle;

  if (__builtin_expect (libgcc_s_getcfa != NULL, 1))
    return;

  handle = __libc_dlopen ("libgcc_s.so.1");

  if (handle == NULL
      || (resume = __libc_dlsym (handle, "_Unwind_Resume")) == NULL
      || (personality = __libc_dlsym (handle, "__gcc_personality_v0")) == NULL
      || (forcedunwind = __libc_dlsym (handle, "_Unwind_ForcedUnwind"))
	 == NULL
      || (getcfa = __libc_dlsym (handle, "_Unwind_GetCFA")) == NULL
#ifdef ARCH_CANCEL_INIT
      || ARCH_CANCEL_INIT (handle)
#endif
      )
    __libc_fatal ("libgcc_s.so.1 must be installed for pthread_cancel to work\n");

  libgcc_s_resume = resume;
  libgcc_s_personality = personality;
  libgcc_s_forcedunwind = forcedunwind;
  libgcc_s_getcfa = getcfa;
}
Exemple #3
0
static void
init (void)
{
  libgcc_handle = __libc_dlopen ("libgcc_s.so.1");

  if (libgcc_handle == NULL)
    return;

  unwind_backtrace = __libc_dlsym (libgcc_handle, "_Unwind_Backtrace");
  unwind_vrs_get = __libc_dlsym (libgcc_handle, "_Unwind_VRS_Get");
  if (unwind_vrs_get == NULL)
    unwind_backtrace = NULL;
}
static void
init (void)
{
  void *resume, *personality;
  void *handle;

  handle = __libc_dlopen ("libgcc_s.so.1");

  if (handle == NULL
      || (resume = __libc_dlsym (handle, "_Unwind_Resume")) == NULL
      || (personality = __libc_dlsym (handle, "__gcc_personality_v0")) == NULL)
    __libc_fatal ("libgcc_s.so.1 must be installed for pthread_cancel to work\n");

  libgcc_s_resume = resume;
  libgcc_s_personality = personality;
}
Exemple #5
0
void * DLLLoader::GetFunction(const char *functionName)
{
  // Now that dlsym is substituted by our own version, we need to use 
  // libc private version of the function for our own purposes
  // return dlsym(handle, functionName);
  return __libc_dlsym(handle, functionName);
}
Exemple #6
0
/*
 * Protect against dlsym interception.
 *
 * We implement the whole API, so we don't need to intercept dlsym -- dlopen is
 * enough. However we need to protect against other dynamic libraries
 * intercepting dlsym, to prevent infinite recursion,
 *
 * In particular the Steam Community Overlay exports dlsym.  See also
 * http://lists.freedesktop.org/archives/apitrace/2013-March/000573.html
 */
PRIVATE
void *
dlsym(void * handle, const char * symbol)
{
    /*
     * We rely on glibc's internal __libc_dlsym.  See also
     * http://www.linuxforu.com/2011/08/lets-hook-a-library-function/
     *
     * Use use it to obtain the true dlsym.  We don't use __libc_dlsym directly
     * because it does not support things such as RTLD_NEXT.
     */
    typedef void * (*PFN_DLSYM)(void *, const char *);
    static PFN_DLSYM dlsym_ptr = NULL;
    if (!dlsym_ptr) {
        void *libdl_handle = __libc_dlopen_mode("libdl.so.2", RTLD_LOCAL | RTLD_NOW);
        if (libdl_handle) {
            dlsym_ptr = (PFN_DLSYM)__libc_dlsym(libdl_handle, "dlsym");
        }
        if (!dlsym_ptr) {
            os::log("apitrace: error: failed to look up real dlsym\n");
            return NULL;
        }
    }

    return dlsym_ptr(handle, symbol);
}
Exemple #7
0
void
__attribute_noinline__
pthread_cancel_init (void)
{
  void *resume;
  void *personality;
  void *forcedunwind;
  void *getcfa;
  void *handle;

  if (__builtin_expect (libgcc_s_handle != NULL, 1))
    {
      /* Force gcc to reload all values.  */
      asm volatile ("" ::: "memory");
      return;
    }

  handle = __libc_dlopen (LIBGCC_S_SO);

  if (handle == NULL
      || (resume = __libc_dlsym (handle, "_Unwind_Resume")) == NULL
      || (personality = __libc_dlsym (handle, "__gcc_personality_v0")) == NULL
      || (forcedunwind = __libc_dlsym (handle, "_Unwind_ForcedUnwind"))
	 == NULL
      || (getcfa = __libc_dlsym (handle, "_Unwind_GetCFA")) == NULL
#ifdef ARCH_CANCEL_INIT
      || ARCH_CANCEL_INIT (handle)
#endif
      )
    __libc_fatal (LIBGCC_S_SO " must be installed for pthread_cancel to work\n");

  PTR_MANGLE (resume);
  libgcc_s_resume = resume;
  PTR_MANGLE (personality);
  libgcc_s_personality = personality;
  PTR_MANGLE (forcedunwind);
  libgcc_s_forcedunwind = forcedunwind;
  PTR_MANGLE (getcfa);
  libgcc_s_getcfa = getcfa;
  /* Make sure libgcc_s_handle is written last.  Otherwise,
     pthread_cancel_init might return early even when the pointer the
     caller is interested in is not initialized yet.  */
  atomic_write_barrier ();
  libgcc_s_handle = handle;
}
Exemple #8
0
__libgcc_s_init(void)
{
  void *resume, *personality;
  void *handle;

  handle = __libc_dlopen (LIBGCC_S_SO);

  if (handle == NULL
      || (resume = __libc_dlsym (handle, "_Unwind_Resume")) == NULL
      || (personality = __libc_dlsym (handle, "__gcc_personality_v0")) == NULL)
  {
    fprintf (stderr,
	     LIBGCC_S_SO " must be installed for pthread_cancel to work\n");
    abort();
  }

  __libgcc_s_resume = resume;
  libgcc_s_personality = personality;
}
Exemple #9
0
static void
init (void)
{
  libgcc_handle = __libc_dlopen ("libgcc_s.so.2");

  if (libgcc_handle == NULL)
    return;

  unwind_backtrace = __libc_dlsym (libgcc_handle, "_Unwind_Backtrace");
  unwind_getip = __libc_dlsym (libgcc_handle, "_Unwind_GetIP");
  unwind_getcfa = __libc_dlsym (libgcc_handle, "_Unwind_GetCFA");
  unwind_getgr = __libc_dlsym (libgcc_handle, "_Unwind_GetGR");
  if (unwind_getip == NULL || unwind_getgr == NULL || unwind_getcfa == NULL)
    {
      unwind_backtrace = NULL;
      __libc_dlclose (libgcc_handle);
      libgcc_handle = NULL;
    }
}
Exemple #10
0
void *libc_dlsym(const char *name)
{
	void *ret, *libc = dlopen("libc.so", RTLD_LAZY);
	if (!libc)
		libc = dlopen("/lib/arm-linux-gnueabihf/libc.so.6", RTLD_LAZY);
	if (!libc)
		libc = dlopen("/lib/arm-linux-gnueabi/libc.so.6", RTLD_LAZY);
	ret = __libc_dlsym(libc, name);
	dlclose(libc);
	return ret;
}
int main(int argc, char **argv) {
	void *handle;
        double (*puts)(char *);
        char *error;

        handle = __libc_dlopen_mode("libc.so.6", RTLD_LAZY);
        if (!handle) {
            exit(1);
        }

        puts = __libc_dlsym(handle, "puts");

        (*puts)("Hello World");
        __libc_dlclose(handle);
    }
struct frame_state *
__frame_state_for (void *pc, struct frame_state *frame_state)
{
  static framesf frame_state_for;

  if (frame_state_for == NULL)
    {
      void *handle = __libc_dlopen (LIBGCC_S_SO);

      if (handle == NULL
	  || (frame_state_for
	      = (framesf) __libc_dlsym (handle, "__frame_state_for")) == NULL)
#ifndef __USING_SJLJ_EXCEPTIONS__
	frame_state_for = fallback_frame_state_for;
#else
      	frame_state_for = abort;
#endif
    }

  return frame_state_for (pc, frame_state);
}
Exemple #13
0
void * threadfunc (void * arg)
{
  printf ("in threadfunc\n");

  void * handle = __libc_dlopen_mode ("./test_unload.so",  RTLD_LAZY | 0x80000000);
  printf ("dlopen ok handle: %p\n", handle);

  void (*pfn_shared_method)(void) = __libc_dlsym(handle, "shared_method");

  printf ("before func\n");
  pfn_shared_method ();
  printf ("after func\n");

  printf ("about to dlclose handle: %p\n", handle);
  __libc_dlclose (handle);
  printf ("done dlclose\n");

  while (!stopping)
      sleep (1);

  printf ("leaving threadfunc\n");
  stopped = 1;
}
Exemple #14
0
void *dlsym(void *handle, const char *name)
{
    if(!real_dlsym) {
	fprintf(stderr, "with_smaa: Getting real dlsym...\n");
	void *libdl = dlopen(lib_path("libdl.so"), RTLD_NOW);
	real_dlsym = __libc_dlsym(libdl, "dlsym");	
	fprintf(stderr, "with_smaa: real_dlsym=%p\n", real_dlsym);
    }
    
    if (!strcmp(name, "dlsym")) {
	return (void*) dlsym;
    } else if(!strcmp(name, "glXGetProcAddressARB")) {
	fprintf(stderr, "with_smaa: dlsym: redirecting glXGetProcAddressARB\n");
	return (void*) glXGetProcAddress;
    } else if(!strcmp(name, "glXGetProcAddress")) {
	fprintf(stderr, "with_smaa: dlsym: redirecting glXGetProcAddress\n");
	return (void*) glXGetProcAddress;
    } else if(!strcmp(name, "glXSwapBuffers")) {
	fprintf(stderr, "with_smaa: dlsym: redirecting glXSwapBuffers\n");
	return (void*) glXSwapBuffers;
    }

    return real_dlsym(handle, name);
}
void *
__nss_lookup_function (service_user *ni, const char *fct_name)
{
  void **found, *result;

  /* We now modify global data.  Protect it.  */
  __libc_lock_lock (lock);

  /* Search the tree of functions previously requested.  Data in the
     tree are `known_function' structures, whose first member is a
     `const char *', the lookup key.  The search returns a pointer to
     the tree node structure; the first member of the is a pointer to
     our structure (i.e. what will be a `known_function'); since the
     first member of that is the lookup key string, &FCT_NAME is close
     enough to a pointer to our structure to use as a lookup key that
     will be passed to `known_compare' (above).  */

  found = __tsearch (&fct_name, (void **) &ni->known, &known_compare);
  if (*found != &fct_name)
    /* The search found an existing structure in the tree.  */
    result = ((known_function *) *found)->fct_ptr;
  else
    {
      /* This name was not known before.  Now we have a node in the tree
	 (in the proper sorted position for FCT_NAME) that points to
	 &FCT_NAME instead of any real `known_function' structure.
	 Allocate a new structure and fill it in.  */

      known_function *known = malloc (sizeof *known);
      if (! known)
	{
	remove_from_tree:
	  /* Oops.  We can't instantiate this node properly.
	     Remove it from the tree.  */
	  __tdelete (&fct_name, (void **) &ni->known, &known_compare);
	  result = NULL;
	}
      else
	{
	  /* Point the tree node at this new structure.  */
	  *found = known;
	  known->fct_name = fct_name;

	  if (ni->library == NULL)
	    {
	      /* This service has not yet been used.  Fetch the service
		 library for it, creating a new one if need be.  If there
		 is no service table from the file, this static variable
		 holds the head of the service_library list made from the
		 default configuration.  */
	      static name_database default_table;
	      ni->library = nss_new_service (service_table ?: &default_table,
					     ni->name);
	      if (ni->library == NULL)
		{
		  /* This only happens when out of memory.  */
		  free (known);
		  goto remove_from_tree;
		}
	    }

#if !defined DO_STATIC_NSS || defined SHARED
	  if (ni->library->lib_handle == NULL)
	    {
	      /* Load the shared library.  */
	      size_t shlen = (7 + strlen (ni->library->name) + 3
			      + strlen (__nss_shlib_revision) + 1);
	      int saved_errno = errno;
	      char shlib_name[shlen];

	      /* Construct shared object name.  */
	      __stpcpy (__stpcpy (__stpcpy (__stpcpy (shlib_name,
						      "libnss_"),
					    ni->library->name),
				  ".so"),
			__nss_shlib_revision);

	      ni->library->lib_handle = __libc_dlopen (shlib_name);
	      if (ni->library->lib_handle == NULL)
		{
		  /* Failed to load the library.  */
		  ni->library->lib_handle = (void *) -1l;
		  __set_errno (saved_errno);
		}
	    }

	  if (ni->library->lib_handle == (void *) -1l)
	    /* Library not found => function not found.  */
	    result = NULL;
	  else
	    {
	      /* Get the desired function.  */
	      size_t namlen = (5 + strlen (ni->library->name) + 1
			       + strlen (fct_name) + 1);
	      char name[namlen];

	      /* Construct the function name.  */
	      __stpcpy (__stpcpy (__stpcpy (__stpcpy (name, "_nss_"),
					    ni->library->name),
				  "_"),
			fct_name);

	      /* Look up the symbol.  */
	      result = __libc_dlsym (ni->library->lib_handle, name);
	    }
#else
	  /* We can't get function address dynamically in static linking. */
	  {
# define DEFINE_ENT(h,nm)						      \
	    { #h"_get"#nm"ent_r", _nss_##h##_get##nm##ent_r },		      \
	    { #h"_end"#nm"ent", _nss_##h##_end##nm##ent },		      \
	    { #h"_set"#nm"ent", _nss_##h##_set##nm##ent },
# define DEFINE_GET(h,nm)						      \
	    { #h"_get"#nm"_r", _nss_##h##_get##nm##_r },
# define DEFINE_GETBY(h,nm,ky)						      \
	    { #h"_get"#nm"by"#ky"_r", _nss_##h##_get##nm##by##ky##_r },
	    static struct fct_tbl { const char *fname; void *fp; } *tp, tbl[] =
	      {
# include "function.def"
		{ NULL, NULL }
	      };
	    size_t namlen = (5 + strlen (ni->library->name) + 1
			     + strlen (fct_name) + 1);
	    char name[namlen];

	    /* Construct the function name.  */
	    __stpcpy (__stpcpy (__stpcpy (name, ni->library->name),
				"_"),
		      fct_name);

	    result = NULL;
	    for (tp = &tbl[0]; tp->fname; tp++)
	      if (strcmp (tp->fname, name) == 0)
		{
		  result = tp->fp;
		  break;
		}
	  }
#endif

	  /* Remember function pointer for later calls.  Even if null, we
	     record it so a second try needn't search the library again.  */
	  known->fct_ptr = result;
	}
    }

  /* Remove the lock.  */
  __libc_lock_unlock (lock);

  return result;
}
Exemple #16
0
static void* real_dlsym(void *handle, const char* symbol)
{
    static fnDlsym internal_dlsym = (fnDlsym)__libc_dlsym(dlopen("libdl.so.2", RTLD_LAZY), "dlsym");
    return (*internal_dlsym)(handle, symbol);
}
Exemple #17
0
void *dlsym(void *handle, const char *symbol)
{
    printf("Ha Ha...dlsym() Hooked\n");
    void* result = __libc_dlsym(handle, symbol); /* now, this will call dlsym() library function */
    return result;
}
Exemple #18
0
/* Open the gconv database if necessary.  A non-negative return value
   means success.  */
struct __gconv_loaded_object *
__gconv_find_shlib (const char *name)
{
  struct __gconv_loaded_object *found;
  void *keyp;

  /* Search the tree of shared objects previously requested.  Data in
     the tree are `loaded_object' structures, whose first member is a
     `const char *', the lookup key.  The search returns a pointer to
     the tree node structure; the first member of the is a pointer to
     our structure (i.e. what will be a `loaded_object'); since the
     first member of that is the lookup key string, &FCT_NAME is close
     enough to a pointer to our structure to use as a lookup key that
     will be passed to `known_compare' (above).  */

  keyp = __tfind (&name, &loaded, known_compare);
  if (keyp == NULL)
    {
      /* This name was not known before.  */
      size_t namelen = strlen (name) + 1;

      found = malloc (sizeof (struct __gconv_loaded_object) + namelen);
      if (found != NULL)
	{
	  /* Point the tree node at this new structure.  */
	  found->name = (char *) memcpy (found + 1, name, namelen);
	  found->counter = -TRIES_BEFORE_UNLOAD - 1;
	  found->handle = NULL;

	  if (__builtin_expect (__tsearch (found, &loaded, known_compare)
				== NULL, 0))
	    {
	      /* Something went wrong while inserting the entry.  */
	      free (found);
	      found = NULL;
	    }
	}
    }
  else
    found = *(struct __gconv_loaded_object **) keyp;

  /* Try to load the shared object if the usage count is 0.  This
     implies that if the shared object is not loadable, the handle is
     NULL and the usage count > 0.  */
  if (found != NULL)
    {
      if (found->counter < -TRIES_BEFORE_UNLOAD)
	{
	  assert (found->handle == NULL);
	  found->handle = __libc_dlopen (found->name);
	  if (found->handle != NULL)
	    {
	      found->fct = __libc_dlsym (found->handle, "gconv");
	      if (found->fct == NULL)
		{
		  /* Argh, no conversion function.  There is something
                     wrong here.  */
		  __gconv_release_shlib (found);
		  found = NULL;
		}
	      else
		{
		  found->init_fct = __libc_dlsym (found->handle, "gconv_init");
		  found->end_fct = __libc_dlsym (found->handle, "gconv_end");

#ifdef PTR_MANGLE
		  PTR_MANGLE (found->fct);
		  PTR_MANGLE (found->init_fct);
		  PTR_MANGLE (found->end_fct);
#endif

		  /* We have succeeded in loading the shared object.  */
		  found->counter = 1;
		}
	    }
	  else
	    /* Error while loading the shared object.  */
	    found = NULL;
	}
      else if (found->handle != NULL)
	found->counter = MAX (found->counter + 1, 1);
    }

  return found;
}
Exemple #19
0
/* returns the address of a symbol or dies */
void *find_symbol(void *hnd, const char *symbol, void *repl)
{
	static void *libc_handle;
	char *error;
	void *addr;
	int i = 0;
	int free_idx = -1;

	if (libc_handle == NULL) {
		libc_handle = dlopen("libc.so.6", RTLD_LAZY);
		if (libc_handle == NULL) {
			fprintf(stderr, "%s: %s\n", symbol, dlerror());
			exit(1);
		}
	}
	dlerror();

	if (hnd == NULL)
		hnd = libc_handle;

	// lookup cache
	if (hnd == libc_handle) {
		pthread_mutex_lock(&cache_mutex);
		for (i = 0; i < SYMBOL_CACHE_SIZE; ++i) {
			if (repl && !symbol_cache[i].name[0]) {
				free_idx = i;
				break;
			}
			if (!strncmp(symbol, symbol_cache[i].name, SYMBOL_MAX_NAME)) {
				addr = symbol_cache[i].addr;
				if (addr == repl)
					fprintf(stderr, "FATAL!!! libdlsym detected a potential endless loop.\n'%s' redirection from %p to %p.\nPlease check your preload libs!", symbol, addr, repl);
				if (repl)
					symbol_cache[i].addr = repl;
				pthread_mutex_unlock(&cache_mutex);
				return addr;
			}
		}
		if (free_idx == -1)
			pthread_mutex_unlock(&cache_mutex);
	}

	addr = __libc_dlsym(hnd, symbol);

	error = dlerror();
	if (error != NULL) {
		fprintf(stderr, "%s: %s\n", symbol, error);
		exit(1);
	}

	/* NULL may be a valid address of a symbol,
	   but we're not going to call it. */
	if (symbol == NULL) {
		fprintf(stderr, "%s: is a NULL pointer\n", symbol);
		exit(1);
	}

	if (repl) {
		if (free_idx != -1) {
			strncpy(symbol_cache[i].name, symbol, SYMBOL_MAX_NAME);
			symbol_cache[i].addr = repl;
			pthread_mutex_unlock(&cache_mutex);
		}
		else {
			fprintf(stderr, "symbol_cache too small!!! abort\n");
			exit(1);
		}
	}

	return addr;
}