Fix crash caused by StrictMode in systemui process

This commit is contained in:
solohsu 2019-05-16 21:12:34 +08:00
parent c1c648a1f8
commit 975bfd20cc
15 changed files with 55 additions and 312 deletions

View File

@ -0,0 +1,21 @@
package com.elderdrivers.riru.edxp.hooker;
import android.os.StrictMode;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedHelpers;
public class SliceProviderFix {
public static final String SYSTEMUI_PACKAGE_NAME = "com.android.systemui";
public static void hook() {
XposedHelpers.findAndHookMethod(StrictMode.ThreadPolicy.Builder.class, "build", new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
XposedHelpers.callMethod(param.thisObject, "permitAll");
}
});
}
}

View File

@ -1,4 +1,4 @@
package com.elderdrivers.riru.edxp.yahfa.entry.hooker;
package com.elderdrivers.riru.edxp.hooker;
import android.annotation.TargetApi;
import android.app.Activity;

View File

@ -1,4 +1,4 @@
package com.elderdrivers.riru.edxp.yahfa.entry.hooker;
package com.elderdrivers.riru.edxp.hooker;
import com.elderdrivers.riru.edxp.util.Utils;

View File

@ -3,10 +3,10 @@ import org.gradle.internal.os.OperatingSystem
apply plugin: 'com.android.library'
version "v0.4.2.0_beta"
version "v0.4.2.1_beta"
ext {
versionCode = "4200"
versionCode = "4210"
module_name = "EdXposed"
jar_dest_dir = "${projectDir}/template_override/system/framework/"
is_windows = OperatingSystem.current().isWindows()

View File

@ -1,6 +1,6 @@
#!/system/bin/sh
EDXP_VERSION="0.4.2.0_beta (4200)"
EDXP_VERSION="0.4.2.1_beta (4210)"
ANDROID_SDK=`getprop ro.build.version.sdk`
BUILD_DESC=`getprop ro.build.description`
PRODUCT=`getprop ro.build.product`

View File

@ -8,6 +8,9 @@ import android.content.res.CompatibilityInfo;
import com.elderdrivers.riru.common.KeepMembers;
import com.elderdrivers.riru.edxp.Main;
import com.elderdrivers.riru.edxp.hooker.SliceProviderFix;
import com.elderdrivers.riru.edxp.hooker.XposedBlackListHooker;
import com.elderdrivers.riru.edxp.hooker.XposedInstallerHooker;
import com.elderdrivers.riru.edxp.sandhook.entry.Router;
import com.elderdrivers.riru.edxp.util.Utils;
import com.swift.sandhook.SandHook;
@ -26,7 +29,8 @@ import de.robv.android.xposed.XposedInit;
import de.robv.android.xposed.callbacks.XC_LoadPackage;
import static com.elderdrivers.riru.edxp.config.InstallerChooser.INSTALLER_PACKAGE_NAME;
import static com.elderdrivers.riru.edxp.sandhook.entry.hooker.XposedBlackListHooker.BLACK_LIST_PACKAGE_NAME;
import static com.elderdrivers.riru.edxp.hooker.SliceProviderFix.SYSTEMUI_PACKAGE_NAME;
import static com.elderdrivers.riru.edxp.hooker.XposedBlackListHooker.BLACK_LIST_PACKAGE_NAME;
import static com.elderdrivers.riru.edxp.util.ClassLoaderUtils.replaceParentClassLoader;
// normal process initialization (for new Activity, Service, BroadcastReceiver etc.)
@ -92,6 +96,9 @@ public class HandleBindAppHooker implements KeepMembers {
if (reportedPackageName.equals(BLACK_LIST_PACKAGE_NAME)) {
XposedBlackListHooker.hook(lpparam.classLoader);
}
if (reportedPackageName.equals(SYSTEMUI_PACKAGE_NAME)) {
SliceProviderFix.hook();
}
} catch (Throwable t) {
Router.logE("error when hooking bindApp", t);
} finally {

View File

@ -8,6 +8,7 @@ import android.content.res.CompatibilityInfo;
import android.util.Log;
import com.elderdrivers.riru.common.KeepMembers;
import com.elderdrivers.riru.edxp.hooker.XposedBlackListHooker;
import com.elderdrivers.riru.edxp.sandhook.entry.Router;
import com.swift.sandhook.SandHook;
import com.swift.sandhook.annotation.HookClass;

View File

@ -1,87 +0,0 @@
package com.elderdrivers.riru.edxp.sandhook.entry.hooker;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.content.ContextWrapper;
import android.os.Build;
import com.elderdrivers.riru.edxp.util.Utils;
import java.io.File;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XSharedPreferences;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;
import static com.elderdrivers.riru.edxp.config.InstallerChooser.INSTALLER_PACKAGE_NAME;
import static com.elderdrivers.riru.edxp.util.FileUtils.IS_USING_PROTECTED_STORAGE;
public class XposedBlackListHooker {
public static final String BLACK_LIST_PACKAGE_NAME = "com.flarejune.xposedblacklist";
private static final String BLACK_LIST_PREF_NAME = "list";
private static final String PREF_KEY_BLACK_LIST = "blackList";
public static final String PREF_FILE_PATH = (IS_USING_PROTECTED_STORAGE ? "/data/user_de/0/" : "/data/data")
+ BLACK_LIST_PACKAGE_NAME + "/shared_prefs/" + BLACK_LIST_PREF_NAME + ".xml";
private static final XSharedPreferences PREFERENCES = new XSharedPreferences(new File(PREF_FILE_PATH));
// always white list. empty string is to make sure blackList does not contain empty packageName
private static final List<String> WHITE_LIST = Arrays.asList(INSTALLER_PACKAGE_NAME, BLACK_LIST_PACKAGE_NAME, "");
static {
try {
PREFERENCES.makeWorldReadable();
} catch (Throwable throwable) {
Utils.logE("error making pref worldReadable", throwable);
}
}
public static boolean shouldDisableHooks(String packageName) {
return XposedBridge.disableHooks || getBlackList().contains(packageName);
}
public static Set<String> getBlackList() {
try {
PREFERENCES.reload();
Set<String> result = PREFERENCES.getStringSet(PREF_KEY_BLACK_LIST, new HashSet<String>());
if (result != null) result.removeAll(WHITE_LIST);
return result;
} catch (Throwable throwable) {
Utils.logE("error when reading black list", throwable);
return new HashSet<>();
}
}
public static void hook(ClassLoader classLoader) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
return;
}
try {
XposedHelpers.findAndHookMethod(ContextWrapper.class, "getSharedPreferences", String.class, int.class, new XC_MethodHook() {
@TargetApi(Build.VERSION_CODES.N)
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
try {
String prefName = (String) param.args[0];
if (!prefName.equals(BLACK_LIST_PREF_NAME)) {
return;
}
Activity activity = (Activity) param.thisObject;
Context context = activity.createDeviceProtectedStorageContext();
context.moveSharedPreferencesFrom(activity, prefName);
param.setResult(context.getSharedPreferences(prefName, (int) param.args[1]));
} catch (Throwable throwable) {
Utils.logE("error hooking Xposed BlackList", throwable);
}
}
});
} catch (Throwable throwable) {
Utils.logE("error hooking Xposed BlackList", throwable);
}
}
}

