From a44a29b7b746943cc94f256201ffcbfa2d7a1f71 Mon Sep 17 00:00:00 2001 From: LittleTurtle2333 Date: Sat, 2 Apr 2022 23:14:54 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BB=86=E5=88=86=E6=A0=B8=E5=BF=83=E7=A0=B4?= =?UTF-8?q?=E8=A7=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../activity/SettingsActivity.kt | 56 ++++++++-- .../simplicitytools/hook/XposedEntry.kt | 4 +- .../simplicitytools/hook/app/Android.kt | 1 + .../hook/app/android/corepatch/CorePatch.java | 104 +++++++++++++++--- .../app/android/corepatch/ReturnConstant.java | 2 +- app/src/main/res/values/strings.xml | 10 ++ 6 files changed, 150 insertions(+), 27 deletions(-) diff --git a/app/src/main/java/com/lt2333/simplicitytools/activity/SettingsActivity.kt b/app/src/main/java/com/lt2333/simplicitytools/activity/SettingsActivity.kt index 7d344f9e..6a14da6f 100644 --- a/app/src/main/java/com/lt2333/simplicitytools/activity/SettingsActivity.kt +++ b/app/src/main/java/com/lt2333/simplicitytools/activity/SettingsActivity.kt @@ -422,6 +422,53 @@ class SettingsActivity : MIUIActivity() { private fun androidItems(): ArrayList { menuButton.visibility = View.VISIBLE return ArrayList().apply { + add(TitleTextV(resId = R.string.corepacth)) + add( + TextSummaryWithSwitchV( + TextSummaryV( + textId = R.string.downgr, + tipsId = R.string.downgr_summary + ), + SwitchV("downgrade") + ) + ) + add( + TextSummaryWithSwitchV( + TextSummaryV( + textId = R.string.authcreak, + tipsId = R.string.authcreak_summary + ), + SwitchV("authcreak") + ) + ) + add( + TextSummaryWithSwitchV( + TextSummaryV( + textId = R.string.digestCreak, + tipsId = R.string.digestCreak_summary + ), + SwitchV("digestCreak") + ) + ) + add( + TextSummaryWithSwitchV( + TextSummaryV( + textId = R.string.UsePreSig, + tipsId = R.string.UsePreSig_summary + ), + SwitchV("UsePreSig") + ) + ) + add( + TextSummaryWithSwitchV( + TextSummaryV( + textId = R.string.enhancedMode, + tipsId = R.string.enhancedMode_summary + ), + SwitchV("enhancedMode") + ) + ) + add(LineV()) add( TextSummaryWithSwitchV( TextSummaryV( @@ -431,15 +478,6 @@ class SettingsActivity : MIUIActivity() { SwitchV("disable_flag_secure") ) ) - add( - TextSummaryWithSwitchV( - TextSummaryV( - textId = R.string.corepacth, - tipsId = R.string.corepacth_summary - ), - SwitchV("corepatch") - ) - ) add( TextSummaryWithSwitchV( TextSummaryV( diff --git a/app/src/main/java/com/lt2333/simplicitytools/hook/XposedEntry.kt b/app/src/main/java/com/lt2333/simplicitytools/hook/XposedEntry.kt index e48acb7a..6a285327 100644 --- a/app/src/main/java/com/lt2333/simplicitytools/hook/XposedEntry.kt +++ b/app/src/main/java/com/lt2333/simplicitytools/hook/XposedEntry.kt @@ -2,13 +2,14 @@ package com.lt2333.simplicitytools.hook import com.lt2333.simplicitytools.BuildConfig import com.lt2333.simplicitytools.hook.app.* +import com.lt2333.simplicitytools.hook.app.android.corepatch.CorePatch import com.lt2333.simplicitytools.util.xposed.EasyXposedInit import com.lt2333.simplicitytools.util.xposed.base.AppRegister import de.robv.android.xposed.IXposedHookZygoteInit import de.robv.android.xposed.XSharedPreferences import de.robv.android.xposed.callbacks.XC_LoadPackage -class XposedEntry: EasyXposedInit() { +class XposedEntry : EasyXposedInit() { private var prefs = XSharedPreferences(BuildConfig.APPLICATION_ID, "config") override val registeredApp: List = listOf( @@ -33,6 +34,7 @@ class XposedEntry: EasyXposedInit() { override fun initZygote(startupParam: IXposedHookZygoteInit.StartupParam?) { super.initZygote(startupParam) + CorePatch().initZygote(startupParam) } } \ No newline at end of file diff --git a/app/src/main/java/com/lt2333/simplicitytools/hook/app/Android.kt b/app/src/main/java/com/lt2333/simplicitytools/hook/app/Android.kt index 1767dba7..7bf45fa9 100644 --- a/app/src/main/java/com/lt2333/simplicitytools/hook/app/Android.kt +++ b/app/src/main/java/com/lt2333/simplicitytools/hook/app/Android.kt @@ -26,4 +26,5 @@ object Android: AppRegister() { MaxWallpaperScale, //壁纸缩放比例 ) } + } \ No newline at end of file diff --git a/app/src/main/java/com/lt2333/simplicitytools/hook/app/android/corepatch/CorePatch.java b/app/src/main/java/com/lt2333/simplicitytools/hook/app/android/corepatch/CorePatch.java index 7450dd35..1e565b1e 100644 --- a/app/src/main/java/com/lt2333/simplicitytools/hook/app/android/corepatch/CorePatch.java +++ b/app/src/main/java/com/lt2333/simplicitytools/hook/app/android/corepatch/CorePatch.java @@ -5,7 +5,10 @@ package com.lt2333.simplicitytools.hook.app.android.corepatch; +import android.app.AndroidAppHelper; import android.content.pm.ApplicationInfo; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; import android.content.pm.Signature; import com.lt2333.simplicitytools.BuildConfig; @@ -14,18 +17,22 @@ import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.security.cert.Certificate; +import java.security.cert.X509Certificate; +import java.util.List; import java.util.Map; import java.util.zip.ZipEntry; import de.robv.android.xposed.IXposedHookLoadPackage; +import de.robv.android.xposed.IXposedHookZygoteInit; import de.robv.android.xposed.XC_MethodHook; +import de.robv.android.xposed.XC_MethodReplacement; import de.robv.android.xposed.XSharedPreferences; +import de.robv.android.xposed.XposedBridge; import de.robv.android.xposed.XposedHelpers; import de.robv.android.xposed.callbacks.XC_LoadPackage; -public class CorePatch extends XposedHelper implements IXposedHookLoadPackage { +public class CorePatch extends XposedHelper implements IXposedHookLoadPackage, IXposedHookZygoteInit { XSharedPreferences prefs = new XSharedPreferences(BuildConfig.APPLICATION_ID, "config"); - String TAG = "ST-CorePatch"; @Override public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws IllegalAccessException, InvocationTargetException, InstantiationException { @@ -35,27 +42,37 @@ public class CorePatch extends XposedHelper implements IXposedHookLoadPackage { "checkDowngrade", "com.android.server.pm.parsing.pkg.AndroidPackage", "android.content.pm.PackageInfoLite", - new ReturnConstant(prefs, "corepatch", null)); + new ReturnConstant(prefs, "downgrade", null)); + + // exists on flyme 9(Android 11) only + findAndHookMethod("com.android.server.pm.PackageManagerService", loadPackageParam.classLoader, + "checkDowngrade", + "android.content.pm.PackageInfoLite", + "android.content.pm.PackageInfoLite", + new ReturnConstant(prefs, "downgrade", true)); + // apk内文件修改后 digest校验会失败 hookAllMethods("android.util.jar.StrictJarVerifier", loadPackageParam.classLoader, "verifyMessageDigest", - new ReturnConstant(prefs, "corepatch", true)); + new ReturnConstant(prefs, "authcreak", true)); hookAllMethods("android.util.jar.StrictJarVerifier", loadPackageParam.classLoader, "verify", - new ReturnConstant(prefs, "corepatch", true)); + new ReturnConstant(prefs, "authcreak", true)); hookAllMethods("java.security.MessageDigest", loadPackageParam.classLoader, "isEqual", - new ReturnConstant(prefs, "corepatch", true)); + new ReturnConstant(prefs, "authcreak", true)); // Targeting R+ (version " + Build.VERSION_CODES.R + " and above) requires" // + " the resources.arsc of installed APKs to be stored uncompressed" // + " and aligned on a 4-byte boundary // target >=30 的情况下 resources.arsc 必须是未压缩的且4K对齐 hookAllMethods("android.content.res.AssetManager", loadPackageParam.classLoader, "containsAllocatedTable", - new ReturnConstant(prefs, "corepatch", false)); + new ReturnConstant(prefs, "authcreak", false)); // No signature found in package of version " + minSignatureSchemeVersion // + " or newer for package " + apkPath findAndHookMethod("android.util.apk.ApkSignatureVerifier", loadPackageParam.classLoader, "getMinimumSignatureSchemeVersionForTargetSdk", int.class, - new ReturnConstant(prefs, "corepatch", 0)); + new ReturnConstant(prefs, "authcreak", 0)); + findAndHookMethod("com.android.apksig.ApkVerifier", loadPackageParam.classLoader, "getMinimumSignatureSchemeVersionForTargetSdk", int.class, + new ReturnConstant(prefs, "authcreak", 0)); // Package " + packageName + " signatures do not match previously installed version; ignoring!" // public boolean checkCapability(String sha256String, @CertCapabilities int flags) { @@ -66,7 +83,7 @@ public class CorePatch extends XposedHelper implements IXposedHookLoadPackage { // Don't handle PERMISSION (grant SIGNATURE permissions to pkgs with this cert) // Or applications will have all privileged permissions // https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/content/pm/PackageParser.java;l=5947?q=CertCapabilities - if (prefs.getBoolean("corepatch", true)) { + if (prefs.getBoolean("authcreak", true)) { if ((Integer) param.args[1] != 4) { param.setResult(true); } @@ -91,20 +108,45 @@ public class CorePatch extends XposedHelper implements IXposedHookLoadPackage { error.setAccessible(true); Object[] signingDetailsArgs = new Object[2]; signingDetailsArgs[1] = 1; - + hookAllMethods("android.util.jar.StrictJarVerifier", loadPackageParam.classLoader, "verifyBytes", new XC_MethodHook() { + public void afterHookedMethod(MethodHookParam param) throws Throwable { + super.afterHookedMethod(param); + if (prefs.getBoolean("digestCreak", true)) { + if(!prefs.getBoolean("UsePreSig", false)) { + final Object block = constructor.newInstance(param.args[0]); + Object[] infos = (Object[]) XposedHelpers.callMethod(block, "getSignerInfos"); + Object info = infos[0]; + List verifiedSignerCertChain = (List) XposedHelpers.callMethod(info, "getCertificateChain", block); + param.setResult(verifiedSignerCertChain.toArray( + new X509Certificate[0])); + } + } + } + }); hookAllMethods("android.util.apk.ApkSignatureVerifier", loadPackageParam.classLoader, "verifyV1Signature", new XC_MethodHook() { public void afterHookedMethod(MethodHookParam methodHookParam) throws Throwable { super.afterHookedMethod(methodHookParam); - if (prefs.getBoolean("corepatch", true)) { + if (prefs.getBoolean("authcreak", true)) { Throwable throwable = methodHookParam.getThrowable(); if (throwable != null) { Signature[] lastSigs = null; - if (prefs.getBoolean("corepatch", true)) { + if(prefs.getBoolean("UsePreSig", false)) { + PackageManager PM = AndroidAppHelper.currentApplication().getPackageManager(); + if(PM == null){ + XposedBridge.log("E: " + BuildConfig.APPLICATION_ID + " Cannot get the Package Manager... Are you using MiUI?"); + }else { + PackageInfo pI = PM.getPackageArchiveInfo((String) methodHookParam.args[0], 0); + PackageInfo InstpI = PM.getPackageInfo(pI.packageName, PackageManager.GET_SIGNATURES); + lastSigs = InstpI.signatures; + } + }else { + if(prefs.getBoolean("digestCreak", true)) { final Object origJarFile = constructorExact.newInstance(methodHookParam.args[0], true, false); final ZipEntry manifestEntry = (ZipEntry) XposedHelpers.callMethod(origJarFile, "findEntry", "AndroidManifest.xml"); final Certificate[][] lastCerts = (Certificate[][]) XposedHelpers.callStaticMethod(ASV, "loadCertificates", origJarFile, manifestEntry); lastSigs = (Signature[]) XposedHelpers.callStaticMethod(ASV, "convertToSignatures", (Object) lastCerts); } + } if (lastSigs != null) { signingDetailsArgs[0] = lastSigs; } else { @@ -117,7 +159,7 @@ public class CorePatch extends XposedHelper implements IXposedHookLoadPackage { if (signingDetailsWithDigests != null) { Constructor signingDetailsWithDigestsConstructorExact = XposedHelpers.findConstructorExact(signingDetailsWithDigests, signingDetails, Map.class); signingDetailsWithDigestsConstructorExact.setAccessible(true); - newInstance = signingDetailsWithDigestsConstructorExact.newInstance(newInstance, null); + newInstance = signingDetailsWithDigestsConstructorExact.newInstance(new Object[]{newInstance, null}); } Throwable cause = throwable.getCause(); @@ -145,7 +187,7 @@ public class CorePatch extends XposedHelper implements IXposedHookLoadPackage { // Don't handle PERMISSION (grant SIGNATURE permissions to pkgs with this cert) // Or applications will have all privileged permissions // https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/content/pm/PackageParser.java;l=5947?q=CertCapabilities - if (((Integer) param.args[1] != 4) && prefs.getBoolean("corepatch", true)) { + if (((Integer) param.args[1] != 4) && prefs.getBoolean("digestCreak", true)) { param.setResult(true); } } @@ -155,7 +197,7 @@ public class CorePatch extends XposedHelper implements IXposedHookLoadPackage { @Override protected void beforeHookedMethod(MethodHookParam param) throws Throwable { super.beforeHookedMethod(param); - if (prefs.getBoolean("corepatch", true)) { + if (prefs.getBoolean("digestCreak", true)) { ApplicationInfo info = (ApplicationInfo) param.thisObject; if ((info.flags & ApplicationInfo.FLAG_SYSTEM) != 0 || (info.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) { @@ -164,6 +206,36 @@ public class CorePatch extends XposedHelper implements IXposedHookLoadPackage { } } }); + if (prefs.getBoolean("digestCreak", true) && prefs.getBoolean("UsePreSig", false)) { + Class pmClass = findClass("com.android.server.pm.PackageManagerService", loadPackageParam.classLoader); + Class pPClass = findClass("com.android.server.pm.parsing.pkg.ParsedPackage", loadPackageParam.classLoader); + XposedHelpers.findAndHookMethod(pmClass, "doesSignatureMatchForPermissions", String.class, pPClass, int.class, new XC_MethodHook() { + @Override + protected void afterHookedMethod(MethodHookParam param) throws Throwable { + //If we decide to crack this then at least make sure they are same apks, avoid another one that tries to impersonate. + if (param.getResult().equals(false)) { + String pPname = (String) XposedHelpers.callMethod(param.args[1], "getPackageName"); + if (pPname.contentEquals((String) param.args[0])) { + param.setResult(true); + } + } + } + }); + } } -} + @Override + public void initZygote(StartupParam startupParam) { + + hookAllMethods("android.content.pm.PackageParser", null, "getApkSigningVersion", XC_MethodReplacement.returnConstant(1)); + hookAllConstructors("android.util.jar.StrictJarVerifier", new XC_MethodHook() { + @Override + protected void beforeHookedMethod(MethodHookParam param) throws Throwable { + if (prefs.getBoolean("enhancedMode", false)) { + super.beforeHookedMethod(param); + param.args[3] = Boolean.FALSE; + } + } + }); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/lt2333/simplicitytools/hook/app/android/corepatch/ReturnConstant.java b/app/src/main/java/com/lt2333/simplicitytools/hook/app/android/corepatch/ReturnConstant.java index 1f51d1f9..8a9888cf 100644 --- a/app/src/main/java/com/lt2333/simplicitytools/hook/app/android/corepatch/ReturnConstant.java +++ b/app/src/main/java/com/lt2333/simplicitytools/hook/app/android/corepatch/ReturnConstant.java @@ -18,7 +18,7 @@ public class ReturnConstant extends XC_MethodHook { protected void beforeHookedMethod(MethodHookParam param) throws Throwable { super.beforeHookedMethod(param); prefs.reload(); - if (prefs.getBoolean(prefsKey, true)) { + if (prefs.getBoolean(prefsKey, false)) { param.setResult(value); } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index ddb5adf7..3f9d8efd 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -202,4 +202,14 @@ Maximum number of notification dots Custom mobile type text Custom mobile type text switch + Allow downgrade + Allow downgrade applications. + Disable digest verify + Allows install apps after modify file in apk (ignore invalid digest error). + Disable compare signatures + Allow re-install app with different signatures. + Use installed signatures + Always use signatures from already installed apps when installing.\nThis is extremely dangerous.\nOnly enable when really needed! + Enhanced Mode + Pass some validation in the application