*/ SharedUserSetting_packages(param.thisObject);
369 | var size = (int) XposedHelpers.callMethod(packages, "size");
370 | for (var i = 0; i < size; i++) {
371 | var p = XposedHelpers.callMethod(packages, "valueAt", i);
372 | if (toAdd.equals(p)) {
373 | // must be an existing package
374 | added = true;
375 | p = toAdd;
376 | }
377 | var packageSig = Setting_getSigningDetails(p);
378 | // if old signing exists, return
379 | if ((boolean) callOriginMethod(packageSig, "checkCapability", sharedUserSig, 0) || (boolean) callOriginMethod(sharedUserSig, "checkCapability", packageSig, 0)) {
380 | return;
381 | }
382 | // otherwise, choose the first signature we meet, and merge with others if possible
383 | // https://cs.android.com/android/platform/superproject/main/+/main:frameworks/base/services/core/java/com/android/server/pm/ReconcilePackageUtils.java;l=193;drc=c9a8baf585e8eb0f3272443930301a61331b65c1
384 | // respect to system
385 | if (newSig == null) newSig = packageSig;
386 | else newSig = SigningDetails_mergeLineageWith(newSig, packageSig);
387 | }
388 | if (!added || newSig == null) return;
389 | XposedBridge.log("CorePatch: updating signature in sharedUser during add " + toAdd + ": " + param.thisObject);
390 | Setting_setSigningDetails(param.thisObject, newSig);
391 | }
392 | }
393 | );
394 |
395 | hookAllMethods(getIsVerificationEnabledClass(loadPackageParam.classLoader), "isVerificationEnabled", new ReturnConstant(prefs, "disableVerificationAgent", false));
396 |
397 | if (BuildConfig.DEBUG) initializeDebugHook(loadPackageParam);
398 | }
399 |
400 | static Object callOriginMethod(Object obj, String methodName, Object... args) {
401 | try {
402 | var method = XposedHelpers.findMethodBestMatch(obj.getClass(), methodName, args);
403 | return XposedBridge.invokeOriginalMethod(method, obj, args);
404 | } catch (IllegalAccessException e) {
405 | // should not happen
406 | XposedBridge.log(e);
407 | throw new IllegalAccessError(e.getMessage());
408 | } catch (IllegalArgumentException e) {
409 | throw e;
410 | } catch (InvocationTargetException e) {
411 | throw new RuntimeException(e.getCause());
412 | }
413 | }
414 |
415 | Class> getIsVerificationEnabledClass(ClassLoader classLoader) {
416 | return XposedHelpers.findClass("com.android.server.pm.PackageManagerService", classLoader);
417 | }
418 |
419 | Class> getSigningDetails(ClassLoader classLoader) {
420 | return XposedHelpers.findClass("android.content.pm.PackageParser.SigningDetails", classLoader);
421 | }
422 |
423 | Object mPMS = null;
424 |
425 | void initializeDebugHook(XC_LoadPackage.LoadPackageParam lpparam) throws IllegalAccessException, InvocationTargetException {
426 | XposedBridge.hookAllMethods(
427 | XposedHelpers.findClass("com.android.server.pm.PackageManagerShellCommand", lpparam.classLoader),
428 | "onCommand",
429 | new XC_MethodHook() {
430 | @Override
431 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
432 | try {
433 | var pms = mPMS;
434 | if (pms == null) return;
435 | var cmd = (String) param.args[0];
436 | if (!"corepatch".equals(cmd)) return;
437 | var self = param.thisObject;
438 | var pw = (PrintWriter) XposedHelpers.callMethod(self, "getOutPrintWriter");
439 | var type = (String) XposedHelpers.callMethod(self, "getNextArgRequired");
440 | var settings = XposedHelpers.getObjectField(pms, "mSettings");
441 | if ("p".equals(type) || "package".equals(type)) {
442 | var packageName = (String) XposedHelpers.callMethod(self, "getNextArgRequired");
443 | var packageSetting = XposedHelpers.callMethod(settings, "getPackageLPr", packageName);
444 | if (packageSetting != null) {
445 | dumpPackageSetting(packageSetting, pw, settings);
446 | } else {
447 | pw.println("no package " + packageName + " found");
448 | }
449 | } else if ("su".equals(type) || "shareduser".equals(type)) {
450 | var name = (String) XposedHelpers.callMethod(self, "getNextArgRequired");
451 | var su = getSharedUser(name, settings);
452 | if (su != null) {
453 | dumpSharedUserSetting(su, pw);
454 | } else {
455 | pw.println("no shared user " + name + " found");
456 | }
457 | } else {
458 | pw.println("usage: ");
459 | }
460 | param.setResult(0);
461 | } catch (Throwable t) {
462 | XposedBridge.log(t);
463 | param.setThrowable(t);
464 | }
465 | }
466 | }
467 | );
468 |
469 | var pmsClass = XposedHelpers.findClassIfExists("com.android.server.pm.PackageManagerService",
470 | lpparam.classLoader);
471 |
472 | XposedBridge.hookAllConstructors(pmsClass, new XC_MethodHook() {
473 | @Override
474 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {
475 | mPMS = param.thisObject;
476 | }
477 | }
478 | );
479 |
480 | deoptimizeMethod(pmsClass, "onShellCommand");
481 | }
482 |
483 | void dumpPackageSetting(Object packageSetting, PrintWriter pw, Object /*Settings*/ settings) {
484 | var signingDetails = Setting_getSigningDetails(packageSetting);
485 | pw.println("signing for package " + packageSetting);
486 | dumpSigningDetails(signingDetails, pw);
487 | var pkg = XposedHelpers.getObjectField(packageSetting, "pkg"); // AndroidPackage
488 | if (pkg == null) {
489 | pw.println("android package is null!");
490 | return;
491 | }
492 | var id = (String) XposedHelpers.callMethod(pkg, "getSharedUserId");
493 | pw.println("shared user id:" + id);
494 | if (settings != null) {
495 | var su = getSharedUser(id, settings);
496 | if (su != null) {
497 | dumpSharedUserSetting(su, pw);
498 | }
499 | }
500 | }
501 |
502 | Object getSharedUser(String id, Object /*Settings*/ settings) {
503 | // TODO: use Setting.getSharedUserSettingLPr(appId)?
504 | var sharedUserSettings = XposedHelpers.getObjectField(settings, "mSharedUsers");
505 | if (sharedUserSettings == null) return null;
506 | return XposedHelpers.callMethod(sharedUserSettings, "get", id);
507 | }
508 |
509 | void dumpSharedUserSetting(Object sharedUser, PrintWriter pw) {
510 | var signingDetails = Setting_getSigningDetails(sharedUser);
511 | pw.println("signing for shared user " + sharedUser);
512 | dumpSigningDetails(signingDetails, pw);
513 | }
514 |
515 | protected void dumpSigningDetails(Object signingDetails, PrintWriter pw) {
516 | var i = 0;
517 | for (var sign : (Signature[]) XposedHelpers.getObjectField(signingDetails, "signatures")) {
518 | i++;
519 | pw.println(i + ": " + sign.toCharsString());
520 | }
521 | }
522 |
523 | /**
524 | * Get signing details for PackageSetting or SharedUserSetting
525 | */
526 | Object Setting_getSigningDetails(Object pkgOrSharedUser) {
527 | // PackageSettingBase(A11)|PackageSetting(A13)|SharedUserSetting.signatures.mSigningDetails
528 | return XposedHelpers.getObjectField(XposedHelpers.getObjectField(pkgOrSharedUser, "signatures"), "mSigningDetails");
529 | }
530 |
531 | /**
532 | * Set signing details for PackageSetting or SharedUserSetting
533 | */
534 | void Setting_setSigningDetails(Object pkgOrSharedUser, Object signingDetails) {
535 | XposedHelpers.setObjectField(XposedHelpers.getObjectField(pkgOrSharedUser, "signatures"), "mSigningDetails", signingDetails);
536 | }
537 |
538 | protected Object SharedUserSetting_packages(Object /*SharedUserSetting*/ sharedUser) {
539 | return XposedHelpers.getObjectField(sharedUser, "packages");
540 | }
541 |
542 | protected Object SigningDetails_mergeLineageWith(Object self, Object other) {
543 | return XposedHelpers.callMethod(self, "mergeLineageWith", other);
544 | }
545 | }
546 |
--------------------------------------------------------------------------------
/app/src/main/java/toolkit/coderstory/CorePatchForS.java:
--------------------------------------------------------------------------------
1 | package toolkit.coderstory;
2 |
3 | import java.lang.reflect.InvocationTargetException;
4 |
5 | import de.robv.android.xposed.XC_MethodHook;
6 | import de.robv.android.xposed.XposedBridge;
7 | import de.robv.android.xposed.XposedHelpers;
8 | import de.robv.android.xposed.callbacks.XC_LoadPackage;
9 |
10 | public class CorePatchForS extends CorePatchForR {
11 | @Override
12 | public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws IllegalAccessException, InvocationTargetException, InstantiationException {
13 | super.handleLoadPackage(loadPackageParam);
14 | var pmService = XposedHelpers.findClassIfExists("com.android.server.pm.PackageManagerService",
15 | loadPackageParam.classLoader);
16 | if (pmService != null) {
17 | var doesSignatureMatchForPermissions = XposedHelpers.findMethodExactIfExists(pmService, "doesSignatureMatchForPermissions",
18 | String.class, "com.android.server.pm.parsing.pkg.ParsedPackage", int.class);
19 | if (doesSignatureMatchForPermissions != null) {
20 | XposedBridge.hookMethod(doesSignatureMatchForPermissions, new XC_MethodHook() {
21 | @Override
22 | protected void afterHookedMethod(MethodHookParam param) {
23 | if (prefs.getBoolean("digestCreak", true) && prefs.getBoolean("UsePreSig", false)) {
24 | //If we decide to crack this then at least make sure they are same apks, avoid another one that tries to impersonate.
25 | if (param.getResult().equals(false)) {
26 | String pPname = (String) XposedHelpers.callMethod(param.args[1], "getPackageName");
27 | if (pPname.contentEquals((String) param.args[0])) {
28 | param.setResult(true);
29 | }
30 | }
31 | }
32 | }
33 | });
34 | }
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/app/src/main/java/toolkit/coderstory/CorePatchForT.java:
--------------------------------------------------------------------------------
1 | package toolkit.coderstory;
2 |
3 | import android.content.pm.Signature;
4 |
5 | import java.io.PrintWriter;
6 | import java.lang.reflect.InvocationTargetException;
7 |
8 | import de.robv.android.xposed.XC_MethodHook;
9 | import de.robv.android.xposed.XposedBridge;
10 | import de.robv.android.xposed.XposedHelpers;
11 | import de.robv.android.xposed.callbacks.XC_LoadPackage;
12 |
13 | public class CorePatchForT extends CorePatchForS {
14 | @Override
15 | public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws IllegalAccessException, InvocationTargetException, InstantiationException {
16 | super.handleLoadPackage(loadPackageParam);
17 | var checkDowngrade = XposedHelpers.findMethodExactIfExists("com.android.server.pm.PackageManagerServiceUtils", loadPackageParam.classLoader,
18 | "checkDowngrade",
19 | "com.android.server.pm.parsing.pkg.AndroidPackage",
20 | "android.content.pm.PackageInfoLite");
21 | if (checkDowngrade != null) {
22 | XposedBridge.hookMethod(checkDowngrade, new ReturnConstant(prefs, "downgrade", null));
23 | }
24 |
25 | Class> signingDetails = getSigningDetails(loadPackageParam.classLoader);
26 | //New package has a different signature
27 | //处理覆盖安装但签名不一致
28 | hookAllMethods(signingDetails, "checkCapability", new XC_MethodHook() {
29 | @Override
30 | protected void beforeHookedMethod(MethodHookParam param) {
31 | // Don't handle PERMISSION & AUTH
32 | // Or applications will have all privileged permissions
33 | // https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/content/pm/PackageParser.java;l=5947?q=CertCapabilities
34 | // https://cs.android.com/android/platform/superproject/main/+/main:frameworks/base/services/core/java/com/android/server/accounts/AccountManagerService.java;l=5867
35 | if (prefs.getBoolean("digestCreak", true)) {
36 | if ((Integer) param.args[1] != 4 && (Integer) param.args[1] != 16) {
37 | param.setResult(true);
38 | }
39 | }
40 | }
41 | });
42 |
43 | Class> ParsedPackage = getParsedPackage(loadPackageParam.classLoader);
44 | findAndHookMethod("com.android.server.pm.InstallPackageHelper", loadPackageParam.classLoader,
45 | "doesSignatureMatchForPermissions", String.class,
46 | ParsedPackage, int.class, new XC_MethodHook() {
47 | @Override
48 | protected void afterHookedMethod(MethodHookParam param) {
49 | if (prefs.getBoolean("digestCreak", true) && prefs.getBoolean("UsePreSig", false)) {
50 | //If we decide to crack this then at least make sure they are same apks, avoid another one that tries to impersonate.
51 | if (param.getResult().equals(false)) {
52 | String pPname = (String) XposedHelpers.callMethod(param.args[1], "getPackageName");
53 | if (pPname.contentEquals((String) param.args[0])) {
54 | param.setResult(true);
55 | }
56 | }
57 | }
58 | }
59 | });
60 |
61 | var assertMinSignatureSchemeIsValid = XposedHelpers.findMethodExactIfExists("com.android.server.pm.ScanPackageUtils", loadPackageParam.classLoader,
62 | "assertMinSignatureSchemeIsValid",
63 | "com.android.server.pm.parsing.pkg.AndroidPackage", int.class);
64 | if (assertMinSignatureSchemeIsValid != null) {
65 | XposedBridge.hookMethod(assertMinSignatureSchemeIsValid, new XC_MethodHook() {
66 | @Override
67 | protected void afterHookedMethod(MethodHookParam param) {
68 | if (prefs.getBoolean("authcreak", false)) {
69 | param.setResult(null);
70 | }
71 | }
72 | });
73 | }
74 |
75 | Class> strictJarVerifier = findClass("android.util.jar.StrictJarVerifier", loadPackageParam.classLoader);
76 | if (strictJarVerifier != null) {
77 | XposedBridge.hookAllConstructors(strictJarVerifier, new XC_MethodHook() {
78 | @Override
79 | protected void afterHookedMethod(MethodHookParam param) {
80 | if (prefs.getBoolean("authcreak", false)) {
81 | XposedHelpers.setBooleanField(param.thisObject, "signatureSchemeRollbackProtectionsEnforced", false);
82 | }
83 | }
84 | });
85 | }
86 |
87 | // ensure verifySignatures success
88 | // https://cs.android.com/android/platform/superproject/main/+/main:frameworks/base/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java;l=621;drc=2e50991320cbef77d3e8504a4b284adae8c2f4d2
89 | var utils = XposedHelpers.findClassIfExists("com.android.server.pm.PackageManagerServiceUtils", loadPackageParam.classLoader);
90 | if (utils != null) {
91 | deoptimizeMethod(utils, "canJoinSharedUserId");
92 | }
93 | }
94 |
95 | Class> getParsedPackage(ClassLoader classLoader) {
96 | return XposedHelpers.findClassIfExists("com.android.server.pm.parsing.pkg.ParsedPackage", classLoader);
97 | }
98 |
99 | Class> getSigningDetails(ClassLoader classLoader) {
100 | return XposedHelpers.findClassIfExists("android.content.pm.SigningDetails", classLoader);
101 | }
102 |
103 | @Override
104 | protected void dumpSigningDetails(Object signingDetails, PrintWriter pw) {
105 | var i = 0;
106 | for (var sign : (Signature[]) XposedHelpers.callMethod(signingDetails, "getSignatures")) {
107 | i++;
108 | pw.println(i + ": " + sign.toCharsString());
109 | }
110 | }
111 |
112 | @Override
113 | protected Object SharedUserSetting_packages(Object sharedUser) {
114 | return XposedHelpers.getObjectField(sharedUser, "mPackages");
115 | }
116 |
117 | @Override
118 | protected Object SigningDetails_mergeLineageWith(Object self, Object other) {
119 | return XposedHelpers.callMethod(self, "mergeLineageWith", other, 2 /*MERGE_RESTRICTED_CAPABILITY*/);
120 | }
121 |
122 | @Override
123 | Class> getIsVerificationEnabledClass(ClassLoader classLoader) {
124 | return XposedHelpers.findClass("com.android.server.pm.VerificationParams", classLoader);
125 | }
126 | }
127 |
--------------------------------------------------------------------------------
/app/src/main/java/toolkit/coderstory/CorePatchForU.java:
--------------------------------------------------------------------------------
1 | package toolkit.coderstory;
2 |
3 | import android.util.Log;
4 |
5 | import java.lang.reflect.InvocationTargetException;
6 |
7 | import de.robv.android.xposed.XC_MethodHook;
8 | import de.robv.android.xposed.XposedBridge;
9 | import de.robv.android.xposed.XposedHelpers;
10 | import de.robv.android.xposed.callbacks.XC_LoadPackage;
11 |
12 | public class CorePatchForU extends CorePatchForT {
13 | @Override
14 | public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws IllegalAccessException, InvocationTargetException, InstantiationException {
15 | super.handleLoadPackage(loadPackageParam);
16 | var utilClass = findClass("com.android.server.pm.ReconcilePackageUtils", loadPackageParam.classLoader);
17 | if (utilClass != null) {
18 | try {
19 | deoptimizeMethod(utilClass, "reconcilePackages");
20 | } catch (Throwable e) {
21 | XposedBridge.log("E/" + MainHook.TAG + " deoptimizing failed" + Log.getStackTraceString(e));
22 | }
23 | }
24 |
25 | // https://cs.android.com/android/platform/superproject/+/android-14.0.0_r60:frameworks/base/services/core/java/com/android/server/pm/ReconcilePackageUtils.java;l=61;bpv=1;bpt=0
26 | if (prefs.getBoolean("digestCreak", true) && prefs.getBoolean("sharedUser", false)) {
27 | setStaticBooleanField(utilClass, "ALLOW_NON_PRELOADS_SYSTEM_SHAREDUIDS", true);
28 | }
29 |
30 | // ee11a9c (Rename AndroidPackageApi to AndroidPackage)
31 | findAndHookMethod("com.android.server.pm.PackageManagerServiceUtils", loadPackageParam.classLoader,
32 | "checkDowngrade",
33 | "com.android.server.pm.pkg.AndroidPackage",
34 | "android.content.pm.PackageInfoLite",
35 | new ReturnConstant(prefs, "downgrade", null));
36 | findAndHookMethod("com.android.server.pm.ScanPackageUtils", loadPackageParam.classLoader,
37 | "assertMinSignatureSchemeIsValid",
38 | "com.android.server.pm.pkg.AndroidPackage", int.class,
39 | new XC_MethodHook() {
40 | @Override
41 | protected void afterHookedMethod(MethodHookParam param) {
42 | if (prefs.getBoolean("authcreak", false)) {
43 | param.setResult(null);
44 | }
45 | }
46 | });
47 |
48 | var ntService = XposedHelpers.findClassIfExists("com.nothing.server.ex.NtConfigListServiceImpl",
49 | loadPackageParam.classLoader);
50 | if (ntService != null) {
51 | findAndHookMethod(ntService, "isInstallingAppForbidden", java.lang.String.class,
52 | new ReturnConstant(prefs, "bypassBlock", false));
53 |
54 | findAndHookMethod(ntService, "isStartingAppForbidden", java.lang.String.class,
55 | new ReturnConstant(prefs, "bypassBlock", false));
56 | }
57 | }
58 |
59 | @Override
60 | Class> getParsedPackage(ClassLoader classLoader) {
61 | var clazz = XposedHelpers.findClassIfExists("com.android.internal.pm.parsing.pkg.ParsedPackage", classLoader);
62 | return clazz != null ? clazz : XposedHelpers.findClassIfExists("com.android.server.pm.parsing.pkg.ParsedPackage", classLoader);
63 | }
64 |
65 | @Override
66 | Class> getIsVerificationEnabledClass(ClassLoader classLoader) {
67 | return XposedHelpers.findClass("com.android.server.pm.VerifyingSession", classLoader);
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/app/src/main/java/toolkit/coderstory/CorePatchForV.java:
--------------------------------------------------------------------------------
1 | package toolkit.coderstory;
2 |
3 | import de.robv.android.xposed.XposedHelpers;
4 |
5 | public class CorePatchForV extends CorePatchForU {
6 | @Override
7 | Class> getParsedPackage(ClassLoader classLoader) {
8 | return XposedHelpers.findClassIfExists("com.android.internal.pm.parsing.pkg.ParsedPackage", classLoader);
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/app/src/main/java/toolkit/coderstory/MainHook.java:
--------------------------------------------------------------------------------
1 | package toolkit.coderstory;
2 |
3 | import android.os.Build;
4 |
5 | import com.coderstory.toolkit.BuildConfig;
6 |
7 | import de.robv.android.xposed.IXposedHookLoadPackage;
8 | import de.robv.android.xposed.XposedBridge;
9 | import de.robv.android.xposed.callbacks.XC_LoadPackage;
10 |
11 | public class MainHook implements IXposedHookLoadPackage {
12 | public static final String TAG = "CorePatch";
13 |
14 | @Override
15 | public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {
16 | if (("android".equals(lpparam.packageName)) && (lpparam.processName.equals("android"))) {
17 | if (BuildConfig.DEBUG)
18 | XposedBridge.log("D/" + TAG + " handleLoadPackage");
19 | switch (Build.VERSION.SDK_INT) {
20 | case Build.VERSION_CODES.BAKLAVA: // 36
21 | case Build.VERSION_CODES.VANILLA_ICE_CREAM: // 35
22 | new CorePatchForV().handleLoadPackage(lpparam);
23 | break;
24 | case Build.VERSION_CODES.UPSIDE_DOWN_CAKE: // 34
25 | new CorePatchForU().handleLoadPackage(lpparam);
26 | break;
27 | case Build.VERSION_CODES.TIRAMISU: // 33
28 | new CorePatchForT().handleLoadPackage(lpparam);
29 | break;
30 | case Build.VERSION_CODES.S_V2: // 32
31 | case Build.VERSION_CODES.S: // 31
32 | new CorePatchForS().handleLoadPackage(lpparam);
33 | break;
34 | case Build.VERSION_CODES.R: // 30
35 | new CorePatchForR().handleLoadPackage(lpparam);
36 | break;
37 | case Build.VERSION_CODES.Q: // 29
38 | case Build.VERSION_CODES.P: // 28
39 | new CorePatchForQ().handleLoadPackage(lpparam);
40 | break;
41 | default:
42 | XposedBridge.log("W/" + TAG + " Unsupported Version of Android " + Build.VERSION.SDK_INT);
43 | XposedBridge.log("I/" + TAG + " Falling back to latest SDK");
44 | new CorePatchForV().handleLoadPackage(lpparam);
45 | break;
46 | }
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/app/src/main/java/toolkit/coderstory/ReturnConstant.java:
--------------------------------------------------------------------------------
1 | package toolkit.coderstory;
2 |
3 | import de.robv.android.xposed.XC_MethodHook;
4 | import de.robv.android.xposed.XSharedPreferences;
5 |
6 | public class ReturnConstant extends XC_MethodHook {
7 | private final XSharedPreferences prefs;
8 | private final String prefsKey;
9 | private final Object value;
10 |
11 | public ReturnConstant(XSharedPreferences prefs, String prefsKey, Object value) {
12 | this.prefs = prefs;
13 | this.prefsKey = prefsKey;
14 | this.value = value;
15 | }
16 |
17 | @Override
18 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
19 | prefs.reload();
20 | if (prefs.getBoolean(prefsKey, true)) {
21 | param.setResult(value);
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/app/src/main/java/toolkit/coderstory/SettingsActivity.java:
--------------------------------------------------------------------------------
1 | package toolkit.coderstory;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.app.Activity;
5 | import android.app.AlertDialog;
6 | import android.content.Context;
7 | import android.content.SharedPreferences;
8 | import android.graphics.Insets;
9 | import android.os.Build;
10 | import android.os.Bundle;
11 | import android.preference.PreferenceFragment;
12 | import android.view.View;
13 | import android.view.ViewGroup;
14 | import android.view.WindowInsets;
15 |
16 | import com.coderstory.toolkit.R;
17 |
18 | import java.lang.reflect.Method;
19 |
20 | @SuppressWarnings("deprecation")
21 | public class SettingsActivity extends Activity {
22 |
23 | @Override
24 | protected void onCreate(Bundle savedInstanceState) {
25 | super.onCreate(savedInstanceState);
26 | setContentView(R.layout.activity_settings);
27 | checkXSharedPreferences();
28 | if (savedInstanceState == null) {
29 | getFragmentManager().beginTransaction()
30 | .add(R.id.fragment_container, new SettingsFragment()).commit();
31 | }
32 | }
33 |
34 | @SuppressLint("WorldReadableFiles")
35 | private void checkXSharedPreferences() {
36 | try {
37 | // getSharedPreferences will hooked by LSPosed
38 | // will not throw SecurityException
39 | //noinspection deprecation
40 | getSharedPreferences("conf", Context.MODE_WORLD_READABLE);
41 | } catch (SecurityException exception) {
42 | new AlertDialog.Builder(this)
43 | .setTitle(R.string.config_error)
44 | .setMessage(R.string.not_supported)
45 | .setPositiveButton(android.R.string.ok, (dialog12, which) -> finish())
46 | .setNegativeButton(R.string.ignore, null)
47 | .show();
48 | }
49 | }
50 |
51 | public static class SettingsFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener {
52 | @Override
53 | public void onCreate(Bundle savedInstanceState) {
54 | super.onCreate(savedInstanceState);
55 | getPreferenceManager().setSharedPreferencesName("conf");
56 | addPreferencesFromResource(R.xml.prefs);
57 | }
58 |
59 | @Override
60 | public void onViewCreated(View view, Bundle savedInstanceState) {
61 | view.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
62 | view.setOnApplyWindowInsetsListener((v, windowInsets) -> {
63 | Insets insets = null;
64 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
65 | insets = windowInsets.getInsets(WindowInsets.Type.systemBars());
66 | } else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.Q) {
67 | insets = windowInsets.getSystemWindowInsets();
68 | }
69 | ViewGroup.MarginLayoutParams mlp = (ViewGroup.MarginLayoutParams) v.getLayoutParams();
70 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
71 | mlp.leftMargin = insets.left;
72 | mlp.bottomMargin = insets.bottom;
73 | mlp.rightMargin = insets.right;
74 | mlp.topMargin = insets.top;
75 | } else {
76 | mlp.leftMargin = windowInsets.getSystemWindowInsetLeft();
77 | mlp.bottomMargin = windowInsets.getSystemWindowInsetBottom();
78 | mlp.rightMargin = windowInsets.getSystemWindowInsetRight();
79 | mlp.topMargin = windowInsets.getSystemWindowInsetTop();
80 | }
81 | v.setLayoutParams(mlp);
82 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
83 | return WindowInsets.CONSUMED;
84 | } else return windowInsets.consumeSystemWindowInsets();
85 | });
86 | super.onViewCreated(view, savedInstanceState);
87 | }
88 |
89 | @Override
90 | public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
91 | if (key.equals("UsePreSig") && sharedPreferences.getBoolean(key, false)) {
92 | try {
93 | @SuppressLint("PrivateApi") Class> c = Class.forName("android.os.SystemProperties");
94 | Method get = c.getMethod("get", String.class);
95 | if (!((String) get.invoke(c, "ro.miui.ui.version.code")).isEmpty()) {
96 | new AlertDialog.Builder(getActivity()).setMessage(R.string.miui_usepresig_warn).setPositiveButton(android.R.string.ok, null).show();
97 | }
98 | } catch (Exception ignored) {
99 | }
100 |
101 | new AlertDialog.Builder(getActivity()).setMessage(R.string.usepresig_warn).setPositiveButton(android.R.string.ok, null).show();
102 | }
103 | }
104 |
105 | @Override
106 | public void onResume() {
107 | super.onResume();
108 | getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
109 | }
110 |
111 | @Override
112 | public void onPause() {
113 | super.onPause();
114 | getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
115 | }
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/app/src/main/java/toolkit/coderstory/XposedHelper.java:
--------------------------------------------------------------------------------
1 | package toolkit.coderstory;
2 |
3 | import android.util.Log;
4 |
5 | import com.coderstory.toolkit.BuildConfig;
6 |
7 | import de.robv.android.xposed.XC_MethodHook;
8 | import de.robv.android.xposed.XposedBridge;
9 | import de.robv.android.xposed.XposedHelpers;
10 |
11 | public class XposedHelper {
12 | public final String SIGNATURE = "308203c6308202aea003020102021426d148b7c65944abcf3a683b4c3dd3b139c4ec85300d06092a864886f70d01010b05003074310b3009060355040613025553311330110603550408130a43616c69666f726e6961311630140603550407130d4d6f756e7461696e205669657731143012060355040a130b476f6f676c6520496e632e3110300e060355040b1307416e64726f69643110300e06035504031307416e64726f6964301e170d3139303130323138353233385a170d3439303130323138353233385a3074310b3009060355040613025553311330110603550408130a43616c69666f726e6961311630140603550407130d4d6f756e7461696e205669657731143012060355040a130b476f6f676c6520496e632e3110300e060355040b1307416e64726f69643110300e06035504031307416e64726f696430820122300d06092a864886f70d01010105000382010f003082010a028201010087fcde48d9beaeba37b733a397ae586fb42b6c3f4ce758dc3ef1327754a049b58f738664ece587994f1c6362f98c9be5fe82c72177260c390781f74a10a8a6f05a6b5ca0c7c5826e15526d8d7f0e74f2170064896b0cf32634a388e1a975ed6bab10744d9b371cba85069834bf098f1de0205cdee8e715759d302a64d248067a15b9beea11b61305e367ac71b1a898bf2eec7342109c9c5813a579d8a1b3e6a3fe290ea82e27fdba748a663f73cca5807cff1e4ad6f3ccca7c02945926a47279d1159599d4ecf01c9d0b62e385c6320a7a1e4ddc9833f237e814b34024b9ad108a5b00786ea15593a50ca7987cbbdc203c096eed5ff4bf8a63d27d33ecc963990203010001a350304e300c0603551d13040530030101ff301d0603551d0e04160414a361efb002034d596c3a60ad7b0332012a16aee3301f0603551d23041830168014a361efb002034d596c3a60ad7b0332012a16aee3300d06092a864886f70d01010b0500038201010022ccb684a7a8706f3ee7c81d6750fd662bf39f84805862040b625ddf378eeefae5a4f1f283deea61a3c7f8e7963fd745415153a531912b82b596e7409287ba26fb80cedba18f22ae3d987466e1fdd88e440402b2ea2819db5392cadee501350e81b8791675ea1a2ed7ef7696dff273f13fb742bb9625fa12ce9c2cb0b7b3d94b21792f1252b1d9e4f7012cb341b62ff556e6864b40927e942065d8f0f51273fcda979b8832dd5562c79acf719de6be5aee2a85f89265b071bf38339e2d31041bc501d5e0c034ab1cd9c64353b10ee70b49274093d13f733eb9d3543140814c72f8e003f301c7a00b1872cc008ad55e26df2e8f07441002c4bcb7dc746745f0db";
13 |
14 | public static void findAndHookMethod(String className, ClassLoader classLoader, String methodName, Object... parameterTypesAndCallback) {
15 | try {
16 | if (findClass(className, classLoader) != null) {
17 | XposedHelpers.findAndHookMethod(className, classLoader, methodName, parameterTypesAndCallback);
18 | }
19 | } catch (Throwable e) {
20 | if (BuildConfig.DEBUG)
21 | XposedBridge.log("E/" + MainHook.TAG + " " + Log.getStackTraceString(e));
22 | }
23 | }
24 |
25 | public static void findAndHookMethod(Class> clazz, String methodName, Object... parameterTypesAndCallback) {
26 | try {
27 | if (clazz != null) {
28 | XposedHelpers.findAndHookMethod(clazz, methodName, parameterTypesAndCallback);
29 | }
30 | } catch (Throwable e) {
31 | if (BuildConfig.DEBUG)
32 | XposedBridge.log("E/" + MainHook.TAG + " " + Log.getStackTraceString(e));
33 | }
34 | }
35 |
36 | public static void hookAllMethods(String className, ClassLoader classLoader, String methodName, XC_MethodHook callback) {
37 | try {
38 | Class> packageParser = findClass(className, classLoader);
39 | XposedBridge.hookAllMethods(packageParser, methodName, callback);
40 | } catch (Throwable e) {
41 | if (BuildConfig.DEBUG)
42 | XposedBridge.log("E/" + MainHook.TAG + " " + Log.getStackTraceString(e));
43 | }
44 | }
45 |
46 | public void hookAllMethods(Class> hookClass, String methodName, XC_MethodHook callback) {
47 | try {
48 | XposedBridge.hookAllMethods(hookClass, methodName, callback);
49 | } catch (Throwable e) {
50 | if (BuildConfig.DEBUG)
51 | XposedBridge.log("E/" + MainHook.TAG + " " + Log.getStackTraceString(e));
52 | }
53 | }
54 |
55 | public static void setStaticBooleanField(Class> hookClass, String fieldName, boolean value) {
56 | try {
57 | XposedHelpers.setStaticBooleanField(hookClass, fieldName, value);
58 | } catch (Throwable e) {
59 | if (BuildConfig.DEBUG)
60 | XposedBridge.log("E/" + MainHook.TAG + " " + Log.getStackTraceString(e));
61 | }
62 | }
63 |
64 | public static Class> findClass(String className, ClassLoader classLoader) {
65 | try {
66 | return Class.forName(className, false, classLoader);
67 | } catch (Throwable e) {
68 | if (BuildConfig.DEBUG)
69 | XposedBridge.log("E/" + MainHook.TAG + " " + Log.getStackTraceString(e));
70 | }
71 | return null;
72 | }
73 |
74 | public static void hookAllConstructors(String className, XC_MethodHook callback) {
75 | try {
76 | Class> packageParser = findClass(className, null);
77 | XposedBridge.hookAllConstructors(packageParser, callback);
78 | } catch (Throwable e) {
79 | if (BuildConfig.DEBUG)
80 | XposedBridge.log("E/" + MainHook.TAG + " " + Log.getStackTraceString(e));
81 | }
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values-fr/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Core Patch
3 | Patch pour Android 9-16
4 | Cette version est pour 10-15 uniquement.\nMerci d\’utiliser la dernière version de LSPosed.
5 | Permettre la rétrogradation
6 | Permettre la rétrogradation d\’applications.
7 | Désactiver la vérification digest
8 | Permettre l\’installation d\’applications après avoir modifier le fichier dans l\’apk (ignorer les erreures invalid digest).
9 | Désactiver la comparaison de signatures
10 | Permettre la réinstallation d\’application avec des signatures différentes.
11 | Utiliser les signatures installées
12 | Toujours utiliser les signatures depuis les applications déjà installées lors d\’installations.\n C\’est extrêmement dangereux.\n A activer uniquement lors ce que c\’est vraiment nécessaire!
13 | Réglages
14 | Ignorer
15 | Vous utilisez apparemment une ancienne version de LSPosed ou LSPosed n\’est pas activé, Merci de mettre LSPosed à jour ou de retenter après activation.
16 | UsePreSig ne fonctionne pas sur MiUI car son sous-système est beaucoup trop différent.\nNous n\’avons pas le temps de nous pencher sur ce cas.
17 | !! N\’importe quel apk peut remplacer celui déjà installé !!\nPrenez garde lors ce que vous installez des apk inconnus
18 |
19 |
--------------------------------------------------------------------------------
/app/src/main/res/values-in/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Core Patch
3 | Android 9-16 core patch
4 | Versi ini adalah untuk Android 9-16 saja.\nHarap gunakan versi LSPosed terbaru.
5 | Izinkan turun versi
6 | Izinkan turun versi aplikasi.
7 | Matikan verifikasi digest
8 | Izinkan pemasangan aplikasi setelah file dalam apk dimodifikasi (abaikan kesalahan digest yang tidak valid).
9 | Matikan pembanding signatures
10 | Izinkan pemasangan ulang aplikasi dengan signatures berbeda.
11 | Gunakan signatures terpasang
12 | Selalu gunakan signatures dari aplikasi yang sudah terpasang ketika memasang.\n Ini sangat berbahaya.\n Hanya aktifkan jika diperlukan sangad!
13 | Pengaturan
14 | Abaikan
15 | Inisialisasi konfigurasi gagal
16 | Sepertinya Anda menggunakan versi LSPosed yang jadul atau LSPosed tidak diaktifkan, harap perbarui LSPosed atau coba lagi setelah diaktifkan.
17 | Terobos blokiran
18 | Terobos daftar blokir dalam beberapa perangkat seperti Nothing Phone
19 | Gunakan signatures terpasang tidak bekerja di MiUI karena framework banyak dimodifikasi.\nKami tidak punya waktu untuk menyelidikinya.
20 | !! Segala apk dapat menggantikan aplikasi yang terpasang !!\nBerhati-hati ketika memasang apk antah-berantah
21 | Terobos verifikasi pengguna bersama
22 | Izinkan pemasangan aplikasi dengan signatures berbeda dari pengguna bersama-nya (\'Matikan pembanding signature\' harus diaktifkan juga)
23 | Matikan Agen Verifikasi Paket
24 | Contoh: Proteksi Google Play
25 |
26 |
--------------------------------------------------------------------------------
/app/src/main/res/values-it/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Core Patch
3 | Android 9-16 core patch
4 | Questa versione è solo per Android 9-16.\nPer favore utilizza la versione più recente di LSPosed.
5 | Consenti Downgrade
6 | Consenti il downgrade delle applicazioni.
7 | Disabilita verifica digest
8 | Consente l\'installazione di app dopo aver modificato il file nell\'apk (ignora l\'errore digest non valido).
9 | Disabilita il confronto delle firme
10 | Consenti la reinstallazione di app con firme diverse.
11 | Utilizza le firme installate
12 | Durante l\'installazione, utilizza sempre le firme delle app già installate.\n Questo è estremamente pericoloso.\n Abilitalo solo quando è veramente necessario!
13 | Impostazioni
14 | Ignora
15 | Inizializzazione della configurazione non riuscita
16 | Sembra che tu stia utilizzando una versione obsoleta di LSPosed oppure LSPosed non è attivato. Aggiorna LSPosed o riprova dopo l\'attivazione.
17 | Bypassa blocchi
18 | Bypassa la lista di blocco di alcuni dispositivi come Nothing Phone
19 | UsePreSig non funzionerà su MiUI perché il suo framework è troppo diverso. Non abbiamo tempo per seguire il caso.
20 | !! Qualsiasi apk può sovrascrivere quello installato !!\nFai attenzione quando installi un apk sconosciuto
21 | Bypassa verifica utente condiviso
22 | Consenti l\'installazione dell\'app con firma diversa da quella dell\'utente condiviso (deve essere abilitato anche \'Disabilita il confronto delle firme\')
23 |
24 |
--------------------------------------------------------------------------------
/app/src/main/res/values-ja/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Core Patch
4 | Android 9-16 コアパッチ
5 | このバージョンは、 Android 9-16 のみで動作します。\n最新版の LSPosed を使用してください。
6 | ダウングレードを許可する
7 | アプリのダウングレードを許可します。
8 | ダイジェストの検証を無効化する
9 | APK ファイルの変更後にアプリをインストールできるようにします。(無効なダイジェストのエラーを無視します)
10 | 署名の比較を無効化する
11 | 署名が異なるアプリの再インストールを許可します。
12 | インストールされている署名を使用する
13 | インストール時に、既にインストールされているアプリの署名を使用します。\nこの操作は、非常に危険です。\n本当に必要となる時のみ有効化してください!
14 | 設定
15 | 無視
16 | 構成の初期化に失敗しました
17 | 古いバージョンの LSPosed を使用しているか、LSPosed が有効化されていないようです。LSPosed を更新、有効化をした後に再試行をしてください。
18 | ブロックをバイパスする
19 | Nothing Phone などの一部のデバイスのブロックリストをバイパスします。
20 | インストールされている署名の使用は、フレームワークが大幅に変更されるため MIUI では動作しません。\nこの問題を解析をする時間がありません。
21 | !! どんな APK でもインストールされている APK を上書きできるようにします !!\n未知の APK をインストールする際は注意してください
22 |
23 |
--------------------------------------------------------------------------------
/app/src/main/res/values-ko/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Core Patch
3 | Android 9-16 core patch
4 | 이 버전은 Android 9-16 전용입니다.\nLSPosed의 최신 버전을 사용하십시오.
5 | 다운그레이드 허용
6 | 애플리케이션 다운그레이드를 허용합니다.
7 | 다이제스트 확인 비활성화
8 | apk의 파일을 수정한 후 앱을 설치할 수 있습니다. (잘못된 다이제스트 오류를 무시).
9 | 비교 서명 비활성화
10 | 다른 서명을 가진 앱을 재설치할 수 있습니다.
11 | 설치된 서명 사용
12 | 설치할 때는 항상 이미 설치된 앱의 서명을 사용하십시오.\n 이것은 매우 위험합니다.\n 정말로 필요한 경우에만 활성화하십시오!
13 | 설정
14 | 무시
15 | LSPosed의 오래된 버전을 사용 중이거나 LSPosed가 활성화되지 않은 것 같습니다. LSPosed를 업데이트하거나 활성화한 후 다시 시도하십시오.
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/values-night/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/values-pt-rBR/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Core Patch
3 | Android 9-16 core patch
4 | Esta versão é apenas para Android 9-16.\nPor favor, use a versão mais recente do LSPosed.
5 | Permitir downgrade
6 | Permite downgrade de apps
7 | Desativar verificação de integridade
8 | Permite instalar apps após modificar o arquivo no apk (ignorar erro de integridade inválido)
9 | Desativar comparação de assinaturas
10 | Permite a reinstalação do app com assinaturas diferentes
11 | Usar assinaturas instaladas
12 | Sempre use assinaturas de apps já instalados durante a instalação.\n Isso é extremamente perigoso.\n Ative apenas quando for realmente necessário!
13 | Configurações
14 | Ignorar
15 | Falha na inicialização da configuração
16 | Parece que você está usando uma versão desatualizada do LSPosed ou o LSPosed não está ativado. Atualize o LSPosed ou tente novamente após a ativação.
17 | Ignorar bloqueio
18 | Ignore a lista de bloqueio em alguns dispositivos como Nothing Phone
19 | Usar assinaturas instaladas não funcionará na MIUI porque sua estrutura muda muito.\nNão temos tempo para acompanhar o caso.
20 | !! Qualquer apk pode substituir o instalado !!\nTenha cuidado ao instalar apk desconhecido.
21 | Ignorar verificação de usuário compartilhado
22 | Permite instalar apps com assinaturas diferentes do usuário compartilhado (\'Desativar comparação de assinaturas\' também deve estar ativado)
23 | Desativar agente de verificação de pacotes
24 | Ex.: Google Play Protect
25 |
26 |
--------------------------------------------------------------------------------
/app/src/main/res/values-ru/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Использовать установленные подписи
4 | "При установке всегда используйте подписи из уже установленных приложений.
5 | Это крайне «опасно».
6 | Включайте только тогда, когда это действительно необходимо! "
7 | Core Patch
8 | Отключить проверку дайджеста
9 | Позволяет устанавливать приложения после изменения файла в apk (игнорировать недопустимую ошибку дайджеста).
10 | «Эта версия предназначена только для Android 9-16.
11 | Пожалуйста, используйте последнюю версию LSPposed. "
12 | Отключить сравнение подписей
13 | Разрешить переустановку приложения с другими подписями.
14 | Разрешить понижать версию.
15 | Разрешить переустановку приложений на прошлые версии.
16 | Игнорировать
17 | Android 9-16 core patch
18 | Похоже, вы используете устаревшую версию LSPposed или LSPposed не активирован, пожалуйста, обновите LSPposed или повторите попытку после активации.
19 | Настройки
20 |
21 |
--------------------------------------------------------------------------------
/app/src/main/res/values-zh-rCN/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | 核心破解
3 | Android 9-16 核心破解
4 | 此版本只支持 Android 9-16\n请安装最新版本的 LSPosed 框架,否则功能可能无法正确启用。
5 | 允许降级安装应用
6 | 允许应用在安装新版本的情况下直接覆盖安装旧版本
7 | 禁用软件包管理器签名验证
8 | 关闭安装应用时的签名验证,可以安装被篡改的应用
9 | 禁用 APK 签名验证
10 | 允许直接覆盖安装同包名不同签名的应用
11 | 安装时始终使用已装 APP 的签名
12 | 不是一般的危险,仅在绝对需要时启用
13 | 设置
14 | 忽略
15 | 模块未激活或正使用旧版 LSPosed,请激活模块或更新 LSPosed 后再试。
16 | 由于 MIUI 大幅度魔改了安卓框架,UsePreSig 无法正常工作\n我们没有时间溯源
17 | !!所有安装包可以覆盖已安装的 APP!!\n安装未知的安装包时请务必小心
18 | 绕过黑名单
19 | 绕过某些设备如 Nothing Phone 上的黑名单
20 | 配置初始化失败
21 | 绕过共享用户签名验证
22 | 允许安装与其共享用户签名不同的 app(需要同时打开“禁用APK签名验证”)
23 | 禁用安装包验证代理
24 | 如 Play 商店的保护机制
25 |
26 |
--------------------------------------------------------------------------------
/app/src/main/res/values-zh-rTW/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 核心修補
4 | Android 9-16 核心修補
5 | 此版本只支援 Android 9-16\n請安裝最新版本的 LSPosed 框架,否則功能可能無法正確啟用。
6 | 允許降版安裝應用程式
7 | 允許應用程式在安裝新版本的情況下直接覆蓋安裝舊版本
8 | 停用套裝安裝程式簽名驗證
9 | 停用安裝應用程式時的簽名驗證,可以安裝被修改的應用程式
10 | 停用 APK 簽名驗證
11 | 允許直接覆蓋安裝同套件名稱但不同簽名的應用程式
12 | 安裝時總是使用已安裝應用程式的簽名
13 | 不是一般的危險,只在絕對需要時啟用
14 | 設定
15 | 忽略
16 | 未啟用模組或正在使用舊版的 LSPosed,請啟用模組或是更新 LSPosed 模組後再試一次。
17 | 由於 MIUI 大幅度修改了 Android 框架,UsePreSig 無法正常運作\n我們沒有時間分析
18 | !!所有安裝檔可以覆蓋已安裝的應用程式!!\n安裝未知的安裝檔時請務必小心
19 | 繞過黑名單
20 | 繞過某些裝置如 Nothing Phone 上的黑名單
21 | 配置初始化失敗
22 |
23 |
--------------------------------------------------------------------------------
/app/src/main/res/values/array.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | - android
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Core Patch
3 | Android 9-16 core patch
4 | This version is for Android 9-16 only.\nPlease use the latest version of the LSPosed.
5 | Allow downgrade
6 | Allow downgrade applications.
7 | Disable digest verify
8 | Allows install apps after modify file in apk (ignore invalid digest error).
9 | Disable compare signatures
10 | Allow re-install app with different signatures.
11 | Use installed signatures
12 | Always use signatures from already installed apps when installing.\n This is extremely dangerous.\n Only enable when really needed!
13 | Settings
14 | Ignore
15 | Configuration initialization failed
16 | It seems that you are using an out dated version of LSPosed or LSPosed is not activated, please update LSPosed or try again after activated.
17 | Bypass block
18 | Bypass blocklist in some devices like Nothing Phone
19 | UsePreSig won\'t work on MiUI because its framework changes too much.\nWe don\'t have time to track the case.
20 | !! Any apk can override the installed one !!\nBe carefully when installing unknown apk
21 | Bypass shared user verify
22 | Allow install app with signature differ from its shared user (\'Disable compare signatures\' must be enabled too)
23 | Disable Package Verification Agent
24 | e.g. Google Play Protection
25 |
26 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/prefs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
10 |
15 |
20 |
21 |
26 |
27 |
32 |
33 |
38 |
39 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/build.gradle.kts:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 | buildscript {
3 |
4 | repositories {
5 | google()
6 | mavenCentral()
7 | }
8 | dependencies {
9 | classpath("com.android.tools.build:gradle:8.7.2")
10 | }
11 | }
12 |
13 | allprojects {
14 | repositories {
15 | google()
16 | mavenCentral()
17 | maven(url = "https://api.xposed.info/")
18 | }
19 | }
20 |
21 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | ## Project-wide Gradle settings.
2 | #
3 | # For more details on how to configure your build environment visit
4 | # http://www.gradle.org/docs/current/userguide/build_environment.html
5 | #
6 | # Specifies the JVM arguments used for the daemon process.
7 | # The setting is particularly useful for tweaking memory settings.
8 | # Default value: -Xmx1024m -XX:MaxPermSize=256m
9 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
10 | #
11 | # When configured, Gradle will run in incubating parallel mode.
12 | # This option should only be used with decoupled projects. More details, visit
13 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
14 | # org.gradle.parallel=true
15 | #Fri Nov 17 23:21:15 CST 2017
16 | android.useAndroidX=true
17 | android.enableAppCompileTimeRClass=true
18 | android.experimental.enableNewResourceShrinker.preciseShrinking=true
19 | android.nonFinalResIds=false
20 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LSPosed/CorePatch/daf30cb847d6210544ac81e8701713703843a274/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.11-bin.zip
4 | networkTimeout=10000
5 | validateDistributionUrl=true
6 | zipStoreBase=GRADLE_USER_HOME
7 | zipStorePath=wrapper/dists
8 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | #
4 | # Copyright © 2015-2021 the original authors.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # https://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | #
18 | # SPDX-License-Identifier: Apache-2.0
19 | #
20 |
21 | ##############################################################################
22 | #
23 | # Gradle start up script for POSIX generated by Gradle.
24 | #
25 | # Important for running:
26 | #
27 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
28 | # noncompliant, but you have some other compliant shell such as ksh or
29 | # bash, then to run this script, type that shell name before the whole
30 | # command line, like:
31 | #
32 | # ksh Gradle
33 | #
34 | # Busybox and similar reduced shells will NOT work, because this script
35 | # requires all of these POSIX shell features:
36 | # * functions;
37 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
38 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»;
39 | # * compound commands having a testable exit status, especially «case»;
40 | # * various built-in commands including «command», «set», and «ulimit».
41 | #
42 | # Important for patching:
43 | #
44 | # (2) This script targets any POSIX shell, so it avoids extensions provided
45 | # by Bash, Ksh, etc; in particular arrays are avoided.
46 | #
47 | # The "traditional" practice of packing multiple parameters into a
48 | # space-separated string is a well documented source of bugs and security
49 | # problems, so this is (mostly) avoided, by progressively accumulating
50 | # options in "$@", and eventually passing that to Java.
51 | #
52 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
53 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
54 | # see the in-line comments for details.
55 | #
56 | # There are tweaks for specific operating systems such as AIX, CygWin,
57 | # Darwin, MinGW, and NonStop.
58 | #
59 | # (3) This script is generated from the Groovy template
60 | # https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
61 | # within the Gradle project.
62 | #
63 | # You can find Gradle at https://github.com/gradle/gradle/.
64 | #
65 | ##############################################################################
66 |
67 | # Attempt to set APP_HOME
68 |
69 | # Resolve links: $0 may be a link
70 | app_path=$0
71 |
72 | # Need this for daisy-chained symlinks.
73 | while
74 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
75 | [ -h "$app_path" ]
76 | do
77 | ls=$( ls -ld "$app_path" )
78 | link=${ls#*' -> '}
79 | case $link in #(
80 | /*) app_path=$link ;; #(
81 | *) app_path=$APP_HOME$link ;;
82 | esac
83 | done
84 |
85 | # This is normally unused
86 | # shellcheck disable=SC2034
87 | APP_BASE_NAME=${0##*/}
88 | # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
89 | APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
90 | ' "$PWD" ) || exit
91 |
92 | # Use the maximum available, or set MAX_FD != -1 to use that value.
93 | MAX_FD=maximum
94 |
95 | warn () {
96 | echo "$*"
97 | } >&2
98 |
99 | die () {
100 | echo
101 | echo "$*"
102 | echo
103 | exit 1
104 | } >&2
105 |
106 | # OS specific support (must be 'true' or 'false').
107 | cygwin=false
108 | msys=false
109 | darwin=false
110 | nonstop=false
111 | case "$( uname )" in #(
112 | CYGWIN* ) cygwin=true ;; #(
113 | Darwin* ) darwin=true ;; #(
114 | MSYS* | MINGW* ) msys=true ;; #(
115 | NONSTOP* ) nonstop=true ;;
116 | esac
117 |
118 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
119 |
120 |
121 | # Determine the Java command to use to start the JVM.
122 | if [ -n "$JAVA_HOME" ] ; then
123 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
124 | # IBM's JDK on AIX uses strange locations for the executables
125 | JAVACMD=$JAVA_HOME/jre/sh/java
126 | else
127 | JAVACMD=$JAVA_HOME/bin/java
128 | fi
129 | if [ ! -x "$JAVACMD" ] ; then
130 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
131 |
132 | Please set the JAVA_HOME variable in your environment to match the
133 | location of your Java installation."
134 | fi
135 | else
136 | JAVACMD=java
137 | if ! command -v java >/dev/null 2>&1
138 | then
139 | die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
140 |
141 | Please set the JAVA_HOME variable in your environment to match the
142 | location of your Java installation."
143 | fi
144 | fi
145 |
146 | # Increase the maximum file descriptors if we can.
147 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
148 | case $MAX_FD in #(
149 | max*)
150 | # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
151 | # shellcheck disable=SC2039,SC3045
152 | MAX_FD=$( ulimit -H -n ) ||
153 | warn "Could not query maximum file descriptor limit"
154 | esac
155 | case $MAX_FD in #(
156 | '' | soft) :;; #(
157 | *)
158 | # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
159 | # shellcheck disable=SC2039,SC3045
160 | ulimit -n "$MAX_FD" ||
161 | warn "Could not set maximum file descriptor limit to $MAX_FD"
162 | esac
163 | fi
164 |
165 | # Collect all arguments for the java command, stacking in reverse order:
166 | # * args from the command line
167 | # * the main class name
168 | # * -classpath
169 | # * -D...appname settings
170 | # * --module-path (only if needed)
171 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
172 |
173 | # For Cygwin or MSYS, switch paths to Windows format before running java
174 | if "$cygwin" || "$msys" ; then
175 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
176 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
177 |
178 | JAVACMD=$( cygpath --unix "$JAVACMD" )
179 |
180 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
181 | for arg do
182 | if
183 | case $arg in #(
184 | -*) false ;; # don't mess with options #(
185 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
186 | [ -e "$t" ] ;; #(
187 | *) false ;;
188 | esac
189 | then
190 | arg=$( cygpath --path --ignore --mixed "$arg" )
191 | fi
192 | # Roll the args list around exactly as many times as the number of
193 | # args, so each arg winds up back in the position where it started, but
194 | # possibly modified.
195 | #
196 | # NB: a `for` loop captures its iteration list before it begins, so
197 | # changing the positional parameters here affects neither the number of
198 | # iterations, nor the values presented in `arg`.
199 | shift # remove old arg
200 | set -- "$@" "$arg" # push replacement arg
201 | done
202 | fi
203 |
204 |
205 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
206 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
207 |
208 | # Collect all arguments for the java command:
209 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
210 | # and any embedded shellness will be escaped.
211 | # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
212 | # treated as '${Hostname}' itself on the command line.
213 |
214 | set -- \
215 | "-Dorg.gradle.appname=$APP_BASE_NAME" \
216 | -classpath "$CLASSPATH" \
217 | org.gradle.wrapper.GradleWrapperMain \
218 | "$@"
219 |
220 | # Stop when "xargs" is not available.
221 | if ! command -v xargs >/dev/null 2>&1
222 | then
223 | die "xargs is not available"
224 | fi
225 |
226 | # Use "xargs" to parse quoted args.
227 | #
228 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed.
229 | #
230 | # In Bash we could simply go:
231 | #
232 | # readarray ARGS < <( xargs -n1 <<<"$var" ) &&
233 | # set -- "${ARGS[@]}" "$@"
234 | #
235 | # but POSIX shell has neither arrays nor command substitution, so instead we
236 | # post-process each arg (as a line of input to sed) to backslash-escape any
237 | # character that might be a shell metacharacter, then use eval to reverse
238 | # that process (while maintaining the separation between arguments), and wrap
239 | # the whole thing up as a single "set" statement.
240 | #
241 | # This will of course break if any of these variables contains a newline or
242 | # an unmatched quote.
243 | #
244 |
245 | eval "set -- $(
246 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
247 | xargs -n1 |
248 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
249 | tr '\n' ' '
250 | )" '"$@"'
251 |
252 | exec "$JAVACMD" "$@"
253 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 | @rem SPDX-License-Identifier: Apache-2.0
17 | @rem
18 |
19 | @if "%DEBUG%"=="" @echo off
20 | @rem ##########################################################################
21 | @rem
22 | @rem Gradle startup script for Windows
23 | @rem
24 | @rem ##########################################################################
25 |
26 | @rem Set local scope for the variables with windows NT shell
27 | if "%OS%"=="Windows_NT" setlocal
28 |
29 | set DIRNAME=%~dp0
30 | if "%DIRNAME%"=="" set DIRNAME=.
31 | @rem This is normally unused
32 | set APP_BASE_NAME=%~n0
33 | set APP_HOME=%DIRNAME%
34 |
35 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
36 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
37 |
38 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
39 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
40 |
41 | @rem Find java.exe
42 | if defined JAVA_HOME goto findJavaFromJavaHome
43 |
44 | set JAVA_EXE=java.exe
45 | %JAVA_EXE% -version >NUL 2>&1
46 | if %ERRORLEVEL% equ 0 goto execute
47 |
48 | echo. 1>&2
49 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
50 | echo. 1>&2
51 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2
52 | echo location of your Java installation. 1>&2
53 |
54 | goto fail
55 |
56 | :findJavaFromJavaHome
57 | set JAVA_HOME=%JAVA_HOME:"=%
58 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
59 |
60 | if exist "%JAVA_EXE%" goto execute
61 |
62 | echo. 1>&2
63 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
64 | echo. 1>&2
65 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2
66 | echo location of your Java installation. 1>&2
67 |
68 | goto fail
69 |
70 | :execute
71 | @rem Setup the command line
72 |
73 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
74 |
75 |
76 | @rem Execute Gradle
77 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
78 |
79 | :end
80 | @rem End local scope for the variables with windows NT shell
81 | if %ERRORLEVEL% equ 0 goto mainEnd
82 |
83 | :fail
84 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
85 | rem the _cmd.exe /c_ return code!
86 | set EXIT_CODE=%ERRORLEVEL%
87 | if %EXIT_CODE% equ 0 set EXIT_CODE=1
88 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
89 | exit /b %EXIT_CODE%
90 |
91 | :mainEnd
92 | if "%OS%"=="Windows_NT" endlocal
93 |
94 | :omega
95 |
--------------------------------------------------------------------------------
/settings.gradle.kts:
--------------------------------------------------------------------------------
1 | include(":app")
2 |
--------------------------------------------------------------------------------