View File

@ -1,64 +0,0 @@
package com.elderdrivers.riru.edxp.sandhook.entry.hooker;
import com.elderdrivers.riru.edxp.util.Utils;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XC_MethodReplacement;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;
import static com.elderdrivers.riru.edxp.config.InstallerChooser.LEGACY_INSTALLER_PACKAGE_NAME;
public class XposedInstallerHooker {
public static void hookXposedInstaller(ClassLoader classLoader) {
try {
final String xposedAppClass = LEGACY_INSTALLER_PACKAGE_NAME + ".XposedApp";
final Class InstallZipUtil = XposedHelpers.findClass(LEGACY_INSTALLER_PACKAGE_NAME
+ ".util.InstallZipUtil", classLoader);
XposedHelpers.findAndHookMethod(xposedAppClass, classLoader, "getActiveXposedVersion",
XC_MethodReplacement.returnConstant(XposedBridge.getXposedVersion()));
XposedHelpers.findAndHookMethod(xposedAppClass, classLoader,
"reloadXposedProp", new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
Utils.logD("before reloadXposedProp...");
final String propFieldName = "mXposedProp";
final Object thisObject = param.thisObject;
if (XposedHelpers.getObjectField(thisObject, propFieldName) != null) {
param.setResult(null);
Utils.logD("reloadXposedProp already done, skip...");
return;
}
File file = new File("/system/framework/edconfig.jar");
FileInputStream is = null;
try {
is = new FileInputStream(file);
Object props = XposedHelpers.callStaticMethod(InstallZipUtil,
"parseXposedProp", is);
synchronized (thisObject) {
XposedHelpers.setObjectField(thisObject, propFieldName, props);
}
Utils.logD("reloadXposedProp done...");
param.setResult(null);
} catch (IOException e) {
Utils.logE("Could not read " + file.getPath(), e);
} finally {
if (is != null) {
try {
is.close();
} catch (IOException ignored) {
}
}
}
}
});
} catch (Throwable t) {
Utils.logE("Could not hook Xposed Installer", t);
}
}
}

