mirror of
https://github.com/LittleTurtle2333/SimplicityTools.git
synced 2026-07-12 19:31:17 +08:00
新增核心破解
This commit is contained in:
@@ -317,6 +317,14 @@ class SettingsActivity : MIUIActivity() {
|
|||||||
SwitchV("disable_flag_secure")
|
SwitchV("disable_flag_secure")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
add(
|
||||||
|
TextSummaryWithSwitchV(
|
||||||
|
TextSummaryV(
|
||||||
|
textId = R.string.corepacth
|
||||||
|
),
|
||||||
|
SwitchV("corepatch")
|
||||||
|
)
|
||||||
|
)
|
||||||
add(
|
add(
|
||||||
TextWithSwitchV(
|
TextWithSwitchV(
|
||||||
TextV(resId = R.string.skip_waiting_time),
|
TextV(resId = R.string.skip_waiting_time),
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package com.lt2333.simplicitytools.hook.app
|
|||||||
|
|
||||||
import com.lt2333.simplicitytools.hook.app.android.DeleteOnPostNotification
|
import com.lt2333.simplicitytools.hook.app.android.DeleteOnPostNotification
|
||||||
import com.lt2333.simplicitytools.hook.app.android.DisableFlagSecure
|
import com.lt2333.simplicitytools.hook.app.android.DisableFlagSecure
|
||||||
|
import com.lt2333.simplicitytools.hook.app.android.corepatch.CorePatch
|
||||||
import de.robv.android.xposed.IXposedHookLoadPackage
|
import de.robv.android.xposed.IXposedHookLoadPackage
|
||||||
import de.robv.android.xposed.XposedBridge
|
import de.robv.android.xposed.XposedBridge
|
||||||
import de.robv.android.xposed.callbacks.XC_LoadPackage
|
import de.robv.android.xposed.callbacks.XC_LoadPackage
|
||||||
@@ -9,6 +10,8 @@ import de.robv.android.xposed.callbacks.XC_LoadPackage
|
|||||||
class Android : IXposedHookLoadPackage {
|
class Android : IXposedHookLoadPackage {
|
||||||
override fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam) {
|
override fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam) {
|
||||||
XposedBridge.log("成功Hook: "+javaClass.simpleName)
|
XposedBridge.log("成功Hook: "+javaClass.simpleName)
|
||||||
|
//核心破解
|
||||||
|
CorePatch().handleLoadPackage(lpparam)
|
||||||
//允许截图
|
//允许截图
|
||||||
DisableFlagSecure().handleLoadPackage(lpparam)
|
DisableFlagSecure().handleLoadPackage(lpparam)
|
||||||
//上层显示
|
//上层显示
|
||||||
|
|||||||
@@ -0,0 +1,171 @@
|
|||||||
|
/**
|
||||||
|
* 代码来自 https://github.com/LSPosed/CorePatch
|
||||||
|
* GPL-2.0 License
|
||||||
|
**/
|
||||||
|
|
||||||
|
package com.lt2333.simplicitytools.hook.app.android.corepatch;
|
||||||
|
|
||||||
|
import android.content.pm.ApplicationInfo;
|
||||||
|
import android.content.pm.Signature;
|
||||||
|
|
||||||
|
import com.lt2333.simplicitytools.BuildConfig;
|
||||||
|
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.security.cert.Certificate;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.zip.ZipEntry;
|
||||||
|
|
||||||
|
import de.robv.android.xposed.IXposedHookLoadPackage;
|
||||||
|
import de.robv.android.xposed.XC_MethodHook;
|
||||||
|
import de.robv.android.xposed.XSharedPreferences;
|
||||||
|
import de.robv.android.xposed.XposedHelpers;
|
||||||
|
import de.robv.android.xposed.callbacks.XC_LoadPackage;
|
||||||
|
|
||||||
|
public class CorePatch extends XposedHelper implements IXposedHookLoadPackage {
|
||||||
|
XSharedPreferences prefs = new XSharedPreferences(BuildConfig.APPLICATION_ID, "config");
|
||||||
|
String TAG = "ST-CorePatch";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws IllegalAccessException, InvocationTargetException, InstantiationException {
|
||||||
|
|
||||||
|
// 允许降级
|
||||||
|
findAndHookMethod("com.android.server.pm.PackageManagerService", loadPackageParam.classLoader,
|
||||||
|
"checkDowngrade",
|
||||||
|
"com.android.server.pm.parsing.pkg.AndroidPackage",
|
||||||
|
"android.content.pm.PackageInfoLite",
|
||||||
|
new ReturnConstant(prefs, "corepatch", null));
|
||||||
|
|
||||||
|
// apk内文件修改后 digest校验会失败
|
||||||
|
hookAllMethods("android.util.jar.StrictJarVerifier", loadPackageParam.classLoader, "verifyMessageDigest",
|
||||||
|
new ReturnConstant(prefs, "corepatch", true));
|
||||||
|
hookAllMethods("android.util.jar.StrictJarVerifier", loadPackageParam.classLoader, "verify",
|
||||||
|
new ReturnConstant(prefs, "corepatch", true));
|
||||||
|
hookAllMethods("java.security.MessageDigest", loadPackageParam.classLoader, "isEqual",
|
||||||
|
new ReturnConstant(prefs, "corepatch", 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));
|
||||||
|
|
||||||
|
// 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));
|
||||||
|
findAndHookMethod("com.android.apksig.ApkVerifier", loadPackageParam.classLoader, "getMinimumSignatureSchemeVersionForTargetSdk", int.class,
|
||||||
|
new ReturnConstant(prefs, "corepatch", 0));
|
||||||
|
|
||||||
|
// Package " + packageName + " signatures do not match previously installed version; ignoring!"
|
||||||
|
// public boolean checkCapability(String sha256String, @CertCapabilities int flags) {
|
||||||
|
// public boolean checkCapability(SigningDetails oldDetails, @CertCapabilities int flags)
|
||||||
|
hookAllMethods("android.content.pm.PackageParser", loadPackageParam.classLoader, "checkCapability", new XC_MethodHook() {
|
||||||
|
@Override
|
||||||
|
protected void beforeHookedMethod(MethodHookParam param) {
|
||||||
|
// 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 ((Integer) param.args[1] != 4) {
|
||||||
|
param.setResult(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 当verifyV1Signature抛出转换异常时,替换一个签名作为返回值
|
||||||
|
// 如果用户已安装apk,并且其定义了私有权限,则安装时会因签名与模块内硬编码的不一致而被拒绝。尝试从待安装apk中获取签名。如果其中apk的签名和已安装的一致(只动了内容)就没有问题。此策略可能有潜在的安全隐患。
|
||||||
|
Class<?> pkc = XposedHelpers.findClass("sun.security.pkcs.PKCS7", loadPackageParam.classLoader);
|
||||||
|
Constructor<?> constructor = XposedHelpers.findConstructorExact(pkc, byte[].class);
|
||||||
|
constructor.setAccessible(true);
|
||||||
|
Class<?> ASV = XposedHelpers.findClass("android.util.apk.ApkSignatureVerifier", loadPackageParam.classLoader);
|
||||||
|
Class<?> sJarClass = XposedHelpers.findClass("android.util.jar.StrictJarFile", loadPackageParam.classLoader);
|
||||||
|
Constructor<?> constructorExact = XposedHelpers.findConstructorExact(sJarClass, String.class, boolean.class, boolean.class);
|
||||||
|
constructorExact.setAccessible(true);
|
||||||
|
Class<?> signingDetails = XposedHelpers.findClass("android.content.pm.PackageParser.SigningDetails", loadPackageParam.classLoader);
|
||||||
|
Constructor<?> findConstructorExact = XposedHelpers.findConstructorExact(signingDetails, Signature[].class, Integer.TYPE);
|
||||||
|
findConstructorExact.setAccessible(true);
|
||||||
|
Class<?> packageParserException = XposedHelpers.findClass("android.content.pm.PackageParser.PackageParserException", loadPackageParam.classLoader);
|
||||||
|
Field error = XposedHelpers.findField(packageParserException, "error");
|
||||||
|
error.setAccessible(true);
|
||||||
|
Object[] signingDetailsArgs = new Object[2];
|
||||||
|
signingDetailsArgs[1] = 1;
|
||||||
|
|
||||||
|
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)) {
|
||||||
|
Throwable throwable = methodHookParam.getThrowable();
|
||||||
|
if (throwable != null) {
|
||||||
|
Signature[] lastSigs = null;
|
||||||
|
if (prefs.getBoolean("corepatch", 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 {
|
||||||
|
signingDetailsArgs[0] = new Signature[]{new Signature(SIGNATURE)};
|
||||||
|
}
|
||||||
|
Object newInstance = findConstructorExact.newInstance(signingDetailsArgs);
|
||||||
|
|
||||||
|
//修复 java.lang.ClassCastException: Cannot cast android.content.pm.PackageParser$SigningDetails to android.util.apk.ApkSignatureVerifier$SigningDetailsWithDigests
|
||||||
|
Class<?> signingDetailsWithDigests = XposedHelpers.findClassIfExists("android.util.apk.ApkSignatureVerifier.SigningDetailsWithDigests", loadPackageParam.classLoader);
|
||||||
|
if (signingDetailsWithDigests != null) {
|
||||||
|
Constructor<?> signingDetailsWithDigestsConstructorExact = XposedHelpers.findConstructorExact(signingDetailsWithDigests, signingDetails, Map.class);
|
||||||
|
signingDetailsWithDigestsConstructorExact.setAccessible(true);
|
||||||
|
newInstance = signingDetailsWithDigestsConstructorExact.newInstance(newInstance, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
Throwable cause = throwable.getCause();
|
||||||
|
if (throwable.getClass() == packageParserException) {
|
||||||
|
if (error.getInt(throwable) == -103) {
|
||||||
|
methodHookParam.setResult(newInstance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (cause != null && cause.getClass() == packageParserException) {
|
||||||
|
if (error.getInt(cause) == -103) {
|
||||||
|
methodHookParam.setResult(newInstance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
//New package has a different signature
|
||||||
|
//处理覆盖安装但签名不一致
|
||||||
|
hookAllMethods(signingDetails, "checkCapability", new XC_MethodHook() {
|
||||||
|
@Override
|
||||||
|
protected void beforeHookedMethod(MethodHookParam param) {
|
||||||
|
// 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)) {
|
||||||
|
param.setResult(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// if app is system app, allow to use hidden api, even if app not using a system signature
|
||||||
|
findAndHookMethod("android.content.pm.ApplicationInfo", loadPackageParam.classLoader, "isPackageWhitelistedForHiddenApis", new XC_MethodHook() {
|
||||||
|
@Override
|
||||||
|
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
|
||||||
|
super.beforeHookedMethod(param);
|
||||||
|
if (prefs.getBoolean("corepatch", true)) {
|
||||||
|
ApplicationInfo info = (ApplicationInfo) param.thisObject;
|
||||||
|
if ((info.flags & ApplicationInfo.FLAG_SYSTEM) != 0
|
||||||
|
|| (info.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) {
|
||||||
|
param.setResult(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package com.lt2333.simplicitytools.hook.app.android.corepatch;
|
||||||
|
|
||||||
|
import de.robv.android.xposed.XC_MethodHook;
|
||||||
|
import de.robv.android.xposed.XSharedPreferences;
|
||||||
|
|
||||||
|
public class ReturnConstant extends XC_MethodHook {
|
||||||
|
private final XSharedPreferences prefs;
|
||||||
|
private final String prefsKey;
|
||||||
|
private final Object value;
|
||||||
|
|
||||||
|
public ReturnConstant(XSharedPreferences prefs, String prefsKey, Object value) {
|
||||||
|
this.prefs = prefs;
|
||||||
|
this.prefsKey = prefsKey;
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
|
||||||
|
super.beforeHookedMethod(param);
|
||||||
|
prefs.reload();
|
||||||
|
if (prefs.getBoolean(prefsKey, true)) {
|
||||||
|
param.setResult(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
package com.lt2333.simplicitytools.hook.app.android.corepatch;
|
||||||
|
|
||||||
|
import com.lt2333.simplicitytools.BuildConfig;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import de.robv.android.xposed.XC_MethodHook;
|
||||||
|
import de.robv.android.xposed.XposedBridge;
|
||||||
|
import de.robv.android.xposed.XposedHelpers;
|
||||||
|
|
||||||
|
public class XposedHelper {
|
||||||
|
public String SIGNATURE = "308203c6308202aea003020102021426d148b7c65944abcf3a683b4c3dd3b139c4ec85300d06092a864886f70d01010b05003074310b3009060355040613025553311330110603550408130a43616c69666f726e6961311630140603550407130d4d6f756e7461696e205669657731143012060355040a130b476f6f676c6520496e632e3110300e060355040b1307416e64726f69643110300e06035504031307416e64726f6964301e170d3139303130323138353233385a170d3439303130323138353233385a3074310b3009060355040613025553311330110603550408130a43616c69666f726e6961311630140603550407130d4d6f756e7461696e205669657731143012060355040a130b476f6f676c6520496e632e3110300e060355040b1307416e64726f69643110300e06035504031307416e64726f696430820122300d06092a864886f70d01010105000382010f003082010a028201010087fcde48d9beaeba37b733a397ae586fb42b6c3f4ce758dc3ef1327754a049b58f738664ece587994f1c6362f98c9be5fe82c72177260c390781f74a10a8a6f05a6b5ca0c7c5826e15526d8d7f0e74f2170064896b0cf32634a388e1a975ed6bab10744d9b371cba85069834bf098f1de0205cdee8e715759d302a64d248067a15b9beea11b61305e367ac71b1a898bf2eec7342109c9c5813a579d8a1b3e6a3fe290ea82e27fdba748a663f73cca5807cff1e4ad6f3ccca7c02945926a47279d1159599d4ecf01c9d0b62e385c6320a7a1e4ddc9833f237e814b34024b9ad108a5b00786ea15593a50ca7987cbbdc203c096eed5ff4bf8a63d27d33ecc963990203010001a350304e300c0603551d13040530030101ff301d0603551d0e04160414a361efb002034d596c3a60ad7b0332012a16aee3301f0603551d23041830168014a361efb002034d596c3a60ad7b0332012a16aee3300d06092a864886f70d01010b0500038201010022ccb684a7a8706f3ee7c81d6750fd662bf39f84805862040b625ddf378eeefae5a4f1f283deea61a3c7f8e7963fd745415153a531912b82b596e7409287ba26fb80cedba18f22ae3d987466e1fdd88e440402b2ea2819db5392cadee501350e81b8791675ea1a2ed7ef7696dff273f13fb742bb9625fa12ce9c2cb0b7b3d94b21792f1252b1d9e4f7012cb341b62ff556e6864b40927e942065d8f0f51273fcda979b8832dd5562c79acf719de6be5aee2a85f89265b071bf38339e2d31041bc501d5e0c034ab1cd9c64353b10ee70b49274093d13f733eb9d3543140814c72f8e003f301c7a00b1872cc008ad55e26df2e8f07441002c4bcb7dc746745f0db";
|
||||||
|
|
||||||
|
public static void findAndHookMethod(String p1, ClassLoader lpparam, String p2, Object... parameterTypesAndCallback) {
|
||||||
|
try {
|
||||||
|
if (findClass(p1, lpparam) != null) {
|
||||||
|
XposedHelpers.findAndHookMethod(p1, lpparam, p2, parameterTypesAndCallback);
|
||||||
|
}
|
||||||
|
} catch (Throwable e) {
|
||||||
|
if (BuildConfig.DEBUG)
|
||||||
|
XposedBridge.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void hookAllMethods(String p1, ClassLoader lpparam, String methodName, XC_MethodHook parameterTypesAndCallback) {
|
||||||
|
try {
|
||||||
|
Class<?> packageParser = findClass(p1, lpparam);
|
||||||
|
XposedBridge.hookAllMethods(packageParser, methodName, parameterTypesAndCallback);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
if (BuildConfig.DEBUG)
|
||||||
|
XposedBridge.log(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void hookAllMethods(Class<?> packageManagerServiceUtils, String verifySignatures, XC_MethodHook methodHook) {
|
||||||
|
try {
|
||||||
|
XposedBridge.hookAllMethods(packageManagerServiceUtils, verifySignatures, methodHook);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
if (BuildConfig.DEBUG)
|
||||||
|
XposedBridge.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Class<?> findClass(String className, ClassLoader classLoader) {
|
||||||
|
try {
|
||||||
|
return Class.forName(className, false, classLoader);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
if (BuildConfig.DEBUG)
|
||||||
|
XposedBridge.log(e);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void hookAllConstructors(String p1, XC_MethodHook parameterTypesAndCallback) {
|
||||||
|
try {
|
||||||
|
Class<?> packageParser = findClass(p1, null);
|
||||||
|
hookAllConstructors(packageParser, parameterTypesAndCallback);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
if (BuildConfig.DEBUG)
|
||||||
|
XposedBridge.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Set<XC_MethodHook.Unhook> hookAllConstructors(Class<?> hookClass, XC_MethodHook callback) {
|
||||||
|
try {
|
||||||
|
return XposedBridge.hookAllConstructors(hookClass, callback);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
if (BuildConfig.DEBUG)
|
||||||
|
XposedBridge.log(e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user