Compare commits

3 Commits

Author SHA1 Message Date
littleturtle2333
60f61649fb 修复Android13核心破解 2023-01-31 18:00:15 +08:00
littleturtle2333
4bbfd4b7d2 修复MIUI14上的移除OTA验证功能 2023-01-31 17:59:59 +08:00
Amatsume Akira
6945b205c9 Update Updater.kt (#209) 2023-01-31 17:01:34 +08:00
3 changed files with 108 additions and 40 deletions

View File

@@ -3,10 +3,10 @@ package com.lt2333.simplicitytools.hook.app
import com.github.kyuubiran.ezxhelper.utils.findMethod import com.github.kyuubiran.ezxhelper.utils.findMethod
import com.github.kyuubiran.ezxhelper.utils.hookReturnConstant import com.github.kyuubiran.ezxhelper.utils.hookReturnConstant
import com.github.kyuubiran.ezxhelper.utils.loadClassOrNull import com.github.kyuubiran.ezxhelper.utils.loadClassOrNull
import com.github.kyuubiran.ezxhelper.utils.hookBefore
import com.lt2333.simplicitytools.util.hasEnable import com.lt2333.simplicitytools.util.hasEnable
import com.lt2333.simplicitytools.util.xposed.base.AppRegister import com.lt2333.simplicitytools.util.xposed.base.AppRegister
import de.robv.android.xposed.callbacks.XC_LoadPackage import de.robv.android.xposed.callbacks.XC_LoadPackage
object Updater : AppRegister() { object Updater : AppRegister() {
override val packageName: String = "com.android.updater" override val packageName: String = "com.android.updater"
@@ -18,6 +18,15 @@ object Updater : AppRegister() {
.firstOrNull { it.declaredFields.size >= 9 && it.declaredMethods.size > 60 } .firstOrNull { it.declaredFields.size >= 9 && it.declaredMethods.size > 60 }
?.findMethod { name == "T" && returnType == Boolean::class.java } ?.findMethod { name == "T" && returnType == Boolean::class.java }
?.hookReturnConstant(false) ?.hookReturnConstant(false)
findMethod("miui.util.FeatureParser") {
name == "hasFeature" && parameterCount == 2
}.hookBefore {
if (it.args[0] == "support_ota_validate") {
it.result = false
}
}
} }
} }
} }

View File

