From 1f6fadf058c6f5df8be507e93b54fef1dcc33743 Mon Sep 17 00:00:00 2001 From: chiteroman <98092901+chiteroman@users.noreply.github.com> Date: Thu, 8 Feb 2024 12:33:37 +0100 Subject: [PATCH] v15.7.2 --- app/build.gradle.kts | 4 +- app/src/main/cpp/main.cpp | 12 +-- .../playintegrityfix/CustomKeyStoreSpi.java | 2 +- .../playintegrityfix/CustomProvider.java | 6 +- .../playintegrityfix/EntryPoint.java | 6 +- module/module.prop | 4 +- module/post-fs-data.sh | 27 +++++++ module/service.sh | 80 ++++++++----------- 8 files changed, 81 insertions(+), 60 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index a6663bbe..22deba99 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -12,8 +12,8 @@ android { applicationId = "es.chiteroman.playintegrityfix" minSdk = 26 targetSdk = 34 - versionCode = 15701 - versionName = "v15.7.1" + versionCode = 15702 + versionName = "v15.7.2" multiDexEnabled = false buildFeatures { diff --git a/app/src/main/cpp/main.cpp b/app/src/main/cpp/main.cpp index 836cd349..b5e914b4 100644 --- a/app/src/main/cpp/main.cpp +++ b/app/src/main/cpp/main.cpp @@ -16,11 +16,13 @@ static std::string FIRST_API_LEVEL, SECURITY_PATCH, BUILD_ID; typedef void (*T_Callback)(void *, const char *, const char *, uint32_t); -static T_Callback o_callback = nullptr; +static std::map callbacks; static void modify_callback(void *cookie, const char *name, const char *value, uint32_t serial) { - if (cookie == nullptr || name == nullptr || value == nullptr || o_callback == nullptr) return; + if (cookie == nullptr || name == nullptr || value == nullptr || + !callbacks.contains(cookie)) + return; std::string_view prop(name); @@ -52,7 +54,7 @@ static void modify_callback(void *cookie, const char *name, const char *value, u } - return o_callback(cookie, name, value, serial); + return callbacks[cookie](cookie, name, value, serial); } static void (*o_system_property_read_callback)(const void *, T_Callback, void *); @@ -62,12 +64,12 @@ my_system_property_read_callback(const void *pi, T_Callback callback, void *cook if (pi == nullptr || callback == nullptr || cookie == nullptr) { return o_system_property_read_callback(pi, callback, cookie); } - o_callback = callback; + callbacks[cookie] = callback; return o_system_property_read_callback(pi, modify_callback, cookie); } static void doHook() { - void *handle = DobbySymbolResolver("libc.so", "__system_property_read_callback"); + void *handle = DobbySymbolResolver(nullptr, "__system_property_read_callback"); if (handle == nullptr) { LOGD("Couldn't hook '__system_property_read_callback'. Report to @chiteroman"); return; diff --git a/app/src/main/java/es/chiteroman/playintegrityfix/CustomKeyStoreSpi.java b/app/src/main/java/es/chiteroman/playintegrityfix/CustomKeyStoreSpi.java index 72ec9a37..078c8cea 100644 --- a/app/src/main/java/es/chiteroman/playintegrityfix/CustomKeyStoreSpi.java +++ b/app/src/main/java/es/chiteroman/playintegrityfix/CustomKeyStoreSpi.java @@ -15,7 +15,7 @@ import java.util.Locale; public final class CustomKeyStoreSpi extends KeyStoreSpi { - public static volatile KeyStoreSpi keyStoreSpi; + public static volatile KeyStoreSpi keyStoreSpi = null; @Override public Key engineGetKey(String alias, char[] password) throws NoSuchAlgorithmException, UnrecoverableKeyException { diff --git a/app/src/main/java/es/chiteroman/playintegrityfix/CustomProvider.java b/app/src/main/java/es/chiteroman/playintegrityfix/CustomProvider.java index e577a91b..f743e145 100644 --- a/app/src/main/java/es/chiteroman/playintegrityfix/CustomProvider.java +++ b/app/src/main/java/es/chiteroman/playintegrityfix/CustomProvider.java @@ -4,19 +4,19 @@ public final class CustomProvider extends Provider { - public CustomProvider(Provider provider) { + public CustomProvider(Provider provider, boolean spoof) { super(provider.getName(), provider.getVersion(), provider.getInfo()); putAll(provider); - put("KeyStore.AndroidKeyStore", CustomKeyStoreSpi.class.getName()); + if (spoof) put("KeyStore.AndroidKeyStore", CustomKeyStoreSpi.class.getName()); } @Override public synchronized Service getService(String type, String algorithm) { EntryPoint.LOG(String.format("Service: '%s' | Algorithm: '%s'", type, algorithm)); - EntryPoint.spoofFields(); + if ("AndroidKeyStore".equals(algorithm)) EntryPoint.spoofFields(); return super.getService(type, algorithm); } diff --git a/app/src/main/java/es/chiteroman/playintegrityfix/EntryPoint.java b/app/src/main/java/es/chiteroman/playintegrityfix/EntryPoint.java index ceff71ea..80136088 100644 --- a/app/src/main/java/es/chiteroman/playintegrityfix/EntryPoint.java +++ b/app/src/main/java/es/chiteroman/playintegrityfix/EntryPoint.java @@ -17,6 +17,7 @@ public final class EntryPoint { private static final Map map = new HashMap<>(); static { + boolean spoof = false; try { KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore"); @@ -24,13 +25,16 @@ public final class EntryPoint { field.setAccessible(true); CustomKeyStoreSpi.keyStoreSpi = (KeyStoreSpi) field.get(keyStore); + + if (CustomKeyStoreSpi.keyStoreSpi != null) spoof = true; + } catch (Throwable t) { LOG("Error spoofing AndroidKeyStore: " + t); } Provider provider = Security.getProvider("AndroidKeyStore"); - Provider customProvider = new CustomProvider(provider); + Provider customProvider = new CustomProvider(provider, spoof); Security.removeProvider("AndroidKeyStore"); Security.insertProviderAt(customProvider, 1); diff --git a/module/module.prop b/module/module.prop index 4d5301e5..e452d1ed 100644 --- a/module/module.prop +++ b/module/module.prop @@ -1,7 +1,7 @@ id=playintegrityfix name=Play Integrity Fix -version=v15.7.1 -versionCode=15701 +version=v15.7.2 +versionCode=15702 author=chiteroman description=Universal modular fix for Play Integrity (and SafetyNet) on devices running Android 8+. updateJson=https://raw.githubusercontent.com/chiteroman/PlayIntegrityFix/main/update.json diff --git a/module/post-fs-data.sh b/module/post-fs-data.sh index 916683df..c61e7cf2 100644 --- a/module/post-fs-data.sh +++ b/module/post-fs-data.sh @@ -8,3 +8,30 @@ if [ -d /data/adb/modules/safetynet-fix ]; then rm -rf /data/adb/modules/safetynet-fix rm -rf /data/adb/SNFix.dex fi + +resetprop_if_diff() { + local NAME="$1" + local EXPECTED="$2" + local CURRENT="$(resetprop "$NAME")" + + [ -z "$CURRENT" ] || [ "$CURRENT" = "$EXPECTED" ] || resetprop "$NAME" "$EXPECTED" +} + +# Conditional early sensitive properties + +# Samsung +resetprop_if_diff ro.boot.warranty_bit 0 +resetprop_if_diff ro.vendor.boot.warranty_bit 0 +resetprop_if_diff ro.vendor.warranty_bit 0 +resetprop_if_diff ro.warranty_bit 0 + +# OnePlus +resetprop_if_diff ro.is_ever_orange 0 + +# Microsoft, RootBeer +resetprop_if_diff ro.build.tags release-keys + +# Other +resetprop_if_diff ro.build.type user +resetprop_if_diff ro.debuggable 0 +resetprop_if_diff ro.secure 1 diff --git a/module/service.sh b/module/service.sh index 37e5ad98..0a70a5c4 100644 --- a/module/service.sh +++ b/module/service.sh @@ -1,19 +1,19 @@ # Conditional sensitive properties resetprop_if_diff() { - local NAME=$1 - local EXPECTED=$2 - local CURRENT=$(resetprop $NAME) - - [ -z "$CURRENT" ] || [ "$CURRENT" == "$EXPECTED" ] || resetprop $NAME $EXPECTED + local NAME="$1" + local EXPECTED="$2" + local CURRENT="$(resetprop "$NAME")" + + [ -z "$CURRENT" ] || [ "$CURRENT" = "$EXPECTED" ] || resetprop "$NAME" "$EXPECTED" } resetprop_if_match() { - local NAME=$1 - local CONTAINS=$2 - local VALUE=$3 - - [[ "$(resetprop $NAME)" == *"$CONTAINS"* ]] && resetprop $NAME $VALUE + local NAME="$1" + local CONTAINS="$2" + local VALUE="$3" + + [[ "$(resetprop "$NAME")" = *"$CONTAINS"* ]] && resetprop "$NAME" "$VALUE" } # Magisk recovery mode @@ -32,45 +32,33 @@ if [ "$(toybox cat /sys/fs/selinux/enforce)" == "0" ]; then chmod 440 /sys/fs/selinux/policy fi -# must be set after boot_completed for various OEMs -until [ "$(getprop sys.boot_completed)" == "1" ]; do - sleep 1 -done - -# RootBeer, Microsoft -resetprop_if_diff ro.build.tags release-keys - -# Samsung -resetprop_if_diff ro.boot.warranty_bit 0 -resetprop_if_diff ro.vendor.boot.warranty_bit 0 -resetprop_if_diff ro.vendor.warranty_bit 0 -resetprop_if_diff ro.warranty_bit 0 - -# Xiaomi -resetprop_if_diff ro.secureboot.lockstate locked - -# Realme -resetprop_if_diff ro.boot.realmebootstate green +# Conditional late sensitive properties -# OnePlus -resetprop_if_diff ro.is_ever_orange 0 +# SafetyNet/Play Integrity +{ + # must be set after boot_completed for various OEMs + until [ "$(getprop sys.boot_completed)" = "1" ]; do + sleep 1 + done -# Other -resetprop_if_diff ro.build.type user -resetprop_if_diff ro.debuggable 0 -resetprop_if_diff ro.secure 1 + # avoid breaking Realme fingerprint scanners + resetprop_if_diff ro.boot.flash.locked 1 + resetprop_if_diff ro.boot.realme.lockstate 1 -# avoid breaking Realme fingerprint scanners -resetprop_if_diff ro.boot.flash.locked 1 -resetprop_if_diff ro.boot.realme.lockstate 1 + # avoid breaking Oppo fingerprint scanners + resetprop_if_diff ro.boot.vbmeta.device_state locked -# avoid breaking Oppo fingerprint scanners -resetprop_if_diff ro.boot.vbmeta.device_state locked + # avoid breaking OnePlus display modes/fingerprint scanners + resetprop_if_diff vendor.boot.verifiedbootstate green -# avoid breaking OnePlus display modes/fingerprint scanners -resetprop_if_diff vendor.boot.verifiedbootstate green + # avoid breaking OnePlus/Oppo display fingerprint scanners on OOS/ColorOS 12+ + resetprop_if_diff ro.boot.verifiedbootstate green + resetprop_if_diff ro.boot.veritymode enforcing + resetprop_if_diff vendor.boot.vbmeta.device_state locked + + # Xiaomi + resetprop_if_diff ro.secureboot.lockstate locked -# avoid breaking OnePlus/Oppo display fingerprint scanners on OOS/ColorOS 12+ -resetprop_if_diff ro.boot.verifiedbootstate green -resetprop_if_diff ro.boot.veritymode enforcing -resetprop_if_diff vendor.boot.vbmeta.device_state locked + # Realme + resetprop_if_diff ro.boot.realmebootstate green +}&