mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-02-21 09:48:30 +00:00
Update zygisk entry implementation
This commit is contained in:
parent
f7c0e407ca
commit
12e9873514
@ -39,17 +39,13 @@ void self_unload() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void *unload_first_stage(void *v) {
|
static void *unload_first_stage(void *v) {
|
||||||
// Setup 1ms
|
// Wait 1ms to make sure first stage is completely done
|
||||||
timespec ts = { .tv_sec = 0, .tv_nsec = 1000000L };
|
timespec ts = { .tv_sec = 0, .tv_nsec = 1000000L };
|
||||||
|
|
||||||
while (getenv(INJECT_ENV_1))
|
|
||||||
nanosleep(&ts, nullptr);
|
|
||||||
|
|
||||||
// Wait another 1ms to make sure all threads left our code
|
|
||||||
nanosleep(&ts, nullptr);
|
nanosleep(&ts, nullptr);
|
||||||
|
|
||||||
char *path = static_cast<char *>(v);
|
auto path = static_cast<const char *>(v);
|
||||||
unmap_all(path);
|
unmap_all(path);
|
||||||
|
free(v);
|
||||||
active_threads--;
|
active_threads--;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -60,13 +56,7 @@ static void sanitize_environ() {
|
|||||||
char *cur = environ[0];
|
char *cur = environ[0];
|
||||||
|
|
||||||
for (int i = 0; environ[i]; ++i) {
|
for (int i = 0; environ[i]; ++i) {
|
||||||
if (str_starts(environ[i], INJECT_ENV_1 "=")) {
|
// Copy all env onto the original stack
|
||||||
// This specific env has to live in heap
|
|
||||||
environ[i] = strdup(environ[i]);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy all filtered env onto the original stack
|
|
||||||
int len = strlen(environ[i]);
|
int len = strlen(environ[i]);
|
||||||
memmove(cur, environ[i], len + 1);
|
memmove(cur, environ[i], len + 1);
|
||||||
environ[i] = cur;
|
environ[i] = cur;
|
||||||
@ -77,7 +67,7 @@ static void sanitize_environ() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((destructor))
|
__attribute__((destructor))
|
||||||
static void inject_cleanup_wait() {
|
static void zygisk_cleanup_wait() {
|
||||||
if (active_threads < 0)
|
if (active_threads < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -92,49 +82,70 @@ static void inject_cleanup_wait() {
|
|||||||
nanosleep(&ts, nullptr);
|
nanosleep(&ts, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define SECOND_STAGE_PTR "ZYGISK_PTR"
|
||||||
|
|
||||||
|
static decltype(&unload_first_stage) second_stage_entry(void *handle) {
|
||||||
|
self_handle = handle;
|
||||||
|
|
||||||
|
unsetenv(INJECT_ENV_2);
|
||||||
|
unsetenv(SECOND_STAGE_PTR);
|
||||||
|
|
||||||
|
zygisk_logging();
|
||||||
|
LOGD("zygisk: inject 2nd stage\n");
|
||||||
|
active_threads = 1;
|
||||||
|
|
||||||
|
hook_functions();
|
||||||
|
|
||||||
|
active_threads++;
|
||||||
|
return &unload_first_stage;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void first_stage_entry() {
|
||||||
|
android_logging();
|
||||||
|
LOGD("zygisk: inject 1st stage\n");
|
||||||
|
|
||||||
|
char *ld = getenv("LD_PRELOAD");
|
||||||
|
char *path;
|
||||||
|
if (char *c = strrchr(ld, ':')) {
|
||||||
|
*c = '\0';
|
||||||
|
setenv("LD_PRELOAD", ld, 1); // Restore original LD_PRELOAD
|
||||||
|
path = strdup(c + 1);
|
||||||
|
} else {
|
||||||
|
unsetenv("LD_PRELOAD");
|
||||||
|
path = strdup(ld);
|
||||||
|
}
|
||||||
|
unsetenv(INJECT_ENV_1);
|
||||||
|
sanitize_environ();
|
||||||
|
|
||||||
|
// Update path to 2nd stage lib
|
||||||
|
*(strrchr(path, '.') - 1) = '2';
|
||||||
|
|
||||||
|
// Load second stage
|
||||||
|
setenv(INJECT_ENV_2, "1", 1);
|
||||||
|
void *handle = dlopen(path, RTLD_LAZY);
|
||||||
|
|
||||||
|
// Revert path to 1st stage lib
|
||||||
|
*(strrchr(path, '.') - 1) = '1';
|
||||||
|
|
||||||
|
// Run second stage entry
|
||||||
|
char *env = getenv(SECOND_STAGE_PTR);
|
||||||
|
decltype(&second_stage_entry) second_stage;
|
||||||
|
sscanf(env, "%p", &second_stage);
|
||||||
|
auto unload = second_stage(handle);
|
||||||
|
|
||||||
|
// Schedule to unload 1st stage
|
||||||
|
new_daemon_thread(unload, path);
|
||||||
|
}
|
||||||
|
|
||||||
__attribute__((constructor))
|
__attribute__((constructor))
|
||||||
static void inject_init() {
|
static void zygisk_init() {
|
||||||
if (char *env = getenv(INJECT_ENV_2)) {
|
if (getenv(INJECT_ENV_2)) {
|
||||||
zygisk_logging();
|
// Return function pointer to first stage
|
||||||
LOGD("zygisk: inject 2nd stage\n");
|
char buf[128];
|
||||||
active_threads = 1;
|
snprintf(buf, sizeof(buf), "%p", &second_stage_entry);
|
||||||
unsetenv(INJECT_ENV_2);
|
setenv(SECOND_STAGE_PTR, buf, 1);
|
||||||
|
|
||||||
// Get our own handle
|
|
||||||
self_handle = dlopen(env, RTLD_LAZY);
|
|
||||||
dlclose(self_handle);
|
|
||||||
|
|
||||||
hook_functions();
|
|
||||||
|
|
||||||
// Update path to 1st stage lib
|
|
||||||
*(strrchr(env, '.') - 1) = '1';
|
|
||||||
|
|
||||||
active_threads++;
|
|
||||||
new_daemon_thread(&unload_first_stage, env);
|
|
||||||
} else if (getenv(INJECT_ENV_1)) {
|
} else if (getenv(INJECT_ENV_1)) {
|
||||||
android_logging();
|
first_stage_entry();
|
||||||
LOGD("zygisk: inject 1st stage\n");
|
|
||||||
|
|
||||||
string ld = getenv("LD_PRELOAD");
|
|
||||||
char *path;
|
|
||||||
if (char *c = strrchr(ld.data(), ':')) {
|
|
||||||
*c = '\0';
|
|
||||||
setenv("LD_PRELOAD", ld.data(), 1); // Restore original LD_PRELOAD
|
|
||||||
path = c + 1;
|
|
||||||
} else {
|
|
||||||
unsetenv("LD_PRELOAD");
|
|
||||||
path = ld.data();
|
|
||||||
}
|
|
||||||
sanitize_environ();
|
|
||||||
|
|
||||||
// Update path to 2nd stage lib
|
|
||||||
*(strrchr(path, '.') - 1) = '2';
|
|
||||||
|
|
||||||
// Setup second stage
|
|
||||||
setenv(INJECT_ENV_2, path, 1);
|
|
||||||
dlopen(path, RTLD_LAZY);
|
|
||||||
|
|
||||||
unsetenv(INJECT_ENV_1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user