@@ -13,6 +13,8 @@ import com.lt2333.simplicitytools.BuildConfig;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.security.cert.Certificate; import java.security.cert.Certificate;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
import java.util.List; import java.util.List;
@@ -102,7 +104,7 @@ public class CorePatchForR extends XposedHelper implements IXposedHookLoadPackag
Class<?> sJarClass = XposedHelpers.findClass("android.util.jar.StrictJarFile", loadPackageParam.classLoader); Class<?> sJarClass = XposedHelpers.findClass("android.util.jar.StrictJarFile", loadPackageParam.classLoader);
Constructor<?> constructorExact = XposedHelpers.findConstructorExact(sJarClass, String.class, boolean.class, boolean.class); Constructor<?> constructorExact = XposedHelpers.findConstructorExact(sJarClass, String.class, boolean.class, boolean.class);
constructorExact.setAccessible(true); constructorExact.setAccessible(true);
Class<?> signingDetails = XposedHelpers.findClass("android.content.pm.PackageParser.SigningDetails", loadPackageParam.classLoader); Class<?> signingDetails = getSigningDetails(loadPackageParam.classLoader);
Constructor<?> findConstructorExact = XposedHelpers.findConstructorExact(signingDetails, Signature[].class, Integer.TYPE); Constructor<?> findConstructorExact = XposedHelpers.findConstructorExact(signingDetails, Signature[].class, Integer.TYPE);
findConstructorExact.setAccessible(true); findConstructorExact.setAccessible(true);
Class<?> packageParserException = XposedHelpers.findClass("android.content.pm.PackageParser.PackageParserException", loadPackageParam.classLoader); Class<?> packageParserException = XposedHelpers.findClass("android.content.pm.PackageParser.PackageParserException", loadPackageParam.classLoader);
@@ -110,6 +112,7 @@ public class CorePatchForR extends XposedHelper implements IXposedHookLoadPackag
error.setAccessible(true); error.setAccessible(true);
Object[] signingDetailsArgs = new Object[2]; Object[] signingDetailsArgs = new Object[2];
signingDetailsArgs[1] = 1; signingDetailsArgs[1] = 1;
Class<?> parseResult = XposedHelpers.findClassIfExists("android.content.pm.parsing.result.ParseResult", loadPackageParam.classLoader);
hookAllMethods("android.util.jar.StrictJarVerifier", loadPackageParam.classLoader, "verifyBytes", new XC_MethodHook() { hookAllMethods("android.util.jar.StrictJarVerifier", loadPackageParam.classLoader, "verifyBytes", new XC_MethodHook() {
public void afterHookedMethod(MethodHookParam param) throws Throwable { public void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param); super.afterHookedMethod(param);
@@ -127,27 +130,49 @@ public class CorePatchForR extends XposedHelper implements IXposedHookLoadPackag
}); });
hookAllMethods("android.util.apk.ApkSignatureVerifier", loadPackageParam.classLoader, "verifyV1Signature", new XC_MethodHook() { hookAllMethods("android.util.apk.ApkSignatureVerifier", loadPackageParam.classLoader, "verifyV1Signature", new XC_MethodHook() {
public void afterHookedMethod(MethodHookParam methodHookParam) throws Throwable { public void afterHookedMethod(MethodHookParam methodHookParam) throws Throwable {
super.afterHookedMethod(methodHookParam);
if (prefs.getBoolean("authcreak", true)) { if (prefs.getBoolean("authcreak", true)) {
Throwable throwable = methodHookParam.getThrowable(); Throwable throwable = methodHookParam.getThrowable();
if (throwable != null) { Integer parseErr = null;
if (parseResult != null && ((Method) methodHookParam.method).getReturnType() == parseResult) {
Object result = methodHookParam.getResult();
if ((boolean) XposedHelpers.callMethod(result, "isError")) {
parseErr = (int) XposedHelpers.callMethod(result, "getErrorCode");
}
}
if (throwable != null || parseErr != null) {
Signature[] lastSigs = null; Signature[] lastSigs = null;
if (prefs.getBoolean("UsePreSig", false)) { try {
PackageManager PM = AndroidAppHelper.currentApplication().getPackageManager(); if (prefs.getBoolean("UsePreSig", false)) {
if (PM == null) { PackageManager PM = AndroidAppHelper.currentApplication().getPackageManager();
XposedBridge.log("E: " + BuildConfig.APPLICATION_ID + " Cannot get the Package Manager... Are you using MiUI?"); if (PM == null) {
} else { XposedBridge.log("E: " + BuildConfig.APPLICATION_ID + " Cannot get the Package Manager... Are you using MiUI?");
PackageInfo pI = PM.getPackageArchiveInfo((String) methodHookParam.args[0], 0); } else {
PackageInfo InstpI = PM.getPackageInfo(pI.packageName, PackageManager.GET_SIGNATURES); PackageInfo pI;
lastSigs = InstpI.signatures; if (parseErr != null) {
pI = PM.getPackageArchiveInfo((String) methodHookParam.args[1], 0);
} else {
pI = PM.getPackageArchiveInfo((String) methodHookParam.args[0], 0);
}
PackageInfo InstpI = PM.getPackageInfo(pI.packageName, PackageManager.GET_SIGNATURES);
lastSigs = InstpI.signatures;
}
} }
} else { } catch (Throwable ignored) {
if (prefs.getBoolean("digestCreak", true)) {
final Object origJarFile = constructorExact.newInstance(methodHookParam.args[0], true, false); }
try {
if (lastSigs == null && prefs.getBoolean("digestCreak", true)) {
final Object origJarFile = constructorExact.newInstance(methodHookParam.args[parseErr == null ? 0 : 1], true, false);
final ZipEntry manifestEntry = (ZipEntry) XposedHelpers.callMethod(origJarFile, "findEntry", "AndroidManifest.xml"); final ZipEntry manifestEntry = (ZipEntry) XposedHelpers.callMethod(origJarFile, "findEntry", "AndroidManifest.xml");
final Certificate[][] lastCerts = (Certificate[][]) XposedHelpers.callStaticMethod(ASV, "loadCertificates", origJarFile, manifestEntry); final Certificate[][] lastCerts;
if (parseErr != null) {
lastCerts = (Certificate[][]) XposedHelpers.callMethod(XposedHelpers.callStaticMethod(ASV, "loadCertificates", methodHookParam.args[0], origJarFile, manifestEntry), "getResult");
} else {
lastCerts = (Certificate[][]) XposedHelpers.callStaticMethod(ASV, "loadCertificates", origJarFile, manifestEntry);
}
lastSigs = (Signature[]) XposedHelpers.callStaticMethod(ASV, "convertToSignatures", (Object) lastCerts); lastSigs = (Signature[]) XposedHelpers.callStaticMethod(ASV, "convertToSignatures", (Object) lastCerts);
} }
} catch (Throwable ignored) {
} }
if (lastSigs != null) { if (lastSigs != null) {
signingDetailsArgs[0] = lastSigs; signingDetailsArgs[0] = lastSigs;
@@ -163,17 +188,23 @@ public class CorePatchForR extends XposedHelper implements IXposedHookLoadPackag
signingDetailsWithDigestsConstructorExact.setAccessible(true); signingDetailsWithDigestsConstructorExact.setAccessible(true);
newInstance = signingDetailsWithDigestsConstructorExact.newInstance(new Object[]{newInstance, null}); newInstance = signingDetailsWithDigestsConstructorExact.newInstance(new Object[]{newInstance, null});
} }
if (throwable != null) {
Throwable cause = throwable.getCause(); Throwable cause = throwable.getCause();
if (throwable.getClass() == packageParserException) { if (throwable.getClass() == packageParserException) {
if (error.getInt(throwable) == -103) { if (error.getInt(throwable) == -103) {
methodHookParam.setResult(newInstance); methodHookParam.setResult(newInstance);
}
}
if (cause != null && cause.getClass() == packageParserException) {
if (error.getInt(cause) == -103) {
methodHookParam.setResult(newInstance);
}
} }
} }
if (cause != null && cause.getClass() == packageParserException) { if (parseErr != null && parseErr == -103) {
if (error.getInt(cause) == -103) { Object input = methodHookParam.args[0];
methodHookParam.setResult(newInstance); XposedHelpers.callMethod(input, "reset");
} methodHookParam.setResult(XposedHelpers.callMethod(input, "success", newInstance));
} }
} }
} }
@@ -208,6 +239,23 @@ public class CorePatchForR extends XposedHelper implements IXposedHookLoadPackag
} }
} }
}); });
var utilClass = findClass("com.android.server.pm.PackageManagerServiceUtils", loadPackageParam.classLoader);
if (utilClass != null) {
for (var m : utilClass.getDeclaredMethods()) {
if ("verifySignatures".equals(m.getName())) {
try {
XposedBridge.class.getDeclaredMethod("deoptimizeMethod", Member.class).invoke(null, m);
} catch (Throwable e) {
Log.e("CorePatch", "deoptimizing failed", e);
}
}
}
}
}
Class<?> getSigningDetails(ClassLoader classLoader) {
return XposedHelpers.findClass("android.content.pm.PackageParser.SigningDetails", classLoader);
} }
@Override @Override