View File

@ -7,8 +7,11 @@ import android.content.pm.ApplicationInfo;
import android.content.res.CompatibilityInfo;
import com.elderdrivers.riru.common.KeepMembers;
import com.elderdrivers.riru.edxp.util.Utils;
import com.elderdrivers.riru.edxp.Main;
import com.elderdrivers.riru.edxp.hooker.SliceProviderFix;
import com.elderdrivers.riru.edxp.hooker.XposedBlackListHooker;
import com.elderdrivers.riru.edxp.hooker.XposedInstallerHooker;
import com.elderdrivers.riru.edxp.util.Utils;
import com.elderdrivers.riru.edxp.whale.entry.Router;
import de.robv.android.xposed.XposedBridge;
@ -17,8 +20,9 @@ import de.robv.android.xposed.XposedInit;
import de.robv.android.xposed.callbacks.XC_LoadPackage;
import static com.elderdrivers.riru.edxp.config.InstallerChooser.INSTALLER_PACKAGE_NAME;
import static com.elderdrivers.riru.edxp.hooker.SliceProviderFix.SYSTEMUI_PACKAGE_NAME;
import static com.elderdrivers.riru.edxp.hooker.XposedBlackListHooker.BLACK_LIST_PACKAGE_NAME;
import static com.elderdrivers.riru.edxp.util.ClassLoaderUtils.replaceParentClassLoader;
import static com.elderdrivers.riru.edxp.whale.entry.hooker.XposedBlackListHooker.BLACK_LIST_PACKAGE_NAME;
// normal process initialization (for new Activity, Service, BroadcastReceiver etc.)
public class HandleBindAppHooker implements KeepMembers {
@ -77,6 +81,9 @@ public class HandleBindAppHooker implements KeepMembers {
if (reportedPackageName.equals(BLACK_LIST_PACKAGE_NAME)) {
XposedBlackListHooker.hook(lpparam.classLoader);
}
if (reportedPackageName.equals(SYSTEMUI_PACKAGE_NAME)) {
SliceProviderFix.hook();
}
} catch (Throwable t) {
Router.logE("error when hooking bindApp", t);
} finally {

View File

@ -8,6 +8,7 @@ import android.content.res.CompatibilityInfo;
import android.util.Log;
import com.elderdrivers.riru.common.KeepMembers;
import com.elderdrivers.riru.edxp.hooker.XposedBlackListHooker;
import com.elderdrivers.riru.edxp.whale.entry.Router;
import de.robv.android.xposed.XposedBridge;

View File

@ -1,87 +0,0 @@
package com.elderdrivers.riru.edxp.whale.entry.hooker;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.content.ContextWrapper;
import android.os.Build;
import com.elderdrivers.riru.edxp.util.Utils;
import java.io.File;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XSharedPreferences;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;
import static com.elderdrivers.riru.edxp.config.InstallerChooser.INSTALLER_PACKAGE_NAME;
import static com.elderdrivers.riru.edxp.util.FileUtils.IS_USING_PROTECTED_STORAGE;
public class XposedBlackListHooker {
public static final String BLACK_LIST_PACKAGE_NAME = "com.flarejune.xposedblacklist";
private static final String BLACK_LIST_PREF_NAME = "list";
private static final String PREF_KEY_BLACK_LIST = "blackList";
public static final String PREF_FILE_PATH = (IS_USING_PROTECTED_STORAGE ? "/data/user_de/0/" : "/data/data")
+ BLACK_LIST_PACKAGE_NAME + "/shared_prefs/" + BLACK_LIST_PREF_NAME + ".xml";
private static final XSharedPreferences PREFERENCES = new XSharedPreferences(new File(PREF_FILE_PATH));
// always white list. empty string is to make sure blackList does not contain empty packageName
private static final List<String> WHITE_LIST = Arrays.asList(INSTALLER_PACKAGE_NAME, BLACK_LIST_PACKAGE_NAME, "");
static {
try {
PREFERENCES.makeWorldReadable();
} catch (Throwable throwable) {
Utils.logE("error making pref worldReadable", throwable);
}
}
public static boolean shouldDisableHooks(String packageName) {
return XposedBridge.disableHooks || getBlackList().contains(packageName);
}
public static Set<String> getBlackList() {
try {
PREFERENCES.reload();
Set<String> result = PREFERENCES.getStringSet(PREF_KEY_BLACK_LIST, new HashSet<String>());
if (result != null) result.removeAll(WHITE_LIST);
return result;
} catch (Throwable throwable) {
Utils.logE("error when reading black list", throwable);
return new HashSet<>();
}
}
public static void hook(ClassLoader classLoader) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
return;
}
try {
XposedHelpers.findAndHookMethod(ContextWrapper.class, "getSharedPreferences", String.class, int.class, new XC_MethodHook() {
@TargetApi(Build.VERSION_CODES.N)
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
try {
String prefName = (String) param.args[0];
if (!prefName.equals(BLACK_LIST_PREF_NAME)) {
return;
}
Activity activity = (Activity) param.thisObject;
Context context = activity.createDeviceProtectedStorageContext();
context.moveSharedPreferencesFrom(activity, prefName);
param.setResult(context.getSharedPreferences(prefName, (int) param.args[1]));
} catch (Throwable throwable) {
Utils.logE("error hooking Xposed BlackList", throwable);
}
}
});
} catch (Throwable throwable) {
Utils.logE("error hooking Xposed BlackList", throwable);
}
}
}

