You've already forked PlayIntegrityFork
mirror of
https://github.com/osm0sis/PlayIntegrityFork.git
synced 2025-09-06 06:37:06 +00:00
Compare commits
84 Commits
v12
...
1afd4278be
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1afd4278be | ||
|
|
77d5ccdc99 | ||
|
|
a2f726b633 | ||
|
|
38631f685a | ||
|
|
39d2610579 | ||
|
|
0132ebb272 | ||
|
|
a82914221e | ||
|
|
4755f88180 | ||
|
|
62150ce6d4 | ||
|
|
88573ca743 | ||
|
|
89de098a83 | ||
|
|
c6739dfa42 | ||
|
|
a7dd416873 | ||
|
|
539ff7351a | ||
|
|
0cd56584df | ||
|
|
2cdee60781 | ||
|
|
7e376e5627 | ||
|
|
ec34417cd9 | ||
|
|
0b957b13b9 | ||
|
|
ec374a7d9b | ||
|
|
17db1e7177 | ||
|
|
451769c341 | ||
|
|
77f91e3a85 | ||
|
|
b4eae8a6b6 | ||
|
|
05520f7881 | ||
|
|
1745060524 | ||
|
|
512ed8a1f1 | ||
|
|
0d8d090014 | ||
|
|
0d03f99499 | ||
|
|
85dd219ea3 | ||
|
|
36cc9573ba | ||
|
|
d72fc9ee04 | ||
|
|
84adafc3ac | ||
|
|
cb49481c45 | ||
|
|
b5a9b26b70 | ||
|
|
39922653db | ||
|
|
58f2c2de57 | ||
|
|
e858134828 | ||
|
|
fafaf418e4 | ||
|
|
da758bc33c | ||
|
|
d66260c3f6 | ||
|
|
1a01e35862 | ||
|
|
028e94e71b | ||
|
|
9e04c5cc5b | ||
|
|
46e5e0a6d2 | ||
|
|
d2db871892 | ||
|
|
7e7812bede | ||
|
|
c2af0fcad5 | ||
|
|
1493650b65 | ||
|
|
3f62cb6a3a | ||
|
|
5daf1b933e | ||
|
|
e8375a02d1 | ||
|
|
fa937983e8 | ||
|
|
83b9d96ce4 | ||
|
|
4bcf51ccfd | ||
|
|
e653659895 | ||
|
|
11e2629a26 | ||
|
|
8805c3736d | ||
|
|
a52cc16b43 | ||
|
|
4740d2048d | ||
|
|
e2b8a3c4b0 | ||
|
|
4dbe12ae58 | ||
|
|
996981a8e7 | ||
|
|
d278b77ced | ||
|
|
a3f68d392e | ||
|
|
9b3801a117 | ||
|
|
df5d5b7ce9 | ||
|
|
b644573e52 | ||
|
|
3e30d553c9 | ||
|
|
8a64752923 | ||
|
|
264a218a79 | ||
|
|
59781b1682 | ||
|
|
a4c8aab031 | ||
|
|
abe69d201b | ||
|
|
da0fad725a | ||
|
|
d9794b2017 | ||
|
|
d08ca33633 | ||
|
|
a7ba40a36c | ||
|
|
140c32befd | ||
|
|
6fc3200df2 | ||
|
|
c3ee7e5c0a | ||
|
|
c635a9e3ba | ||
|
|
8ddab06840 | ||
|
|
16002e28c6 |
5
.github/workflows/android.yml
vendored
5
.github/workflows/android.yml
vendored
@@ -1,6 +1,7 @@
|
||||
name: Android CI
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches: main
|
||||
paths-ignore: '**.md'
|
||||
@@ -11,7 +12,7 @@ on:
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: macos-14
|
||||
runs-on: macos-15
|
||||
|
||||
steps:
|
||||
- name: Check out
|
||||
@@ -30,7 +31,7 @@ jobs:
|
||||
run: chmod +x gradlew
|
||||
|
||||
- name: Build with Gradle
|
||||
run: ./gradlew assembleRelease
|
||||
run: ./gradlew --warning-mode all assembleRelease
|
||||
|
||||
- name: Upload CI module zip as artifact zip
|
||||
uses: actions/upload-artifact@v4
|
||||
|
||||
2
.gitmodules
vendored
2
.gitmodules
vendored
@@ -1,6 +1,6 @@
|
||||
[submodule "Dobby"]
|
||||
path = app/src/main/cpp/Dobby
|
||||
url = https://github.com/jmpews/Dobby
|
||||
url = https://github.com/JingMatrix/Dobby
|
||||
[submodule "json"]
|
||||
path = app/src/main/cpp/json
|
||||
url = https://github.com/nlohmann/json
|
||||
|
||||
36
CHANGELOG.md
36
CHANGELOG.md
@@ -1,19 +1,23 @@
|
||||
## Custom Fork v12
|
||||
- Add support to autopif2 for generating from Pixel Beta point releases
|
||||
- Improve autopif2 by catching more unsupported/broken environments
|
||||
- Improve migrate parsing lines with comments
|
||||
- Update default/example app replace list for helluvaOS
|
||||
- Fix retaining disabled non-system ROM apps on KSU/APatch
|
||||
- Add autopif2 --strong arg for initial setup with Tricky Store
|
||||
- Add skipping resetprop --delete to avoid app detections if skipdelprop file exists
|
||||
## Custom Fork v13
|
||||
|
||||
## Custom Fork v11
|
||||
- Improve autopif busybox tests, default api_level 32, pass --advanced arg
|
||||
- Improve scripts for special configs with Tricky Store
|
||||
- Fix resetprop fallback Magisk check
|
||||
- Add Action button support to run autopif in root managers
|
||||
- Fix root check for Termux/KSU/APatch
|
||||
- Improve PixelPropsUtils workaround on more setups
|
||||
- Replace autopif with autopif2 to generate a random print from latest Pixel Beta
|
||||
- Improve Action on KSU/APatch, KSU-Next, MMRL
|
||||
- Improve autopif2 to ignore Preview builds by default
|
||||
- Remove unnecessary adb props spoof
|
||||
- Add all known opt-out props for PPU/PIH variants/hybrids
|
||||
- Add new verified boot error props deletion
|
||||
- Update killgms to killpi by adding vending
|
||||
- Improve autopif2 to populate TS's optional security_patch.txt
|
||||
- Improve ROM overlay xml disabling support
|
||||
- Improve autopif2 for wget2 on arm
|
||||
- Improve Action to use Platform Preview builds
|
||||
|
||||
## Custom Fork v12
|
||||
- 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)_
|
||||
|
||||
61
README.md
61
README.md
@@ -6,27 +6,26 @@
|
||||
[](https://github.com/osm0sis/PlayIntegrityFork/releases/latest)
|
||||
[](https://github.com/osm0sis/PlayIntegrityFork/releases)
|
||||
|
||||
A Zygisk module which fixes "ctsProfileMatch" (SafetyNet) and "MEETS_DEVICE_INTEGRITY" (Play Integrity).
|
||||
A Zygisk module which fixes "MEETS_DEVICE_INTEGRITY" for Android <13 "deviceRecognitionVerdict" with the Play Integrity API.
|
||||
|
||||
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/releases) 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 Next](https://github.com/KernelSU-Next/KernelSU-Next) 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) module installed
|
||||
|
||||
## 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 (SafetyNet/Play Integrity) service.
|
||||
|
||||
The purpose of the module is to avoid hardware attestation.
|
||||
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
|
||||
|
||||
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).
|
||||
|
||||
Note this is just a template with the current suggested defaults, 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.
|
||||
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.
|
||||
|
||||
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 autopif section below for usage and caveats, and see the Resources below for information and scripts to help find a working private fingerprint.
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
@@ -50,34 +49,40 @@ A migration may also be performed manually with `sh migrate.sh` and custom.pif.j
|
||||
- [pif-test-json-file.sh](https://xdaforums.com/t/module-play-integrity-fix-safetynet-fix.4607985/post-89561228) - Script to automate generating and testing json files to attempt to find working fingerprints
|
||||
- [install-random-fp.sh](https://xdaforums.com/t/script-for-randomly-installing-custom-device-fingerprints.4647408/) - Script to randomly switch between multiple working fingerprints found by the user
|
||||
|
||||
- Apps:
|
||||
- [FP BETA Checker](https://xdaforums.com/t/tricky-store-bootloader-keybox-spoofing.4683446/post-89754890) - Tasker App to check the estimated expiry of the Pixel Beta fingerprint and trigger autopif2.sh to update
|
||||
- [FP XEU Checker](https://xdaforums.com/t/module-play-integrity-fix-safetynet-fix.4607985/post-89390931) - Tasker App to check for a new Xiaomi.eu public fingerprint and trigger autopif.sh to update
|
||||
|
||||
</details>
|
||||
|
||||
## 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.
|
||||
|
||||
## About 'autopif2.sh' and 'killgms.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 then simply run the generation script from a root manager app that supports the module Action button, a root prompt with `sh autopif2.sh` in the module directory (/data/adb/modules/playintegrityfix), or from a file explorer app that supports script execution.
|
||||
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).
|
||||
|
||||
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 and SafetyNet in that time.
|
||||
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 killgms script forces the Google Play Services DroidGuard process (com.google.android.gms.unstable) to end, making it 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.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
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 Android <13 deviceRecognitionVerdict Play Integrity API, not the Android 13+ deviceRecognitionVerdict (which relies on locked bootloader checks to pass even DEVICE verdict).
|
||||
|
||||
### Failing BASIC verdict
|
||||
|
||||
If you are failing basicIntegrity (SafetyNet) or 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
|
||||
- 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).
|
||||
|
||||
### Failing DEVICE verdict (on KernelSU/APatch)
|
||||
### Failing DEVICE verdict (on KernelSU/KernelSU Next/APatch)
|
||||
|
||||
- Disable Zygisk Next
|
||||
- Reboot
|
||||
@@ -126,23 +131,21 @@ The advanced spoofing options add granular control over what exactly gets spoofe
|
||||
<details>
|
||||
<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` or `sh autopif2.sh -a` command or configured directly for Tricky Store to achieve STRONG integrity (see below) with the `sh autopif2.sh --strong` or `sh autopif2.sh -s` command. Other than for the "verboseLogs" entry (see above), they are all 0 (disabled) or 1 (enabled).
|
||||
- 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 "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 verdicts.
|
||||
|
||||
- For spoofing locked bootloader and attempting to pass Play Integrity 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. 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 STRONG integrity (with an unrevoked hardware keybox.xml) requires the Advanced Settings "spoofProvider" disabled and either "spoofProps" disabled or the "*.security_patch" entry commented out, but to achieve DEVICE integrity (with Tricky Store default AOSP software keybox.xml or a revoked keybox.xml) requires at least "spoofProps" enabled, and some fingerprints may also require "spoofProvider". More known working private fingerprints can achieve 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 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.
|
||||
|
||||
- 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 <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 <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.
|
||||
|
||||
</details>
|
||||
|
||||
## About Skipping Property Deletion
|
||||
|
||||
An advanced feature (unrelated to Play Integrity) intended for those who also need to use apps which detect prop tampering. To avoid triggering these detections by skipping any `resetprop --delete` commands in the module scripts, manually opt-in by creating a file named skipdelprop in the module directory, either from a root prompt with `touch /data/adb/modules/playintegrityfix/skipdelprop` or from a file explorer app, after the module is already installed, then reboot.
|
||||
|
||||
## 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 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 Play Integrity <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.
|
||||
|
||||
<details>
|
||||
<summary><strong>Details</strong></summary>
|
||||
@@ -155,12 +158,20 @@ An advanced feature intended for older Android <10 ROMs, mostly stock ROMs or th
|
||||
|
||||
</details>
|
||||
|
||||
## About Play Integrity (SafetyNet is deprecated)
|
||||
## About skipping property deletion
|
||||
|
||||
An advanced feature (unrelated to Play Integrity) intended for those who also need to use apps which detect prop tampering. To avoid triggering these detections by skipping any `resetprop --delete` commands in the module scripts, manually opt-in by creating a file named skipdelprop in the module directory after installation, either from a root prompt with `touch /data/adb/modules/playintegrityfix/skipdelprop` or from a file explorer app, then reboot.
|
||||
|
||||
## About Play Integrity (SafetyNet has been shut down)
|
||||
|
||||
[Play Integrity API](https://xdaforums.com/t/info-play-integrity-api-replacement-for-safetynet.4479337/) - FAQ/information about PI (Play Integrity) replacing SN (SafetyNet)
|
||||
|
||||
[Play Integrity Improved Verdicts](https://developer.android.com/google/play/integrity/improvements) - Information about the more secure verdicts for Android 13+ ROMs (also see the spoofing Advanced Settings section above)
|
||||
|
||||
## 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 Universal SafetyNet Fix (USNF) MOD module, please see the commit history of [Displax's USNF MOD Fork](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 scripts 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.
|
||||
|
||||
@@ -4,9 +4,9 @@ plugins {
|
||||
|
||||
android {
|
||||
namespace = "es.chiteroman.playintegrityfix"
|
||||
compileSdk = 34
|
||||
ndkVersion = "27.2.12479018"
|
||||
buildToolsVersion = "34.0.0"
|
||||
compileSdk = 36
|
||||
ndkVersion = "28.1.13356709"
|
||||
buildToolsVersion = "36.0.0"
|
||||
|
||||
buildFeatures {
|
||||
prefab = true
|
||||
@@ -22,7 +22,7 @@ android {
|
||||
defaultConfig {
|
||||
applicationId = "es.chiteroman.playintegrityfix"
|
||||
minSdk = 26
|
||||
targetSdk = 34
|
||||
targetSdk = 36
|
||||
versionCode = 1
|
||||
versionName = "1.0"
|
||||
|
||||
@@ -62,16 +62,16 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation("org.lsposed.libcxx:libcxx:27.0.12077973")
|
||||
implementation("org.lsposed.hiddenapibypass:hiddenapibypass:4.3")
|
||||
implementation("org.lsposed.libcxx:libcxx:28.1.13356709")
|
||||
implementation("org.lsposed.hiddenapibypass:hiddenapibypass:6.1")
|
||||
}
|
||||
|
||||
tasks.register("copyFiles") {
|
||||
doLast {
|
||||
val moduleFolder = project.rootDir.resolve("module")
|
||||
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 moduleFolder = project.rootDir.resolve("module")
|
||||
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")
|
||||
|
||||
doLast {
|
||||
dexFile.copyTo(moduleFolder.resolve("classes.dex"), overwrite = true)
|
||||
|
||||
soDir.walk().filter { it.isFile && it.extension == "so" }.forEach { soFile ->
|
||||
|
||||
9
app/proguard-rules.pro
vendored
9
app/proguard-rules.pro
vendored
@@ -1,4 +1,5 @@
|
||||
-keep class es.chiteroman.playintegrityfix.EntryPoint {public <methods>;}
|
||||
-keep class es.chiteroman.playintegrityfix.CustomProvider
|
||||
-keep class es.chiteroman.playintegrityfix.CustomKeyStoreSpi
|
||||
-keep class es.chiteroman.playintegrityfix.CustomPackageInfoCreator
|
||||
-keep class es.chiteroman.playintegrityfix.EntryPoint { public <methods>; }
|
||||
-keep class es.chiteroman.playintegrityfix.EntryPointVending { public <methods>; }
|
||||
-keepclassmembers class es.chiteroman.playintegrityfix.CustomKeyStoreSpi
|
||||
-keepclassmembers class es.chiteroman.playintegrityfix.CustomPackageInfoCreator { public <init>(...); }
|
||||
-keepclassmembers class es.chiteroman.playintegrityfix.CustomProvider
|
||||
|
||||
Submodule app/src/main/cpp/Dobby updated: b0176de574...05a09ac680
Submodule app/src/main/cpp/json updated: 9cca280a4d...55f93686c0
@@ -12,12 +12,15 @@
|
||||
|
||||
#define JSON_FILE_PATH "/data/adb/modules/playintegrityfix/pif.json"
|
||||
#define CUSTOM_JSON_FILE_PATH "/data/adb/modules/playintegrityfix/custom.pif.json"
|
||||
#define VENDING_PACKAGE "com.android.vending"
|
||||
#define DROIDGUARD_PACKAGE "com.google.android.gms.unstable"
|
||||
|
||||
static int verboseLogs = 0;
|
||||
static int spoofBuild = 1;
|
||||
static int spoofProps = 1;
|
||||
static int spoofProvider = 1;
|
||||
static int spoofSignature = 0;
|
||||
static int spoofVendingSdk = 0;
|
||||
|
||||
static std::map<std::string, std::string> jsonProps;
|
||||
|
||||
@@ -32,13 +35,6 @@ static void modify_callback(void *cookie, const char *name, const char *value, u
|
||||
|
||||
std::string prop(name);
|
||||
|
||||
// Spoof specific property values
|
||||
if (prop == "init.svc.adbd") {
|
||||
value = "stopped";
|
||||
} else if (prop == "sys.usb.state") {
|
||||
value = "mtp";
|
||||
}
|
||||
|
||||
if (jsonProps.count(prop)) {
|
||||
// Exact property match
|
||||
value = jsonProps[prop].c_str();
|
||||
@@ -90,7 +86,7 @@ public:
|
||||
}
|
||||
|
||||
void preAppSpecialize(zygisk::AppSpecializeArgs *args) override {
|
||||
bool isGms = false, isGmsUnstable = false;
|
||||
bool isGms = false, isDroidGuardOrVending = false;
|
||||
|
||||
auto rawProcess = env->GetStringUTFChars(args->nice_name, nullptr);
|
||||
auto rawDir = env->GetStringUTFChars(args->app_data_dir, nullptr);
|
||||
@@ -102,11 +98,11 @@ public:
|
||||
return;
|
||||
}
|
||||
|
||||
std::string_view process(rawProcess);
|
||||
pkgName = rawProcess;
|
||||
std::string_view dir(rawDir);
|
||||
|
||||
isGms = dir.ends_with("/com.google.android.gms");
|
||||
isGmsUnstable = process == "com.google.android.gms.unstable";
|
||||
isGms = dir.ends_with("/com.google.android.gms") || dir.ends_with("/com.android.vending");
|
||||
isDroidGuardOrVending = pkgName == DROIDGUARD_PACKAGE || pkgName == VENDING_PACKAGE;
|
||||
|
||||
env->ReleaseStringUTFChars(args->nice_name, rawProcess);
|
||||
env->ReleaseStringUTFChars(args->app_data_dir, rawDir);
|
||||
@@ -119,7 +115,7 @@ public:
|
||||
// We are in GMS now, force unmount
|
||||
api->setOption(zygisk::FORCE_DENYLIST_UNMOUNT);
|
||||
|
||||
if (!isGmsUnstable) {
|
||||
if (!isDroidGuardOrVending) {
|
||||
api->setOption(zygisk::DLCLOSE_MODULE_LIBRARY);
|
||||
return;
|
||||
}
|
||||
@@ -168,8 +164,12 @@ public:
|
||||
if (dexVector.empty() || json.empty()) return;
|
||||
|
||||
readJson();
|
||||
|
||||
if (pkgName == VENDING_PACKAGE) spoofProps = spoofBuild = spoofProvider = spoofSignature = 0;
|
||||
else spoofVendingSdk = 0;
|
||||
|
||||
if (spoofProps > 0) doHook();
|
||||
inject();
|
||||
if (spoofBuild + spoofProvider + spoofSignature + spoofVendingSdk > 0) inject();
|
||||
|
||||
dexVector.clear();
|
||||
json.clear();
|
||||
@@ -184,6 +184,7 @@ private:
|
||||
JNIEnv *env = nullptr;
|
||||
std::vector<char> dexVector;
|
||||
nlohmann::json json;
|
||||
std::string pkgName;
|
||||
|
||||
void readJson() {
|
||||
LOGD("JSON contains %d keys!", static_cast<int>(json.size()));
|
||||
@@ -200,6 +201,19 @@ private:
|
||||
}
|
||||
|
||||
// Advanced spoofing settings
|
||||
if (json.contains("spoofVendingSdk")) {
|
||||
if (!json["spoofVendingSdk"].is_null() && json["spoofVendingSdk"].is_string() && json["spoofVendingSdk"] != "") {
|
||||
spoofVendingSdk = stoi(json["spoofVendingSdk"].get<std::string>());
|
||||
if (verboseLogs > 0) LOGD("Spoofing SDK Level in Play Store %s!", (spoofVendingSdk > 0) ? "enabled" : "disabled");
|
||||
} else {
|
||||
LOGD("Error parsing spoofVendingSdk!");
|
||||
}
|
||||
json.erase("spoofVendingSdk");
|
||||
}
|
||||
if (pkgName == VENDING_PACKAGE) {
|
||||
json.clear();
|
||||
return;
|
||||
}
|
||||
if (json.contains("spoofBuild")) {
|
||||
if (!json["spoofBuild"].is_null() && json["spoofBuild"].is_string() && json["spoofBuild"] != "") {
|
||||
spoofBuild = stoi(json["spoofBuild"].get<std::string>());
|
||||
@@ -262,32 +276,41 @@ private:
|
||||
}
|
||||
|
||||
void inject() {
|
||||
LOGD("JNI: Getting system classloader");
|
||||
const char* niceName = pkgName == VENDING_PACKAGE ? "PS" : "DG";
|
||||
|
||||
LOGD("JNI %s: Getting system classloader", niceName);
|
||||
auto clClass = env->FindClass("java/lang/ClassLoader");
|
||||
auto getSystemClassLoader = env->GetStaticMethodID(clClass, "getSystemClassLoader", "()Ljava/lang/ClassLoader;");
|
||||
auto systemClassLoader = env->CallStaticObjectMethod(clClass, getSystemClassLoader);
|
||||
|
||||
LOGD("JNI: Creating module classloader");
|
||||
LOGD("JNI %s: Creating module classloader", niceName);
|
||||
auto dexClClass = env->FindClass("dalvik/system/InMemoryDexClassLoader");
|
||||
auto dexClInit = env->GetMethodID(dexClClass, "<init>", "(Ljava/nio/ByteBuffer;Ljava/lang/ClassLoader;)V");
|
||||
auto buffer = env->NewDirectByteBuffer(dexVector.data(), static_cast<jlong>(dexVector.size()));
|
||||
auto dexCl = env->NewObject(dexClClass, dexClInit, buffer, systemClassLoader);
|
||||
|
||||
LOGD("JNI: Loading module class");
|
||||
LOGD("JNI %s: Loading module class", niceName);
|
||||
auto loadClass = env->GetMethodID(clClass, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;");
|
||||
auto entryClassName = env->NewStringUTF("es.chiteroman.playintegrityfix.EntryPoint");
|
||||
const char* className = pkgName == VENDING_PACKAGE ? "es.chiteroman.playintegrityfix.EntryPointVending" : "es.chiteroman.playintegrityfix.EntryPoint";
|
||||
auto entryClassName = env->NewStringUTF(className);
|
||||
auto entryClassObj = env->CallObjectMethod(dexCl, loadClass, entryClassName);
|
||||
|
||||
auto entryClass = (jclass) entryClassObj;
|
||||
|
||||
LOGD("JNI: Sending JSON");
|
||||
auto receiveJson = env->GetStaticMethodID(entryClass, "receiveJson", "(Ljava/lang/String;)V");
|
||||
auto javaStr = env->NewStringUTF(json.dump().c_str());
|
||||
env->CallStaticVoidMethod(entryClass, receiveJson, javaStr);
|
||||
if (pkgName == VENDING_PACKAGE) {
|
||||
LOGD("JNI %s: Calling EntryPointVending.init", niceName);
|
||||
auto entryInit = env->GetStaticMethodID(entryClass, "init", "(II)V");
|
||||
env->CallStaticVoidMethod(entryClass, entryInit, verboseLogs, spoofVendingSdk);
|
||||
} else {
|
||||
LOGD("JNI %s: Sending JSON", niceName);
|
||||
auto receiveJson = env->GetStaticMethodID(entryClass, "receiveJson", "(Ljava/lang/String;)V");
|
||||
auto javaStr = env->NewStringUTF(json.dump().c_str());
|
||||
env->CallStaticVoidMethod(entryClass, receiveJson, javaStr);
|
||||
|
||||
LOGD("JNI: Calling init");
|
||||
auto entryInit = env->GetStaticMethodID(entryClass, "init", "(IIII)V");
|
||||
env->CallStaticVoidMethod(entryClass, entryInit, verboseLogs, spoofBuild, spoofProvider, spoofSignature);
|
||||
LOGD("JNI %s: Calling EntryPoint.init", niceName);
|
||||
auto entryInit = env->GetStaticMethodID(entryClass, "init", "(IIII)V");
|
||||
env->CallStaticVoidMethod(entryClass, entryInit, verboseLogs, spoofBuild, spoofProvider, spoofSignature);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ public class CustomPackageInfoCreator implements Parcelable.Creator<PackageInfo>
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public PackageInfo createFromParcel(Parcel source) {
|
||||
PackageInfo packageInfo = originalCreator.createFromParcel(source);
|
||||
if (packageInfo.packageName.equals("android")) {
|
||||
|
||||
@@ -265,6 +265,6 @@ public final class EntryPoint {
|
||||
}
|
||||
|
||||
static void LOG(String msg) {
|
||||
Log.d("PIF/Java", msg);
|
||||
Log.d("PIF/Java:DG", msg);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
package es.chiteroman.playintegrityfix;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.os.Build;
|
||||
import java.lang.reflect.Field;
|
||||
import android.util.Log;
|
||||
|
||||
public final class EntryPointVending {
|
||||
|
||||
private static void LOG(String msg) {
|
||||
Log.d("PIF/Java:PS", msg);
|
||||
}
|
||||
|
||||
@SuppressLint("DefaultLocale")
|
||||
public static void init(int verboseLogs, int spoofVendingSdk) {
|
||||
if (spoofVendingSdk < 1) return;
|
||||
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);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,3 @@
|
||||
plugins {
|
||||
id("com.android.application") version "8.7.2" apply false
|
||||
id("com.android.application") version "8.10.1" apply false
|
||||
}
|
||||
|
||||
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,6 +1,6 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.2-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
||||
9
gradlew
vendored
9
gradlew
vendored
@@ -86,8 +86,7 @@ done
|
||||
# shellcheck disable=SC2034
|
||||
APP_BASE_NAME=${0##*/}
|
||||
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
||||
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
|
||||
' "$PWD" ) || exit
|
||||
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD=maximum
|
||||
@@ -115,7 +114,7 @@ case "$( uname )" in #(
|
||||
NONSTOP* ) nonstop=true ;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
CLASSPATH="\\\"\\\""
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
@@ -206,7 +205,7 @@ fi
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Collect all arguments for the java command:
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
|
||||
# and any embedded shellness will be escaped.
|
||||
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
|
||||
# treated as '${Hostname}' itself on the command line.
|
||||
@@ -214,7 +213,7 @@ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
-classpath "$CLASSPATH" \
|
||||
org.gradle.wrapper.GradleWrapperMain \
|
||||
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
|
||||
"$@"
|
||||
|
||||
# Stop when "xargs" is not available.
|
||||
|
||||
4
gradlew.bat
vendored
4
gradlew.bat
vendored
@@ -70,11 +70,11 @@ goto fail
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
set CLASSPATH=
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
|
||||
@@ -4,12 +4,12 @@ MODPATH="${0%/*}"
|
||||
set +o standalone
|
||||
unset ASH_STANDALONE
|
||||
|
||||
sh $MODPATH/autopif2.sh || exit 1
|
||||
sh $MODPATH/autopif2.sh -a -m -p || exit 1
|
||||
|
||||
echo -e "\nDone!"
|
||||
|
||||
# warn since Magisk/KernelSU's implementation automatically closes if successful
|
||||
if [ "$APATCH" != "true" ]; then
|
||||
# warn since KernelSU/APatch's implementation automatically closes if successful
|
||||
if [ "$KSU" = "true" -o "$APATCH" = "true" ] && [ "$KSU_NEXT" != "true" ] && [ "$MMRL" != "true" ]; then
|
||||
echo -e "\nClosing dialog in 20 seconds ..."
|
||||
sleep 20
|
||||
fi
|
||||
|
||||
@@ -7,11 +7,18 @@ case "$HOME" in
|
||||
*termux*) echo "autopif2: need su root environment"; exit 1;;
|
||||
esac;
|
||||
|
||||
case "$1" in
|
||||
-h|--help|help) echo "sh autopif2.sh [-a|-s]"; exit 0;;
|
||||
-a|--advanced|advanced) ARGS="-a"; shift;;
|
||||
-s|--strong|strong) ARGS="-a"; PATCH_COMMENT=1; spoofProvider=0; shift;;
|
||||
esac;
|
||||
FORCE_DEPTH=1;
|
||||
until [ -z "$1" ]; do
|
||||
case "$1" in
|
||||
-h|--help|help) echo "sh autopif2.sh [-a|-s] [-m] [-p] [-d #]"; exit 0;;
|
||||
-a|--advanced|advanced) ARGS="-a"; shift;;
|
||||
-s|--strong|strong) ARGS="-a"; PATCH_COMMENT=1; spoofProvider=0; shift;;
|
||||
-m|--match|match) FORCE_MATCH=1; shift;;
|
||||
-p|--preview|preview) FORCE_PREVIEW=1; shift;;
|
||||
-d|--depth|depth) echo "$2" | grep -q '^[1-9]$' || exit 1; FORCE_DEPTH=$2; shift 2;;
|
||||
*) break;;
|
||||
esac;
|
||||
done;
|
||||
|
||||
echo "Pixel Beta pif.json generator script \
|
||||
\n by osm0sis @ xda-developers";
|
||||
@@ -37,7 +44,9 @@ find_busybox() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ! which wget >/dev/null || grep -q "wget-curl" $(which wget); then
|
||||
if which wget2 >/dev/null; then
|
||||
wget() { wget2 "$@"; }
|
||||
elif ! which wget >/dev/null || grep -q "wget-curl" $(which wget); then
|
||||
if ! find_busybox; then
|
||||
die "wget not found";
|
||||
elif $BUSYBOX ping -c1 -s2 android.com 2>&1 | grep -q "bad address"; then
|
||||
@@ -71,9 +80,15 @@ cd "$DIR";
|
||||
|
||||
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_LATEST_HTML --no-check-certificate $(grep -m1 'developer.android.com/about/versions/' PIXEL_VERSIONS_HTML | cut -d\" -f2) 2>&1 || exit 1;
|
||||
wget -q -O PIXEL_OTA_HTML --no-check-certificate https://developer.android.com$(grep -om1 'href=".*download-ota"' PIXEL_LATEST_HTML | cut -d\" -f2) 2>&1 || exit 1;
|
||||
grep -m1 -o 'data-category.*Beta' PIXEL_OTA_HTML | cut -d\" -f2;
|
||||
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;
|
||||
if grep -qE 'Developer Preview|tooltip>.*preview program' PIXEL_LATEST_HTML && [ ! "$FORCE_PREVIEW" ]; then
|
||||
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;
|
||||
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_EXP_DATE="$(date -D '%s' -d "$(($(date -D '%Y-%m-%d' -d "$BETA_REL_DATE" '+%s') + 60 * 60 * 24 * 7 * 6))" '+%Y-%m-%d')";
|
||||
@@ -84,18 +99,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)";
|
||||
OTA_LIST="$(grep 'ota/.*_beta' PIXEL_OTA_HTML | cut -d\" -f2)";
|
||||
|
||||
case "$1" in
|
||||
-m)
|
||||
DEVICE="$(getprop ro.product.device)";
|
||||
case "$PRODUCT_LIST" in
|
||||
*${DEVICE}_beta*)
|
||||
MODEL="$(getprop ro.product.model)";
|
||||
PRODUCT="${DEVICE}_beta";
|
||||
OTA="$(echo "$OTA_LIST" | grep "$PRODUCT")";
|
||||
;;
|
||||
esac;
|
||||
;;
|
||||
esac;
|
||||
if [ "$FORCE_MATCH" ]; then
|
||||
DEVICE="$(getprop ro.product.device)";
|
||||
case "$PRODUCT_LIST" in
|
||||
*${DEVICE}_beta*)
|
||||
MODEL="$(getprop ro.product.model)";
|
||||
PRODUCT="${DEVICE}_beta";
|
||||
OTA="$(echo "$OTA_LIST" | grep "$PRODUCT")";
|
||||
;;
|
||||
esac;
|
||||
fi;
|
||||
item "Selecting Pixel Beta device ...";
|
||||
if [ -z "$PRODUCT" ]; then
|
||||
set_random_beta() {
|
||||
@@ -115,8 +128,8 @@ fi;
|
||||
echo "$MODEL ($PRODUCT)";
|
||||
|
||||
(ulimit -f 2; wget -q -O PIXEL_ZIP_METADATA --no-check-certificate $OTA) 2>/dev/null;
|
||||
FINGERPRINT="$(grep -am1 'post-build=' PIXEL_ZIP_METADATA | cut -d= -f2)";
|
||||
SECURITY_PATCH="$(grep -am1 'security-patch-level=' PIXEL_ZIP_METADATA | 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)";
|
||||
if [ -z "$FINGERPRINT" -o -z "$SECURITY_PATCH" ]; then
|
||||
echo "\nError: Failed to extract information from metadata!";
|
||||
exit 1;
|
||||
@@ -144,13 +157,14 @@ if [ -f "$MIGRATE" ]; then
|
||||
grep -q '//"\*.security_patch"' $OLDJSON && PATCH_COMMENT=1;
|
||||
grep -qE "verboseLogs|VERBOSE_LOGS" $OLDJSON && ARGS="-a";
|
||||
fi;
|
||||
[ -f /data/adb/tricky_store/security_patch.txt ] && unset PATCH_COMMENT;
|
||||
item "Converting pif.json to custom.pif.json with migrate.sh:";
|
||||
rm -f custom.pif.json;
|
||||
sh $MIGRATE -i $ARGS pif.json;
|
||||
if [ -n "$ARGS" ]; then
|
||||
grep_json() { [ -f "$2" ] && grep -m1 "$1" $2 | cut -d\" -f4; }
|
||||
verboseLogs=$(grep_json "VERBOSE_LOGS" $OLDJSON);
|
||||
ADVSETTINGS="spoofBuild spoofProps spoofProvider spoofSignature verboseLogs";
|
||||
ADVSETTINGS="spoofBuild spoofProps spoofProvider spoofSignature spoofVendingSdk verboseLogs";
|
||||
for SETTING in $ADVSETTINGS; do
|
||||
eval [ -z \"\$$SETTING\" ] \&\& $SETTING=$(grep_json "$SETTING" $OLDJSON);
|
||||
eval TMPVAL=\$$SETTING;
|
||||
@@ -174,8 +188,16 @@ if [ "$DIR" = /data/adb/modules/playintegrityfix/autopif2 ]; then
|
||||
fi;
|
||||
item "Installing new json ...";
|
||||
cp -fv $NEWNAME ..;
|
||||
if [ -f /data/adb/modules/playintegrityfix/killgms.sh ]; then
|
||||
item "Killing any running GMS DroidGuard process ...";
|
||||
sh /data/adb/modules/playintegrityfix/killgms.sh 2>&1 || true;
|
||||
TS_SECPAT=/data/adb/tricky_store/security_patch.txt;
|
||||
if [ -f "$TS_SECPAT" ]; then
|
||||
item "Updating Tricky Store security_patch.txt ...";
|
||||
[ -s "$TS_SECPAT" ] || echo "all=" > $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;
|
||||
cat $TS_SECPAT;
|
||||
fi;
|
||||
if [ -f /data/adb/modules/playintegrityfix/killpi.sh ]; then
|
||||
item "Killing any running GMS DroidGuard/Play Store processes ...";
|
||||
sh /data/adb/modules/playintegrityfix/killpi.sh 2>&1 || true;
|
||||
fi;
|
||||
fi;
|
||||
|
||||
@@ -1,6 +1,29 @@
|
||||
SKIPDELPROP=false
|
||||
[ -f "$MODPATH/skipdelprop" ] && SKIPDELPROP=true
|
||||
|
||||
# delprop_if_exist <prop name>
|
||||
delprop_if_exist() {
|
||||
local NAME="$1"
|
||||
|
||||
[ -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"
|
||||
[ -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
|
||||
|
||||
@@ -24,7 +47,7 @@ resetprop_hexpatch() {
|
||||
local PROPFILE="/dev/__properties__/$(resetprop -Z "$NAME")"
|
||||
fi
|
||||
[ ! -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>
|
||||
local NEWHEX="$(printf '%02x' "$NEWLEN")$(printf "$NEWVALUE" | od -A n -t x1 -v | tr -d ' \n')$(printf "%$((92-NEWLEN))s" | sed 's/ /00/g')"
|
||||
|
||||
@@ -39,7 +39,7 @@ for APP in $(grep -v '^#' $LIST); do
|
||||
APK=$(readlink -f $APP);
|
||||
fi
|
||||
if [ -s "$APK" ]; then
|
||||
PKGNAME=$(unzip -p $APK AndroidManifest.xml | tr -d '\0' | grep -oE '[[:alnum:].-_]+\*http' | cut -d\* -f1)
|
||||
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
|
||||
HIDECFG=$MODPATH$PREFIX$CFG
|
||||
if [ ! -f "$HIDECFG" ]; then
|
||||
@@ -59,16 +59,21 @@ for APP in $(grep -v '^#' $LIST); do
|
||||
fi
|
||||
done
|
||||
|
||||
# Work around AOSPA PropImitationHooks conflict when their persist props don't exist
|
||||
if [ -n "$(resetprop ro.aospa.version)" ]; then
|
||||
# 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)" -o -f /data/system/gms_certified_props.json ]; then
|
||||
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
|
||||
fi
|
||||
|
||||
# Work around supported custom ROM PixelPropsUtils conflict when spoofProvider is disabled
|
||||
if [ -n "$(resetprop persist.sys.pixelprops.pi)" ]; then
|
||||
resetprop -n -p persist.sys.pixelprops.pi false
|
||||
resetprop -n -p persist.sys.pixelprops.gapps false
|
||||
resetprop -n -p persist.sys.pixelprops.gms false
|
||||
# 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.spoof|persist.sys.pixelprops" || [ -f /data/system/gms_certified_props.json ]; then
|
||||
persistprop persist.sys.pihooks.disable.gms_props true
|
||||
persistprop persist.sys.pihooks.disable.gms_key_attestation_block true
|
||||
persistprop persist.sys.entryhooks_enabled false
|
||||
persistprop persist.sys.spoof.gms false
|
||||
persistprop persist.sys.pixelprops.gms false
|
||||
persistprop persist.sys.pixelprops.gapps false
|
||||
persistprop persist.sys.pixelprops.google false
|
||||
persistprop persist.sys.pixelprops.pi false
|
||||
fi
|
||||
|
||||
@@ -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"
|
||||
touch $MODPATH/scripts-only-mode
|
||||
sed -i 's/\(description=\)\(.*\)/\1[Scripts-only mode] \2/' $MODPATH/module.prop
|
||||
rm -rf $MODPATH/autopif2.sh $MODPATH/classes.dex $MODPATH/common_setup.sh \
|
||||
[ -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 \
|
||||
$MODPATH/custom.pif.json $MODPATH/example.app_replace.list $MODPATH/example.pif.json \
|
||||
$MODPATH/migrate.sh $MODPATH/pif.json $MODPATH/zygisk \
|
||||
/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
|
||||
|
||||
# Copy any disabled app files to updated module
|
||||
@@ -17,7 +20,7 @@ if [ -d /data/adb/modules/playintegrityfix/system ]; then
|
||||
fi
|
||||
|
||||
# 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
|
||||
ui_print "- Restoring $FILE"
|
||||
cp -af /data/adb/modules/playintegrityfix/$FILE $MODPATH/$FILE
|
||||
@@ -30,14 +33,17 @@ if [ -d /data/adb/modules/MagiskHidePropsConf ]; then
|
||||
fi
|
||||
|
||||
# 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
|
||||
if [ -f "$MODPATH/custom.pif.json" ] && ! grep -q "api_level" $MODPATH/custom.pif.json; then
|
||||
ui_print "- Running migration script on custom.pif.json:"
|
||||
ui_print " "
|
||||
chmod 755 $MODPATH/migrate.sh
|
||||
sh $MODPATH/migrate.sh install $MODPATH/custom.pif.json
|
||||
sh $MODPATH/migrate.sh --install --advanced $MODPATH/custom.pif.json
|
||||
ui_print " "
|
||||
fi
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
/system/app/EliteDevelopmentModule
|
||||
/system/app/XInjectModule
|
||||
|
||||
# helluvaOS / hentaiOS
|
||||
# helluvaOS, hentaiOS
|
||||
/system_ext/app/helluvaProductDevice*
|
||||
/system_ext/app/helluvaProductSecretStub
|
||||
/system_ext/app/hentaiLewdbSVTDummy
|
||||
@@ -19,5 +19,5 @@
|
||||
# Evolution X
|
||||
/system_ext/app/PifPrebuilt
|
||||
|
||||
# PixelOS
|
||||
# PixelOS, YAAP
|
||||
/system_ext/overlay/CertifiedPropsOverlay.apk
|
||||
|
||||
@@ -24,5 +24,13 @@
|
||||
// System Properties
|
||||
"*.build.id": "", // for ro.build.id
|
||||
"*.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",
|
||||
"spoofVendingSdk": "0",
|
||||
"verboseLogs": "0"
|
||||
}
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
#!/system/bin/sh
|
||||
# killgms.sh by osm0sis @ xda-developers
|
||||
#
|
||||
# Kill the Google Play services DroidGuard process
|
||||
# (com.google.android.gms.unstable)
|
||||
|
||||
if [ "$USER" != "root" -a "$(whoami 2>/dev/null)" != "root" ]; then
|
||||
echo "killgms: need root permissions";
|
||||
exit 1;
|
||||
fi;
|
||||
|
||||
killall -v com.google.android.gms.unstable;
|
||||
13
module/killpi.sh
Normal file
13
module/killpi.sh
Normal file
@@ -0,0 +1,13 @@
|
||||
#!/system/bin/sh
|
||||
# killpi.sh by osm0sis @ xda-developers
|
||||
#
|
||||
# Kill the Google Play services DroidGuard and Play Store processes
|
||||
# (com.google.android.gms.unstable and com.android.vending)
|
||||
|
||||
if [ "$USER" != "root" -a "$(whoami 2>/dev/null)" != "root" ]; then
|
||||
echo "killpi: need root permissions";
|
||||
exit 1;
|
||||
fi;
|
||||
|
||||
killall -v com.google.android.gms.unstable;
|
||||
killall -v com.android.vending;
|
||||
@@ -114,12 +114,13 @@ if [ -z "$DEVICE_INITIAL_SDK_INT" -o "$DEVICE_INITIAL_SDK_INT" = "null" ]; then
|
||||
DEVICE_INITIAL_SDK_INT=25;
|
||||
fi;
|
||||
|
||||
ADVSETTINGS="spoofBuild spoofProps spoofProvider spoofSignature verboseLogs";
|
||||
ADVSETTINGS="spoofBuild spoofProps spoofProvider spoofSignature spoofVendingSdk verboseLogs";
|
||||
|
||||
spoofBuild=1;
|
||||
spoofProps=1;
|
||||
spoofProvider=1;
|
||||
spoofSignature=0;
|
||||
spoofVendingSdk=0;
|
||||
verboseLogs=0;
|
||||
|
||||
if [ -f "$OUT" ]; then
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
id=playintegrityfix
|
||||
name=Play Integrity Fork
|
||||
version=v12
|
||||
versionCode=120000
|
||||
version=v13
|
||||
versionCode=130001
|
||||
author=osm0sis & chiteroman @ xda-developers
|
||||
description=Fix ctsProfile (SafetyNet) and DEVICE (Play Integrity) verdicts
|
||||
description=Fix <A13 DEVICE (Play Integrity) verdict
|
||||
updateJson=https://raw.githubusercontent.com/osm0sis/PlayIntegrityFork/main/update.json
|
||||
|
||||
@@ -2,15 +2,17 @@ MODPATH="${0%/*}"
|
||||
. $MODPATH/common_func.sh
|
||||
|
||||
if [ -d "$MODPATH/zygisk" ]; then
|
||||
# Remove Play Services from Magisk DenyList when set to Enforce in normal mode
|
||||
# Remove Play Services and Play Store from Magisk DenyList when set to Enforce in normal mode
|
||||
if magisk --denylist status; then
|
||||
magisk --denylist rm com.google.android.gms
|
||||
magisk --denylist rm com.android.vending
|
||||
fi
|
||||
# Run common tasks for installation and boot-time
|
||||
. $MODPATH/common_setup.sh
|
||||
else
|
||||
# Add Play Services DroidGuard process to Magisk DenyList for better results in scripts-only mode
|
||||
# Add Play Services DroidGuard and Play Store processes to Magisk DenyList for better results in scripts-only mode
|
||||
magisk --denylist add com.google.android.gms com.google.android.gms.unstable
|
||||
magisk --denylist add com.android.vending
|
||||
fi
|
||||
|
||||
# Conditional early sensitive properties
|
||||
@@ -37,6 +39,11 @@ for PROP in $(resetprop | grep -oE 'ro.*.build.type'); do
|
||||
resetprop_if_diff $PROP user
|
||||
done
|
||||
resetprop_if_diff ro.adb.secure 1
|
||||
if ! $SKIPDELPROP; then
|
||||
delprop_if_exist ro.boot.verifiedbooterror
|
||||
delprop_if_exist ro.boot.verifyerrorpart
|
||||
fi
|
||||
resetprop_if_diff ro.boot.veritymode.managed yes
|
||||
resetprop_if_diff ro.debuggable 0
|
||||
resetprop_if_diff ro.force.debuggable 0
|
||||
resetprop_if_diff ro.secure 1
|
||||
|
||||
@@ -11,8 +11,8 @@ resetprop_if_match vendor.boot.mode recovery unknown
|
||||
# SELinux
|
||||
resetprop_if_diff ro.boot.selinux enforcing
|
||||
# use delete since it can be 0 or 1 for enforcing depending on OEM
|
||||
if ! $SKIPDELPROP && [ -n "$(resetprop ro.build.selinux)" ]; then
|
||||
resetprop --delete ro.build.selinux
|
||||
if ! $SKIPDELPROP; then
|
||||
delprop_if_exist ro.build.selinux
|
||||
fi
|
||||
# use toybox to protect stat access time reading
|
||||
if [ "$(toybox cat /sys/fs/selinux/enforce)" = "0" ]; then
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"version": "v12",
|
||||
"versionCode": 120000,
|
||||
"zipUrl": "https://github.com/osm0sis/PlayIntegrityFork/releases/download/v12/PlayIntegrityFork-v12.zip",
|
||||
"version": "v13",
|
||||
"versionCode": 130000,
|
||||
"zipUrl": "https://github.com/osm0sis/PlayIntegrityFork/releases/download/v13/PlayIntegrityFork-v13.zip",
|
||||
"changelog": "https://raw.githubusercontent.com/osm0sis/PlayIntegrityFork/main/CHANGELOG.md"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user