View File

@@ -3,7 +3,6 @@ package com.lt2333.simplicitytools.hook.app.android.corepatch;
import android.util.Log; import android.util.Log;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Member;
import de.robv.android.xposed.XC_MethodHook; import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedBridge; import de.robv.android.xposed.XposedBridge;
@@ -21,8 +20,7 @@ public class CorePatchForT extends CorePatchForSv2 {
"android.content.pm.PackageInfoLite", "android.content.pm.PackageInfoLite",
new ReturnConstant(prefs, "downgrade", null)); new ReturnConstant(prefs, "downgrade", null));
var utilClass = findClass("com.android.server.pm.PackageManagerServiceUtils", loadPackageParam.classLoader); Class<?> signingDetails = getSigningDetails(loadPackageParam.classLoader);
Class<?> signingDetails = XposedHelpers.findClass("android.content.pm.SigningDetails", loadPackageParam.classLoader);
//New package has a different signature //New package has a different signature
//处理覆盖安装但签名不一致 //处理覆盖安装但签名不一致
hookAllMethods(signingDetails, "checkCapability", new XC_MethodHook() { hookAllMethods(signingDetails, "checkCapability", new XC_MethodHook() {
@@ -37,17 +35,6 @@ public class CorePatchForT extends CorePatchForSv2 {
} }
}); });
if (utilClass != null) {
for (var m : utilClass.getDeclaredMethods()) {
if ("verifySignatures".equals(m.getName())) {
try {
XposedBridge.class.getDeclaredMethod("deoptimizeMethod", Member.class).invoke(null, m);
} catch (Throwable e) {
Log.e("CorePatch", "deoptimizing failed", e);
}
}
}
}
// Package " + packageName + " signatures do not match previously installed version; ignoring!" // Package " + packageName + " signatures do not match previously installed version; ignoring!"
// public boolean checkCapability(String sha256String, @CertCapabilities int flags) { // public boolean checkCapability(String sha256String, @CertCapabilities int flags) {
// public boolean checkCapability(SigningDetails oldDetails, @CertCapabilities int flags) // public boolean checkCapability(SigningDetails oldDetails, @CertCapabilities int flags)
@@ -81,5 +68,29 @@ public class CorePatchForT extends CorePatchForSv2 {
} }
}); });
} }
findAndHookMethod("com.android.server.pm.ScanPackageUtils", loadPackageParam.classLoader, "assertMinSignatureSchemeIsValid", "com.android.server.pm.parsing.pkg.AndroidPackage", int.class, new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
if (prefs.getBoolean("authcreak", true)) {
param.setResult(null);
}
}
});
Class<?> strictJarVerifier = findClass("android.util.jar.StrictJarVerifier", loadPackageParam.classLoader);
if (strictJarVerifier != null) {
XposedBridge.hookAllConstructors(strictJarVerifier, new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) {
if (prefs.getBoolean("authcreak", true)) {
XposedHelpers.setBooleanField(param.thisObject, "signatureSchemeRollbackProtectionsEnforced", false);
}
}
});
}
}
@Override
Class<?> getSigningDetails(ClassLoader classLoader) {
return XposedHelpers.findClassIfExists("android.content.pm.SigningDetails", classLoader);
} }
} }