View File

@ -1,64 +0,0 @@
package com.elderdrivers.riru.edxp.whale.entry.hooker;
import com.elderdrivers.riru.edxp.util.Utils;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XC_MethodReplacement;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;
import static com.elderdrivers.riru.edxp.config.InstallerChooser.LEGACY_INSTALLER_PACKAGE_NAME;
public class XposedInstallerHooker {
public static void hookXposedInstaller(ClassLoader classLoader) {
try {
final String xposedAppClass = LEGACY_INSTALLER_PACKAGE_NAME + ".XposedApp";
final Class InstallZipUtil = XposedHelpers.findClass(LEGACY_INSTALLER_PACKAGE_NAME
+ ".util.InstallZipUtil", classLoader);
XposedHelpers.findAndHookMethod(xposedAppClass, classLoader, "getActiveXposedVersion",
XC_MethodReplacement.returnConstant(XposedBridge.getXposedVersion()));
XposedHelpers.findAndHookMethod(xposedAppClass, classLoader,
"reloadXposedProp", new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
Utils.logD("before reloadXposedProp...");
final String propFieldName = "mXposedProp";
final Object thisObject = param.thisObject;
if (XposedHelpers.getObjectField(thisObject, propFieldName) != null) {
param.setResult(null);
Utils.logD("reloadXposedProp already done, skip...");
return;
}
File file = new File("/system/framework/edconfig.jar");
FileInputStream is = null;
try {
is = new FileInputStream(file);
Object props = XposedHelpers.callStaticMethod(InstallZipUtil,
"parseXposedProp", is);
synchronized (thisObject) {
XposedHelpers.setObjectField(thisObject, propFieldName, props);
}
Utils.logD("reloadXposedProp done...");
param.setResult(null);
} catch (IOException e) {
Utils.logE("Could not read " + file.getPath(), e);
} finally {
if (is != null) {
try {
is.close();
} catch (IOException ignored) {
}
}
}
}
});
} catch (Throwable t) {
Utils.logE("Could not hook Xposed Installer", t);
}
}
}

View File

@ -7,8 +7,11 @@ import android.content.pm.ApplicationInfo;
import android.content.res.CompatibilityInfo;
import com.elderdrivers.riru.common.KeepMembers;
import com.elderdrivers.riru.edxp.util.Utils;
import com.elderdrivers.riru.edxp.Main;
import com.elderdrivers.riru.edxp.hooker.SliceProviderFix;
import com.elderdrivers.riru.edxp.hooker.XposedBlackListHooker;
import com.elderdrivers.riru.edxp.hooker.XposedInstallerHooker;
import com.elderdrivers.riru.edxp.util.Utils;
import com.elderdrivers.riru.edxp.yahfa.entry.Router;
import de.robv.android.xposed.XposedBridge;
@ -17,8 +20,9 @@ import de.robv.android.xposed.XposedInit;
import de.robv.android.xposed.callbacks.XC_LoadPackage;
import static com.elderdrivers.riru.edxp.config.InstallerChooser.INSTALLER_PACKAGE_NAME;
import static com.elderdrivers.riru.edxp.hooker.SliceProviderFix.SYSTEMUI_PACKAGE_NAME;
import static com.elderdrivers.riru.edxp.hooker.XposedBlackListHooker.BLACK_LIST_PACKAGE_NAME;
import static com.elderdrivers.riru.edxp.util.ClassLoaderUtils.replaceParentClassLoader;
import static com.elderdrivers.riru.edxp.yahfa.entry.hooker.XposedBlackListHooker.BLACK_LIST_PACKAGE_NAME;
// normal process initialization (for new Activity, Service, BroadcastReceiver etc.)
public class HandleBindAppHooker implements KeepMembers {
@ -77,6 +81,9 @@ public class HandleBindAppHooker implements KeepMembers {
if (reportedPackageName.equals(BLACK_LIST_PACKAGE_NAME)) {
XposedBlackListHooker.hook(lpparam.classLoader);
}
if (reportedPackageName.equals(SYSTEMUI_PACKAGE_NAME)) {
SliceProviderFix.hook();
}
} catch (Throwable t) {
Router.logE("error when hooking bindApp", t);
} finally {

View File

@ -8,6 +8,7 @@ import android.content.res.CompatibilityInfo;
import android.util.Log;
import com.elderdrivers.riru.common.KeepMembers;
import com.elderdrivers.riru.edxp.hooker.XposedBlackListHooker;
import com.elderdrivers.riru.edxp.yahfa.entry.Router;
import de.robv.android.xposed.XposedBridge;