This commit is contained in:
Shauli Bracha 2019-02-28 18:49:05 +02:00
commit 57fd982979
14 changed files with 235 additions and 56 deletions

View File

@ -34,36 +34,32 @@ public class Main implements KeepAll {
int[][] rlimits, int mountExternal, String seInfo,
String niceName, int[] fdsToClose, int[] fdsToIgnore,
boolean startChildZygote, String instructionSet,
String appDataDir, boolean isBlackWhiteListMode,
boolean isDynamicModulesMode) {
String appDataDir) {
if (BuildConfig.DEBUG) {
forkAndSpecializePramsStr = String.format(
"Zygote#forkAndSpecialize(%d, %d, %s, %d, %s, %d, %s, %s, %s, %s, %s, %s, %s)",
uid, gid, Arrays.toString(gids), debugFlags, Arrays.toString(rlimits),
mountExternal, seInfo, niceName, Arrays.toString(fdsToClose),
Arrays.toString(fdsToIgnore), startChildZygote, instructionSet, appDataDir,
isDynamicModulesMode);
Arrays.toString(fdsToIgnore), startChildZygote, instructionSet, appDataDir);
}
if (isBlackWhiteListMode) {
if (isBlackWhiteListEnabled()) {
BlackWhiteListProxy.forkAndSpecializePre(uid, gid, gids, debugFlags, rlimits,
mountExternal, seInfo, niceName, fdsToClose, fdsToIgnore, startChildZygote,
instructionSet, appDataDir, isDynamicModulesMode);
instructionSet, appDataDir);
} else {
NormalProxy.forkAndSpecializePre(uid, gid, gids, debugFlags, rlimits, mountExternal,
seInfo, niceName, fdsToClose, fdsToIgnore, startChildZygote, instructionSet,
appDataDir, isDynamicModulesMode);
appDataDir);
}
}
public static void forkAndSpecializePost(int pid, String appDataDir,
boolean isBlackWhiteListMode,
boolean isDynamicModulesMode) {
public static void forkAndSpecializePost(int pid, String appDataDir) {
if (pid == 0) {
Utils.logD(forkAndSpecializePramsStr + " = " + Process.myPid());
if (isBlackWhiteListMode) {
BlackWhiteListProxy.forkAndSpecializePost(pid, appDataDir, isDynamicModulesMode);
if (isBlackWhiteListEnabled()) {
BlackWhiteListProxy.forkAndSpecializePost(pid, appDataDir);
} else {
NormalProxy.forkAndSpecializePost(pid, appDataDir, isDynamicModulesMode);
NormalProxy.forkAndSpecializePost(pid, appDataDir);
}
} else {
// in zygote process, res is child zygote pid
@ -72,30 +68,28 @@ public class Main implements KeepAll {
}
public static void forkSystemServerPre(int uid, int gid, int[] gids, int debugFlags, int[][] rlimits,
long permittedCapabilities, long effectiveCapabilities,
boolean isBlackWhiteListMode, boolean isDynamicModulesMode) {
long permittedCapabilities, long effectiveCapabilities) {
if (BuildConfig.DEBUG) {
forkSystemServerPramsStr = String.format("Zygote#forkSystemServer(%d, %d, %s, %d, %s, %d, %d)",
uid, gid, Arrays.toString(gids), debugFlags, Arrays.toString(rlimits),
permittedCapabilities, effectiveCapabilities);
}
if (isBlackWhiteListMode) {
if (isBlackWhiteListEnabled()) {
BlackWhiteListProxy.forkSystemServerPre(uid, gid, gids, debugFlags, rlimits,
permittedCapabilities, effectiveCapabilities, isDynamicModulesMode);
permittedCapabilities, effectiveCapabilities);
} else {
NormalProxy.forkSystemServerPre(uid, gid, gids, debugFlags, rlimits,
permittedCapabilities, effectiveCapabilities, isDynamicModulesMode);
permittedCapabilities, effectiveCapabilities);
}
}
public static void forkSystemServerPost(int pid, boolean isBlackWhiteListMode,
boolean isDynamicModulesMode) {
public static void forkSystemServerPost(int pid) {
if (pid == 0) {
Utils.logD(forkSystemServerPramsStr + " = " + Process.myPid());
if (isBlackWhiteListMode) {
BlackWhiteListProxy.forkSystemServerPost(pid, isDynamicModulesMode);
if (isBlackWhiteListEnabled()) {
BlackWhiteListProxy.forkSystemServerPost(pid);
} else {
NormalProxy.forkSystemServerPost(pid, isDynamicModulesMode);
NormalProxy.forkSystemServerPost(pid);
}
} else {
// in zygote process, res is child zygote pid
@ -118,6 +112,10 @@ public class Main implements KeepAll {
public static native String getInstallerPkgName();
public static native boolean isBlackWhiteListEnabled();
public static native boolean isDynamicModulesEnabled();
// prevent from fatal error caused by holding not whitelisted file descriptors when forking zygote
// https://github.com/rovo89/Xposed/commit/b3ba245ad04cd485699fb1d2ebde7117e58214ff
public static native void closeFilesBeforeForkNative();
@ -125,4 +123,8 @@ public class Main implements KeepAll {
public static native void reopenFilesAfterForkNative();
public static native void deoptMethodNative(Object object);
public static native long suspendAllThreads();
public static native void resumeAllThreads(long obj);
}

View File

@ -1,5 +1,6 @@
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.util.Utils;
@ -111,8 +112,13 @@ public class HookMain {
if (backup != null) {
HookMethodResolver.resolveMethod(hook, backup);
}
if (!backupAndHookNative(target, hook, backup)) {
throw new RuntimeException("Failed to hook " + target + " with " + hook);
long obj = Main.suspendAllThreads();
try {
if (!backupAndHookNative(target, hook, backup)) {
throw new RuntimeException("Failed to hook " + target + " with " + hook);
}
} finally {
Main.resumeAllThreads(obj);
}
}

View File

@ -2,15 +2,19 @@ package com.elderdrivers.riru.xposed.entry;
import android.text.TextUtils;
import com.elderdrivers.riru.xposed.config.InstallerChooser;
import com.elderdrivers.riru.xposed.Main;
import com.elderdrivers.riru.xposed.core.HookMain;
import com.elderdrivers.riru.xposed.entry.bootstrap.AppBootstrapHookInfo;
import com.elderdrivers.riru.xposed.entry.bootstrap.SysBootstrapHookInfo;
import com.elderdrivers.riru.xposed.entry.bootstrap.SysInnerHookInfo;
import com.elderdrivers.riru.xposed.entry.hooker.SystemMainHooker;
import com.elderdrivers.riru.xposed.util.InlinedMethodCallers;
import com.elderdrivers.riru.xposed.util.Utils;
import java.util.Arrays;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.XposedInit;
public class Router {

View File

@ -4,6 +4,7 @@ import android.app.ActivityThread;
import com.elderdrivers.riru.common.KeepMembers;
import com.elderdrivers.riru.xposed.entry.Router;
import com.elderdrivers.riru.xposed.util.PrebuiltMethodsDeopter;
import de.robv.android.xposed.XposedBridge;
@ -30,6 +31,8 @@ public class SystemMainHooker implements KeepMembers {
try {
// get system_server classLoader
systemServerCL = Thread.currentThread().getContextClassLoader();
// deopt methods in SYSTEMSERVERCLASSPATH
PrebuiltMethodsDeopter.deoptSystemServerMethods(systemServerCL);
Router.startSystemServerHook();
} catch (Throwable t) {
logE("error when hooking systemMain", t);

View File

@ -3,6 +3,7 @@ package com.elderdrivers.riru.xposed.proxy.yahfa;
import com.elderdrivers.riru.xposed.Main;
import com.elderdrivers.riru.xposed.config.ConfigManager;
import com.elderdrivers.riru.xposed.entry.Router;
import com.elderdrivers.riru.xposed.util.PrebuiltMethodsDeopter;
import static com.elderdrivers.riru.xposed.util.FileUtils.getDataPathPrefix;
@ -12,16 +13,22 @@ public class BlackWhiteListProxy {
int[][] rlimits, int mountExternal, String seInfo,
String niceName, int[] fdsToClose, int[] fdsToIgnore,
boolean startChildZygote, String instructionSet,
String appDataDir, boolean isDynamicModulesMode) {
String appDataDir) {
// always enter here, make sure secondary zygote's modules is loaded only once
// when isDynamicModulesMode is not on
final boolean isDynamicModulesMode = Main.isDynamicModulesEnabled();
ConfigManager.setDynamicModulesMode(isDynamicModulesMode);
PrebuiltMethodsDeopter.deoptBootMethods(); // do it once for secondary zygote
if (!isDynamicModulesMode) {
Router.loadModulesSafely();
Main.closeFilesBeforeForkNative();
}
}
public static void forkAndSpecializePost(int pid, String appDataDir,
boolean isDynamicModulesMode) {
public static void forkAndSpecializePost(int pid, String appDataDir) {
// when this process is in white list or not in black list
// installBootstrapHooks -> loadModules if needed
final boolean isDynamicModulesMode = Main.isDynamicModulesEnabled();
if (!isDynamicModulesMode) {
Main.reopenFilesAfterForkNative();
}
@ -34,16 +41,25 @@ public class BlackWhiteListProxy {
public static void forkSystemServerPre(int uid, int gid, int[] gids, int debugFlags,
int[][] rlimits, long permittedCapabilities,
long effectiveCapabilities,
boolean isDynamicModulesMode) {
long effectiveCapabilities) {
// we always enter here whether black/white list is on or not
final boolean isDynamicModulesMode = Main.isDynamicModulesEnabled();
ConfigManager.setDynamicModulesMode(isDynamicModulesMode);
PrebuiltMethodsDeopter.deoptBootMethods(); // do it once for main zygote
// we never install bootstrap hooks here in black/white list mode
// because installed hooks would be propagated to all child processes of main zygote
// hence we cannot install hooks for processes like com.android.phone process who are
// not from forkAndSpecialize as a side effect
if (!isDynamicModulesMode) {
Router.loadModulesSafely();
Main.closeFilesBeforeForkNative();
}
}
public static void forkSystemServerPost(int pid, boolean isDynamicModulesMode) {
public static void forkSystemServerPost(int pid) {
// should only here when system_server is in white list or not in black list
// installBootstrapHooks -> loadModules if needed
final boolean isDynamicModulesMode = Main.isDynamicModulesEnabled();
if (!isDynamicModulesMode) {
Main.reopenFilesAfterForkNative();
}

View File

@ -4,6 +4,7 @@ import com.elderdrivers.riru.xposed.Main;
import com.elderdrivers.riru.xposed.config.ConfigManager;
import com.elderdrivers.riru.xposed.dexmaker.DynamicBridge;
import com.elderdrivers.riru.xposed.entry.Router;
import com.elderdrivers.riru.xposed.util.PrebuiltMethodsDeopter;
import static com.elderdrivers.riru.xposed.util.FileUtils.getDataPathPrefix;
@ -13,9 +14,11 @@ public class NormalProxy {
int[][] rlimits, int mountExternal, String seInfo,
String niceName, int[] fdsToClose, int[] fdsToIgnore,
boolean startChildZygote, String instructionSet,
String appDataDir, boolean isDynamicModulesMode) {
String appDataDir) {
final boolean isDynamicModulesMode = Main.isDynamicModulesEnabled();
Main.appDataDir = appDataDir;
ConfigManager.setDynamicModulesMode(isDynamicModulesMode);
PrebuiltMethodsDeopter.deoptBootMethods(); // do it once for secondary zygote
Router.prepare(false);
// install bootstrap hooks for secondary zygote
Router.installBootstrapHooks(false);
@ -24,7 +27,7 @@ public class NormalProxy {
Main.closeFilesBeforeForkNative();
}
public static void forkAndSpecializePost(int pid, String appDataDir, boolean isDynamicModulesMode) {
public static void forkAndSpecializePost(int pid, String appDataDir) {
// TODO consider processes without forkAndSpecializePost called
Main.reopenFilesAfterForkNative();
Router.onEnterChildProcess();
@ -34,11 +37,12 @@ public class NormalProxy {
}
public static void forkSystemServerPre(int uid, int gid, int[] gids, int debugFlags, int[][] rlimits,
long permittedCapabilities, long effectiveCapabilities,
boolean isDynamicModulesMode) {
long permittedCapabilities, long effectiveCapabilities) {
final boolean isDynamicModulesMode = Main.isDynamicModulesEnabled();
Main.appDataDir = getDataPathPrefix() + "android";
ConfigManager.setDynamicModulesMode(isDynamicModulesMode);
Router.prepare(true);
PrebuiltMethodsDeopter.deoptBootMethods(); // do it once for main zygote
// install bootstrap hooks for main zygote as early as possible
// in case we miss some processes not forked via forkAndSpecialize
// for instance com.android.phone
@ -50,7 +54,7 @@ public class NormalProxy {
Main.closeFilesBeforeForkNative();
}
public static void forkSystemServerPost(int pid, boolean isDynamicModulesMode) {
public static void forkSystemServerPost(int pid) {
// in system_server process
Main.reopenFilesAfterForkNative();
Router.onEnterChildProcess();

View File

@ -0,0 +1,49 @@
package com.elderdrivers.riru.xposed.util;
import java.util.HashMap;
/**
* Providing a whitelist of methods which are the callers of the target methods we want to hook.
* Because the target methods are inlined into the callers, we deoptimize the callers to
* run in intercept mode to make target methods hookable.
* <p>
* Only for methods which are included in pre-compiled framework codes.
* TODO recompile system apps and priv-apps since their original dex files are available
*/
public class InlinedMethodCallers {
public static final String KEY_BOOT_IMAGE = "boot_image";
public static final String KEY_SYSTEM_SERVER = "system_server";
/**
* Key should be {@link #KEY_BOOT_IMAGE}, {@link #KEY_SYSTEM_SERVER}, or a package name
* of system apps or priv-apps i.e. com.android.systemui
*/
private static final HashMap<String, String[][]> CALLERS = new HashMap<>();
/**
* format for each row: {className, methodName, methodSig}
*/
private static final String[][] BOOT_IMAGE = {
// callers of Application#attach(Context)
{"android.app.Instrumentation", "newApplication", "(Ljava/lang/ClassLoader;Ljava/lang/String;Landroid/content/Context;)Landroid/app/Application;"}
};
private static final String[][] SYSTEM_SERVER = {};
private static final String[][] SYSTEM_UI = {};
static {
CALLERS.put(KEY_BOOT_IMAGE, BOOT_IMAGE);
CALLERS.put(KEY_SYSTEM_SERVER, SYSTEM_SERVER);
CALLERS.put("com.android.systemui", SYSTEM_UI);
}
public static HashMap<String, String[][]> getAll() {
return CALLERS;
}
public static String[][] get(String where) {
return CALLERS.get(where);
}
}

View File

@ -0,0 +1,39 @@
package com.elderdrivers.riru.xposed.util;
import com.elderdrivers.riru.xposed.Main;
import java.util.Arrays;
import de.robv.android.xposed.XposedHelpers;
import static com.elderdrivers.riru.xposed.util.InlinedMethodCallers.KEY_BOOT_IMAGE;
import static com.elderdrivers.riru.xposed.util.InlinedMethodCallers.KEY_SYSTEM_SERVER;
public class PrebuiltMethodsDeopter {
public static void deoptMethods(String where, ClassLoader cl) {
String[][] callers = InlinedMethodCallers.get(where);
if (callers == null) {
return;
}
for (String[] caller : callers) {
try {
Object method = Main.findMethodNative(
XposedHelpers.findClass(caller[0], cl), caller[1], caller[2]);
if (method != null) {
Main.deoptMethodNative(method);
}
} catch (Throwable throwable) {
Utils.logE("error when deopting method: " + Arrays.toString(caller), throwable);
}
}
}
public static void deoptBootMethods() {
deoptMethods(KEY_BOOT_IMAGE, null);
}
public static void deoptSystemServerMethods(ClassLoader sysCL) {
deoptMethods(KEY_SYSTEM_SERVER, sysCL);
}
}

View File

@ -2,6 +2,9 @@ package de.robv.android.xposed.callbacks;
import android.os.Bundle;
import com.elderdrivers.riru.xposed.entry.Router;
import com.elderdrivers.riru.xposed.util.PrebuiltMethodsDeopter;
import java.io.Serializable;
import de.robv.android.xposed.XposedBridge;
@ -98,6 +101,14 @@ public abstract class XCallback implements Comparable<XCallback> {
/** @hide */
public static void callAll(Param param) {
if (param instanceof XC_LoadPackage.LoadPackageParam) {
// deopt methods in system apps or priv-apps, this would be not necessary
// only if we found out how to recompile their apks
XC_LoadPackage.LoadPackageParam lpp = (XC_LoadPackage.LoadPackageParam) param;
PrebuiltMethodsDeopter.deoptMethods(lpp.packageName, lpp.classLoader);
}
if (param.callbacks == null)
throw new IllegalStateException("This object was not created for use with callAll");

View File

@ -50,9 +50,8 @@ void onNativeForkSystemServerPre(JNIEnv *env, jclass clazz, uid_t uid, gid_t gid
}
prepareJavaEnv(env);
// jump to java code
findAndCall(env, "forkSystemServerPre", "(II[II[[IJJZZ)V", uid, gid, gids, runtime_flags,
rlimits, permittedCapabilities, effectiveCapabilities,
is_black_white_list_mode, is_dynamic_modules_mode);
findAndCall(env, "forkSystemServerPre", "(II[II[[IJJ)V", uid, gid, gids, runtime_flags,
rlimits, permittedCapabilities, effectiveCapabilities);
}
@ -63,8 +62,7 @@ int onNativeForkSystemServerPost(JNIEnv *env, jclass clazz, jint res) {
}
prepareJavaEnv(env);
// only do work in child since findAndCall would print log
findAndCall(env, "forkSystemServerPost", "(IZZ)V", res,
is_black_white_list_enabled(), is_dynamic_modules_enabled());
findAndCall(env, "forkSystemServerPost", "(I)V", res);
} else {
// in zygote process, res is child zygote pid
// don't print log here, see https://github.com/RikkaApps/Riru/blob/77adfd6a4a6a81bfd20569c910bc4854f2f84f5e/riru-core/jni/main/jni_native_method.cpp#L55-L66
@ -94,11 +92,10 @@ void onNativeForkAndSpecializePre(JNIEnv *env, jclass clazz,
}
prepareJavaEnv(env);
findAndCall(env, "forkAndSpecializePre",
"(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;ZZ)V",
"(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;)V",
uid, gid, gids, runtime_flags, rlimits,
_mount_external, se_info, se_name, fdsToClose, fdsToIgnore,
is_child_zygote, instructionSet, appDataDir,
is_black_white_list_mode, is_dynamic_modules_mode);
is_child_zygote, instructionSet, appDataDir);
}
int onNativeForkAndSpecializePost(JNIEnv *env, jclass clazz, jint res) {
@ -107,8 +104,7 @@ int onNativeForkAndSpecializePost(JNIEnv *env, jclass clazz, jint res) {
return 0;
}
prepareJavaEnv(env);
findAndCall(env, "forkAndSpecializePost", "(ILjava/lang/String;ZZ)V", res, sAppDataDir,
is_black_white_list_enabled(), is_dynamic_modules_enabled());
findAndCall(env, "forkAndSpecializePost", "(ILjava/lang/String;)V", res, sAppDataDir);
} else {
// in zygote process, res is child zygote pid
// don't print log here, see https://github.com/RikkaApps/Riru/blob/77adfd6a4a6a81bfd20569c910bc4854f2f84f5e/riru-core/jni/main/jni_native_method.cpp#L55-L66

View File

@ -20,13 +20,13 @@ jobject gInjectDexClassLoader;
static bool isInited = false;
static FileDescriptorTable* gClosedFdTable = nullptr;
static FileDescriptorTable *gClosedFdTable = nullptr;
void closeFilesBeforeForkNative(JNIEnv*, jclass) {
void closeFilesBeforeForkNative(JNIEnv *, jclass) {
gClosedFdTable = FileDescriptorTable::Create();
}
void reopenFilesAfterForkNative(JNIEnv*, jclass) {
void reopenFilesAfterForkNative(JNIEnv *, jclass) {
if (!gClosedFdTable) {
LOGE("gClosedFdTable is null when reopening files");
return;
@ -36,6 +36,22 @@ void reopenFilesAfterForkNative(JNIEnv*, jclass) {
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[] = {
{
"init",
@ -58,16 +74,28 @@ static JNINativeMethod hookMethods[] = {
(void *) Java_lab_galaxy_yahfa_HookMain_ensureMethodCached
},
{
"getInstallerPkgName", "()Ljava/lang/String;", (void *)get_installer_pkg_name
"isBlackWhiteListEnabled", "()Z", (void *) is_black_white_list_enabled
},
{
"closeFilesBeforeForkNative", "()V", (void *)closeFilesBeforeForkNative
"isDynamicModulesEnabled", "()Z", (void *) is_dynamic_modules_enabled
},
{
"reopenFilesAfterForkNative", "()V", (void *)reopenFilesAfterForkNative
"getInstallerPkgName", "()Ljava/lang/String;", (void *) get_installer_pkg_name
},
{
"deoptMethodNative", "(Ljava/lang/Object;)V", (void *)deoptimize_method
"closeFilesBeforeForkNative", "()V", (void *) closeFilesBeforeForkNative
},
{
"reopenFilesAfterForkNative", "()V", (void *) reopenFilesAfterForkNative
},
{
"deoptMethodNative", "(Ljava/lang/Object;)V", (void *) deoptimize_method
},
{
"suspendAllThreads", "()J", (void *) suspendAllThreads
},
{
"resumeAllThreads", "(J)V", (void *) resumeAllThreads
}
};
@ -106,7 +134,7 @@ void loadDexAndInit(JNIEnv *env, const char *dexPath) {
jclass entry_class = findClassFromLoader(env, myClassLoader, ENTRY_CLASS_NAME);
if (NULL != entry_class) {
LOGD("HookEntry Class %p", entry_class);
env->RegisterNatives(entry_class, hookMethods, 8);
env->RegisterNatives(entry_class, hookMethods, 12);
isInited = true;
LOGD("RegisterNatives succeed for HookEntry.");
} else {

View File

@ -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() {
if (inlineHooksInstalled) {
LOGI("inline hooks installed, skip");
@ -243,6 +256,7 @@ void install_inline_hooks() {
}
hookRuntime(api_level, artHandle, hookFun);
hookInstrumentation(api_level, artHandle, hookFun);
getSuspendSyms(api_level, artHandle, hookFun);
hookIsInSamePackage(api_level, artHandle, hookFun);
if (disableHiddenAPIPolicyImpl(api_level, artHandle, hookFun)) {
LOGI("disableHiddenAPIPolicyImpl done.");

View File

@ -19,6 +19,13 @@ static constexpr const char *kLibWhalePath = "/system/lib/libwhale.so";
static ret (*old_##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 deoptimize_method(JNIEnv *env, jclass clazz, jobject method);

View File

@ -17,7 +17,7 @@ supolicy --live "allow system_server system_server process {execmem}"
supolicy --live "allow coredomain coredomain process {execmem}"
# read configs set in our app
supolicy --live "allow {zygote system_server} app_data_file * *"
supolicy --live "allow coredomain app_data_file * *"
supolicy --live "attradd {system_app platform_app} mlstrustedsubject"
# read module apk file in zygote