Last active
May 31, 2021 13:41
-
-
Save jakobrs/f1e260031c697ced5e353fd2079b9472 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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))); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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