Suspend all threads when doing hook stuffs to prevent crashes caused by GC
This commit is contained in:
parent
9a0044b674
commit
2ac5eb19c9
|
|
@ -125,4 +125,8 @@ public class Main implements KeepAll {
|
||||||
public static native void reopenFilesAfterForkNative();
|
public static native void reopenFilesAfterForkNative();
|
||||||
|
|
||||||
public static native void deoptMethodNative(Object object);
|
public static native void deoptMethodNative(Object object);
|
||||||
|
|
||||||
|
public static native long suspendAllThreads();
|
||||||
|
|
||||||
|
public static native void resumeAllThreads(long obj);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package com.elderdrivers.riru.xposed.core;
|
package com.elderdrivers.riru.xposed.core;
|
||||||
|
|
||||||
|
import com.elderdrivers.riru.xposed.Main;
|
||||||
import com.elderdrivers.riru.xposed.entry.hooker.OnePlusWorkAroundHooker;
|
import com.elderdrivers.riru.xposed.entry.hooker.OnePlusWorkAroundHooker;
|
||||||
import com.elderdrivers.riru.xposed.util.Utils;
|
import com.elderdrivers.riru.xposed.util.Utils;
|
||||||
|
|
||||||
|
|
@ -111,8 +112,13 @@ public class HookMain {
|
||||||
if (backup != null) {
|
if (backup != null) {
|
||||||
HookMethodResolver.resolveMethod(hook, backup);
|
HookMethodResolver.resolveMethod(hook, backup);
|
||||||
}
|
}
|
||||||
if (!backupAndHookNative(target, hook, backup)) {
|
long obj = Main.suspendAllThreads();
|
||||||
throw new RuntimeException("Failed to hook " + target + " with " + hook);
|
try {
|
||||||
|
if (!backupAndHookNative(target, hook, backup)) {
|
||||||
|
throw new RuntimeException("Failed to hook " + target + " with " + hook);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
Main.resumeAllThreads(obj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,13 +20,13 @@ jobject gInjectDexClassLoader;
|
||||||
|
|
||||||
static bool isInited = false;
|
static bool isInited = false;
|
||||||
|
|
||||||
static FileDescriptorTable* gClosedFdTable = nullptr;
|
static FileDescriptorTable *gClosedFdTable = nullptr;
|
||||||
|
|
||||||
void closeFilesBeforeForkNative(JNIEnv*, jclass) {
|
void closeFilesBeforeForkNative(JNIEnv *, jclass) {
|
||||||
gClosedFdTable = FileDescriptorTable::Create();
|
gClosedFdTable = FileDescriptorTable::Create();
|
||||||
}
|
}
|
||||||
|
|
||||||
void reopenFilesAfterForkNative(JNIEnv*, jclass) {
|
void reopenFilesAfterForkNative(JNIEnv *, jclass) {
|
||||||
if (!gClosedFdTable) {
|
if (!gClosedFdTable) {
|
||||||
LOGE("gClosedFdTable is null when reopening files");
|
LOGE("gClosedFdTable is null when reopening files");
|
||||||
return;
|
return;
|
||||||
|
|
@ -36,6 +36,22 @@ void reopenFilesAfterForkNative(JNIEnv*, jclass) {
|
||||||
gClosedFdTable = nullptr;
|
gClosedFdTable = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
jlong suspendAllThreads(JNIEnv *, jclass) {
|
||||||
|
if (!suspendAll) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
ScopedSuspendAll *suspendAllObj = (ScopedSuspendAll *) malloc(sizeof(ScopedSuspendAll));
|
||||||
|
suspendAll(suspendAllObj, "edxp_stop_gc", false);
|
||||||
|
return reinterpret_cast<jlong>(suspendAllObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
void resumeAllThreads(JNIEnv *, jclass, jlong obj) {
|
||||||
|
if (!resumeAll) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
resumeAll(reinterpret_cast<ScopedSuspendAll *>(obj));
|
||||||
|
}
|
||||||
|
|
||||||
static JNINativeMethod hookMethods[] = {
|
static JNINativeMethod hookMethods[] = {
|
||||||
{
|
{
|
||||||
"init",
|
"init",
|
||||||
|
|
@ -58,16 +74,22 @@ static JNINativeMethod hookMethods[] = {
|
||||||
(void *) Java_lab_galaxy_yahfa_HookMain_ensureMethodCached
|
(void *) Java_lab_galaxy_yahfa_HookMain_ensureMethodCached
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"getInstallerPkgName", "()Ljava/lang/String;", (void *)get_installer_pkg_name
|
"getInstallerPkgName", "()Ljava/lang/String;", (void *) get_installer_pkg_name
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"closeFilesBeforeForkNative", "()V", (void *)closeFilesBeforeForkNative
|
"closeFilesBeforeForkNative", "()V", (void *) closeFilesBeforeForkNative
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"reopenFilesAfterForkNative", "()V", (void *)reopenFilesAfterForkNative
|
"reopenFilesAfterForkNative", "()V", (void *) reopenFilesAfterForkNative
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"deoptMethodNative", "(Ljava/lang/Object;)V", (void *)deoptimize_method
|
"deoptMethodNative", "(Ljava/lang/Object;)V", (void *) deoptimize_method
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"suspendAllThreads", "()J", (void *) suspendAllThreads
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resumeAllThreads", "(J)V", (void *) resumeAllThreads
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -106,7 +128,7 @@ void loadDexAndInit(JNIEnv *env, const char *dexPath) {
|
||||||
jclass entry_class = findClassFromLoader(env, myClassLoader, ENTRY_CLASS_NAME);
|
jclass entry_class = findClassFromLoader(env, myClassLoader, ENTRY_CLASS_NAME);
|
||||||
if (NULL != entry_class) {
|
if (NULL != entry_class) {
|
||||||
LOGD("HookEntry Class %p", entry_class);
|
LOGD("HookEntry Class %p", entry_class);
|
||||||
env->RegisterNatives(entry_class, hookMethods, 8);
|
env->RegisterNatives(entry_class, hookMethods, 10);
|
||||||
isInited = true;
|
isInited = true;
|
||||||
LOGD("RegisterNatives succeed for HookEntry.");
|
LOGD("RegisterNatives succeed for HookEntry.");
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -212,6 +212,19 @@ void hookRuntime(int api_level, void *artHandle, void (*hookFun)(void *, void *,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void (*suspendAll)(ScopedSuspendAll*, const char*, bool) = nullptr;
|
||||||
|
void (*resumeAll)(ScopedSuspendAll*) = nullptr;
|
||||||
|
|
||||||
|
void getSuspendSyms(int api_level, void *artHandle, void (*hookFun)(void *, void *, void **)) {
|
||||||
|
if (api_level < ANDROID_N) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
suspendAll = reinterpret_cast<void (*)(ScopedSuspendAll*,const char*, bool)>(dlsym(artHandle,
|
||||||
|
"_ZN3art16ScopedSuspendAllC2EPKcb"));
|
||||||
|
resumeAll = reinterpret_cast<void (*)(ScopedSuspendAll*)>(dlsym(artHandle,
|
||||||
|
"_ZN3art16ScopedSuspendAllD2Ev"));
|
||||||
|
}
|
||||||
|
|
||||||
void install_inline_hooks() {
|
void install_inline_hooks() {
|
||||||
if (inlineHooksInstalled) {
|
if (inlineHooksInstalled) {
|
||||||
LOGI("inline hooks installed, skip");
|
LOGI("inline hooks installed, skip");
|
||||||
|
|
@ -243,6 +256,7 @@ void install_inline_hooks() {
|
||||||
}
|
}
|
||||||
hookRuntime(api_level, artHandle, hookFun);
|
hookRuntime(api_level, artHandle, hookFun);
|
||||||
hookInstrumentation(api_level, artHandle, hookFun);
|
hookInstrumentation(api_level, artHandle, hookFun);
|
||||||
|
getSuspendSyms(api_level, artHandle, hookFun);
|
||||||
hookIsInSamePackage(api_level, artHandle, hookFun);
|
hookIsInSamePackage(api_level, artHandle, hookFun);
|
||||||
if (disableHiddenAPIPolicyImpl(api_level, artHandle, hookFun)) {
|
if (disableHiddenAPIPolicyImpl(api_level, artHandle, hookFun)) {
|
||||||
LOGI("disableHiddenAPIPolicyImpl done.");
|
LOGI("disableHiddenAPIPolicyImpl done.");
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,13 @@ static constexpr const char *kLibWhalePath = "/system/lib/libwhale.so";
|
||||||
static ret (*old_##func)(__VA_ARGS__); \
|
static ret (*old_##func)(__VA_ARGS__); \
|
||||||
static ret new_##func(__VA_ARGS__)
|
static ret new_##func(__VA_ARGS__)
|
||||||
|
|
||||||
|
class ScopedSuspendAll {
|
||||||
|
};
|
||||||
|
|
||||||
|
extern void (*suspendAll)(ScopedSuspendAll *, const char *, bool);
|
||||||
|
|
||||||
|
extern void (*resumeAll)(ScopedSuspendAll *);
|
||||||
|
|
||||||
void install_inline_hooks();
|
void install_inline_hooks();
|
||||||
|
|
||||||
void deoptimize_method(JNIEnv *env, jclass clazz, jobject method);
|
void deoptimize_method(JNIEnv *env, jclass clazz, jobject method);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue