From d1867122d0a91de073c9fc1755a8bf8bb9e09f32 Mon Sep 17 00:00:00 2001 From: tehcneko <7764726+tehcneko@users.noreply.github.com> Date: Fri, 26 Feb 2021 23:45:19 +0800 Subject: [PATCH] [core] Enable optimize (#205) * [core] Load module with DelegateLastClassLoader * [core] Drop support for API26 * [core] Enable optimize * [core] Update proguard rules * [core] Enable obfuscation --- core/proguard-rules.pro | 22 +++++++-- .../de/robv/android/xposed/XposedInit.java | 49 +++++-------------- .../io/github/lsposed/lspd/core/Impl.java | 6 +-- .../io/github/lsposed/lspd/core/Main.java | 48 ++++++++---------- .../io/github/lsposed/lspd/core/Proxy.java | 4 +- .../lspd/nativebridge/ClassLinker.java | 3 -- .../lspd/nativebridge/ModuleLogger.java | 13 ++--- .../lspd/sandhook/core/SandHookImpl.java | 17 ++----- .../lsposed/lspd/service/BridgeService.java | 6 +-- .../lsposed/lspd/service/ConfigManager.java | 2 - .../lsposed/lspd/service/PackageReceiver.java | 4 +- .../lsposed/lspd/service/ServiceManager.java | 2 +- .../lsposed/lspd/yahfa/core/YahfaImpl.java | 9 ---- gradle.properties | 2 +- 14 files changed, 70 insertions(+), 117 deletions(-) diff --git a/core/proguard-rules.pro b/core/proguard-rules.pro index 867f7975..95342ee5 100644 --- a/core/proguard-rules.pro +++ b/core/proguard-rules.pro @@ -20,7 +20,23 @@ # hide the original source file name. #-renamesourcefileattribute SourceFile --dontobfuscate --dontoptimize -keep class de.robv.android.xposed.** {*;} --keep class android.** { *; } \ No newline at end of file +-keep class android.** { *; } +-keepclasseswithmembers class io.github.lsposed.lspd.core.Main { + public static void forkSystemServerPost(android.os.IBinder); + public static void forkAndSpecializePost(java.lang.String, java.lang.String, android.os.IBinder); + public static void main(java.lang.String[]); +} +-keepclasseswithmembers class io.github.lsposed.lspd.nativebridge.* { + native *; +} +-keepclasseswithmembers class io.github.lsposed.lspd.nativebridge.ClassLinker { + public static void onPostFixupStaticTrampolines(java.lang.Class); +} +-keepclasseswithmembers class io.github.lsposed.lspd.service.BridgeService { + public static boolean execTransact(int, long, long, int); + public static android.os.IBinder getApplicationServiceForSystemServer(android.os.IBinder, android.os.IBinder); +} +-keepclasseswithmembers class io.github.lsposed.lspd.service.ConfigManager { + public static void main(java.lang.String[]); +} \ No newline at end of file diff --git a/core/src/main/java/de/robv/android/xposed/XposedInit.java b/core/src/main/java/de/robv/android/xposed/XposedInit.java index a4ebb317..e51e1497 100644 --- a/core/src/main/java/de/robv/android/xposed/XposedInit.java +++ b/core/src/main/java/de/robv/android/xposed/XposedInit.java @@ -20,6 +20,7 @@ package de.robv.android.xposed; +import android.annotation.SuppressLint; import android.app.AndroidAppHelper; import android.content.pm.ApplicationInfo; import android.content.res.Resources; @@ -34,16 +35,12 @@ import android.util.Log; import com.android.internal.os.ZygoteInit; -import hidden.HiddenApiBridge; -import io.github.lsposed.lspd.config.LSPdConfigGlobal; - import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.lang.ref.WeakReference; -import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; @@ -51,13 +48,15 @@ import java.util.HashSet; import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; -import dalvik.system.PathClassLoader; -import io.github.lsposed.lspd.annotation.ApiSensitive; -import io.github.lsposed.lspd.annotation.Level; +import dalvik.system.DelegateLastClassLoader; 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.XCallback; +import hidden.HiddenApiBridge; +import io.github.lsposed.lspd.annotation.ApiSensitive; +import io.github.lsposed.lspd.annotation.Level; +import io.github.lsposed.lspd.config.LSPdConfigGlobal; import io.github.lsposed.lspd.nativebridge.NativeAPI; import static de.robv.android.xposed.XposedBridge.hookAllMethods; @@ -81,7 +80,6 @@ public final class XposedInit { public static boolean startsSystemServer = false; private static final String startClassName = ""; // ed: no support for tool process anymore - private static final String INSTANT_RUN_CLASS = "com.android.tools.fd.runtime.BootstrapApplication"; public static volatile boolean disableResources = false; private static final String[] XRESOURCES_CONFLICTING_PACKAGES = {"com.sygic.aura"}; @@ -195,7 +193,7 @@ public final class XposedInit { new XResources.XTypedArray((Resources) param.args[0]); int len = (int) param.args[1]; Method resizeMethod = XposedHelpers.findMethodBestMatch( - TypedArray.class, "resize", new Class[]{int.class}); + TypedArray.class, "resize", int.class); resizeMethod.setAccessible(true); resizeMethod.invoke(newResult, len); param.setResult(newResult); @@ -259,12 +257,6 @@ public final class XposedInit { return false; } synchronized (moduleLoadLock) { - ClassLoader topClassLoader = XposedBridge.BOOTCLASSLOADER; - ClassLoader parent; - while ((parent = topClassLoader.getParent()) != null) { - topClassLoader = parent; - } - // TODO: process name String[] moduleList = serviceClient.getModulesList(); ArraySet newLoadedApk = new ArraySet<>(); @@ -273,7 +265,7 @@ public final class XposedInit { newLoadedApk.add(apk); } else { loadedModules.add(apk); // temporarily add it for XSharedPreference - boolean loadSuccess = loadModule(apk, topClassLoader, callInitZygote); + boolean loadSuccess = loadModule(apk, callInitZygote); if (loadSuccess) { newLoadedApk.add(apk); } @@ -406,7 +398,8 @@ public final class XposedInit { * Load a module from an APK by calling the init(String) method for all classes defined * in assets/xposed_init. */ - private static boolean loadModule(String apk, ClassLoader topClassLoader, boolean callInitZygote) { + @SuppressLint("PrivateApi") + private static boolean loadModule(String apk, boolean callInitZygote) { Log.i(TAG, "Loading modules from " + apk); if (!new File(apk).exists()) { @@ -420,18 +413,11 @@ public final class XposedInit { nativePath.append(apk).append("!/lib/").append(i).append(File.pathSeparator); } // Log.d(TAG, "Allowed native path" + nativePath.toString()); - ClassLoader mcl = new PathClassLoader(apk, nativePath.toString(), topClassLoader); + ClassLoader initLoader = XposedInit.class.getClassLoader(); + ClassLoader mcl = new DelegateLastClassLoader(apk, nativePath.toString(), initLoader); try { - if (mcl.loadClass(INSTANT_RUN_CLASS) != null) { - Log.e(TAG, " Cannot load module, please disable \"Instant Run\" in Android Studio."); - return false; - } - } catch (ClassNotFoundException ignored) { - } - - try { - if (mcl.loadClass(XposedBridge.class.getName()) != null) { + if (mcl.loadClass(XposedBridge.class.getName()).getClassLoader() != initLoader) { Log.e(TAG, " Cannot load module:"); Log.e(TAG, " The Xposed API classes are compiled into the module's APK."); Log.e(TAG, " This may cause strange issues and must be fixed by the module developer."); @@ -441,15 +427,6 @@ public final class XposedInit { } catch (ClassNotFoundException ignored) { } - try { - Field parentField = ClassLoader.class.getDeclaredField("parent"); - parentField.setAccessible(true); - parentField.set(mcl, XposedInit.class.getClassLoader()); - } catch (NoSuchFieldException | IllegalAccessException e) { - Log.e(TAG, " Cannot load module:"); - Log.e(TAG, " Classloader cannot change parent."); - return false; - } boolean res = initModule(mcl, apk, callInitZygote); res = res && initNativeModule(mcl, apk); return res; diff --git a/core/src/main/java/io/github/lsposed/lspd/core/Impl.java b/core/src/main/java/io/github/lsposed/lspd/core/Impl.java index 680c53ae..bf1d7085 100644 --- a/core/src/main/java/io/github/lsposed/lspd/core/Impl.java +++ b/core/src/main/java/io/github/lsposed/lspd/core/Impl.java @@ -21,16 +21,14 @@ package io.github.lsposed.lspd.core; import androidx.annotation.IntDef; -import androidx.annotation.Keep; import androidx.annotation.NonNull; -import io.github.lsposed.lspd.proxy.Router; - import java.lang.annotation.Retention; +import io.github.lsposed.lspd.proxy.Router; + import static java.lang.annotation.RetentionPolicy.SOURCE; -@Keep public interface Impl { int NONE = 0; diff --git a/core/src/main/java/io/github/lsposed/lspd/core/Main.java b/core/src/main/java/io/github/lsposed/lspd/core/Main.java index 1ed07206..aadbc405 100644 --- a/core/src/main/java/io/github/lsposed/lspd/core/Main.java +++ b/core/src/main/java/io/github/lsposed/lspd/core/Main.java @@ -21,22 +21,20 @@ package io.github.lsposed.lspd.core; import android.annotation.SuppressLint; -import android.os.Binder; -import android.os.IBinder; import android.ddm.DdmHandleAppName; - -import androidx.annotation.Keep; - -import io.github.lsposed.lspd.config.LSPApplicationServiceClient; -import io.github.lsposed.lspd.service.ServiceManager; -import io.github.lsposed.lspd.util.Utils; +import android.os.IBinder; import java.util.concurrent.atomic.AtomicReference; +import io.github.lsposed.lspd.config.LSPApplicationServiceClient; +import io.github.lsposed.lspd.sandhook.core.SandHookImpl; +import io.github.lsposed.lspd.service.ServiceManager; +import io.github.lsposed.lspd.util.Utils; +import io.github.lsposed.lspd.yahfa.core.YahfaImpl; + import static io.github.lsposed.lspd.config.LSPApplicationServiceClient.serviceClient; @SuppressLint("DefaultLocale") -@Keep public class Main { private static final AtomicReference lspdImplRef = new AtomicReference<>(null); @@ -61,32 +59,28 @@ public class Main { lspd.getNormalProxy().forkSystemServerPost(); } - public static synchronized boolean setImpl(Impl lspd) { - return lspdImplRef.compareAndSet(null, lspd); - } - public static synchronized Impl getImpl(int variant) { Impl lspd = lspdImplRef.get(); if (lspd != null) { return lspd; } Utils.logD("Loading variant " + variant); - try { - switch (variant) { - case Impl.YAHFA: - Class.forName("io.github.lsposed.lspd.yahfa.core.YahfaImpl"); - break; - case Impl.SANDHOOK: - Class.forName("io.github.lsposed.lspd.sandhook.core.SandHookImpl"); - break; - default: - Utils.logE("Unsupported variant " + variant); + Impl impl = null; + switch (variant) { + case Impl.YAHFA: + impl = new YahfaImpl(); + break; + case Impl.SANDHOOK: + impl = new SandHookImpl(); + break; + default: + Utils.logE("Unsupported variant " + variant); - } - } catch (ClassNotFoundException e) { - Utils.logE("loadEdxpImpls: Class not found", e); } - return lspdImplRef.get(); + if (impl != null && lspdImplRef.compareAndSet(null, impl)) { + impl.init(); + } + return impl; } public static synchronized Impl getImpl() { diff --git a/core/src/main/java/io/github/lsposed/lspd/core/Proxy.java b/core/src/main/java/io/github/lsposed/lspd/core/Proxy.java index cf9e0d24..82dd5372 100644 --- a/core/src/main/java/io/github/lsposed/lspd/core/Proxy.java +++ b/core/src/main/java/io/github/lsposed/lspd/core/Proxy.java @@ -20,13 +20,11 @@ package io.github.lsposed.lspd.core; -import androidx.annotation.Keep; - -@Keep public interface Proxy { boolean init(); void forkAndSpecializePost(String appDataDir, String niceName); + void forkSystemServerPost(); } diff --git a/core/src/main/java/io/github/lsposed/lspd/nativebridge/ClassLinker.java b/core/src/main/java/io/github/lsposed/lspd/nativebridge/ClassLinker.java index ba2b6a86..4cf55120 100644 --- a/core/src/main/java/io/github/lsposed/lspd/nativebridge/ClassLinker.java +++ b/core/src/main/java/io/github/lsposed/lspd/nativebridge/ClassLinker.java @@ -20,13 +20,10 @@ package io.github.lsposed.lspd.nativebridge; -import androidx.annotation.Keep; - import java.lang.reflect.Member; import de.robv.android.xposed.PendingHooks; -@Keep public class ClassLinker { public static native void setEntryPointsToInterpreter(Member method); diff --git a/core/src/main/java/io/github/lsposed/lspd/nativebridge/ModuleLogger.java b/core/src/main/java/io/github/lsposed/lspd/nativebridge/ModuleLogger.java index 6afc9309..9691f668 100644 --- a/core/src/main/java/io/github/lsposed/lspd/nativebridge/ModuleLogger.java +++ b/core/src/main/java/io/github/lsposed/lspd/nativebridge/ModuleLogger.java @@ -20,25 +20,22 @@ package io.github.lsposed.lspd.nativebridge; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.Locale; - import android.app.ActivityThread; import android.os.ParcelFileDescriptor; import android.os.Process; -import androidx.annotation.Keep; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; import io.github.lsposed.lspd.util.Utils; -@Keep public class ModuleLogger { static SimpleDateFormat logDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.sss", Locale.getDefault()); static int fd = -1; public static void initLogger(ParcelFileDescriptor fileDescriptor) { - if (fd == -1 && fileDescriptor!= null) { + if (fd == -1 && fileDescriptor != null) { fd = fileDescriptor.detachFd(); } } @@ -49,7 +46,7 @@ public class ModuleLogger { if (fd == -1) { Utils.logE("Logger is not initialized"); return; - }; + } StringBuilder sb = new StringBuilder(); sb.append(logDateFormat.format(new Date())); sb.append(' '); diff --git a/core/src/main/java/io/github/lsposed/lspd/sandhook/core/SandHookImpl.java b/core/src/main/java/io/github/lsposed/lspd/sandhook/core/SandHookImpl.java index 1834965b..7cc60c06 100644 --- a/core/src/main/java/io/github/lsposed/lspd/sandhook/core/SandHookImpl.java +++ b/core/src/main/java/io/github/lsposed/lspd/sandhook/core/SandHookImpl.java @@ -22,23 +22,14 @@ package io.github.lsposed.lspd.sandhook.core; import android.os.Build; -import io.github.lsposed.lspd.core.BaseImpl; -import io.github.lsposed.lspd.core.Impl; -import io.github.lsposed.lspd.core.Main; -import io.github.lsposed.lspd.nativebridge.SandHook; -import io.github.lsposed.lspd.nativebridge.Yahfa; - import com.swift.sandhook.ClassNeverCall; import com.swift.sandhook.xposedcompat.methodgen.SandHookXposedBridge; -public class SandHookImpl extends BaseImpl { +import io.github.lsposed.lspd.core.BaseImpl; +import io.github.lsposed.lspd.nativebridge.SandHook; +import io.github.lsposed.lspd.nativebridge.Yahfa; - static { - final Impl lspdImpl = new SandHookImpl(); - if (Main.setImpl(lspdImpl)) { - lspdImpl.init(); - } - } +public class SandHookImpl extends BaseImpl { @Override protected io.github.lsposed.lspd.proxy.Router createRouter() { diff --git a/core/src/main/java/io/github/lsposed/lspd/service/BridgeService.java b/core/src/main/java/io/github/lsposed/lspd/service/BridgeService.java index 7555f178..7fc28e28 100644 --- a/core/src/main/java/io/github/lsposed/lspd/service/BridgeService.java +++ b/core/src/main/java/io/github/lsposed/lspd/service/BridgeService.java @@ -25,13 +25,12 @@ import android.content.Intent; import android.os.Binder; import android.os.IBinder; import android.os.Parcel; +import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; import android.util.ArrayMap; import android.util.Log; -import android.os.Process; -import androidx.annotation.Keep; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -272,8 +271,6 @@ public class BridgeService { return false; } - @SuppressWarnings({"unused", "RedundantSuppression"}) - @Keep public static boolean execTransact(int code, long dataObj, long replyObj, int flags) { if (code != TRANSACTION_CODE) return false; @@ -311,7 +308,6 @@ public class BridgeService { return res; } - @Keep public static IBinder getApplicationServiceForSystemServer(IBinder binder, IBinder heartBeat) { if (binder == null || heartBeat == null) return null; try { diff --git a/core/src/main/java/io/github/lsposed/lspd/service/ConfigManager.java b/core/src/main/java/io/github/lsposed/lspd/service/ConfigManager.java index 244c8759..75f9ddd2 100644 --- a/core/src/main/java/io/github/lsposed/lspd/service/ConfigManager.java +++ b/core/src/main/java/io/github/lsposed/lspd/service/ConfigManager.java @@ -31,7 +31,6 @@ import android.system.Os; import android.util.Log; import android.util.Pair; -import androidx.annotation.Keep; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -630,7 +629,6 @@ public class ConfigManager { } // migrate setting - @Keep public static void main(String[] args) { if (!miscFile.exists()) { System.exit(1); diff --git a/core/src/main/java/io/github/lsposed/lspd/service/PackageReceiver.java b/core/src/main/java/io/github/lsposed/lspd/service/PackageReceiver.java index b234a616..d11987dc 100644 --- a/core/src/main/java/io/github/lsposed/lspd/service/PackageReceiver.java +++ b/core/src/main/java/io/github/lsposed/lspd/service/PackageReceiver.java @@ -30,11 +30,11 @@ import android.os.Handler; import android.os.HandlerThread; import android.os.UserHandle; -import io.github.lsposed.lspd.util.Utils; - import java.lang.reflect.Field; import java.lang.reflect.Method; +import io.github.lsposed.lspd.util.Utils; + public class PackageReceiver { public static void register(BroadcastReceiver receiver) { ActivityThread activityThread = ActivityThread.currentActivityThread(); diff --git a/core/src/main/java/io/github/lsposed/lspd/service/ServiceManager.java b/core/src/main/java/io/github/lsposed/lspd/service/ServiceManager.java index 5f0eb86f..5f78e40f 100644 --- a/core/src/main/java/io/github/lsposed/lspd/service/ServiceManager.java +++ b/core/src/main/java/io/github/lsposed/lspd/service/ServiceManager.java @@ -43,7 +43,7 @@ public class ServiceManager { } private static void putBinderForSystemServer() { - android.os.ServiceManager.addService("serial", (IBinder) mainService); + android.os.ServiceManager.addService("serial", mainService); } // call by ourselves diff --git a/core/src/main/java/io/github/lsposed/lspd/yahfa/core/YahfaImpl.java b/core/src/main/java/io/github/lsposed/lspd/yahfa/core/YahfaImpl.java index 8a7be367..bf526a65 100644 --- a/core/src/main/java/io/github/lsposed/lspd/yahfa/core/YahfaImpl.java +++ b/core/src/main/java/io/github/lsposed/lspd/yahfa/core/YahfaImpl.java @@ -23,8 +23,6 @@ package io.github.lsposed.lspd.yahfa.core; import android.os.Build; import io.github.lsposed.lspd.core.BaseImpl; -import io.github.lsposed.lspd.core.Impl; -import io.github.lsposed.lspd.core.Main; import io.github.lsposed.lspd.core.Proxy; import io.github.lsposed.lspd.nativebridge.Yahfa; import io.github.lsposed.lspd.proxy.NormalProxy; @@ -32,13 +30,6 @@ import io.github.lsposed.lspd.proxy.Router; public class YahfaImpl extends BaseImpl { - static { - final Impl lspdImpl = new YahfaImpl(); - if (Main.setImpl(lspdImpl)) { - lspdImpl.init(); - } - } - @Variant @Override public int getVariant() { diff --git a/gradle.properties b/gradle.properties index 61770680..73dc6225 100644 --- a/gradle.properties +++ b/gradle.properties @@ -16,7 +16,7 @@ androidCompileNdkVersion=22.0.7026061 androidBuildToolsVersion=30.0.3 apiCode=93 androidCompileSdkVersion=30 -androidMinSdkVersion=26 +androidMinSdkVersion=27 android.useAndroidX=true android.enableJetifier=true android.prefabVersion=1.1.2