From ed8501d8575e931ced119bbd28b2280b6182f631 Mon Sep 17 00:00:00 2001 From: osm0sis Date: Sat, 30 Aug 2025 22:06:52 -0300 Subject: [PATCH] Rename to spoofVendingFinger, add custom FINGERPRINT support, tidy 0 = disabled 1 = enabled and use FINGERPRINT from json for vending (Play Store) = enabled and use as FINGERPRINT for vending (Play Store) --- app/src/main/cpp/main.cpp | 52 ++++++++++++------- .../playintegrityfix/EntryPointVending.java | 14 ++--- module/autopif2.sh | 2 +- module/example.pif.json | 2 +- module/migrate.sh | 4 +- 5 files changed, 43 insertions(+), 31 deletions(-) diff --git a/app/src/main/cpp/main.cpp b/app/src/main/cpp/main.cpp index 54b3fad..ab6abc2 100644 --- a/app/src/main/cpp/main.cpp +++ b/app/src/main/cpp/main.cpp @@ -12,6 +12,7 @@ #define JSON_FILE_PATH "/data/adb/modules/playintegrityfix/pif.json" #define CUSTOM_JSON_FILE_PATH "/data/adb/modules/playintegrityfix/custom.pif.json" + #define VENDING_PACKAGE "com.android.vending" #define DROIDGUARD_PACKAGE "com.google.android.gms.unstable" @@ -20,7 +21,7 @@ static int spoofBuild = 1; static int spoofProps = 1; static int spoofProvider = 1; static int spoofSignature = 0; -static int spoofVendingFingerprint = 0; +static int spoofVendingFinger = 0; static int spoofVendingSdk = 0; static std::map jsonProps; @@ -166,11 +167,11 @@ public: readJson(); - if (pkgName == VENDING_PACKAGE) spoofProps = spoofBuild = spoofProvider = spoofSignature = 0; - else spoofVendingFingerprint = spoofVendingSdk = 0; + if (pkgName == VENDING_PACKAGE) spoofBuild = spoofProps = spoofProvider = spoofSignature = 0; + else spoofVendingFinger = spoofVendingSdk = 0; if (spoofProps > 0) doHook(); - if (spoofBuild + spoofProvider + spoofSignature + spoofVendingFingerprint + spoofVendingSdk > 0) inject(); + if (spoofBuild + spoofProvider + spoofSignature + spoofVendingFinger + spoofVendingSdk > 0) inject(); dexVector.clear(); json.clear(); @@ -186,7 +187,7 @@ private: std::vector dexVector; nlohmann::json json; std::string pkgName; - std::string spoofFingerprintValue = ""; + std::string vendingFingerprintValue; void readJson() { LOGD("JSON contains %d keys!", static_cast(json.size())); @@ -202,7 +203,7 @@ private: json.erase("verboseLogs"); } - // Advanced spoofing settings + // Vending advanced spoofing settings if (json.contains("spoofVendingSdk")) { if (!json["spoofVendingSdk"].is_null() && json["spoofVendingSdk"].is_string() && json["spoofVendingSdk"] != "") { spoofVendingSdk = stoi(json["spoofVendingSdk"].get()); @@ -212,21 +213,29 @@ private: } json.erase("spoofVendingSdk"); } - if (json.contains("spoofVendingFingerprint")) { - if (!json["spoofVendingFingerprint"].is_null() && json["spoofVendingFingerprint"].is_string() && json["spoofVendingFingerprint"] != "" && - json.contains("FINGERPRINT") && !json["FINGERPRINT"].is_null() && json["FINGERPRINT"].is_string() && json["FINGERPRINT"] != "") { - spoofVendingFingerprint = stoi(json["spoofVendingFingerprint"].get()); - spoofFingerprintValue = json["FINGERPRINT"].get(); - if (verboseLogs > 0) LOGD("Spoofing Fingerprint in Play Store %s!", (spoofVendingFingerprint > 0) ? "enabled" : "disabled"); + if (json.contains("spoofVendingFinger")) { + if (!json["spoofVendingFinger"].is_null() && json["spoofVendingFinger"].is_string() && json["spoofVendingFinger"] != "") { + if (json["spoofVendingFinger"].get().find_first_not_of("01") != std::string::npos) { + spoofVendingFinger = 1; + vendingFingerprintValue = json["spoofVendingFinger"].get(); + } else if (json.contains("FINGERPRINT") && !json["FINGERPRINT"].is_null() && json["FINGERPRINT"].is_string() && json["FINGERPRINT"] != "") { + spoofVendingFinger = stoi(json["spoofVendingFinger"].get()); + vendingFingerprintValue = json["FINGERPRINT"].get(); + } else { + LOGD("Error parsing spoofVendingFinger or FINGERPRINT field!"); + } + if (verboseLogs > 0) LOGD("Spoofing Fingerprint in Play Store %s!", (spoofVendingFinger > 0) ? "enabled" : "disabled"); } else { - LOGD("Error parsing spoofVendingFingerprint or FINGERPRINT field!"); + LOGD("Error parsing spoofVendingFinger!"); } - json.erase("spoofVendingFingerprint"); + json.erase("spoofVendingFinger"); } if (pkgName == VENDING_PACKAGE) { json.clear(); return; } + + // DroidGuard advanced spoofing settings if (json.contains("spoofBuild")) { if (!json["spoofBuild"].is_null() && json["spoofBuild"].is_string() && json["spoofBuild"] != "") { spoofBuild = stoi(json["spoofBuild"].get()); @@ -313,8 +322,9 @@ private: if (pkgName == VENDING_PACKAGE) { LOGD("JNI %s: Calling EntryPointVending.init", niceName); auto entryInit = env->GetStaticMethodID(entryClass, "init", "(IIILjava/lang/String;)V"); - auto javaStr = env->NewStringUTF(spoofFingerprintValue.c_str()); - env->CallStaticVoidMethod(entryClass, entryInit, verboseLogs, spoofVendingFingerprint, spoofVendingSdk, javaStr); + auto javaStr = env->NewStringUTF(vendingFingerprintValue.c_str()); + env->CallStaticVoidMethod(entryClass, entryInit, verboseLogs, spoofVendingFinger, spoofVendingSdk, javaStr); + env->DeleteLocalRef(javaStr); } else { LOGD("JNI %s: Sending JSON", niceName); auto receiveJson = env->GetStaticMethodID(entryClass, "receiveJson", "(Ljava/lang/String;)V"); @@ -327,10 +337,10 @@ private: env->DeleteLocalRef(javaStr); } env->DeleteLocalRef(clClass); - env->DeleteLocalRef(dexClClass); env->DeleteLocalRef(systemClassLoader); - env->DeleteLocalRef(dexCl); + env->DeleteLocalRef(dexClClass); env->DeleteLocalRef(buffer); + env->DeleteLocalRef(dexCl); env->DeleteLocalRef(entryClassName); env->DeleteLocalRef(entryClassObj); } @@ -379,8 +389,10 @@ static void companion(int fd) { } /* - * - The fix is public now: https://github.com/JingMatrix/NeoZygisk/commit/76d54228c7e6fe14cca93338865008946b94f7ee - * - Remeber to add this for all other zygisk c++ library + * Fix for Dobby detections + * Must be added to all Zygisk C++ libraries in a project + * + * Reference: https://github.com/JingMatrix/NeoZygisk/commit/76d54228c7e6fe14cca93338865008946b94f7ee */ extern "C" int __cxa_atexit(void (*func)(void*), void* arg, void* dso) { return 0; diff --git a/app/src/main/java/es/chiteroman/playintegrityfix/EntryPointVending.java b/app/src/main/java/es/chiteroman/playintegrityfix/EntryPointVending.java index 02271ba..2b9c7d3 100644 --- a/app/src/main/java/es/chiteroman/playintegrityfix/EntryPointVending.java +++ b/app/src/main/java/es/chiteroman/playintegrityfix/EntryPointVending.java @@ -12,23 +12,23 @@ public final class EntryPointVending { } @SuppressLint("DefaultLocale") - public static void init(int verboseLogs, int spoofVendingFingerprint, int spoofVendingSdk, String spoofFingerprintValue) { - if (spoofVendingSdk < 1){ - // Only spoof FINGERPRINT to Play Store if not forcing legacy verdict - if (spoofVendingFingerprint < 1) return; + public static void init(int verboseLogs, int spoofVendingFinger, int spoofVendingSdk, String vendingFingerprintValue) { + // Only spoof FINGERPRINT to Play Store if not forcing Android <13 Play Integrity verdict + if (spoofVendingSdk < 1) { + if (spoofVendingFinger < 1) return; String oldValue; try { Field field = Build.class.getDeclaredField("FINGERPRINT"); field.setAccessible(true); oldValue = String.valueOf(field.get(null)); - if (oldValue.equals(spoofFingerprintValue)) { + if (oldValue.equals(vendingFingerprintValue)) { if (verboseLogs > 2) LOG(String.format("[FINGERPRINT]: %s (unchanged)", oldValue)); field.setAccessible(false); return; } - field.set(null, spoofFingerprintValue); + field.set(null, vendingFingerprintValue); field.setAccessible(false); - LOG(String.format("[FINGERPRINT]: %s -> %s", oldValue, spoofFingerprintValue)); + LOG(String.format("[FINGERPRINT]: %s -> %s", oldValue, vendingFingerprintValue)); } catch (NoSuchFieldException e) { LOG("FINGERPRINT field not found: " + e); } catch (SecurityException | IllegalAccessException | IllegalArgumentException | diff --git a/module/autopif2.sh b/module/autopif2.sh index 7a187b2..4aae8c8 100644 --- a/module/autopif2.sh +++ b/module/autopif2.sh @@ -162,7 +162,7 @@ if [ -f "$MIGRATE" ]; then if [ -n "$ARGS" ]; then grep_json() { [ -f "$2" ] && grep -m1 "$1" $2 | cut -d\" -f4; } verboseLogs=$(grep_json "VERBOSE_LOGS" $OLDJSON); - ADVSETTINGS="spoofBuild spoofProps spoofProvider spoofSignature spoofVendingFingerprint spoofVendingSdk verboseLogs"; + ADVSETTINGS="spoofBuild spoofProps spoofProvider spoofSignature spoofVendingFinger spoofVendingSdk verboseLogs"; for SETTING in $ADVSETTINGS; do eval [ -z \"\$$SETTING\" ] \&\& $SETTING=$(grep_json "$SETTING" $OLDJSON); eval TMPVAL=\$$SETTING; diff --git a/module/example.pif.json b/module/example.pif.json index a1ed701..564c310 100644 --- a/module/example.pif.json +++ b/module/example.pif.json @@ -31,7 +31,7 @@ "spoofProps": "1", "spoofProvider": "1", "spoofSignature": "0", - "spoofVendingFingerprint": "0", + "spoofVendingFinger": "0", "spoofVendingSdk": "0", "verboseLogs": "0" } diff --git a/module/migrate.sh b/module/migrate.sh index aad351a..edf1577 100644 --- a/module/migrate.sh +++ b/module/migrate.sh @@ -114,13 +114,13 @@ if [ -z "$DEVICE_INITIAL_SDK_INT" -o "$DEVICE_INITIAL_SDK_INT" = "null" ]; then DEVICE_INITIAL_SDK_INT=25; fi; -ADVSETTINGS="spoofBuild spoofProps spoofProvider spoofSignature spoofVendingFingerprint spoofVendingSdk verboseLogs"; +ADVSETTINGS="spoofBuild spoofProps spoofProvider spoofSignature spoofVendingFinger spoofVendingSdk verboseLogs"; spoofBuild=1; spoofProps=1; spoofProvider=1; spoofSignature=0; -spoofVendingFingerprint=0; +spoofVendingFinger=0; spoofVendingSdk=0; verboseLogs=0;