Black/White mode: postpone initZygote callbacks
in case some modules hook methods in zygote, which would be propagated into blacklisted processes
This commit is contained in:
parent
6dccef53d3
commit
661a675a09
|
|
@ -1,4 +1,4 @@
|
||||||
version: '0.4.4.5_alpha({build})'
|
version: '0.4.4.6_alpha({build})'
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
ANDROID_HOME: C:\android-sdk-windows
|
ANDROID_HOME: C:\android-sdk-windows
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
package com.elderdrivers.riru.edxp.config;
|
||||||
|
|
||||||
|
import com.elderdrivers.riru.edxp.hooker.XposedBlackListHooker;
|
||||||
|
|
||||||
|
public class BaseEdxpConfig implements EdxpConfig {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getInstallerBaseDir() {
|
||||||
|
return InstallerChooser.INSTALLER_DATA_BASE_DIR;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getBlackListModulePackageName() {
|
||||||
|
return XposedBlackListHooker.BLACK_LIST_PACKAGE_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isDynamicModulesMode() {
|
||||||
|
return ConfigManager.isDynamicModulesEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isResourcesHookEnabled() {
|
||||||
|
return ConfigManager.isResourcesHookEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isBlackWhiteListMode() {
|
||||||
|
return ConfigManager.isBlackWhiteListEnabled();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -106,6 +106,9 @@ public class BlackWhiteListProxy extends BaseProxy {
|
||||||
mRouter.installBootstrapHooks(isSystemServer);
|
mRouter.installBootstrapHooks(isSystemServer);
|
||||||
if (isDynamicModulesMode) {
|
if (isDynamicModulesMode) {
|
||||||
mRouter.loadModulesSafely(false);
|
mRouter.loadModulesSafely(false);
|
||||||
|
} else {
|
||||||
|
XposedBridge.callInitZygotes();
|
||||||
|
XposedBridge.clearInitZygotes(); // one-time use
|
||||||
}
|
}
|
||||||
mRouter.onForkFinish();
|
mRouter.onForkFinish();
|
||||||
}
|
}
|
||||||
|
|
@ -130,5 +133,6 @@ public class BlackWhiteListProxy extends BaseProxy {
|
||||||
private static void onBlackListed() {
|
private static void onBlackListed() {
|
||||||
XposedBridge.clearLoadedPackages();
|
XposedBridge.clearLoadedPackages();
|
||||||
XposedBridge.clearInitPackageResources();
|
XposedBridge.clearInitPackageResources();
|
||||||
|
XposedBridge.clearInitZygotes();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import org.gradle.internal.os.OperatingSystem
|
||||||
apply plugin: 'com.android.library'
|
apply plugin: 'com.android.library'
|
||||||
|
|
||||||
// Values set here will be overriden by AppVeyor, feel free to modify during development.
|
// Values set here will be overriden by AppVeyor, feel free to modify during development.
|
||||||
def buildVersionName = 'v0.4.4.5_alpha'
|
def buildVersionName = 'v0.4.4.6_alpha'
|
||||||
def buildVersionCode = 10000
|
def buildVersionCode = 10000
|
||||||
|
|
||||||
if (System.env.APPVEYOR_BUILD_VERSION != null) {
|
if (System.env.APPVEYOR_BUILD_VERSION != null) {
|
||||||
|
|
|
||||||
|
|
@ -1,28 +1,7 @@
|
||||||
package com.elderdrivers.riru.edxp.sandhook.config;
|
package com.elderdrivers.riru.edxp.sandhook.config;
|
||||||
|
|
||||||
import com.elderdrivers.riru.edxp.config.ConfigManager;
|
import com.elderdrivers.riru.edxp.config.BaseEdxpConfig;
|
||||||
import com.elderdrivers.riru.edxp.config.EdXpConfig;
|
|
||||||
import com.elderdrivers.riru.edxp.config.InstallerChooser;
|
|
||||||
import com.elderdrivers.riru.edxp.hooker.XposedBlackListHooker;
|
|
||||||
|
|
||||||
public class SandHookEdxpConfig implements EdXpConfig {
|
public class SandHookEdxpConfig extends BaseEdxpConfig {
|
||||||
@Override
|
|
||||||
public String getInstallerBaseDir() {
|
|
||||||
return InstallerChooser.INSTALLER_DATA_BASE_DIR;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getBlackListModulePackageName() {
|
|
||||||
return XposedBlackListHooker.BLACK_LIST_PACKAGE_NAME;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isDynamicModulesMode() {
|
|
||||||
return ConfigManager.isDynamicModulesEnabled();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isResourcesHookEnabled() {
|
|
||||||
return ConfigManager.isResourcesHookEnabled();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,28 +1,7 @@
|
||||||
package com.elderdrivers.riru.edxp.whale.config;
|
package com.elderdrivers.riru.edxp.whale.config;
|
||||||
|
|
||||||
import com.elderdrivers.riru.edxp.config.ConfigManager;
|
import com.elderdrivers.riru.edxp.config.BaseEdxpConfig;
|
||||||
import com.elderdrivers.riru.edxp.config.EdXpConfig;
|
|
||||||
import com.elderdrivers.riru.edxp.config.InstallerChooser;
|
|
||||||
import com.elderdrivers.riru.edxp.hooker.XposedBlackListHooker;
|
|
||||||
|
|
||||||
public class WhaleEdxpConfig implements EdXpConfig {
|
public class WhaleEdxpConfig extends BaseEdxpConfig {
|
||||||
@Override
|
|
||||||
public String getInstallerBaseDir() {
|
|
||||||
return InstallerChooser.INSTALLER_DATA_BASE_DIR;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getBlackListModulePackageName() {
|
|
||||||
return XposedBlackListHooker.BLACK_LIST_PACKAGE_NAME;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isDynamicModulesMode() {
|
|
||||||
return ConfigManager.isDynamicModulesEnabled();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isResourcesHookEnabled() {
|
|
||||||
return ConfigManager.isResourcesHookEnabled();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,28 +1,7 @@
|
||||||
package com.elderdrivers.riru.edxp.yahfa.config;
|
package com.elderdrivers.riru.edxp.yahfa.config;
|
||||||
|
|
||||||
import com.elderdrivers.riru.edxp.config.ConfigManager;
|
import com.elderdrivers.riru.edxp.config.BaseEdxpConfig;
|
||||||
import com.elderdrivers.riru.edxp.config.EdXpConfig;
|
|
||||||
import com.elderdrivers.riru.edxp.config.InstallerChooser;
|
|
||||||
import com.elderdrivers.riru.edxp.hooker.XposedBlackListHooker;
|
|
||||||
|
|
||||||
public class YahfaEdxpConfig implements EdXpConfig {
|
public class YahfaEdxpConfig extends BaseEdxpConfig {
|
||||||
@Override
|
|
||||||
public String getInstallerBaseDir() {
|
|
||||||
return InstallerChooser.INSTALLER_DATA_BASE_DIR;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getBlackListModulePackageName() {
|
|
||||||
return XposedBlackListHooker.BLACK_LIST_PACKAGE_NAME;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isDynamicModulesMode() {
|
|
||||||
return ConfigManager.isDynamicModulesEnabled();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isResourcesHookEnabled() {
|
|
||||||
return ConfigManager.isResourcesHookEnabled();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,10 +4,10 @@ import com.elderdrivers.riru.edxp.hook.HookProvider;
|
||||||
|
|
||||||
public class EdXpConfigGlobal {
|
public class EdXpConfigGlobal {
|
||||||
|
|
||||||
public static volatile EdXpConfig sConfig;
|
public static volatile EdxpConfig sConfig;
|
||||||
public static volatile HookProvider sHookProvider;
|
public static volatile HookProvider sHookProvider;
|
||||||
|
|
||||||
public static EdXpConfig getConfig() {
|
public static EdxpConfig getConfig() {
|
||||||
if (sConfig == null) {
|
if (sConfig == null) {
|
||||||
throw new IllegalArgumentException("sConfig should not be null.");
|
throw new IllegalArgumentException("sConfig should not be null.");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package com.elderdrivers.riru.edxp.config;
|
package com.elderdrivers.riru.edxp.config;
|
||||||
|
|
||||||
public interface EdXpConfig {
|
public interface EdxpConfig {
|
||||||
|
|
||||||
String getInstallerBaseDir();
|
String getInstallerBaseDir();
|
||||||
|
|
||||||
|
|
@ -10,4 +10,5 @@ public interface EdXpConfig {
|
||||||
|
|
||||||
boolean isResourcesHookEnabled();
|
boolean isResourcesHookEnabled();
|
||||||
|
|
||||||
|
boolean isBlackWhiteListMode();
|
||||||
}
|
}
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
package de.robv.android.xposed;
|
package de.robv.android.xposed;
|
||||||
|
|
||||||
|
import de.robv.android.xposed.callbacks.XC_InitZygote;
|
||||||
|
import de.robv.android.xposed.callbacks.XCallback;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hook the initialization of Zygote process(es), from which all the apps are forked.
|
* Hook the initialization of Zygote process(es), from which all the apps are forked.
|
||||||
*
|
*
|
||||||
|
|
@ -20,9 +23,17 @@ public interface IXposedHookZygoteInit extends IXposedMod {
|
||||||
void initZygote(StartupParam startupParam) throws Throwable;
|
void initZygote(StartupParam startupParam) throws Throwable;
|
||||||
|
|
||||||
/** Data holder for {@link #initZygote}. */
|
/** Data holder for {@link #initZygote}. */
|
||||||
final class StartupParam {
|
final class StartupParam extends XCallback.Param {
|
||||||
/*package*/ StartupParam() {}
|
/*package*/ StartupParam() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param callbacks
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public StartupParam(XposedBridge.CopyOnWriteSortedSet<? extends XCallback> callbacks) {
|
||||||
|
super(callbacks);
|
||||||
|
}
|
||||||
|
|
||||||
/** The path to the module's APK. */
|
/** The path to the module's APK. */
|
||||||
public String modulePath;
|
public String modulePath;
|
||||||
|
|
||||||
|
|
@ -32,4 +43,24 @@ public interface IXposedHookZygoteInit extends IXposedMod {
|
||||||
*/
|
*/
|
||||||
public boolean startsSystemServer;
|
public boolean startsSystemServer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
final class Wrapper extends XC_InitZygote {
|
||||||
|
private final IXposedHookZygoteInit instance;
|
||||||
|
private final StartupParam startupParam;
|
||||||
|
|
||||||
|
public Wrapper(IXposedHookZygoteInit instance, StartupParam startupParam) {
|
||||||
|
this.instance = instance;
|
||||||
|
this.startupParam = startupParam;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initZygote(StartupParam startupParam) throws Throwable {
|
||||||
|
// NOTE: parameter startupParam not used
|
||||||
|
// cause startupParam info is generated and saved along with instance here
|
||||||
|
instance.initZygote(this.startupParam);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,9 @@ import java.util.Set;
|
||||||
import dalvik.system.InMemoryDexClassLoader;
|
import dalvik.system.InMemoryDexClassLoader;
|
||||||
import de.robv.android.xposed.XC_MethodHook.MethodHookParam;
|
import de.robv.android.xposed.XC_MethodHook.MethodHookParam;
|
||||||
import de.robv.android.xposed.callbacks.XC_InitPackageResources;
|
import de.robv.android.xposed.callbacks.XC_InitPackageResources;
|
||||||
|
import de.robv.android.xposed.callbacks.XC_InitZygote;
|
||||||
import de.robv.android.xposed.callbacks.XC_LoadPackage;
|
import de.robv.android.xposed.callbacks.XC_LoadPackage;
|
||||||
|
import de.robv.android.xposed.callbacks.XCallback;
|
||||||
import external.com.android.dx.DexMaker;
|
import external.com.android.dx.DexMaker;
|
||||||
import external.com.android.dx.TypeId;
|
import external.com.android.dx.TypeId;
|
||||||
|
|
||||||
|
|
@ -67,6 +69,7 @@ public final class XposedBridge {
|
||||||
public static final Map<Member, CopyOnWriteSortedSet<XC_MethodHook>> sHookedMethodCallbacks = new HashMap<>();
|
public static final Map<Member, CopyOnWriteSortedSet<XC_MethodHook>> sHookedMethodCallbacks = new HashMap<>();
|
||||||
public static final CopyOnWriteSortedSet<XC_LoadPackage> sLoadedPackageCallbacks = new CopyOnWriteSortedSet<>();
|
public static final CopyOnWriteSortedSet<XC_LoadPackage> sLoadedPackageCallbacks = new CopyOnWriteSortedSet<>();
|
||||||
/*package*/ static final CopyOnWriteSortedSet<XC_InitPackageResources> sInitPackageResourcesCallbacks = new CopyOnWriteSortedSet<>();
|
/*package*/ static final CopyOnWriteSortedSet<XC_InitPackageResources> sInitPackageResourcesCallbacks = new CopyOnWriteSortedSet<>();
|
||||||
|
/*package*/ static final CopyOnWriteSortedSet<XC_InitZygote> sInitZygoteCallbacks = new CopyOnWriteSortedSet<>();
|
||||||
|
|
||||||
private XposedBridge() {}
|
private XposedBridge() {}
|
||||||
|
|
||||||
|
|
@ -427,6 +430,22 @@ public final class XposedBridge {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void hookInitZygote(XC_InitZygote callback) {
|
||||||
|
synchronized (sInitZygoteCallbacks) {
|
||||||
|
sInitZygoteCallbacks.add(callback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void clearInitZygotes() {
|
||||||
|
synchronized (sInitZygoteCallbacks) {
|
||||||
|
sInitZygoteCallbacks.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void callInitZygotes() {
|
||||||
|
XCallback.callAll(new IXposedHookZygoteInit.StartupParam(sInitZygoteCallbacks));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Intercept every call to the specified method and call a handler function instead.
|
* Intercept every call to the specified method and call a handler function instead.
|
||||||
* @param method The method to intercept
|
* @param method The method to intercept
|
||||||
|
|
|
||||||
|
|
@ -414,8 +414,18 @@ public final class XposedInit {
|
||||||
IXposedHookZygoteInit.StartupParam param = new IXposedHookZygoteInit.StartupParam();
|
IXposedHookZygoteInit.StartupParam param = new IXposedHookZygoteInit.StartupParam();
|
||||||
param.modulePath = apk;
|
param.modulePath = apk;
|
||||||
param.startsSystemServer = startsSystemServer;
|
param.startsSystemServer = startsSystemServer;
|
||||||
|
if (EdXpConfigGlobal.getConfig().isBlackWhiteListMode()
|
||||||
|
&& !EdXpConfigGlobal.getConfig().isDynamicModulesMode()) {
|
||||||
|
// postpone initZygote callbacks under black/white list mode
|
||||||
|
// if dynamic modules mode is on, callback directly cause we
|
||||||
|
// are already in app process here
|
||||||
|
XposedBridge.hookInitZygote(new IXposedHookZygoteInit.Wrapper(
|
||||||
|
(IXposedHookZygoteInit) moduleInstance, param));
|
||||||
|
} else {
|
||||||
|
// FIXME under dynamic modules mode, initZygote is called twice
|
||||||
((IXposedHookZygoteInit) moduleInstance).initZygote(param);
|
((IXposedHookZygoteInit) moduleInstance).initZygote(param);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (moduleInstance instanceof IXposedHookLoadPackage)
|
if (moduleInstance instanceof IXposedHookLoadPackage)
|
||||||
XposedBridge.hookLoadPackage(new IXposedHookLoadPackage.Wrapper((IXposedHookLoadPackage) moduleInstance));
|
XposedBridge.hookLoadPackage(new IXposedHookLoadPackage.Wrapper((IXposedHookLoadPackage) moduleInstance));
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
package de.robv.android.xposed.callbacks;
|
||||||
|
|
||||||
|
import de.robv.android.xposed.IXposedHookZygoteInit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is only used for internal purposes, except for the {@link StartupParam}
|
||||||
|
* subclass.
|
||||||
|
*/
|
||||||
|
public abstract class XC_InitZygote extends XCallback implements IXposedHookZygoteInit {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new callback with default priority.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
public XC_InitZygote() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new callback with a specific priority.
|
||||||
|
*
|
||||||
|
* @param priority See {@link XCallback#priority}.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public XC_InitZygote(int priority) {
|
||||||
|
super(priority);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void call(Param param) throws Throwable {
|
||||||
|
if (param instanceof StartupParam)
|
||||||
|
initZygote((StartupParam) param);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue