17 Commits

Author SHA1 Message Date
V0latyle
5cef27ffa9 Fix typo in README.md (#40) 2025-09-05 12:31:13 -03:00
Chris Renshaw
6dffba43ab Tweak example.app_replace.list organization 2025-09-03 23:50:07 -03:00
Chris Renshaw
8558751cc7 Update AGP 2025-09-03 23:44:59 -03:00
osm0sis
0a216e0cd9 Switch to improved workaround for Dobby detection 2025-09-03 21:29:04 -03:00
Chris Renshaw
6506283874 Fix custom.pif.json migration check on clean installs 2025-08-30 23:04:07 -03:00
Chris Renshaw
8f06a06659 Update GitHub Actions 2025-08-30 22:29:41 -03:00
Chris Renshaw
1b99917151 Update AGP 2025-08-30 22:26:39 -03:00
osm0sis
b92e80fbc6 Fix errant Windows line endings 2025-08-30 22:21:27 -03:00
osm0sis
ed8501d857 Rename to spoofVendingFinger, add custom FINGERPRINT support, tidy
0 = disabled
1 = enabled and use FINGERPRINT from json for vending (Play Store)
<string> = enabled and use <string> as FINGERPRINT for vending (Play Store)
2025-08-30 22:07:10 -03:00
gavdoc38
9c6f065bb6 Add advanced setting spoofVendingFingerprint (#38)
spoofVendingFingerprint = 0 / 1

When 0, no impact on Vending
When 1, same FINGERPRINT from custom.pif.json is injected into Vending

Unless spoofVendingSdk is enabled also, in which case FINGERPRINT is not injected since it's not used
2025-08-30 15:02:50 -03:00
simonpunk
ffd8d77d6f Update fixes for detection
- Details for detection and fix: https://github.com/JingMatrix/NeoZygisk/commit/76d54228c7e6fe14cca93338865008946b94f7e
- Ensure no memory leaks related to local references
- With the __cxa_atexit fix, Dobby should not be detected by user apps anymore
2025-08-28 21:54:52 -03:00
Chris Renshaw
3c9c13e3ff autopif2: RIP Preview program, hello top level version arg
-p or --preview has been removed since the Platform Preview program has been replaced by Android Canary

-t # or --top # chooses the top level version depth to crawl down the Android version list for when there are multiple active Betas in multiple Android versions, e.g. with 16 as latest the default value of 1 would get its listed QPRs and -t 2 would force it to get the second listed (15)
2025-08-20 22:05:40 -03:00
gavdoc38
bee383bb99 Update README.md (#36)
Clarify the section about Google Wallet requirements. In particular, that spoofVendingSdk is only to test that <A13 PI passes DEVICE and that the option does not need to be enabled in order to use Wallet after this.
2025-08-20 12:56:15 -03:00
Chris Renshaw
b4bdc5bafc Update GitHub Actions 2025-08-19 22:31:20 -03:00
osm0sis
58664b2294 Update Gradle 2025-08-19 20:44:56 -03:00
Chris Renshaw
cc74eebd33 Update AGP 2025-08-18 23:23:47 -03:00
Chris Renshaw
b08dba14ea Begin next development cycle 2025-08-18 23:21:43 -03:00
19 changed files with 137 additions and 76 deletions

View File

@@ -16,13 +16,13 @@ jobs:
steps: steps:
- name: Check out - name: Check out
uses: actions/checkout@v4 uses: actions/checkout@v5
with: with:
submodules: 'recursive' submodules: 'recursive'
fetch-depth: 0 fetch-depth: 0
- name: Set up JDK - name: Set up JDK
uses: actions/setup-java@v4 uses: actions/setup-java@v5
with: with:
distribution: 'temurin' distribution: 'temurin'
java-version: 21 java-version: 21

3
.gitmodules vendored
View File

@@ -1,6 +1,9 @@
[submodule "Dobby"] [submodule "Dobby"]
path = app/src/main/cpp/Dobby path = app/src/main/cpp/Dobby
url = https://github.com/JingMatrix/Dobby url = https://github.com/JingMatrix/Dobby
[submodule "local_cxa_atexit_finalize_impl"]
path = app/src/main/cpp/local_cxa_atexit_finalize_impl
url = https://github.com/5ec1cff/local_cxa_atexit_finalize_impl
[submodule "json"] [submodule "json"]
path = app/src/main/cpp/json path = app/src/main/cpp/json
url = https://github.com/nlohmann/json url = https://github.com/nlohmann/json

View File

@@ -127,7 +127,7 @@ Note: RCS is most easily checked using Gemini in Messages and usually clearing M
### Failing Google Wallet Tap To Pay Setup Security Requirements ### Failing Google Wallet Tap To Pay Setup Security Requirements
- Reflash the module in your root manager app - Reflash the module in your root manager app
- Ensure you are passing <A13 PI DEVICE or higher integrity - Ensure you are passing <A13 PI DEVICE or higher integrity. Wallet requires this verdict even on A13+ ROMs as it is checked/enforced in the background.
- Clear Google Wallet (com.google.android.apps.walletnfcrel) and/or Google Pay (com.google.android.apps.nbu.paisa.user) cache, if you have them installed - Clear Google Wallet (com.google.android.apps.walletnfcrel) and/or Google Pay (com.google.android.apps.nbu.paisa.user) cache, if you have them installed
- Clear Google Play Services (com.google.android.gms) cache and data, or, optionally skip clearing data and wait some time (24-72h) for it to resolve on its own - Clear Google Play Services (com.google.android.gms) cache and data, or, optionally skip clearing data and wait some time (24-72h) for it to resolve on its own
- Reboot - Reboot
@@ -161,7 +161,7 @@ The advanced spoofing options add granular control over what exactly gets spoofe
- For spoofing locked bootloader and attempting to pass <A13 PI STRONG integrity, or A13+ PI DEVICE or STRONG integrity, I only recommend using the latest official [Tricky Store](https://github.com/5ec1cff/TrickyStore) or [Tricky Store OSS](https://github.com/beakthoven/TrickyStoreOSS) release. - For spoofing locked bootloader and attempting to pass <A13 PI STRONG integrity, or A13+ PI DEVICE or STRONG integrity, I only recommend using the latest official [Tricky Store](https://github.com/5ec1cff/TrickyStore) or [Tricky Store OSS](https://github.com/beakthoven/TrickyStoreOSS) release.
- Note: Using Tricky Store to achieve <A13 PI STRONG integrtiy, or A13+ PI DEVICE or STRONG integrity (with an unrevoked hardware keybox.xml), requires the Advanced Settings "spoofProvider" disabled and sometimes the "\*.security_patch" entry commented out (often unless spoofing a matching OS Patch Level with system= or all= or Simple date in Tricky Store's security_patch.txt; autopif2 will do this automatically if security_patch.txt exists in the Tricky Store directory), and/or "\*api_level" entry set >25 (usually 26-32). To achieve <A13 PI DEVICE integrity (with Tricky Store default AOSP software keybox.xml) requires at least "spoofProps" enabled, and some fingerprints may also require "spoofProvider" enabled and/or "\*api_level" entry lowered to <26 (usually 21-25). More known working private fingerprints can achieve <A13 PI DEVICE/STRONG integrity on more devices using these Advanced Settings in conjunction with Tricky Store than was possible with Tricky Store alone since they require fingerprint props spoofing. - Note: Using Tricky Store to achieve <A13 PI STRONG integrity (with an unrevoked hardware keybox.xml), requires the Advanced Settings "spoofProvider" disabled and sometimes the "\*.security_patch" entry commented out (often unless spoofing a matching OS Patch Level with system= or all= or Simple date in Tricky Store's security_patch.txt; autopif2 will do this automatically if security_patch.txt exists in the Tricky Store directory), and/or "\*api_level" entry set >25 (usually 26-32). To achieve <A13 PI DEVICE integrity (with Tricky Store default AOSP software keybox.xml) requires at least "spoofProps" enabled, and some fingerprints may also require "spoofProvider" enabled and/or "\*api_level" entry lowered to <26 (usually 21-25). More known working private fingerprints can achieve <A13 PI DEVICE/STRONG integrity on more devices using these Advanced Settings in conjunction with Tricky Store than was possible with Tricky Store alone since they require fingerprint props spoofing.
</details> </details>

View File

@@ -6,7 +6,7 @@ find_package(cxx REQUIRED CONFIG)
link_libraries(cxx::cxx) link_libraries(cxx::cxx)
add_library(${CMAKE_PROJECT_NAME} SHARED ${CMAKE_SOURCE_DIR}/main.cpp) add_library(${CMAKE_PROJECT_NAME} SHARED main.cpp local_cxa_atexit_finalize_impl/atexit.cpp)
add_subdirectory(Dobby) add_subdirectory(Dobby)

View File

@@ -12,6 +12,7 @@
#define JSON_FILE_PATH "/data/adb/modules/playintegrityfix/pif.json" #define JSON_FILE_PATH "/data/adb/modules/playintegrityfix/pif.json"
#define CUSTOM_JSON_FILE_PATH "/data/adb/modules/playintegrityfix/custom.pif.json" #define CUSTOM_JSON_FILE_PATH "/data/adb/modules/playintegrityfix/custom.pif.json"
#define VENDING_PACKAGE "com.android.vending" #define VENDING_PACKAGE "com.android.vending"
#define DROIDGUARD_PACKAGE "com.google.android.gms.unstable" #define DROIDGUARD_PACKAGE "com.google.android.gms.unstable"
@@ -20,6 +21,7 @@ static int spoofBuild = 1;
static int spoofProps = 1; static int spoofProps = 1;
static int spoofProvider = 1; static int spoofProvider = 1;
static int spoofSignature = 0; static int spoofSignature = 0;
static int spoofVendingFinger = 0;
static int spoofVendingSdk = 0; static int spoofVendingSdk = 0;
static std::map<std::string, std::string> jsonProps; static std::map<std::string, std::string> jsonProps;
@@ -165,11 +167,11 @@ public:
readJson(); readJson();
if (pkgName == VENDING_PACKAGE) spoofProps = spoofBuild = spoofProvider = spoofSignature = 0; if (pkgName == VENDING_PACKAGE) spoofBuild = spoofProps = spoofProvider = spoofSignature = 0;
else spoofVendingSdk = 0; else spoofVendingFinger = spoofVendingSdk = 0;
if (spoofProps > 0) doHook(); if (spoofProps > 0) doHook();
if (spoofBuild + spoofProvider + spoofSignature + spoofVendingSdk > 0) inject(); if (spoofBuild + spoofProvider + spoofSignature + spoofVendingFinger + spoofVendingSdk > 0) inject();
dexVector.clear(); dexVector.clear();
json.clear(); json.clear();
@@ -185,6 +187,7 @@ private:
std::vector<char> dexVector; std::vector<char> dexVector;
nlohmann::json json; nlohmann::json json;
std::string pkgName; std::string pkgName;
std::string vendingFingerprintValue;
void readJson() { void readJson() {
LOGD("JSON contains %d keys!", static_cast<int>(json.size())); LOGD("JSON contains %d keys!", static_cast<int>(json.size()));
@@ -200,7 +203,7 @@ private:
json.erase("verboseLogs"); json.erase("verboseLogs");
} }
// Advanced spoofing settings // Vending advanced spoofing settings
if (json.contains("spoofVendingSdk")) { if (json.contains("spoofVendingSdk")) {
if (!json["spoofVendingSdk"].is_null() && json["spoofVendingSdk"].is_string() && json["spoofVendingSdk"] != "") { if (!json["spoofVendingSdk"].is_null() && json["spoofVendingSdk"].is_string() && json["spoofVendingSdk"] != "") {
spoofVendingSdk = stoi(json["spoofVendingSdk"].get<std::string>()); spoofVendingSdk = stoi(json["spoofVendingSdk"].get<std::string>());
@@ -210,10 +213,29 @@ private:
} }
json.erase("spoofVendingSdk"); json.erase("spoofVendingSdk");
} }
if (json.contains("spoofVendingFinger")) {
if (!json["spoofVendingFinger"].is_null() && json["spoofVendingFinger"].is_string() && json["spoofVendingFinger"] != "") {
if (json["spoofVendingFinger"].get<std::string>().find_first_not_of("01") != std::string::npos) {
spoofVendingFinger = 1;
vendingFingerprintValue = json["spoofVendingFinger"].get<std::string>();
} else if (json.contains("FINGERPRINT") && !json["FINGERPRINT"].is_null() && json["FINGERPRINT"].is_string() && json["FINGERPRINT"] != "") {
spoofVendingFinger = stoi(json["spoofVendingFinger"].get<std::string>());
vendingFingerprintValue = json["FINGERPRINT"].get<std::string>();
} 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 spoofVendingFinger!");
}
json.erase("spoofVendingFinger");
}
if (pkgName == VENDING_PACKAGE) { if (pkgName == VENDING_PACKAGE) {
json.clear(); json.clear();
return; return;
} }
// DroidGuard advanced spoofing settings
if (json.contains("spoofBuild")) { if (json.contains("spoofBuild")) {
if (!json["spoofBuild"].is_null() && json["spoofBuild"].is_string() && json["spoofBuild"] != "") { if (!json["spoofBuild"].is_null() && json["spoofBuild"].is_string() && json["spoofBuild"] != "") {
spoofBuild = stoi(json["spoofBuild"].get<std::string>()); spoofBuild = stoi(json["spoofBuild"].get<std::string>());
@@ -299,8 +321,10 @@ private:
if (pkgName == VENDING_PACKAGE) { if (pkgName == VENDING_PACKAGE) {
LOGD("JNI %s: Calling EntryPointVending.init", niceName); LOGD("JNI %s: Calling EntryPointVending.init", niceName);
auto entryInit = env->GetStaticMethodID(entryClass, "init", "(II)V"); auto entryInit = env->GetStaticMethodID(entryClass, "init", "(IIILjava/lang/String;)V");
env->CallStaticVoidMethod(entryClass, entryInit, verboseLogs, spoofVendingSdk); auto javaStr = env->NewStringUTF(vendingFingerprintValue.c_str());
env->CallStaticVoidMethod(entryClass, entryInit, verboseLogs, spoofVendingFinger, spoofVendingSdk, javaStr);
env->DeleteLocalRef(javaStr);
} else { } else {
LOGD("JNI %s: Sending JSON", niceName); LOGD("JNI %s: Sending JSON", niceName);
auto receiveJson = env->GetStaticMethodID(entryClass, "receiveJson", "(Ljava/lang/String;)V"); auto receiveJson = env->GetStaticMethodID(entryClass, "receiveJson", "(Ljava/lang/String;)V");
@@ -310,7 +334,15 @@ private:
LOGD("JNI %s: Calling EntryPoint.init", niceName); LOGD("JNI %s: Calling EntryPoint.init", niceName);
auto entryInit = env->GetStaticMethodID(entryClass, "init", "(IIII)V"); auto entryInit = env->GetStaticMethodID(entryClass, "init", "(IIII)V");
env->CallStaticVoidMethod(entryClass, entryInit, verboseLogs, spoofBuild, spoofProvider, spoofSignature); env->CallStaticVoidMethod(entryClass, entryInit, verboseLogs, spoofBuild, spoofProvider, spoofSignature);
env->DeleteLocalRef(javaStr);
} }
env->DeleteLocalRef(clClass);
env->DeleteLocalRef(systemClassLoader);
env->DeleteLocalRef(dexClClass);
env->DeleteLocalRef(buffer);
env->DeleteLocalRef(dexCl);
env->DeleteLocalRef(entryClassName);
env->DeleteLocalRef(entryClassObj);
} }
}; };

View File

@@ -1,40 +1,62 @@
package es.chiteroman.playintegrityfix; package es.chiteroman.playintegrityfix;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.os.Build; import android.os.Build;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import android.util.Log; import android.util.Log;
public final class EntryPointVending { public final class EntryPointVending {
private static void LOG(String msg) { private static void LOG(String msg) {
Log.d("PIF/Java:PS", msg); Log.d("PIF/Java:PS", msg);
} }
@SuppressLint("DefaultLocale") @SuppressLint("DefaultLocale")
public static void init(int verboseLogs, int spoofVendingSdk) { public static void init(int verboseLogs, int spoofVendingFinger, int spoofVendingSdk, String vendingFingerprintValue) {
if (spoofVendingSdk < 1) return; // Only spoof FINGERPRINT to Play Store if not forcing Android <13 Play Integrity verdict
int requestSdk = spoofVendingSdk == 1 ? 32 : spoofVendingSdk; if (spoofVendingSdk < 1) {
int targetSdk = Math.min(Build.VERSION.SDK_INT, requestSdk); if (spoofVendingFinger < 1) return;
int oldValue; String oldValue;
try { try {
Field field = Build.VERSION.class.getDeclaredField("SDK_INT"); Field field = Build.class.getDeclaredField("FINGERPRINT");
field.setAccessible(true); field.setAccessible(true);
oldValue = field.getInt(null); oldValue = String.valueOf(field.get(null));
if (oldValue == targetSdk) { if (oldValue.equals(vendingFingerprintValue)) {
if (verboseLogs > 2) LOG(String.format("[SDK_INT]: %d (unchanged)", oldValue)); if (verboseLogs > 2) LOG(String.format("[FINGERPRINT]: %s (unchanged)", oldValue));
field.setAccessible(false); field.setAccessible(false);
return; return;
} }
field.set(null, targetSdk); field.set(null, vendingFingerprintValue);
field.setAccessible(false); field.setAccessible(false);
LOG(String.format("[SDK_INT]: %d -> %d", oldValue, targetSdk)); LOG(String.format("[FINGERPRINT]: %s -> %s", oldValue, vendingFingerprintValue));
} catch (NoSuchFieldException e) { } catch (NoSuchFieldException e) {
LOG("SDK_INT field not found: " + e); LOG("FINGERPRINT field not found: " + e);
} catch (SecurityException | IllegalAccessException | IllegalArgumentException | } catch (SecurityException | IllegalAccessException | IllegalArgumentException |
NullPointerException | ExceptionInInitializerError e) { NullPointerException | ExceptionInInitializerError e) {
LOG("SDK_INT field not accessible: " + e); LOG("FINGERPRINT field not accessible: " + e);
}
} } else {
} int requestSdk = spoofVendingSdk == 1 ? 32 : spoofVendingSdk;
} int targetSdk = Math.min(Build.VERSION.SDK_INT, requestSdk);
int oldValue;
try {
Field field = Build.VERSION.class.getDeclaredField("SDK_INT");
field.setAccessible(true);
oldValue = field.getInt(null);
if (oldValue == targetSdk) {
if (verboseLogs > 2) LOG(String.format("[SDK_INT]: %d (unchanged)", oldValue));
field.setAccessible(false);
return;
}
field.set(null, targetSdk);
field.setAccessible(false);
LOG(String.format("[SDK_INT]: %d -> %d", oldValue, targetSdk));
} catch (NoSuchFieldException e) {
LOG("SDK_INT field not found: " + e);
} catch (SecurityException | IllegalAccessException | IllegalArgumentException |
NullPointerException | ExceptionInInitializerError e) {
LOG("SDK_INT field not accessible: " + e);
}
}
}
}

View File

@@ -1,3 +1,3 @@
plugins { plugins {
id("com.android.application") version "8.11.1" apply false id("com.android.application") version "8.13.0" apply false
} }

View File

@@ -4,6 +4,8 @@
# any settings specified in this file. # any settings specified in this file.
# For more details on how to configure your build environment visit # For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html # http://www.gradle.org/docs/current/userguide/build_environment.html
# Enable the configuration cache persistently
org.gradle.configuration-cache=true
# Specifies the JVM arguments used for the daemon process. # Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings. # The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8

Binary file not shown.

View File

@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-9.0.0-bin.zip
networkTimeout=10000 networkTimeout=10000
validateDistributionUrl=true validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME

2
gradlew vendored
View File

@@ -1,7 +1,7 @@
#!/bin/sh #!/bin/sh
# #
# Copyright © 2015-2021 the original authors. # Copyright © 2015 the original authors.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.

View File

@@ -4,7 +4,7 @@ MODPATH="${0%/*}"
set +o standalone set +o standalone
unset ASH_STANDALONE unset ASH_STANDALONE
sh $MODPATH/autopif2.sh -s -m -p || exit 1 sh $MODPATH/autopif2.sh -s -m || exit 1
echo -e "\nDone!" echo -e "\nDone!"

View File

@@ -7,14 +7,15 @@ case "$HOME" in
*termux*) echo "autopif2: need su root environment"; exit 1;; *termux*) echo "autopif2: need su root environment"; exit 1;;
esac; esac;
FORCE_TOP=1;
FORCE_DEPTH=1; FORCE_DEPTH=1;
until [ -z "$1" ]; do until [ -z "$1" ]; do
case "$1" in case "$1" in
-h|--help|help) echo "sh autopif2.sh [-a|-s] [-m] [-p] [-d #]"; exit 0;; -h|--help|help) echo "sh autopif2.sh [-a|-s] [-m] [-t #] [-d #]"; exit 0;;
-a|--advanced|advanced) ARGS="-a"; shift;; -a|--advanced|advanced) ARGS="-a"; shift;;
-s|--strong|strong) ARGS="-a"; PATCH_COMMENT=1; spoofProvider=0; shift;; -s|--strong|strong) ARGS="-a"; PATCH_COMMENT=1; spoofProvider=0; shift;;
-m|--match|match) FORCE_MATCH=1; shift;; -m|--match|match) FORCE_MATCH=1; shift;;
-p|--preview|preview) FORCE_PREVIEW=1; shift;; -t|--top|top) echo "$2" | grep -q '^[1-9]$' || exit 1; FORCE_TOP=$2; shift 2;;
-d|--depth|depth) echo "$2" | grep -q '^[1-9]$' || exit 1; FORCE_DEPTH=$2; shift 2;; -d|--depth|depth) echo "$2" | grep -q '^[1-9]$' || exit 1; FORCE_DEPTH=$2; shift 2;;
*) break;; *) break;;
esac; esac;
@@ -80,15 +81,9 @@ cd "$DIR";
item "Crawling Android Developers for latest Pixel Beta ..."; item "Crawling Android Developers for latest Pixel Beta ...";
wget -q -O PIXEL_VERSIONS_HTML --no-check-certificate https://developer.android.com/about/versions 2>&1 || exit 1; wget -q -O PIXEL_VERSIONS_HTML --no-check-certificate https://developer.android.com/about/versions 2>&1 || exit 1;
wget -q -O PIXEL_LATEST_HTML --no-check-certificate $(grep -o 'https://developer.android.com/about/versions/.*[0-9]"' PIXEL_VERSIONS_HTML | sort -ru | cut -d\" -f1 | head -n1) 2>&1 || exit 1; wget -q -O PIXEL_LATEST_HTML --no-check-certificate $(grep -o 'https://developer.android.com/about/versions/.*[0-9]"' PIXEL_VERSIONS_HTML | sort -ru | cut -d\" -f1 | head -n$FORCE_TOP | tail -n1) 2>&1 || exit 1;
if grep -qE 'Developer Preview|tooltip>.*preview program' PIXEL_LATEST_HTML && [ ! "$FORCE_PREVIEW" ]; then wget -q -O PIXEL_OTA_HTML --no-check-certificate https://developer.android.com$(grep -o 'href=".*download-ota.*"' PIXEL_LATEST_HTML | grep 'qpr' | cut -d\" -f2 | head -n$FORCE_DEPTH | tail -n1) 2>&1 || exit 1;
wget -q -O PIXEL_BETA_HTML --no-check-certificate $(grep -o 'https://developer.android.com/about/versions/.*[0-9]"' PIXEL_VERSIONS_HTML | sort -ru | cut -d\" -f1 | head -n2 | tail -n1) 2>&1 || exit 1; echo "$(grep -m1 -oE 'tooltip>Android .*[0-9]' PIXEL_OTA_HTML | cut -d\> -f2) $(grep -oE 'tooltip>QPR.* Beta' PIXEL_OTA_HTML | cut -d\> -f2 | head -n$FORCE_DEPTH | tail -n1)";
else
TITLE="Preview ";
mv -f PIXEL_LATEST_HTML PIXEL_BETA_HTML;
fi;
wget -q -O PIXEL_OTA_HTML --no-check-certificate https://developer.android.com$(grep -o 'href=".*download-ota.*"' PIXEL_BETA_HTML | cut -d\" -f2 | head -n$FORCE_DEPTH | tail -n1) 2>&1 || exit 1;
echo "$(grep -m1 -oE 'tooltip>Android .*[0-9]' PIXEL_OTA_HTML | cut -d\> -f2) $TITLE$(grep -oE 'tooltip>QPR.* Beta' PIXEL_OTA_HTML | cut -d\> -f2 | head -n$FORCE_DEPTH | tail -n1)";
BETA_REL_DATE="$(date -D '%B %e, %Y' -d "$(grep -m1 -A1 'Release date' PIXEL_OTA_HTML | tail -n1 | sed 's;.*<td>\(.*\)</td>.*;\1;')" '+%Y-%m-%d')"; BETA_REL_DATE="$(date -D '%B %e, %Y' -d "$(grep -m1 -A1 'Release date' PIXEL_OTA_HTML | tail -n1 | sed 's;.*<td>\(.*\)</td>.*;\1;')" '+%Y-%m-%d')";
BETA_EXP_DATE="$(date -D '%s' -d "$(($(date -D '%Y-%m-%d' -d "$BETA_REL_DATE" '+%s') + 60 * 60 * 24 * 7 * 6))" '+%Y-%m-%d')"; BETA_EXP_DATE="$(date -D '%s' -d "$(($(date -D '%Y-%m-%d' -d "$BETA_REL_DATE" '+%s') + 60 * 60 * 24 * 7 * 6))" '+%Y-%m-%d')";
@@ -167,7 +162,7 @@ if [ -f "$MIGRATE" ]; then
if [ -n "$ARGS" ]; then if [ -n "$ARGS" ]; then
grep_json() { [ -f "$2" ] && grep -m1 "$1" $2 | cut -d\" -f4; } grep_json() { [ -f "$2" ] && grep -m1 "$1" $2 | cut -d\" -f4; }
verboseLogs=$(grep_json "VERBOSE_LOGS" $OLDJSON); verboseLogs=$(grep_json "VERBOSE_LOGS" $OLDJSON);
ADVSETTINGS="spoofBuild spoofProps spoofProvider spoofSignature spoofVendingSdk verboseLogs"; ADVSETTINGS="spoofBuild spoofProps spoofProvider spoofSignature spoofVendingFinger spoofVendingSdk verboseLogs";
for SETTING in $ADVSETTINGS; do for SETTING in $ADVSETTINGS; do
eval [ -z \"\$$SETTING\" ] \&\& $SETTING=$(grep_json "$SETTING" $OLDJSON); eval [ -z \"\$$SETTING\" ] \&\& $SETTING=$(grep_json "$SETTING" $OLDJSON);
eval TMPVAL=\$$SETTING; eval TMPVAL=\$$SETTING;

View File

@@ -39,12 +39,14 @@ if [ -d "$MODPATH/zygisk" ]; then
fi fi
# Migrate custom.pif.json to latest defaults if needed # Migrate custom.pif.json to latest defaults if needed
if [ -f "$MODPATH/custom.pif.json" ] && ! grep -q "api_level" $MODPATH/custom.pif.json || ! grep -q "verboseLogs" $MODPATH/custom.pif.json || ! grep -q "spoofVendingSdk" $MODPATH/custom.pif.json; then if [ -f "$MODPATH/custom.pif.json" ]; then
ui_print "- Running migration script on custom.pif.json:" if ! grep -q "api_level" $MODPATH/custom.pif.json || ! grep -q "verboseLogs" $MODPATH/custom.pif.json || ! grep -q "spoofVendingFinger" $MODPATH/custom.pif.json; then
ui_print " " ui_print "- Running migration script on custom.pif.json:"
chmod 755 $MODPATH/migrate.sh ui_print " "
sh $MODPATH/migrate.sh --install --force --advanced $MODPATH/custom.pif.json chmod 755 $MODPATH/migrate.sh
ui_print " " sh $MODPATH/migrate.sh --install --force --advanced $MODPATH/custom.pif.json
ui_print " "
fi
fi fi
# Clean up any leftover files from previous deprecated methods # Clean up any leftover files from previous deprecated methods

View File

@@ -11,9 +11,11 @@
/system/app/EliteDevelopmentModule /system/app/EliteDevelopmentModule
/system/app/XInjectModule /system/app/XInjectModule
# helluvaOS, hentaiOS # helluvaOS
/system_ext/app/helluvaProductDevice* /system_ext/app/helluvaProductDevice*
/system_ext/app/helluvaProductSecretStub /system_ext/app/helluvaProductSecretStub
# hentaiOS
/system_ext/app/hentaiLewdbSVTDummy /system_ext/app/hentaiLewdbSVTDummy
# Evolution X # Evolution X

View File

@@ -31,6 +31,7 @@
"spoofProps": "1", "spoofProps": "1",
"spoofProvider": "1", "spoofProvider": "1",
"spoofSignature": "0", "spoofSignature": "0",
"spoofVendingFinger": "0",
"spoofVendingSdk": "0", "spoofVendingSdk": "0",
"verboseLogs": "0" "verboseLogs": "0"
} }

View File

@@ -114,12 +114,13 @@ if [ -z "$DEVICE_INITIAL_SDK_INT" -o "$DEVICE_INITIAL_SDK_INT" = "null" ]; then
DEVICE_INITIAL_SDK_INT=25; DEVICE_INITIAL_SDK_INT=25;
fi; fi;
ADVSETTINGS="spoofBuild spoofProps spoofProvider spoofSignature spoofVendingSdk verboseLogs"; ADVSETTINGS="spoofBuild spoofProps spoofProvider spoofSignature spoofVendingFinger spoofVendingSdk verboseLogs";
spoofBuild=1; spoofBuild=1;
spoofProps=1; spoofProps=1;
spoofProvider=1; spoofProvider=1;
spoofSignature=0; spoofSignature=0;
spoofVendingFinger=0;
spoofVendingSdk=0; spoofVendingSdk=0;
verboseLogs=0; verboseLogs=0;

View File

@@ -1,7 +1,7 @@
id=playintegrityfix id=playintegrityfix
name=Play Integrity Fork name=Play Integrity Fork
version=v14 version=v14
versionCode=140000 versionCode=140001
author=osm0sis & chiteroman @ xda-developers author=osm0sis & chiteroman @ xda-developers
description=Fix <A13 Play Integrity DEVICE verdict description=Fix <A13 Play Integrity DEVICE verdict
updateJson=https://raw.githubusercontent.com/osm0sis/PlayIntegrityFork/main/update.json updateJson=https://raw.githubusercontent.com/osm0sis/PlayIntegrityFork/main/update.json