From 1735a713cbb05fdca3abad243f1223e5262071a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=AE=8B=E9=A1=B5?= <31466456+canyie@users.noreply.github.com> Date: Mon, 8 Aug 2022 17:43:19 +0800 Subject: [PATCH] Use `ANDROID_DLEXT_FORCE_LOAD` to load second stage if possible Fix #6095 --- native/src/zygisk/entry.cpp | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/native/src/zygisk/entry.cpp b/native/src/zygisk/entry.cpp index 5733178f1..cb2304d2b 100644 --- a/native/src/zygisk/entry.cpp +++ b/native/src/zygisk/entry.cpp @@ -51,16 +51,20 @@ static void *unload_first_stage(void *) { return nullptr; } +#if defined(__LP64__) +// Use symlink to workaround linker bug on old broken Android +// https://issuetracker.google.com/issues/36914295 +#define SECOND_STAGE_PATH "/system/bin/app_process" +#else +#define SECOND_STAGE_PATH "/system/bin/app_process32" +#endif + static void second_stage_entry() { zygisk_logging(); ZLOGD("inject 2nd stage\n"); MAGISKTMP = getenv(MAGISKTMP_ENV); -#if defined(__LP64__) - self_handle = dlopen("/system/bin/app_process", RTLD_NOLOAD); -#else - self_handle = dlopen("/system/bin/app_process32", RTLD_NOLOAD); -#endif + self_handle = dlopen(SECOND_STAGE_PATH, RTLD_NOLOAD); dlclose(self_handle); unsetenv(MAGISKTMP_ENV); @@ -81,12 +85,18 @@ static void first_stage_entry() { } // Load second stage + android_dlextinfo info { + .flags = ANDROID_DLEXT_FORCE_LOAD + }; setenv(INJECT_ENV_2, "1", 1); -#if defined(__LP64__) - dlopen("/system/bin/app_process", RTLD_LAZY); -#else - dlopen("/system/bin/app_process32", RTLD_LAZY); -#endif + if (android_dlopen_ext(SECOND_STAGE_PATH, RTLD_LAZY, &info) == nullptr) { + // Android 5.x doesn't support ANDROID_DLEXT_FORCE_LOAD + ZLOGI("ANDROID_DLEXT_FORCE_LOAD is not supported, fallback to dlopen\n"); + if (dlopen(SECOND_STAGE_PATH, RTLD_LAZY) == nullptr) { + ZLOGE("Cannot load the second stage\n"); + unsetenv(INJECT_ENV_2); + } + } } [[gnu::constructor]] [[maybe_unused]]