Manually release all Xposed hooks and GC if blacklisted
This commit is contained in:
parent
3702bf333b
commit
e9c03a8f37
|
|
@ -26,6 +26,7 @@ namespace edxp {
|
||||||
static constexpr auto kClassLinkerClassName = "com.elderdrivers.riru.edxp.art.ClassLinker";
|
static constexpr auto kClassLinkerClassName = "com.elderdrivers.riru.edxp.art.ClassLinker";
|
||||||
static constexpr auto kSandHookClassName = "com.swift.sandhook.SandHook";
|
static constexpr auto kSandHookClassName = "com.swift.sandhook.SandHook";
|
||||||
static constexpr auto kSandHookNeverCallClassName = "com.swift.sandhook.ClassNeverCall";
|
static constexpr auto kSandHookNeverCallClassName = "com.swift.sandhook.ClassNeverCall";
|
||||||
|
static constexpr auto kXposedBridgeClassName = "de.robv.android.xposed.XposedBridge";
|
||||||
|
|
||||||
static constexpr auto kLibArtName = "libart.so";
|
static constexpr auto kLibArtName = "libart.so";
|
||||||
static constexpr auto kLibFwkName = "libandroid_runtime.so";
|
static constexpr auto kLibFwkName = "libandroid_runtime.so";
|
||||||
|
|
|
||||||
|
|
@ -81,8 +81,6 @@ namespace edxp {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO clear up all these global refs if blacklisted?
|
|
||||||
|
|
||||||
inject_class_loader_ = env->NewGlobalRef(my_cl);
|
inject_class_loader_ = env->NewGlobalRef(my_cl);
|
||||||
|
|
||||||
env->DeleteLocalRef(my_cl);
|
env->DeleteLocalRef(my_cl);
|
||||||
|
|
@ -175,6 +173,16 @@ namespace edxp {
|
||||||
|
|
||||||
void Context::ReleaseJavaEnv(JNIEnv *env) {
|
void Context::ReleaseJavaEnv(JNIEnv *env) {
|
||||||
if (UNLIKELY(!instance_)) return;
|
if (UNLIKELY(!instance_)) return;
|
||||||
|
|
||||||
|
auto xposed_bridge_class = FindClassFromLoader(env, inject_class_loader_, kXposedBridgeClassName);
|
||||||
|
if(LIKELY(xposed_bridge_class)){
|
||||||
|
jmethodID clear_all_callbacks_method = JNI_GetStaticMethodID(env, xposed_bridge_class, "clearAllCallbacks",
|
||||||
|
"()V");
|
||||||
|
if(LIKELY(clear_all_callbacks_method)) {
|
||||||
|
JNI_CallStaticVoidMethod(env, xposed_bridge_class, clear_all_callbacks_method);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
initialized_ = false;
|
initialized_ = false;
|
||||||
if (entry_class_) {
|
if (entry_class_) {
|
||||||
env->DeleteGlobalRef(entry_class_);
|
env->DeleteGlobalRef(entry_class_);
|
||||||
|
|
@ -193,6 +201,10 @@ namespace edxp {
|
||||||
vm_ = nullptr;
|
vm_ = nullptr;
|
||||||
pre_fixup_static_mid_ = nullptr;
|
pre_fixup_static_mid_ = nullptr;
|
||||||
post_fixup_static_mid_ = nullptr;
|
post_fixup_static_mid_ = nullptr;
|
||||||
|
|
||||||
|
auto systemClass = env->FindClass("java/lang/System");
|
||||||
|
auto systemGCMethod = env->GetStaticMethodID(systemClass, "gc", "()V");
|
||||||
|
env->CallStaticVoidMethod(systemClass, systemGCMethod);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -239,13 +251,15 @@ namespace edxp {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Context::ShouldSkipInject(JNIEnv *env, jstring nice_name, jstring data_dir, jint uid,
|
std::tuple<bool, bool> Context::ShouldSkipInject(JNIEnv *env, jstring nice_name, jstring data_dir, jint uid,
|
||||||
jboolean is_child_zygote) {
|
jboolean is_child_zygote) {
|
||||||
const auto app_id = uid % PER_USER_RANGE;
|
const auto app_id = uid % PER_USER_RANGE;
|
||||||
const JUTFString package_name(env, nice_name, "UNKNOWN");
|
const JUTFString package_name(env, nice_name, "UNKNOWN");
|
||||||
bool skip = false;
|
bool skip = false;
|
||||||
|
bool release = true;
|
||||||
if (is_child_zygote) {
|
if (is_child_zygote) {
|
||||||
skip = true;
|
skip = true;
|
||||||
|
release = false; // In Android R, calling XposedBridge.clearAllCallbacks cause crashes.
|
||||||
LOGW("skip injecting into %s because it's a child zygote", package_name.get());
|
LOGW("skip injecting into %s because it's a child zygote", package_name.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -253,17 +267,17 @@ namespace edxp {
|
||||||
(app_id >= FIRST_APP_ZYGOTE_ISOLATED_UID && app_id <= LAST_APP_ZYGOTE_ISOLATED_UID) ||
|
(app_id >= FIRST_APP_ZYGOTE_ISOLATED_UID && app_id <= LAST_APP_ZYGOTE_ISOLATED_UID) ||
|
||||||
app_id == SHARED_RELRO_UID) {
|
app_id == SHARED_RELRO_UID) {
|
||||||
skip = true;
|
skip = true;
|
||||||
|
release = false; // In Android R, calling XposedBridge.clearAllCallbacks cause crashes.
|
||||||
LOGW("skip injecting into %s because it's isolated", package_name.get());
|
LOGW("skip injecting into %s because it's isolated", package_name.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(yujincheng08): check whitelist/blacklist.
|
|
||||||
const JUTFString dir(env, data_dir);
|
const JUTFString dir(env, data_dir);
|
||||||
if(!dir || !ConfigManager::GetInstance()->IsAppNeedHook(dir)) {
|
if(!dir || !ConfigManager::GetInstance()->IsAppNeedHook(dir)) {
|
||||||
skip = true;
|
skip = true;
|
||||||
LOGW("skip injecting xposed into %s because it's whitelisted/blacklisted",
|
LOGW("skip injecting xposed into %s because it's whitelisted/blacklisted",
|
||||||
package_name.get());
|
package_name.get());
|
||||||
}
|
}
|
||||||
return skip;
|
return {skip, release};
|
||||||
}
|
}
|
||||||
|
|
||||||
void Context::OnNativeForkAndSpecializePre(JNIEnv *env, jclass clazz,
|
void Context::OnNativeForkAndSpecializePre(JNIEnv *env, jclass clazz,
|
||||||
|
|
@ -279,7 +293,7 @@ namespace edxp {
|
||||||
jboolean is_child_zygote,
|
jboolean is_child_zygote,
|
||||||
jstring instruction_set,
|
jstring instruction_set,
|
||||||
jstring app_data_dir) {
|
jstring app_data_dir) {
|
||||||
skip_ = ShouldSkipInject(env, nice_name, app_data_dir, uid, is_child_zygote);
|
std::tie(skip_, release_) = ShouldSkipInject(env, nice_name, app_data_dir, uid, is_child_zygote);
|
||||||
app_data_dir_ = app_data_dir;
|
app_data_dir_ = app_data_dir;
|
||||||
nice_name_ = nice_name;
|
nice_name_ = nice_name;
|
||||||
PrepareJavaEnv(env);
|
PrepareJavaEnv(env);
|
||||||
|
|
@ -302,7 +316,8 @@ namespace edxp {
|
||||||
res, app_data_dir_, nice_name_);
|
res, app_data_dir_, nice_name_);
|
||||||
LOGD("injected xposed into %s", package_name.get());
|
LOGD("injected xposed into %s", package_name.get());
|
||||||
} else {
|
} else {
|
||||||
ReleaseJavaEnv(env);
|
if(release_)
|
||||||
|
ReleaseJavaEnv(env);
|
||||||
LOGD("skipped %s", package_name.get());
|
LOGD("skipped %s", package_name.get());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -80,6 +80,7 @@ namespace edxp {
|
||||||
jmethodID pre_fixup_static_mid_ = nullptr;
|
jmethodID pre_fixup_static_mid_ = nullptr;
|
||||||
jmethodID post_fixup_static_mid_ = nullptr;
|
jmethodID post_fixup_static_mid_ = nullptr;
|
||||||
bool skip_ = false;
|
bool skip_ = false;
|
||||||
|
bool release_ = true;
|
||||||
|
|
||||||
Context() {}
|
Context() {}
|
||||||
|
|
||||||
|
|
@ -91,7 +92,7 @@ namespace edxp {
|
||||||
|
|
||||||
void CallPostFixupStaticTrampolinesCallback(void *class_ptr, jmethodID mid);
|
void CallPostFixupStaticTrampolinesCallback(void *class_ptr, jmethodID mid);
|
||||||
|
|
||||||
static bool ShouldSkipInject(JNIEnv *env, jstring nice_name, jstring data_dir, jint uid,
|
static std::tuple<bool, bool> ShouldSkipInject(JNIEnv *env, jstring nice_name, jstring data_dir, jint uid,
|
||||||
jboolean is_child_zygote);
|
jboolean is_child_zygote);
|
||||||
|
|
||||||
void ReleaseJavaEnv(JNIEnv *env);
|
void ReleaseJavaEnv(JNIEnv *env);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue