Skip to content

Instantly share code, notes, and snippets.

@jakobrs
Last active May 31, 2021 13:41
Show Gist options
  • Save jakobrs/f1e260031c697ced5e353fd2079b9472 to your computer and use it in GitHub Desktop.
Save jakobrs/f1e260031c697ced5e353fd2079b9472 to your computer and use it in GitHub Desktop.
#define _GNU_SOURCE
#include <stdio.h>
#include <stddef.h>
#include <dlfcn.h>
struct dlopen_args
{
/* The arguments for dlopen_doit. */
const char *file;
int mode;
/* The return value of dlopen_doit. */
void *new;
/* Address of the caller. */
const void *caller;
};
struct dlfcn_hook
{
void *(*dlopen) (const char *file, int mode, void *dl_caller);
int (*dlclose) (void *handle);
void *(*dlsym) (void *handle, const char *name, void *dl_caller);
void *(*dlvsym) (void *handle, const char *name, const char *version,
void *dl_caller);
char *(*dlerror) (void);
int (*dladdr) (const void *address, Dl_info *info);
int (*dladdr1) (const void *address, Dl_info *info,
void **extra_info, int flags);
int (*dlinfo) (void *handle, int request, void *arg, void *dl_caller);
void *(*dlmopen) (Lmid_t nsid, const char *file, int mode, void *dl_caller);
void *pad[4];
};
/* NOTE: These two functions are usually defined as static
You'll want to preload a version of libdl.so where they're not.
./rebind.py -b global /path/to/libdl.so -o ./libdl.so -- _dlerror_run dlopen_doit
*/
extern void *_dlerror_run(void (*)(void *), void *);
extern void dlopen_doit(void *);
extern void _rtld_global_ro;
extern struct dlfcn_hook *_dlfcn_hook;
static inline int rtld_active() {
return *(void **)(&_rtld_global_ro + 0x218) != NULL;
}
void *dlopen_from(const char *file, int mode, void *dl_caller) {
if (!rtld_active())
return _dlfcn_hook->dlopen(file, mode, dl_caller);
struct dlopen_args args;
args.file = file;
args.mode = mode;
args.caller = dl_caller;
return _dlerror_run(dlopen_doit, &args) ? NULL : args.new;
}
void *dlopen(const char *file, int mode) {
return dlopen_from(file, mode, __builtin_extract_return_addr(__builtin_return_address(0)));
}
#include <stdio.h>
void *dlopen_from(const char *, int, void *);
void *dlopen(const char *file, int mode) {
void *caller = __builtin_extract_return_addr(__builtin_return_address(0));
printf("Loading file %s with mode %d from 0x%lx\n", file, mode, (size_t)caller);
return dlopen_from(file, mode, caller);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment