70 Commits
v13 ... main

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
Chris Renshaw
9cea06e64d README: add Tricky Store OSS to recommendation 2025-08-08 10:56:04 -03:00
Chris Renshaw
4a14d97c24 README: improve TS configs description and detail api_level better 2025-07-30 23:45:25 -03:00
Chris Renshaw
dd44d2c1a8 README: fix typo and slight reorganization 2025-07-29 13:26:07 -03:00
osm0sis
a9eca199b6 Prepare v14 2025-07-28 23:04:08 -03:00
Chris Renshaw
abe81968db migrate.sh: show when adding Advanced Settings 2025-07-28 00:10:10 -03:00
Chris Renshaw
6cde52fc8a Fix ui_print regression during late installation 2025-07-27 23:39:35 -03:00
Chris Renshaw
18eeb7d92d Force custom.pif.json to latest Advanced Settings during install 2025-07-27 22:06:26 -03:00
Chris Renshaw
7ec4d37949 Update Action to run autopif2 --strong since Pixel Betas no longer pass Device 2025-07-23 18:42:13 -03:00
Chris Renshaw
72e2124a8e autopif2.sh: also support Simple dashed date, ensure newline 2025-07-17 23:05:38 -03:00
Chris Renshaw
8cd6155ffb autopif2.sh: Support updating TS security_patch.txt in Simple format 2025-07-17 22:25:59 -03:00
Chris Renshaw
c9d4064dfe Update NDK 2025-07-10 21:16:20 -03:00
Chris Renshaw
a99ebc6689 Update AGP 2025-07-10 21:12:14 -03:00
Chris Renshaw
ed312200cb autopif2.sh: inform to install wget2 when 32bit busybox is the likely issue 2025-07-08 22:53:58 -03:00
osm0sis
0a964415f3 Update C++ Standard 2025-07-04 22:36:54 -03:00
osm0sis
f12b85d67f Update Java 2025-07-04 21:42:34 -03:00
osm0sis
59a1eea076 Update Gradle 2025-07-04 20:55:48 -03:00
Halhadus
51619d2de4 Added open source module alternative for KernelSUs and APatch. 2025-07-01 14:49:38 -03:00
Chris Renshaw
fcb6a2df3e Update AGP 2025-06-28 21:44:06 -03:00
Chris Renshaw
1afd4278be Avoid potential issues from greedy matching 2025-06-28 01:19:15 -03:00
Chris Renshaw
77d5ccdc99 Cosmetic changes to match other cut usage 2025-06-28 01:06:52 -03:00
Chris Renshaw
a2f726b633 Improve overlay AndroidManifest.xml parsing, support PixelOS 15 2025-06-28 00:52:06 -03:00
Chris Renshaw
38631f685a Allow CI builds on demand 2025-06-23 19:17:21 -03:00
osm0sis
39d2610579 Refine proguard rules further
Thanks @TheFreeman193!
2025-06-22 20:38:24 -03:00
Chris Renshaw
0132ebb272 Fix persistprop during installation
Thanks geekboy38 on xda!
2025-06-20 09:03:18 -03:00
osm0sis
a82914221e README: document spoofVendingSdk, add credit for original PIF repo, fixes 2025-06-16 23:03:10 -03:00
Chris Renshaw
4755f88180 Promote autopif2 --match to documented feature
-m or --match will attempt to match the print to your current device if run on a Pixel, and will otherwise fall back to random

- make matching the Action button default since there was some evidence that matching your actual Pixel device may be important for accessing the Pixel exclusive features for your device
2025-06-11 23:05:58 -03:00
Chris Renshaw
62150ce6d4 Add Advanced Settings to example.pif.json
- needing the Advanced Settings is the more likely scenario nowadays, so display them more prominently to help people know how to use them
2025-06-11 22:36:15 -03:00
Chris Renshaw
88573ca743 Show Advanced Settings by default from install migrate and autopif2 2025-06-11 22:17:29 -03:00
Chris Renshaw
89de098a83 Update SDK Build Tools 2025-06-11 10:22:04 -03:00
Chris Renshaw
c6739dfa42 Promote experimental spoofVendingSdk to Advanced Settings
- many are experimenting and using it already across forks anyway 
- proper documentation to come for next stable release with known issues and potential use cases
2025-06-11 10:19:34 -03:00
osm0sis
a7dd416873 Revert "Disable R8 until proguard rules can be reimplemented correctly"
- resolved in 539ff7351a

This reverts commit 2cdee60781.
2025-06-11 01:16:44 -03:00
osm0sis
539ff7351a Fix proguard rules for AGP 8.9.0+
- CustomPackageInfoCreator public methods must now be explicitly kept to avoid spoofSignature crashes documented in 2cdee60781
2025-06-11 01:14:03 -03:00
osm0sis
0cd56584df Update AGP 2025-06-09 23:06:39 -03:00
osm0sis
2cdee60781 Disable R8 until proguard rules can be reimplemented correctly
- most Java classes were being kept fully unoptimized anyway, which should be generally avoided
- AGP 8.9.0-alpha07 is the last where spoofSignature works with R8 enabled, alpha08 and all later AGP results in:
  msg: java.lang.StackOverflowError: stack size 8188KB
  stacktrace: java.lang.StackOverflowError: stack size 8188KB
	at es.chiteroman.playintegrityfix.CustomPackageInfoCreator.createFromParcel(Unknown Source:2)
  [TRUNCATED 3288424 CHARS]
	at es.chiteroman.playintegrityfix.CustomPackageInfoCreator.createFromParcel(Unknown Source:2)
	at android.os.Parcel.readTypedObject(Parcel.java:4025)
	at android.content.pm.IPackageManager$Stub$Proxy.getPackageInfo(IPackageManager.java:4470)
	at android.content.pm.PackageManager.getPackageInfoAsUserUncached(PackageManager.java:10969)
	at android.content.pm.PackageManager.-$$Nest$smgetPackageInfoAsUserUncached(Unknown Source:0)
	at android.content.pm.PackageManager$2.recompute(PackageManager.java:10982)
	at android.content.pm.PackageManager$2.recompute(PackageManager.java:10979)
	at android.app.PropertyInvalidatedCache.query(PropertyInvalidatedCache.java:999)
	at android.content.pm.PackageManager.getPackageInfoAsUserCached(PackageManager.java:10996)
	at android.app.LoadedApk.initializeJavaContextClassLoader(LoadedApk.java:1215)
	at android.app.LoadedApk.makeApplicationInner(LoadedApk.java:1448)
	at android.app.LoadedApk.makeApplicationInner(LoadedApk.java:1405)
	at android.app.ActivityThread.handleBindApplication(ActivityThread.java:7029)
	at android.app.ActivityThread.-$$Nest$mhandleBindApplication(Unknown Source:0)
	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2262)
	at android.os.Handler.dispatchMessage(Handler.java:106)
	at android.os.Looper.loopOnce(Looper.java:205)
	at android.os.Looper.loop(Looper.java:294)
	at android.app.ActivityThread.main(ActivityThread.java:8282)
	at java.lang.reflect.Method.invoke(Native Method)
	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:554)
	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:885)
2025-06-09 23:03:47 -03:00
Chris Renshaw
7e376e5627 Update libcxx 2025-06-08 01:59:21 -03:00
Chris Renshaw
ec34417cd9 Also add new PIHooks detection to empty prop workaround 2025-06-08 01:46:26 -03:00
Chris Renshaw
0b957b13b9 Add support for disabling more PIHooks variants 2025-06-08 01:34:30 -03:00
Chris Renshaw
ec374a7d9b Fix persist prop deletion 2025-06-08 00:38:26 -03:00
Chris Renshaw
17db1e7177 Keep uninstall.sh through updates
- uninstall.sh is generated at first install so it must be kept to ensure it has the original states/values for the persist props
- run then remove uninstall.sh if it exists when switching to Scripts-Only Mode
2025-06-07 23:54:50 -03:00
osm0sis
451769c341 Clean up any modified custom ROM persist props on uninstall 2025-06-07 23:54:48 -03:00
osm0sis
77f91e3a85 Add new persistprop common function 2025-06-07 08:57:58 -03:00
osm0sis
b4eae8a6b6 Update Gradle 2025-06-07 08:38:53 -03:00
Chris Renshaw
05520f7881 autopif2.sh: abort if --depth arg is not a single digit positive integer 2025-06-01 21:54:05 -03:00
Chris Renshaw
1745060524 No stacktraces needed though
The remaining Gradle deprecation warnings are from Android Gradle Plugin (AGP), so figuring out why AGP 8.9.x+ breaks spoofSignature, and fixing that so that AGP can be updated is the only way to resolve things for Gradle 9.0:

Declaring an 'is-' property with a Boolean type has been deprecated. Starting with Gradle 9.0, this property will be ignored by Gradle.
[...]
Add a method named 'getCrunchPngs' with the same behavior and mark the old one with @Deprecated, or change the type of 'com.android.build.gradle.internal.dsl.BuildType$AgpDecorated.isCrunchPngs' (and the setter) to 'boolean'. [...]
Add a method named 'getUseProguard' with the same behavior and mark the old one with @Deprecated, or change the type of 'com.android.build.gradle.internal.dsl.BuildType.isUseProguard' (and the setter) to 'boolean'. [...]
Add a method named 'getWearAppUnbundled' with the same behavior and mark the old one with @Deprecated, or change the type of 'com.android.build.api.variant.impl.ApplicationVariantImpl.isWearAppUnbundled' (and the setter) to 'boolean'. [...]
2025-06-01 20:49:48 -03:00
Chris Renshaw
512ed8a1f1 Show all Gradle warnings in CI 2025-05-31 23:45:56 -03:00
osm0sis
0d8d090014 Suppress PackageInfo signatures deprecated API warning 2025-05-31 21:51:15 -03:00
osm0sis
0d03f99499 Fix Gradle Task.project execution time deprecation warning 2025-05-31 21:24:48 -03:00
osm0sis
85dd219ea3 Update Gradle 2025-05-31 11:32:11 -03:00
osm0sis
36cc9573ba Update Dobby submodule to JingMatrix fork 2025-05-31 11:27:28 -03:00
osm0sis
d72fc9ee04 Update nlohmann/json submodule to v3.12.0 2025-05-31 11:02:11 -03:00
Chris Renshaw
84adafc3ac autopif2.sh: retain experimental spoofVendingSdk entry and value if it exists 2025-05-30 10:14:34 -03:00
Chris Renshaw
cb49481c45 Begin next development cycle 2025-05-30 09:55:23 -03:00
Chris Renshaw
b5a9b26b70 README: update for May 20th legacyDeviceRecognitionVerdict removal from PI API 2025-05-20 22:37:32 -03:00
28 changed files with 312 additions and 182 deletions

View File

@@ -1,6 +1,7 @@
name: Android CI name: Android CI
on: on:
workflow_dispatch:
push: push:
branches: main branches: main
paths-ignore: '**.md' paths-ignore: '**.md'
@@ -15,22 +16,22 @@ 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: 17 java-version: 21
- name: Grant execute permission for gradlew - name: Grant execute permission for gradlew
run: chmod +x gradlew run: chmod +x gradlew
- name: Build with Gradle - name: Build with Gradle
run: ./gradlew assembleRelease run: ./gradlew --warning-mode all assembleRelease
- name: Upload CI module zip as artifact zip - name: Upload CI module zip as artifact zip
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4

5
.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/jmpews/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

@@ -1,23 +1,24 @@
## Custom Fork v14
- Add cleaning modified custom ROM persist props on uninstall
- Add opt-out props and detection for more PIH variants
- Fix spoofSignature crash when built with AGP 8.9+
- Add experimental spoofVendingSdk to Advanced Settings
- Update Action and install migrate to show Advanced Settings
- Improve Action to match device print on Pixel devices
- Improve ROM overlay xml disabling support (PixelOS 15)
- Add TS security_patch.txt Simple format support
- Update Action for Strong since Pixel Beta no longer pass Device
## Custom Fork v13 ## Custom Fork v13
- Improve Action on KSU/APatch, KSU-Next, MMRL - Improve Action on KSU/APatch, KSU-Next, MMRL
- Improve autopif2 to ignore Preview builds by default
- Remove unnecessary adb props spoof - Remove unnecessary adb props spoof
- Add all known opt-out props for PPU/PIH variants/hybrids - Add all known opt-out props for PPU/PIH variants/hybrids
- Add new verified boot error props deletion - Add new verified boot error props deletion
- Update killgms to killpi by adding vending - Update killgms to killpi
- Improve autopif2 to populate TS's optional security_patch.txt - Improve autopif2 to populate TS's optional security_patch.txt
- Improve ROM overlay xml disabling support - Improve ROM overlay xml disabling support (YAAP)
- Improve autopif2 for wget2 on arm - Improve autopif2 for wget2 on arm
- Improve Action to use Platform Preview builds
## Custom Fork v12 _[Full changelogs](https://github.com/osm0sis/PlayIntegrityFork/releases)_
- Improve autopif2 to generate from Pixel Beta point releases
- Improve autopif2 to catch more broken environments
- Improve migrate parsing lines with comments
- Update default app replace list for helluvaOS
- Fix retaining replaced non-system ROM apps on KSU/APatch
- Add autopif2 --strong for initial setup with TS
- Add skipping prop deletion to avoid app detections if skipdelprop file exists
_[Previous changelogs](https://github.com/osm0sis/PlayIntegrityFork/releases)_

View File

@@ -6,30 +6,36 @@
[![GitHub Releases](https://img.shields.io/github/downloads/osm0sis/PlayIntegrityFork/latest/total?label=Downloads%20%28Latest%20Release%29&color=blue&style=flat)](https://github.com/osm0sis/PlayIntegrityFork/releases/latest) [![GitHub Releases](https://img.shields.io/github/downloads/osm0sis/PlayIntegrityFork/latest/total?label=Downloads%20%28Latest%20Release%29&color=blue&style=flat)](https://github.com/osm0sis/PlayIntegrityFork/releases/latest)
[![GitHub All Releases](https://img.shields.io/github/downloads/osm0sis/PlayIntegrityFork/total?label=Total%20Downloads%20%28All%20Releases%29&color=brightgreen&style=flat)](https://github.com/osm0sis/PlayIntegrityFork/releases) [![GitHub All Releases](https://img.shields.io/github/downloads/osm0sis/PlayIntegrityFork/total?label=Total%20Downloads%20%28All%20Releases%29&color=brightgreen&style=flat)](https://github.com/osm0sis/PlayIntegrityFork/releases)
A Zygisk module which fixes "MEETS_DEVICE_INTEGRITY" for "legacyDeviceRecognitionVerdict" or Android <13 "deviceRecognitionVerdict" in the Play Integrity API. A Zygisk module which fixes "MEETS_DEVICE_INTEGRITY" for the Android <13 "deviceRecognitionVerdict" of the Play Integrity API. On Android 13+ ROMs it still helps to pass checks in Google Wallet and Google Messages RCS support.
To use this module you must have one of the following (latest versions): To use this module you must have one of the following (latest versions):
- [Magisk](https://github.com/topjohnwu/Magisk) with Zygisk enabled (and Enforce DenyList enabled if NOT also using [Shamiko](https://github.com/LSPosed/LSPosed.github.io/releases) or [Zygisk Assistant](https://github.com/snake-4/Zygisk-Assistant), for best results) - [Magisk](https://github.com/topjohnwu/Magisk) with Zygisk enabled (and Enforce DenyList enabled if NOT also using [Shamiko](https://github.com/LSPosed/LSPosed.github.io?tab=readme-ov-file#shamiko) or [Zygisk Assistant](https://github.com/snake-4/Zygisk-Assistant) or [NoHello](https://github.com/MhmRdd/NoHello), for best results)
- [KernelSU](https://github.com/tiann/KernelSU) with [Zygisk Next](https://github.com/Dr-TSNG/ZygiskNext) module installed - [KernelSU](https://github.com/tiann/KernelSU) with [Zygisk Next](https://github.com/Dr-TSNG/ZygiskNext) or [ReZygisk](https://github.com/PerformanC/ReZygisk) or [NeoZygisk](https://github.com/JingMatrix/NeoZygisk) module installed
- [KernelSU-Next](https://github.com/KernelSU-Next/KernelSU-Next) with [Zygisk Next](https://github.com/Dr-TSNG/ZygiskNext) module installed - [KernelSU Next](https://github.com/KernelSU-Next/KernelSU-Next) with [Zygisk Next](https://github.com/Dr-TSNG/ZygiskNext) or [ReZygisk](https://github.com/PerformanC/ReZygisk) or [NeoZygisk](https://github.com/JingMatrix/NeoZygisk) module installed
- [APatch](https://github.com/bmax121/APatch) with [Zygisk Next](https://github.com/Dr-TSNG/ZygiskNext) module installed - [APatch](https://github.com/bmax121/APatch) with [Zygisk Next](https://github.com/Dr-TSNG/ZygiskNext) or [ReZygisk](https://github.com/PerformanC/ReZygisk) or [NeoZygisk](https://github.com/JingMatrix/NeoZygisk) module installed
## About module ## About module
It injects a classes.dex file to modify fields in the android.os.Build class. Also, it creates a hook in the native code to modify system properties. These are spoofed only to Google Play Services' DroidGuard (Play Integrity) service. It injects a classes.dex file to modify fields in the android.os.Build class. Also, it creates a hook in the native code to modify system properties. These are spoofed only to Google Play Services' DroidGuard (Play Integrity) service.
## About 'custom.pif.json' file Note: Unless otherwise stated, verdicts here are all referring to the Android <13 Play Integrity "deviceRecognitionVerdict" (or "<A13 PI") which was formerly SafetyNet "ctsProfileMatch", not the Android 13+ Play Integrity "deviceRecognitionVerdict" (or "A13+ PI") which relies on locked bootloader checks to pass even DEVICE integrity.
You can fill out the included template [example.pif.json](https://raw.githubusercontent.com/osm0sis/PlayIntegrityFork/main/module/example.pif.json) from the module directory (/data/adb/modules/playintegrityfix) then rename it to custom.pif.json to spoof custom values to the GMS unstable process. It will be used instead of any included pif.json (none included currently). ## Configuration
Note this is just a template with the current suggested default entries, but with this fork you can include as few or as many android.os.Build class fields and Android system properties as needed to pass DEVICE verdict now and in the future if the enforced checks by Play Integrity change. The module is configured by editing json/list (text) files in the module directory (/data/adb/modules/playintegrityfix), by running one of the included scripts there, or by creating a file there to enable some advanced features. These are most easily done using the root file explorer app of your choice, as all should include a file editor and support script execution. The scripts also support command line arguments, which may be added when run from a root file explorer app, or when run in a root (su) shell from adb or a terminal emulator app. Unless otherwise stated, configuration changes will take effect after running the killpi.sh script to restart the Play Integrity (PI) processes, or you may also reboot.
As a general rule you can't use values from recent devices due to them only being allowed with full hardware backed attestation. A script to extract the latest Pixel Beta fingerprint is included with the module; see the autopif2 section below for usage and caveats, and see the Resources below for information and scripts to help find a working private fingerprint. ### About 'custom.pif.json' file
You can fill out the included template [example.pif.json](https://raw.githubusercontent.com/osm0sis/PlayIntegrityFork/main/module/example.pif.json) then rename it to custom.pif.json to spoof your own custom values. It will be used instead of any included pif.json (none included currently).
Note this is just a template with the current suggested default entries, but with this fork you can include as few or as many android.os.Build class fields and Android system properties as needed to pass DEVICE integrity now and in the future if the checks enforced by Play Integrity change.
As a general rule you can't use values from recent devices due to them only being allowed with full hardware backed attestation, but sets of these values can still be found which pass DEVICE integrity, and still others can also pass STRONG integrity when [setup correctly](#about-spoofing-advanced-settings). These are known as "private fingerprints" since widely publicly shared ones will get banned by Google. A script to extract a random latest Pixel Beta fingerprint is included with the module; see the autopif2 section below for usage and caveats, and expand the Resources below for information and scripts to help find a working private fingerprint.
Older formatted custom.pif.json files from cross-forks and previous releases will be automatically migrated to the latest format. Simply ensure the filename is custom.pif.json and place it in the module directory before upgrading. Older formatted custom.pif.json files from cross-forks and previous releases will be automatically migrated to the latest format. Simply ensure the filename is custom.pif.json and place it in the module directory before upgrading.
A migration may also be performed manually with `sh migrate.sh` and custom.pif.json in the same directory, or from a file explorer app that supports script execution. A migration may also be performed manually in the module directory with a custom.pif.json present by running migrate.sh with the `-a` or `--advanced` argument (to add Advanced Settings) in a file explorer app or with `sh migrate.sh --advanced` in a root shell, and `-f` or `--force` if desired.
<details> <details>
<summary><strong>Resources</strong></summary> <summary><strong>Resources</strong></summary>
@@ -55,15 +61,15 @@ A migration may also be performed manually with `sh migrate.sh` and custom.pif.j
</details> </details>
## About 'custom.app_replace.list' file ### About 'custom.app_replace.list' file
You can customize the included default [example.app_replace.list](https://raw.githubusercontent.com/osm0sis/PlayIntegrityFork/main/module/example.app_replace.list) from the module directory (/data/adb/modules/playintegrityfix) then rename it to custom.app_replace.list to systemlessly replace any additional conflicting custom ROM spoof injection app paths to disable them. You can customize the included default [example.app_replace.list](https://raw.githubusercontent.com/osm0sis/PlayIntegrityFork/main/module/example.app_replace.list) then rename it to custom.app_replace.list to systemlessly replace any additional conflicting custom ROM spoof injection app paths to disable them. Changes take effect after a reboot.
## About 'autopif2.sh' and 'killpi.sh' script files ### About 'autopif2.sh' and 'killpi.sh' script files
There's intentionally no pif.json in the module because the goal remains to be futureproof, and including something that may be banned and obsolete within days would be contrary to that goal. If you don't care to have your own private fingerprint to use or don't have time to look for one currently (since very few remain) then simply run the generation script from a root manager app that supports the module Action button, a root prompt with `sh autopif2.sh --preview` in the module directory (/data/adb/modules/playintegrityfix), or from a file explorer app that supports script execution. For arm/x86 devices wget2 is required but may be installed via [addon module](https://xdaforums.com/t/tools-zips-scripts-osm0sis-odds-and-ends-multiple-devices-platforms.2239421/post-89991315). There's intentionally no pif.json in the module because the goal remains to be futureproof, and including something that may be banned/expired within days of release would be contrary to that goal. If you don't care to have your own private fingerprint to use or don't have time to look for one currently (since very few remain) then simply run the generation script from a root manager app that supports the module Action button, or by running autopif.sh with the `-s -p` or `--strong --preview` arguments in a file explorer app or with `sh autopif2.sh --strong --preview` in a root shell. For arm/x86 devices wget2 is required but may be installed via [addon module](https://xdaforums.com/t/tools-zips-scripts-osm0sis-odds-and-ends-multiple-devices-platforms.2239421/post-89991315).
The autopif2 script generates a random device fingerprint from the latest Pixel Beta, ideally only to test an initial setup, since they expire roughly every 6 weeks from the Pixel Beta release date (dates included in the generated fingerprint), and the public mass-used ones from other modules or ROMs may also get banned or may be banned for RCS use while otherwise passing Play Integrity in that time. Notable advanced commandline options are: `-p` or `--preview` forces not to ignore Android Platform Preview builds (Developer Previews and Betas); and `-d #` or `--depth #` chooses the depth to crawl down the QPR Betas list when there are multiple active Betas, e.g. when QPR2 is concurrent with QPR1 the default value of 1 would get the first listed (QPR2) and `-d 2` would force it to get the second listed (QPR1). The autopif2 script generates a random device fingerprint from the latest Pixel Beta, ideally only to test an initial setup, since they expire roughly every 6 weeks from the Pixel Beta release date (dates included in the generated fingerprint), and the public mass-used ones from other modules or custom ROMs may also get banned, or may be banned for RCS use while otherwise passing Play Integrity in that time. In addition, unfortunately Pixel Beta fingerprints have changed and no longer pass DEVICE integrity, so can now only be used for STRONG integrity [setups](#about-spoofing-advanced-settings). Notable advanced command line arguments are: `-m` or `--match` matches the Pixel Beta fingerprint to the device when run on a current Pixel device; `-p` or `--preview` forces not to ignore Android Platform Preview builds (Developer Previews and Betas); and `-d #` or `--depth #` chooses the depth to crawl down the QPR Betas list when there are multiple active Betas, e.g. when QPR2 is concurrent with QPR1 the default value of 1 would get the first listed (QPR2) and `-d 2` would force it to get the second listed (QPR1).
The killpi script forces the Google Play Services DroidGuard (com.google.android.gms.unstable) and Play Store (com.android.vending) processes to end, making them restart with the next attestation attempt; useful for testing out different fingerprints without requiring a reboot in between. The killpi script forces the Google Play Services DroidGuard (com.google.android.gms.unstable) and Play Store (com.android.vending) processes to end, making them restart with the next attestation attempt; useful for testing out different fingerprints without requiring a reboot in between.
@@ -71,43 +77,59 @@ The killpi script forces the Google Play Services DroidGuard (com.google.android
Make sure Google Play Services (com.google.android.gms) is NOT on the Magisk DenyList if Enforce DenyList is enabled since this interferes with the module; the module does prevent this using scripts but it only happens once during each reboot. Make sure Google Play Services (com.google.android.gms) is NOT on the Magisk DenyList if Enforce DenyList is enabled since this interferes with the module; the module does prevent this using scripts but it only happens once during each reboot.
Note: The below verdicts are all referring to the legacyDeviceRecognitionVerdict or Android <13 deviceRecognitionVerdict Play Integrity API, not the Android 13+ deviceRecognitionVerdict (which relies on locked bootloader checks to pass even DEVICE verdict). Note: To test <A13 PI verdicts on an A13+ ROM the spoofVendingSdk option in the custom.pif.json Advanced Settings must be temporarily enabled. See the spoofing Advanced Settings section below.
### Failing BASIC verdict ### Failing BASIC integrity
If you are failing MEETS_BASIC_INTEGRITY (Play Integrity) something is wrong in your setup. Recommended steps in order to find the problem: If you are failing MEETS_BASIC_INTEGRITY something is wrong in your setup. Recommended steps in order to find the problem:
- Disable all modules except this one - Disable all modules except this one
- Try a different (ideally known working) custom.pif.json - Try a different (ideally known working) custom.pif.json
Note: Some modules which modify system (e.g. Xposed) can trigger DroidGuard detections, as can any which hook GMS processes (e.g. custom fonts). Note: Some modules which modify system (e.g. Xposed) can trigger DroidGuard detections, as can any which hook Google Play Services (GMS) processes (e.g. custom fonts).
### Failing DEVICE verdict (on KernelSU/KernelSU-Next/APatch) ### Failing DEVICE integrity (on KernelSU/KernelSU Next/APatch)
- Disable Zygisk Next - Disable Zygisk Next
- Reboot - Reboot
- Enable Zygisk Next - Enable Zygisk Next
- Reboot again - Reboot again
### Failing DEVICE verdict (on custom kernel/ROM) ### Failing DEVICE integrity (on custom kernel/ROM)
- Check the kernel release string with command `adb shell uname -r` or `uname -r` - Check the kernel release string with command `adb shell uname -r` or `uname -r`
- If it's on the [Known Banned Kernel List](https://xdaforums.com/t/module-play-integrity-fix-safetynet-fix.4607985/post-89308909) then inform your kernel developer/ROM maintainer to remove their branding for their next build - If it's on the [Known Banned Kernel List](https://xdaforums.com/t/module-play-integrity-fix-safetynet-fix.4607985/post-89308909) then inform your kernel developer/ROM maintainer to remove their branding for their next build
- You may also try a different custom kernel, or go back to the default kernel for your ROM, if available/possible - You may also try a different custom kernel, or go back to the default kernel for your ROM, if available/possible
### Failing DEVICE verdict (on custom ROM) ### Failing DEVICE integrity (on custom ROM)
- Check the ROM signing keys with command `adb shell unzip -l /system/etc/security/otacerts.zip` or `unzip -l /system/etc/security/otacerts.zip` - Check the ROM signing keys with command `adb shell unzip -l /system/etc/security/otacerts.zip` or `unzip -l /system/etc/security/otacerts.zip`
- If the output shows the ROM is signed with the AOSP testkey then inform your ROM maintainer to start signing their builds with a private key for their next build and ideally also provide a ROM signature migration build to allow users to update to it without requiring a data wipe - If the output shows the ROM is signed with the AOSP testkey then inform your ROM maintainer to start signing their builds with a private key for their next build and ideally also provide a ROM signature migration build to allow users to update to it without requiring a data wipe
- Pixel Beta fingerprints and some private fingerprints appear to be exempt from this testkey ROM ban
- There is an experimental advanced feature to attempt to work around this by spoofing the ROM signature in Package Manager, see the spoofing Advanced Settings section below - There is an experimental advanced feature to attempt to work around this by spoofing the ROM signature in Package Manager, see the spoofing Advanced Settings section below
- You may also try a different custom ROM, or go back to the stock ROM for your device, if available/possible - You may also try a different custom ROM, or go back to the stock ROM for your device, if available/possible
### Failing Play Protect/Store Certification and/or Google Wallet Tap To Pay Setup Security Requirements ### Failing Play Protect/Store Certification
- Reflash the module in your root manager app - Reflash the module in your root manager app
- 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 Store (com.android.vending) and, if present, Google Play Protect Service (com.google.android.odad) cache and data - Clear Google Play Store (com.android.vending) and, if present, Google Play Protect Service (com.google.android.odad) cache and data
- Clear Google Play Services (com.google.android.gms) cache and data, or, optionally skip clearing data and wait some time (~24h) for it to resolve on its own - Reboot
### Failing Google Messages RCS setup or failing to send messages
- Reflash the module in your root manager app
- Try a different (ideally known working) custom.pif.json
- Clear Google Messages (com.google.android.apps.messaging) cache and data
- Reboot
Note: RCS is most easily checked using Gemini in Messages and usually clearing Messages app data is not required.
### Failing Google Wallet Tap To Pay Setup Security Requirements
- Reflash the module in your root manager app
- 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 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
Note: Clearing Google Play Services app ***data*** will then require you to reset any WearOS devices paired to your device. Note: Clearing Google Play Services app ***data*** will then require you to reset any WearOS devices paired to your device.
@@ -118,32 +140,34 @@ You can read module logs using one of these commands directly after boot:
`adb shell "logcat | grep 'PIF/'"` or `su -c "logcat | grep 'PIF/'"` `adb shell "logcat | grep 'PIF/'"` or `su -c "logcat | grep 'PIF/'"`
Add a "verboseLogs" entry with a value of "0", "1", "2", "3" or "100" to your custom.pif.json to enable higher logging levels; "100" will dump all Build fields, and all the system properties that DroidGuard is checking. Adding the entry can also be done using the migration script with the `sh migrate.sh --force --advanced` or `sh migrate.sh -f -a` command. Adjust the Advanced Settings "verboseLogs" entry to a value of "0", "1", "2", "3" or "100" in your custom.pif.json to enable higher logging levels; "100" will dump all Build fields and all system properties that DroidGuard is checking.
## Can this module pass MEETS_STRONG_INTEGRITY? ## Can this module pass MEETS_STRONG_INTEGRITY?
No... [No...](#about-spoofing-advanced-settings)
## About spoofing Advanced Settings ## About spoofing Advanced Settings
The advanced spoofing options add granular control over what exactly gets spoofed, allowing one to disable the parts that may conflict with other kinds of spoofing modules, and provide an option to work around the testkey ROM ban for those needing that feature. See more in the Details area below. The advanced spoofing options add granular control over what exactly gets spoofed to Play Integrity (PI), allowing one to disable the parts that may conflict with other kinds of spoofing modules, and provides options to force a device to use <A13 PI verdicts or work around the testkey ROM ban for those needing those features. See more in the Details area below.
<details> <details>
<summary><strong>Details</strong></summary> <summary><strong>Details</strong></summary>
- Adding the Advanced Settings entries is best done using the migration script with the `sh migrate.sh --force --advanced` or `sh migrate.sh -f -a` command. They may also be added on initial setups using the `sh autopif2.sh --advanced --preview` or `sh autopif2.sh -a -p` command or configured directly for Tricky Store to achieve <A13 STRONG or A13+ DEVICE or STRONG integrity (see below) with the `sh autopif2.sh --strong --preview` or `sh autopif2.sh -s -p` command. Other than for the "verboseLogs" entry (see above), they are all 0 (disabled) or 1 (enabled). - The Advanced Settings entries are present by default from autopif2 or migrate (during installation), but may be added to any fingerprint by running migrate.sh with the `-f -a` or `--force --advanced` arguments in a file explorer app or with `sh migrate.sh --force --advanced` in a root shell. They may also be configured directly for Tricky Store to achieve <A13 PI STRONG or A13+ PI DEVICE/STRONG integrity (see below) by running autopif2.sh with the `-s -p` or `--strong --preview` arguments in a file explorer app or with `sh autopif2.sh --strong --preview` in a root shell. Other than for the "verboseLogs" entry (see above), they are all 0 (disabled) or 1 (enabled).
- The "spoofBuild" entry (default 1) controls spoofing the Build Fields from the fingerprint; the "spoofProps" entry (default 1) controls spoofing the System Properties from the fingerprint; the "spoofProvider" entry (default 1) controls spoofing the Keystore Provider, and the "spoofSignature" entry (default 0) controls spoofing the ROM Signature. - The "spoofBuild" entry (default 1) controls spoofing the Build Fields from the fingerprint; the "spoofProps" entry (default 1) controls spoofing the System Properties from the fingerprint; the "spoofProvider" entry (default 1) controls spoofing the Keystore Provider; the "spoofSignature" entry (default 0) controls spoofing the ROM Signature, and the "spoofVendingSdk" entry (default 0) controls spoofing ROM SDK_INT/sdkVersion 32 to the Play Store (com.android.vending) to force Play Integrity to use the <A13 PI verdicts.
- For spoofing locked bootloader and attempting to pass Play Integrity <A13 STRONG or A13+ DEVICE or STRONG verdict I only recommend using the latest official [Tricky Store](https://github.com/5ec1cff/TrickyStore) build. - Leaving spoofVendingSdk enabled is NOT recommended, it [will break](https://github.com/osm0sis/PlayIntegrityFork/pull/30) the behavior of the Play Store to some extent (back gesture/navbar button for all, account sign-in and downloads for higher original ROM SDK_INT) and could have other unintended effects like incorrect app variants being served, crashes, etc. Play Store must be fully set up before (and data not cleared during) enabling spoofVendingSdk or it and PI checks will only crash/hang. One possible use case is with the [spoofVendingSdk QSTile](https://xdaforums.com/t/tricky-store-bootloader-keybox-spoofing.4683446/post-90118016) Tasker App to quickly toggle it on only as needed, then toggle it off again afterward.
- Note: Using Tricky Store to achieve <A13 STRONG or A13+ DEVICE or STRONG integrity (with an unrevoked hardware keybox.xml) requires the Advanced Settings "spoofProvider" disabled and the "*.security_patch" entry commented out (unless spoofing a matching OS Patch Level with system= or all= in Tricky Store's security_patch.txt; autopif2 will do this automatically if security_patch.txt exists in the Tricky Store directory), but to achieve Legacy/<A13 DEVICE integrity (with Tricky Store default AOSP software keybox.xml) requires at least "spoofProps" enabled, and some fingerprints may also require "spoofProvider". More known working private fingerprints can achieve Legacy/<A13 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. - 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 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>
## About Scripts-only mode ## About Scripts-only mode
An advanced feature intended for older Android <10 ROMs, mostly stock ROMs or those with stock-like values, (and some other rare special cases), since they generally only need a few prop changes to pass Play Integrity Legacy/<A13 DEVICE verdict. Due to this the majority of the previous information does not apply to or contradicts that of Scripts-only mode, so to avoid confusion it's contained in the Details area below. An advanced feature intended for older Android <10 ROMs, mostly stock ROMs or those with stock-like values, (and some other rare special cases), since they generally only need a few prop changes to pass <A13 PI DEVICE integrity. Due to this the majority of the previous information does not apply to or contradicts that of Scripts-only mode, so to avoid confusion it's contained in the Details area below.
<details> <details>
<summary><strong>Details</strong></summary> <summary><strong>Details</strong></summary>
@@ -152,7 +176,7 @@ An advanced feature intended for older Android <10 ROMs, mostly stock ROMs or th
- During install all unused default mode files (including custom.pif.json) are removed from the module directory, effectively disabling the Zygisk components of PIF: attestation fallback and device spoofing. You'll see "Scripts-only mode" indicated in the module description in your root manager app. - During install all unused default mode files (including custom.pif.json) are removed from the module directory, effectively disabling the Zygisk components of PIF: attestation fallback and device spoofing. You'll see "Scripts-only mode" indicated in the module description in your root manager app.
- For best results, you should still most likely enable Magisk's Enforce DenyList option if NOT also using [Shamiko](https://github.com/LSPosed/LSPosed.github.io/releases) or [Zygisk Assistant](https://github.com/snake-4/Zygisk-Assistant). The module will automatically add the Google Play Services DroidGuard process (com.google.android.gms.unstable) to the Magisk DenyList, if missing, since for Scripts-only mode it's necessary on some configurations (generally Android 9). - For best results, you should still most likely enable Magisk's Enforce DenyList option if NOT also using [Shamiko](https://github.com/LSPosed/LSPosed.github.io/releases) or [Zygisk Assistant](https://github.com/snake-4/Zygisk-Assistant) or [NoHello](https://github.com/MhmRdd/NoHello). The module will automatically add the Google Play Services DroidGuard process (com.google.android.gms.unstable) to the Magisk DenyList, if missing, since for Scripts-only mode it's necessary on some configurations (generally Android 9).
</details> </details>
@@ -168,6 +192,8 @@ An advanced feature (unrelated to Play Integrity) intended for those who also ne
## Credits ## Credits
Original concept and general mechanism of PIF were from kdrag0n's [ProtonAOSP](https://protonaosp.org/) and [Universal SafetyNet Fix (USNF)](https://github.com/kdrag0n/safetynet-fix) projects. Forked from chiteroman's [Play Integrity Fix (PIF)](https://github.com/chiteroman/PlayIntegrityFix) (no longer online).
Module scripts were adapted from those of Displax's forked Universal SafetyNet Fix (USNF MOD) module, please see the commit history of [Displax's USNF MOD](https://github.com/Displax/safetynet-fix/tree/dev/magisk) for proper attribution. Original concept and general mechanism of PIF from kdrag0n's [ProtonAOSP](https://protonaosp.org/) and [Universal SafetyNet Fix (USNF)](https://github.com/kdrag0n/safetynet-fix) projects.
Module boot scripts adapted from those of Displax's forked [Universal SafetyNet Fix (USNF MOD)](https://github.com/Displax/safetynet-fix); please see the module files [commit history](https://github.com/Displax/safetynet-fix/commits/dev/magisk) for proper attribution.

View File

@@ -4,9 +4,9 @@ plugins {
android { android {
namespace = "es.chiteroman.playintegrityfix" namespace = "es.chiteroman.playintegrityfix"
compileSdk = 35 compileSdk = 36
ndkVersion = "28.1.13356709" ndkVersion = "28.2.13676358"
buildToolsVersion = "35.0.1" buildToolsVersion = "36.0.0"
buildFeatures { buildFeatures {
prefab = true prefab = true
@@ -22,7 +22,7 @@ android {
defaultConfig { defaultConfig {
applicationId = "es.chiteroman.playintegrityfix" applicationId = "es.chiteroman.playintegrityfix"
minSdk = 26 minSdk = 26
targetSdk = 35 targetSdk = 36
versionCode = 1 versionCode = 1
versionName = "1.0" versionName = "1.0"
@@ -31,7 +31,7 @@ android {
arguments += "-DANDROID_STL=none" arguments += "-DANDROID_STL=none"
arguments += "-DCMAKE_BUILD_TYPE=Release" arguments += "-DCMAKE_BUILD_TYPE=Release"
cppFlags += "-std=c++20" cppFlags += "-std=c++23"
cppFlags += "-fno-exceptions" cppFlags += "-fno-exceptions"
cppFlags += "-fno-rtti" cppFlags += "-fno-rtti"
cppFlags += "-fvisibility=hidden" cppFlags += "-fvisibility=hidden"
@@ -49,8 +49,8 @@ android {
} }
compileOptions { compileOptions {
sourceCompatibility = JavaVersion.VERSION_17 sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_17 targetCompatibility = JavaVersion.VERSION_21
} }
externalNativeBuild { externalNativeBuild {
@@ -62,16 +62,16 @@ android {
} }
dependencies { dependencies {
implementation("org.lsposed.libcxx:libcxx:27.0.12077973") implementation("org.lsposed.libcxx:libcxx:28.1.13356709")
implementation("org.lsposed.hiddenapibypass:hiddenapibypass:6.1") implementation("org.lsposed.hiddenapibypass:hiddenapibypass:6.1")
} }
tasks.register("copyFiles") { tasks.register("copyFiles") {
doLast { val moduleFolder = project.rootDir.resolve("module")
val moduleFolder = project.rootDir.resolve("module") val dexFile = project.layout.buildDirectory.get().asFile.resolve("intermediates/dex/release/minifyReleaseWithR8/classes.dex")
val dexFile = project.layout.buildDirectory.get().asFile.resolve("intermediates/dex/release/minifyReleaseWithR8/classes.dex") val soDir = project.layout.buildDirectory.get().asFile.resolve("intermediates/stripped_native_libs/release/stripReleaseDebugSymbols/out/lib")
val soDir = project.layout.buildDirectory.get().asFile.resolve("intermediates/stripped_native_libs/release/stripReleaseDebugSymbols/out/lib")
doLast {
dexFile.copyTo(moduleFolder.resolve("classes.dex"), overwrite = true) dexFile.copyTo(moduleFolder.resolve("classes.dex"), overwrite = true)
soDir.walk().filter { it.isFile && it.extension == "so" }.forEach { soFile -> soDir.walk().filter { it.isFile && it.extension == "so" }.forEach { soFile ->

View File

@@ -1,5 +1,5 @@
-keep class es.chiteroman.playintegrityfix.EntryPoint {public <methods>;} -keep class es.chiteroman.playintegrityfix.EntryPoint { public <methods>; }
-keep class es.chiteroman.playintegrityfix.EntryPointVending {public <methods>;} -keep class es.chiteroman.playintegrityfix.EntryPointVending { public <methods>; }
-keep class es.chiteroman.playintegrityfix.CustomProvider -keepclassmembers class es.chiteroman.playintegrityfix.CustomKeyStoreSpi
-keep class es.chiteroman.playintegrityfix.CustomKeyStoreSpi -keepclassmembers class es.chiteroman.playintegrityfix.CustomPackageInfoCreator { public <init>(...); }
-keep class es.chiteroman.playintegrityfix.CustomPackageInfoCreator -keepclassmembers class es.chiteroman.playintegrityfix.CustomProvider

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

@@ -16,6 +16,7 @@ public class CustomPackageInfoCreator implements Parcelable.Creator<PackageInfo>
} }
@Override @Override
@SuppressWarnings("deprecation")
public PackageInfo createFromParcel(Parcel source) { public PackageInfo createFromParcel(Parcel source) {
PackageInfo packageInfo = originalCreator.createFromParcel(source); PackageInfo packageInfo = originalCreator.createFromParcel(source);
if (packageInfo.packageName.equals("android")) { if (packageInfo.packageName.equals("android")) {

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.8.2" 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-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 -p || exit 1 sh $MODPATH/autopif2.sh -s -m || exit 1
echo -e "\nDone!" echo -e "\nDone!"

View File

@@ -7,14 +7,16 @@ 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] [-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;;
-p|--preview|preview) FORCE_PREVIEW=1; shift;; -m|--match|match) FORCE_MATCH=1; shift;;
-d|--depth|depth) FORCE_DEPTH=$2; shift 2;; -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;;
*) break;; *) break;;
esac; esac;
done; done;
@@ -79,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')";
@@ -98,18 +94,16 @@ MODEL_LIST="$(grep -A1 'tr id=' PIXEL_OTA_HTML | grep 'td' | sed 's;.*<td>\(.*\)
PRODUCT_LIST="$(grep -o 'ota/.*_beta' PIXEL_OTA_HTML | cut -d\/ -f2)"; PRODUCT_LIST="$(grep -o 'ota/.*_beta' PIXEL_OTA_HTML | cut -d\/ -f2)";
OTA_LIST="$(grep 'ota/.*_beta' PIXEL_OTA_HTML | cut -d\" -f2)"; OTA_LIST="$(grep 'ota/.*_beta' PIXEL_OTA_HTML | cut -d\" -f2)";
case "$1" in if [ "$FORCE_MATCH" ]; then
-m) DEVICE="$(getprop ro.product.device)";
DEVICE="$(getprop ro.product.device)"; case "$PRODUCT_LIST" in
case "$PRODUCT_LIST" in *${DEVICE}_beta*)
*${DEVICE}_beta*) MODEL="$(getprop ro.product.model)";
MODEL="$(getprop ro.product.model)"; PRODUCT="${DEVICE}_beta";
PRODUCT="${DEVICE}_beta"; OTA="$(echo "$OTA_LIST" | grep "$PRODUCT")";
OTA="$(echo "$OTA_LIST" | grep "$PRODUCT")"; ;;
;; esac;
esac; fi;
;;
esac;
item "Selecting Pixel Beta device ..."; item "Selecting Pixel Beta device ...";
if [ -z "$PRODUCT" ]; then if [ -z "$PRODUCT" ]; then
set_random_beta() { set_random_beta() {
@@ -132,7 +126,10 @@ echo "$MODEL ($PRODUCT)";
FINGERPRINT="$(grep -am1 'post-build=' PIXEL_ZIP_METADATA 2>/dev/null | cut -d= -f2)"; FINGERPRINT="$(grep -am1 'post-build=' PIXEL_ZIP_METADATA 2>/dev/null | cut -d= -f2)";
SECURITY_PATCH="$(grep -am1 'security-patch-level=' PIXEL_ZIP_METADATA 2>/dev/null | cut -d= -f2)"; SECURITY_PATCH="$(grep -am1 'security-patch-level=' PIXEL_ZIP_METADATA 2>/dev/null | cut -d= -f2)";
if [ -z "$FINGERPRINT" -o -z "$SECURITY_PATCH" ]; then if [ -z "$FINGERPRINT" -o -z "$SECURITY_PATCH" ]; then
echo "\nError: Failed to extract information from metadata!"; case "$(getprop ro.product.cpu.abi)" in
armeabi-v7a|x86) [ "$BUSYBOX" ] && ISBB32MSG=", install wget2";;
esac;
echo "\nError: Failed to extract information from metadata$ISBB32MSG!";
exit 1; exit 1;
fi; fi;
@@ -165,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 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;
@@ -193,8 +190,11 @@ if [ "$DIR" = /data/adb/modules/playintegrityfix/autopif2 ]; then
if [ -f "$TS_SECPAT" ]; then if [ -f "$TS_SECPAT" ]; then
item "Updating Tricky Store security_patch.txt ..."; item "Updating Tricky Store security_patch.txt ...";
[ -s "$TS_SECPAT" ] || echo "all=" > $TS_SECPAT; [ -s "$TS_SECPAT" ] || echo "all=" > $TS_SECPAT;
grep -qE '^[0-9]{8}$' $TS_SECPAT && sed -i "s/^.*$/${SECURITY_PATCH//-}/" $TS_SECPAT;
grep -qE '^[0-9]{4}-[0-9]{2}-[0-9]{2}$' $TS_SECPAT && sed -i "s/^.*$/$SECURITY_PATCH/" $TS_SECPAT;
grep -q 'all=' $TS_SECPAT && sed -i "s/all=.*/all=$SECURITY_PATCH/" $TS_SECPAT; grep -q 'all=' $TS_SECPAT && sed -i "s/all=.*/all=$SECURITY_PATCH/" $TS_SECPAT;
grep -q 'system=' $TS_SECPAT && sed -i "s/system=.*/system=$(echo ${SECURITY_PATCH//-} | cut -c-6)/" $TS_SECPAT; grep -q 'system=' $TS_SECPAT && sed -i "s/system=.*/system=$(echo ${SECURITY_PATCH//-} | cut -c-6)/" $TS_SECPAT;
sed -i '$a\' $TS_SECPAT;
cat $TS_SECPAT; cat $TS_SECPAT;
fi; fi;
if [ -f /data/adb/modules/playintegrityfix/killpi.sh ]; then if [ -f /data/adb/modules/playintegrityfix/killpi.sh ]; then

View File

@@ -8,6 +8,22 @@ delprop_if_exist() {
[ -n "$(resetprop "$NAME")" ] && resetprop --delete "$NAME" [ -n "$(resetprop "$NAME")" ] && resetprop --delete "$NAME"
} }
# persistprop <prop name> <new value>
persistprop() {
local NAME="$1"
local NEWVALUE="$2"
local CURVALUE="$(resetprop "$NAME")"
if ! grep -q "$NAME" $MODPATH/uninstall.sh 2>/dev/null; then
if [ "$CURVALUE" ]; then
[ "$NEWVALUE" = "$CURVALUE" ] || echo "resetprop -n -p \"$NAME\" \"$CURVALUE\"" >> $MODPATH/uninstall.sh
else
echo "resetprop -p --delete \"$NAME\"" >> $MODPATH/uninstall.sh
fi
fi
resetprop -n -p "$NAME" "$NEWVALUE"
}
RESETPROP="resetprop -n" RESETPROP="resetprop -n"
[ -f /data/adb/magisk/util_functions.sh ] && [ "$(grep MAGISK_VER_CODE /data/adb/magisk/util_functions.sh | cut -d= -f2)" -lt 27003 ] && RESETPROP=resetprop_hexpatch [ -f /data/adb/magisk/util_functions.sh ] && [ "$(grep MAGISK_VER_CODE /data/adb/magisk/util_functions.sh | cut -d= -f2)" -lt 27003 ] && RESETPROP=resetprop_hexpatch
@@ -31,7 +47,7 @@ resetprop_hexpatch() {
local PROPFILE="/dev/__properties__/$(resetprop -Z "$NAME")" local PROPFILE="/dev/__properties__/$(resetprop -Z "$NAME")"
fi fi
[ ! -f "$PROPFILE" ] && return 3 [ ! -f "$PROPFILE" ] && return 3
local NAMEOFFSET=$(echo $(strings -t d "$PROPFILE" | grep "$NAME") | cut -d ' ' -f 1) local NAMEOFFSET=$(echo $(strings -t d "$PROPFILE" | grep "$NAME") | cut -d\ -f1)
#<hex 2-byte change counter><flags byte><hex length of prop value><prop value + nul padding to 92 bytes><prop name> #<hex 2-byte change counter><flags byte><hex length of prop value><prop value + nul padding to 92 bytes><prop name>
local NEWHEX="$(printf '%02x' "$NEWLEN")$(printf "$NEWVALUE" | od -A n -t x1 -v | tr -d ' \n')$(printf "%$((92-NEWLEN))s" | sed 's/ /00/g')" local NEWHEX="$(printf '%02x' "$NEWLEN")$(printf "$NEWVALUE" | od -A n -t x1 -v | tr -d ' \n')$(printf "%$((92-NEWLEN))s" | sed 's/ /00/g')"
@@ -63,4 +79,6 @@ resetprop_if_match() {
} }
# stub for boot-time # stub for boot-time
ui_print() { return; } if [ "$(getprop sys.boot_completed)" != "1" ]; then
ui_print() { return; }
fi

View File

@@ -39,7 +39,7 @@ for APP in $(grep -v '^#' $LIST); do
APK=$(readlink -f $APP); APK=$(readlink -f $APP);
fi fi
if [ -s "$APK" ]; then if [ -s "$APK" ]; then
PKGNAME=$(unzip -p $APK AndroidManifest.xml | tr -d '\0' | grep -oE 'android.*http' | sed -e 's/android//' -e 's/.application//' -e 's/*http//' | cut -c2-) PKGNAME=$(unzip -p $APK AndroidManifest.xml | tr -d '\0' | grep -oE 'android.*overlay' | strings | tr -d '\n' | sed -e 's/^android//' -e 's/application//' -e 's;*http.*res/android;;' -e 's/manifest//' -e 's/overlay$//' | grep -oE '[[:alnum:].-_].*overlay' | cut -d\ -f2)
if [ "$PKGNAME" ] && grep -q "overlay package=\"$PKGNAME" $CFG; then if [ "$PKGNAME" ] && grep -q "overlay package=\"$PKGNAME" $CFG; then
HIDECFG=$MODPATH$PREFIX$CFG HIDECFG=$MODPATH$PREFIX$CFG
if [ ! -f "$HIDECFG" ]; then if [ ! -f "$HIDECFG" ]; then
@@ -60,19 +60,20 @@ for APP in $(grep -v '^#' $LIST); do
done done
# Work around custom ROM PropImitationHooks conflict when their persist props don't exist # Work around custom ROM PropImitationHooks conflict when their persist props don't exist
if [ -n "$(resetprop ro.aospa.version)" -o -n "$(resetprop net.pixelos.version)" -o -n "$(resetprop ro.afterlife.version)" ]; then if [ -n "$(resetprop ro.aospa.version)" -o -n "$(resetprop net.pixelos.version)" -o -n "$(resetprop ro.afterlife.version)" -o -f /data/system/gms_certified_props.json ]; then
for PROP in persist.sys.pihooks.first_api_level persist.sys.pihooks.security_patch; do for PROP in persist.sys.pihooks.first_api_level persist.sys.pihooks.security_patch; do
resetprop | grep -q "\[$PROP\]" || resetprop -n -p "$PROP" "" resetprop | grep -q "\[$PROP\]" || persistprop "$PROP" ""
done done
fi fi
# Work around supported custom ROM PropImitationHooks/PixelPropsUtils (and hybrids) conflict when spoofProvider is disabled # Work around supported custom ROM PropImitationHooks/PixelPropsUtils (and hybrids) conflict when spoofProvider is disabled
if resetprop | grep -qE "persist.sys.pihooks|persist.sys.entryhooks|persist.sys.pixelprops"; then if resetprop | grep -qE "persist.sys.pihooks|persist.sys.entryhooks|persist.sys.spoof|persist.sys.pixelprops" || [ -f /data/system/gms_certified_props.json ]; then
resetprop -n -p persist.sys.pihooks.disable.gms_props true persistprop persist.sys.pihooks.disable.gms_props true
resetprop -n -p persist.sys.pihooks.disable.gms_key_attestation_block true persistprop persist.sys.pihooks.disable.gms_key_attestation_block true
resetprop -n -p persist.sys.entryhooks_enabled false persistprop persist.sys.entryhooks_enabled false
resetprop -n -p persist.sys.pixelprops.gms false persistprop persist.sys.spoof.gms false
resetprop -n -p persist.sys.pixelprops.gapps false persistprop persist.sys.pixelprops.gms false
resetprop -n -p persist.sys.pixelprops.google false persistprop persist.sys.pixelprops.gapps false
resetprop -n -p persist.sys.pixelprops.pi false persistprop persist.sys.pixelprops.google false
persistprop persist.sys.pixelprops.pi false
fi fi

View File

@@ -3,11 +3,14 @@ if [ -f /data/adb/modules/playintegrityfix/scripts-only-mode ]; then
ui_print "! Installing global scripts only; Zygisk attestation fallback and device spoofing disabled" ui_print "! Installing global scripts only; Zygisk attestation fallback and device spoofing disabled"
touch $MODPATH/scripts-only-mode touch $MODPATH/scripts-only-mode
sed -i 's/\(description=\)\(.*\)/\1[Scripts-only mode] \2/' $MODPATH/module.prop sed -i 's/\(description=\)\(.*\)/\1[Scripts-only mode] \2/' $MODPATH/module.prop
[ -f /data/adb/modules/playintegrityfix/uninstall.sh ] && sh /data/adb/modules/playintegrityfix/uninstall.sh
rm -rf $MODPATH/action.sh $MODPATH/autopif2.sh $MODPATH/classes.dex $MODPATH/common_setup.sh \ rm -rf $MODPATH/action.sh $MODPATH/autopif2.sh $MODPATH/classes.dex $MODPATH/common_setup.sh \
$MODPATH/custom.pif.json $MODPATH/example.app_replace.list $MODPATH/example.pif.json \ $MODPATH/custom.pif.json $MODPATH/example.app_replace.list $MODPATH/example.pif.json \
$MODPATH/migrate.sh $MODPATH/pif.json $MODPATH/zygisk \ $MODPATH/migrate.sh $MODPATH/pif.json $MODPATH/zygisk \
/data/adb/modules/playintegrityfix/custom.app_replace.list \ /data/adb/modules/playintegrityfix/custom.app_replace.list \
/data/adb/modules/playintegrityfix/custom.pif.json /data/adb/modules/playintegrityfix/system /data/adb/modules/playintegrityfix/custom.pif.json \
/data/adb/modules/playintegrityfix/system \
/data/adb/modules/playintegrityfix/uninstall.sh
fi fi
# Copy any disabled app files to updated module # Copy any disabled app files to updated module
@@ -17,7 +20,7 @@ if [ -d /data/adb/modules/playintegrityfix/system ]; then
fi fi
# Copy any supported custom files to updated module # Copy any supported custom files to updated module
for FILE in custom.app_replace.list custom.pif.json skipdelprop; do for FILE in custom.app_replace.list custom.pif.json skipdelprop uninstall.sh; do
if [ -f "/data/adb/modules/playintegrityfix/$FILE" ]; then if [ -f "/data/adb/modules/playintegrityfix/$FILE" ]; then
ui_print "- Restoring $FILE" ui_print "- Restoring $FILE"
cp -af /data/adb/modules/playintegrityfix/$FILE $MODPATH/$FILE cp -af /data/adb/modules/playintegrityfix/$FILE $MODPATH/$FILE
@@ -30,15 +33,20 @@ if [ -d /data/adb/modules/MagiskHidePropsConf ]; then
fi fi
# Run common tasks for installation and boot-time # Run common tasks for installation and boot-time
[ -d "$MODPATH/zygisk" ] && . $MODPATH/common_setup.sh if [ -d "$MODPATH/zygisk" ]; then
. $MODPATH/common_func.sh
. $MODPATH/common_setup.sh
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; 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 $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

@@ -24,5 +24,14 @@
// System Properties // System Properties
"*.build.id": "", // for ro.build.id "*.build.id": "", // for ro.build.id
"*.security_patch": "", // for ro.build.version.security_patch "*.security_patch": "", // for ro.build.version.security_patch
"*api_level": "" // for ro.board.api_level, ro.board.first_api_level, ro.product.first_api_level and ro.vendor.api_level "*api_level": "", // for ro.board.api_level, ro.board.first_api_level, ro.product.first_api_level and ro.vendor.api_level
// Advanced Settings
"spoofBuild": "1",
"spoofProps": "1",
"spoofProvider": "1",
"spoofSignature": "0",
"spoofVendingFinger": "0",
"spoofVendingSdk": "0",
"verboseLogs": "0"
} }

View File

@@ -114,12 +114,14 @@ 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 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;
verboseLogs=0; verboseLogs=0;
if [ -f "$OUT" ]; then if [ -f "$OUT" ]; then
@@ -136,6 +138,7 @@ if [ -f "$OUT" ]; then
fi; fi;
[ "$INSTALL" ] || item "Writing fields and properties to updated custom.pif.json ..."; [ "$INSTALL" ] || item "Writing fields and properties to updated custom.pif.json ...";
[ "$ADVANCED" ] && item "Adding Advanced Settings entries ...";
(echo "{"; (echo "{";
echo " // Build Fields"; echo " // Build Fields";

View File

@@ -1,7 +1,7 @@
id=playintegrityfix id=playintegrityfix
name=Play Integrity Fork name=Play Integrity Fork
version=v13 version=v14
versionCode=130000 versionCode=140001
author=osm0sis & chiteroman @ xda-developers author=osm0sis & chiteroman @ xda-developers
description=Fix <A13 DEVICE (Play Integrity) 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

View File

@@ -1,6 +1,6 @@
{ {
"version": "v13", "version": "v14",
"versionCode": 130000, "versionCode": 140000,
"zipUrl": "https://github.com/osm0sis/PlayIntegrityFork/releases/download/v13/PlayIntegrityFork-v13.zip", "zipUrl": "https://github.com/osm0sis/PlayIntegrityFork/releases/download/v14/PlayIntegrityFork-v14.zip",
"changelog": "https://raw.githubusercontent.com/osm0sis/PlayIntegrityFork/main/CHANGELOG.md" "changelog": "https://raw.githubusercontent.com/osm0sis/PlayIntegrityFork/main/CHANGELOG.md"
} }