329 Commits
v5 ... 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
osm0sis
39922653db README: fix KSU-Next link typo 2025-05-16 16:35:48 -03:00
osm0sis
58f2c2de57 Prepare v13 2025-05-16 16:29:06 -03:00
Chris Renshaw
e858134828 Update HiddenApiBypass 2025-05-16 13:49:22 -03:00
Chris Renshaw
fafaf418e4 Update NDK 2025-04-29 21:59:01 -03:00
osm0sis
da758bc33c Update Gradle 2025-04-29 21:56:56 -03:00
Chris Renshaw
d66260c3f6 Revert AGP to 8.8.x due to reported instability 2025-03-27 06:55:50 -03:00
Chris Renshaw
1a01e35862 Update AGP 2025-03-26 21:17:41 -03:00
Chris Renshaw
028e94e71b Organize common functions better (again) 2025-03-09 23:52:16 -03:00
Chris Renshaw
9e04c5cc5b Update AGP 2025-03-05 18:51:35 -04:00
Chris Renshaw
46e5e0a6d2 Force Platform builds via Action button 2025-03-03 07:02:37 -04:00
Chris Renshaw
d2db871892 Update AGP 2025-02-26 22:56:35 -04:00
osm0sis
7e7812bede Update Gradle 2025-02-25 16:14:33 -04:00
Chris Renshaw
c2af0fcad5 autopif2.sh: use wget2 over wget since arm busybox doesn't have LFS 2025-02-25 16:10:41 -04:00
osm0sis
1493650b65 autopif2.sh: promote --preview and --depth to documented features
-p or --preview forces not to ignore Android Platform Preview builds (Developer Previews and Betas)
-d # or --depth # chooses the depth to crawl down the QPR Betas list when there are multiple active Betas, e.g. when QPR2 was 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)
2025-02-21 23:19:07 -04:00
Chris Renshaw
3f62cb6a3a Update README.md 2025-02-15 06:53:11 -04:00
Chris Renshaw
5daf1b933e Update AGP 2025-02-14 18:03:29 -04:00
Chris Renshaw
e8375a02d1 Update NDK 2025-02-12 23:01:58 -04:00
Chris Renshaw
fa937983e8 Improve overlay AndroidManifest.xml parsing, support YAAP 2025-02-11 21:27:17 -04:00
Chris Renshaw
83b9d96ce4 autopif2.sh: always default to all= since TS system= date parsing seems different/bugged across some devices 2025-02-09 23:31:59 -04:00
Chris Renshaw
4bcf51ccfd autopif2.sh: use all instead of system if boot or vendor 11 months or more old 2025-02-08 20:01:37 -04:00
Chris Renshaw
e653659895 autopif2.sh: automatically update TrickyStore security_patch.txt system date
- opt in by creating /data/adb/tricky_store/security_patch.txt
- OS Patch Level (system= entry in TS 1.2.1+) must match *.security_patch spoofed to gms in order to pass Legacy PI Strong so automatically update with Beta print
- if boot= or vendor= entries are also needed in security_patch.txt to pass New PI Strong (due to an old/custom ROM) these must be manually added, or, all= may be used instead of system= and autopif2 will keep it up to date

Note: TS's OS Patch Level (system=), Boot Patch Level (boot=), and Vendor Patch Level (vendor=) must all be 11 months or less old in order to pass New PI Strong.
2025-02-08 10:50:57 -04:00
Nicholas Bissell
11e2629a26 Remove special case for logFields, simplify logs
- Run logFields only when spoofProvider, spoofBuild, or spoofSignature is on
- Simplify log outputs; PS -> Play Store, DG -> DroidGuard
2025-02-08 10:34:11 -04:00
Chris Renshaw
8805c3736d Add com.android.vending to DenyList changes 2025-02-08 10:34:11 -04:00
Nicholas Bissell
a52cc16b43 No class loading if Java features disabled
- No longer loads custom classes if not needed for respective packages
- Renames isGmsUnstable to isDroidGuardOrVending
- Removes spoofVendingSdk from migrate/autopif scripts (don't document yet)
- Adds missing setAccessible() call for early return in EntryPointVending.init()
- Adds missing set of spoofSignature -> 0 for vending
2025-02-08 10:34:11 -04:00
Nicholas Bissell
4740d2048d Add spoofVendingSdk to force legacy verdicts from new PI
Squashed: Add spoofVendingSdk for forcing new PI legacy verdicts
Squashed: Move vending SDK spoof to EntryPointVending, replace killgms.sh with killpi.sh
2025-02-08 10:34:11 -04:00
Chris Renshaw
e2b8a3c4b0 Group resetprop common functions together 2025-02-07 00:22:31 -04:00
Chris Renshaw
4dbe12ae58 Update HiddenApiBypass 2025-01-27 00:09:49 -04:00
osm0sis
996981a8e7 Update Gradle 2025-01-26 17:11:15 -04:00
Chris Renshaw
d278b77ced autopif2.sh: handle platform preview Betas like Developer Previews 2025-01-23 23:43:24 -04:00
Chris Renshaw
a3f68d392e README: be clear this is all legacyDeviceRecognitionVerdict 2025-01-18 13:14:23 -04:00
Chris Renshaw
9b3801a117 Add new verified boot error props deletion 2025-01-18 00:00:41 -04:00
Chris Renshaw
df5d5b7ce9 Remove action.sh in scripts-only-mode 2025-01-17 23:57:23 -04:00
Chris Renshaw
b644573e52 Update SDK Build Tools 2025-01-16 19:23:22 -04:00
Chris Renshaw
3e30d553c9 Update AGP 2025-01-09 22:13:05 -04:00
Chris Renshaw
8a64752923 KernelSU-Next does not auto-close Action dialog when successful 2025-01-08 10:25:39 -04:00
Chris Renshaw
264a218a79 Support more PIH and PPU variants and hybrids 2025-01-07 00:25:53 -04:00
Chris Renshaw
59781b1682 Properly support all known opt-out props for PixelPropUtils and PropImitationHooks 2025-01-05 23:20:20 -04:00
Chris Renshaw
a4c8aab031 Add other custom ROMs now using PIHooks 2025-01-05 22:57:13 -04:00
Chris Renshaw
abe69d201b Remove unnecessary/unenforced adb prop spoofs 2025-01-05 19:21:13 -04:00
Chris Renshaw
da0fad725a MMRL (3rd party module manager) doesn't auto-close Actions so exclude it 2024-12-29 23:59:50 -04:00
Chris Renshaw
d9794b2017 APatch upstream now also auto-closes successful Actions 2024-12-29 23:55:44 -04:00
osm0sis
d08ca33633 Update Gradle 2024-12-24 21:53:13 -04:00
Chris Renshaw
a7ba40a36c Use latest Apple Silicon for CI 2024-12-24 15:22:20 -04:00
osm0sis
140c32befd Update Gradle 2024-12-07 15:17:23 -04:00
Chris Renshaw
6fc3200df2 Update AGP 2024-12-07 15:11:18 -04:00
Chris Renshaw
c3ee7e5c0a autopif2.sh: ignore Developer Previews to only use latest Beta 2024-12-07 14:50:19 -04:00
Chris Renshaw
c635a9e3ba Only KSU auto-closes if successful now 2024-12-07 14:38:02 -04:00
Chris Renshaw
8ddab06840 Begin next development cycle 2024-12-07 14:36:30 -04:00
Chris Renshaw
16002e28c6 README: move skipdelprop down and touch up wording 2024-11-18 00:40:12 -04:00
osm0sis
148dea0344 Prepare v12 2024-11-18 00:10:51 -04:00
osm0sis
e01b3b5ada Fix autopif2.sh removal in scripts-only-mode 2024-11-18 00:10:49 -04:00
osm0sis
4666737242 Update Gradle 2024-11-12 17:18:41 -04:00
Chris Renshaw
cd32f0cb0a Allow optional skipping resetprop --delete to avoid detections 2024-11-10 13:09:56 -04:00
Chris Renshaw
4e96fdef9d autopif2.sh: add -s / --strong output feature, fix grep errors 2024-11-07 19:15:07 -04:00
Chris Renshaw
19d31cffea Update AGP 2024-10-31 23:23:32 -03:00
Rev4N1
1edc85dec4 Fix retaining disabled ROM apps in some cases again 2024-10-31 22:34:27 -03:00
Benjamin Ruiz
f351c97b2b Add Action dialog timeout also on KernelSU 2024-10-29 07:16:34 -03:00
Rev4N1
0de5574d53 Add newer hOS prebuilds to default/example app replace list 2024-10-25 12:51:26 -03:00
Chris Renshaw
3f346f3735 autopif2.sh: add test and busybox fallback for broken ROM toybox grep
- outdated/broken toybox grep would ignore -A1 if -m1 was present
2024-10-22 23:14:18 -03:00
Chris Renshaw
b83de28f0b Update NDK 2024-10-22 18:53:38 -03:00
Chris Renshaw
bc591c5732 migrate.sh: fix parsing lines with trailing comments containing special chars 2024-10-21 21:42:15 -03:00
Chris Renshaw
7233c66f8a README: further credit original PIF concept 2024-10-21 16:41:24 -03:00
osm0sis
78dd16ae09 Revert "Don't coexist with those who behave inappropriately"
This reverts commit 565d895a96.

Thanks to @daboynb for properly licensing their derived work and making the acknowledgement more visible
2024-10-21 16:25:13 -03:00
osm0sis
240a52b558 Revert "Remove more who took without proper credit"
This reverts commit 785622321e.

Thanks to @Citra-Standalone for taking steps to properly acknowledge and license their derived works
2024-10-20 14:01:41 -03:00
Chris Renshaw
785622321e Remove more who took without proper credit 2024-10-19 16:35:35 -03:00
Chris Renshaw
565d895a96 Don't coexist with those who behave inappropriately 2024-10-19 14:12:47 -03:00
Chris Renshaw
7dd9ed8f1d autopif2.sh: don't support Termux tsu or similar root environments 2024-10-19 13:48:54 -03:00
Chris Renshaw
2e74733319 autopif2.sh: fix dates with Termux GNU coreutils 2024-10-19 13:24:47 -03:00
Chris Renshaw
153aefbe57 autopif2.sh: use beta FOTA zip metadata instead of GSI zip name
- adds support for generating from beta point releases (e.g. Beta 1.1, etc.), which also fixes producing potentially bad prints when devices are added/removed from the beta list on a point release
2024-10-19 00:24:30 -03:00
Chris Renshaw
91231e12f2 Update AGP 2024-10-18 00:32:11 -03:00
Chris Renshaw
787936d94f Begin next development cycle 2024-10-18 00:31:06 -03:00
osm0sis
fe57017255 Prepare v11 2024-10-06 19:05:38 -03:00
osm0sis
0d05112f38 Replace autopif with autopif2 2024-10-06 18:51:30 -03:00
xqyz
d8ff58d9ca Add additional PixelPropsUtils props to workaround 2024-10-06 18:48:35 -03:00
Chris Renshaw
ea65aef097 Only show dialog auto-close message on Magisk where it's needed 2024-10-03 22:40:22 -03:00
Chris Renshaw
ebdbccdad2 Fix fallback whoami root check logic 2024-10-03 17:13:51 -03:00
Chris Renshaw
08e3fb4d29 Update AGP 2024-10-01 22:45:58 -03:00
Chris Renshaw
a671c3b0d3 README: latest Advanced Settings best practices 2024-09-28 23:44:38 -03:00
Chris Renshaw
c13a7b1299 20 second Action dialog timeout seems about right 2024-09-27 07:19:05 -03:00
Chris Renshaw
629de14990 Increase action.sh dialog timeout 2024-09-26 23:06:38 -03:00
osm0sis
bd4fdcf0c3 Update Gradle 2024-09-25 21:09:45 -03:00
Chris Renshaw
8c216e2d40 Add action.sh support to run autopif.sh from root managers 2024-09-25 12:43:39 -03:00
Chris Renshaw
27fc24337b Copy pasta fixes 2024-09-23 22:37:36 -03:00
Chris Renshaw
796f776534 autopif.sh: pass advanced argument to migrate script 2024-09-22 20:08:42 -03:00
Chris Renshaw
c972637347 migrate.sh: clean up user argument parsing 2024-09-22 19:28:23 -03:00
Chris Renshaw
b10828f199 Update NDK 2024-09-18 23:01:36 -03:00
osm0sis
726aecb2be Add nlohmann/json as submodule 2024-09-18 21:35:00 -03:00
Chris Renshaw
a790f2c0db Update AGP 2024-09-18 12:48:09 -03:00
Chris Renshaw
165d370bc8 migrate.sh: retain commented security_patch if advanced 2024-09-12 20:07:35 -03:00
Chris Renshaw
915b87e6be autopif.sh: retain commented security_patch if present
- commenting out the security_patch line is needed if enabling spoofProps (e.g. for api_level) when used with Tricky Store
2024-09-12 20:00:58 -03:00
Chris Renshaw
1255a49274 Fix Magisk version check
- the variable only gets set during installations, not in the boot script env
2024-09-12 06:51:24 -03:00
osm0sis
6cc82e3e7b Update Gradle 2024-09-11 22:22:44 -03:00
Chris Renshaw
87fde1f4ca Update AGP 2024-09-11 21:36:18 -03:00
Chris Renshaw
d535747c91 autopif.sh: improve error catching, busybox finding, etc.
- simplify error display
- catch missing inject_fields.xml or FINGERPRINT, from e.g. bad download/extraction failure
- more robust busybox finding function
- accept a local migrate.sh and give it precedence over the module copy
2024-09-11 21:31:25 -03:00
Chris Renshaw
98bb23460e autopif.sh: default to api_level 32 now that the betas are served 2024-09-11 21:21:42 -03:00
Chris Renshaw
027e5855a0 Begin next development cycle 2024-09-11 18:25:54 -03:00
Chris Renshaw
8d2d1ecbd2 README: document spoofSignature in Troubleshooting 2024-09-08 22:17:19 -03:00
Chris Renshaw
3775b5448e README: more accurate note about spoofProps
- spoofProps enabled is sometimes necessary to pass STRONG depending on the underlying device/ROM and the fingerprint attempting to be spoofed
2024-08-30 13:47:06 -03:00
Chris Renshaw
00023fb111 README: recommend only latest official Tricky Store 2024-08-20 09:51:02 -03:00
osm0sis
481491758c Hotfix v10(103000) 2024-08-18 21:23:44 -03:00
Chris Renshaw
b42773671a Add missing ro.adb.secure prop early with the others 2024-08-18 19:24:15 -03:00
Chris Renshaw
3d55dc59c1 Work around PixelPropsUtils framework spoof conflict where supported 2024-08-18 19:03:51 -03:00
osm0sis
33f4fa2ce0 Update Gradle 2024-08-18 17:08:35 -03:00
Chris Renshaw
2857e3d2f8 autopif.sh: prefer and use my busybox directly if somehow not on PATH 2024-08-16 14:52:37 -03:00
Chris Renshaw
4b8d6497d0 Hotfix v10(102000) 2024-08-16 00:37:23 -03:00
Chris Renshaw
f3a7f3d5e9 Move Xiaomi fix even later to avoid bootloops on yet more devices 2024-08-16 00:20:49 -03:00
Chris Renshaw
bee755d8f3 Update Changelog 2024-08-14 01:51:13 -03:00
osm0sis
dd4db53ca2 Hotfix v10(101000) 2024-08-14 01:00:22 -03:00
osm0sis
c30b3ab8a8 Fix bootloop on some Xiaomi devices 2024-08-14 00:50:48 -03:00
osm0sis
9d0a67d119 Prepare v10 2024-08-12 23:35:33 -03:00
Chris Renshaw
667efdd6a6 Update AGP 2024-08-09 22:17:44 -03:00
Chris Renshaw
6e7377b3de autopif.sh: tidy using existing if 2024-08-09 12:15:02 -03:00
pershoot
98ab70a0b6 autopif.sh: Do not execute killgms.sh if not in default directory 2024-08-08 22:05:51 -03:00
osm0sis
418e7306e3 Fix advanced spoofing always displaying enabled in logs 2024-08-07 14:16:09 -03:00
osm0sis
44420c89ab autopif.sh: retain previous Advanced Settings values, fixes 2024-08-07 12:01:16 -03:00
osm0sis
adcdd80d65 migrate.sh: tidy up now that functions are multi-line 2024-08-07 11:48:06 -03:00
Chris Renshaw
096c8941b9 migrate.sh: retain previous Advanced Settings values 2024-08-05 22:52:14 -03:00
osm0sis
a926c520f2 Restore resetprop_hexpatch for older Magisk which still needs it 2024-08-04 00:06:54 -03:00
osm0sis
9ef7a7f04e Revert "Use resetprop -w to wait for boot_completed"
This reverts commit 0bc9a45.

Cater to the lowest common denominator (older Magisk) at least until after next Magisk stable
2024-08-03 23:49:42 -03:00
osm0sis
e9c1ec1d5d Clearer log messages for advanced spoof options 2024-08-03 23:49:14 -03:00
osm0sis
a7c2f348ea Add granular advanced spoofing options 2024-08-02 15:30:52 -03:00
4h9fbZ
a5d9980ea7 Fix Signature Data 2024-08-01 23:42:08 -03:00
4h9fbZ
58db03d596 Implement system signature spoofing 2024-08-01 23:42:08 -03:00
Chris Renshaw
64e412c351 Correct module description 2024-07-18 23:07:01 -03:00
Chris Renshaw
914750104f Update libcxx prefab 2024-07-17 23:36:00 -03:00
Chris Renshaw
1db82e2ccb Update NDK 2024-07-17 23:01:56 -03:00
osm0sis
f20c2dff1e Update Gradle 2024-07-12 07:59:05 -03:00
Chris Renshaw
620581b4de Update AGP 2024-07-12 06:20:11 -03:00
Chris Renshaw
ebfd0c292a Make example.pif.json reference more clear 2024-07-11 00:04:08 -03:00
osm0sis
3e58be1e24 Correct type prop heading, add another missing prop
- if sys.oem_unlock_allowed is reset to 0 before sys.boot_completed is 1 it results in a boot hang and then reboot or poweroff
- even though sys.oem_unlock_allowed has been reset to 0 the act of opening Developer Options will set it back to 1 until next reboot
2024-07-05 16:35:04 -03:00
Chris Renshaw
662b9c59c7 Ensure all prop changes bypass property_service
- resetprop only bypasses for ro.* properties by default
2024-07-05 14:15:19 -03:00
Chris Renshaw
0bc9a4543a Use resetprop -w to wait for boot_completed 2024-07-05 12:10:42 -03:00
Chris Renshaw
e3e4bbb95f Match file code style correctly 2024-07-04 15:41:41 -03:00
Chris Renshaw
7c3d0bd8dd Fix all tags and type props, add missing prop 2024-07-04 14:55:45 -03:00
Chris Renshaw
b26b043a02 Remove resetprop_hexpatch since counter is fixed in Magisk Canary 2024-07-04 14:43:50 -03:00
Chris Renshaw
5aabd4b6b5 Don't remove killgms.sh in Scripts-only mode
- it's still useful for testing purposes
2024-07-04 14:36:29 -03:00
Wang Han
6d173fb3a1 Use unique project name
This also works around a shamiko bug which will be
fixed later.
2024-07-04 14:29:20 -03:00
Chris Renshaw
efa3e98a94 Update AGP 2024-07-04 14:25:21 -03:00
Chris Renshaw
8756c3963a Begin next development cycle 2024-07-04 14:22:45 -03:00
Chris Renshaw
6109918511 README: more tweaks 2024-06-16 14:05:52 -03:00
Chris Renshaw
0386e085b5 README: next day fixes 2024-06-14 13:26:06 -03:00
Chris Renshaw
b24d538e82 README: final tidy 2024-06-13 22:30:21 -03:00
osm0sis
dc1ac51008 Prepare v9 2024-06-13 22:17:57 -03:00
Chris Renshaw
e0d288ac10 README: mention Zygisk Assistant as Shamiko alternative 2024-06-10 23:34:02 -03:00
Chris Renshaw
36084324bc Update AGP 2024-06-10 23:29:12 -03:00
osm0sis
07effe41b7 README: AOSP testkey ban, RCS print ban, PPS and testing automation 2024-06-10 22:32:21 -03:00
osm0sis
7b058d9bef Update Gradle 2024-06-01 20:53:22 -03:00
Chris Renshaw
ae1322b907 Work around AOSPA PropImitationHooks conflict 2024-06-01 01:50:52 -03:00
Chris Renshaw
ee8e56b401 migrate.sh: check only trailing quote
- fixes grep_check_json for prop entries with leading wildcard
2024-05-31 10:00:02 -03:00
Chris Renshaw
96a1475ac7 Update AGP 2024-05-20 23:05:47 -03:00
Chris Renshaw
2dd7a17ac2 autopif.sh: don't use half-baked wget-curl wrapper some ROMs include 2024-05-19 04:01:56 -03:00
Chris Renshaw
c7b87b944f autopif.sh: catch Termux issues properly 2024-05-15 23:36:56 -03:00
Chris Renshaw
31adf6b3b9 autopif.sh: install/output improvements
- back up old json if running as built-in to module
- keep Advanced Settings if present in old json
2024-05-11 09:10:13 -03:00
Chris Renshaw
2027b7ba74 migrate.sh: keep Advanced Settings if present in old json 2024-05-11 09:02:58 -03:00
osm0sis
bbfdc87724 Add new files to scripts-only-mode removals 2024-05-06 13:14:56 -03:00
Chris Renshaw
4d116c6a42 Add DroidGuard process killing script 2024-05-06 09:59:41 -03:00
Chris Renshaw
afddeaf340 Add Xiaomi.eu custom.pif.json extraction script 2024-05-06 09:58:44 -03:00
Chris Renshaw
61b018ae21 Update AGP 2024-04-30 23:35:31 -03:00
osm0sis
c7c8b549df Update Gradle 2024-04-25 00:38:06 -03:00
Chris Renshaw
7f1bdf69c5 Update NDK 2024-04-24 22:34:18 -03:00
Chris Renshaw
95e6cbe53b Update AGP 2024-04-10 13:44:43 -03:00
Chris Renshaw
ee714d1e21 Fix description sed with forgotten in-place flag 2024-04-09 08:44:14 -03:00
Chris Renshaw
6aa58bbc5e Indicate scripts-only mode in module description 2024-04-09 08:24:33 -03:00
Chris Renshaw
63bcb3c3f6 README: add examples of known incompatible modules 2024-04-08 12:55:44 -03:00
Chris Renshaw
25262ce07e migrate.sh: fix parsing/formatting regressions
- DEVICE_INITIAL_SDK_INT value would erroneously be used for DEVICE if DEVICE was missing
- a malformed json trailing , on the last input file entry would break the output format
2024-04-07 02:40:51 -03:00
Chris Renshaw
b4821fb03e migrate.sh: fix parsing for \" and , in json values 2024-04-07 01:45:25 -03:00
Chris Renshaw
8e4e7d1cef migrate.sh: add option to override values using derived fingerprint values 2024-04-06 01:37:55 -03:00
Chris Renshaw
58e04392bf migrate.sh: fix deriving from FINGERPRINT values with unexpected spaces 2024-04-05 16:14:14 -03:00
osm0sis
2c13b924ed Tweak/update comments 2024-03-30 15:19:30 -03:00
Chris Renshaw
8215587745 Make scripts-only mode opt-in only
- older custom ROMs may be able to pass only with the Zygisk components active, since the custom ROM doesn't have the correct stock ROM values
2024-03-28 11:33:08 -03:00
Chris Renshaw
8414785806 migrate.sh: allow specifying an output file 2024-03-27 02:27:15 -03:00
Chris Renshaw
75cf629015 Fix mistakenly forced scripts-only mode on clean installs
- use manual opt-in trigger of a scripts-only-mode file existing in the PIF module subdirectory
- clarify installer message since Magisk Zygisk actually functions on Android < 8 now, but the Zygisk attestation fallback and device spoofing aren't necessary to pass on these (and also some later) devices
2024-03-27 00:59:20 -03:00
osm0sis
36ce25f154 Bring back USNF's scripts-only mode for older Android, but better
- do scripts-only mode automatically on Android < 8.0 since it doesn't support Zygisk and generally doesn't need a PIF module to pass at all
- clean up all unused files in scripts-only mode, and modify script behaviors for it, including allowing GMS on DenyList, and even add it if missing since it's necessary on some scripts-only configurations
- allow manually entering scripts-only mode by deleting the zygisk directory of the currently installed module and reinstalling
- intentionally don't alter the Enforce DenyList state, since we don't know what other modules are installed that might depend on it one way or the other, so leave that up to the user
2024-03-25 15:00:49 -03:00
Chris Renshaw
af7063d055 migrate.sh: support compacted json and some CR/LF mangling 2024-03-23 00:26:20 -03:00
Chris Renshaw
ecbf6d1db8 Begin next development cycle 2024-03-22 19:11:02 -03:00
Chris Renshaw
287ce1ee9b Update AGP 2024-03-19 01:18:39 -03:00
Chris Renshaw
77653d25cb README: update for latest APatch supporting official Zygisk Next 2024-03-18 09:51:19 -03:00
Chris Renshaw
009815692c Update NDK 2024-03-12 01:56:54 -03:00
Chris Renshaw
c0618cf9d8 CI only on main again 2024-03-09 22:30:14 -04:00
osm0sis
7d216c30f1 Prepare v8 2024-03-09 22:19:52 -04:00
Chris Renshaw
d620dcdecb Fix CI with AGP 8.3.0 2024-03-09 21:59:52 -04:00
Chris Renshaw
d0acafd34a Update AGP 2024-03-09 02:01:56 -04:00
Chris Renshaw
f99696e894 README: RIP PIFS, point out Resources using words 2024-03-08 17:15:18 -04:00
Chris Renshaw
12b55630fb README: emphasize the flexibility and futureproofing in the json 2024-03-07 13:57:21 -04:00
osm0sis
5703c9bca1 Work around inconsitent wildcard matching behavior in ash [[
- *"/overlay"* is correct for bash [[, and works during an install in ash, but during a boot script in ash results in attempted filename completion and gives an operand error
- "*/overlay/*" works in ash [[, but shouldn't, since it doesn't work in bash [[
- the inconsitent ash behavior in install vs. boot script is likely due to the operating directory of the script in each scenario
2024-03-04 16:16:12 -04:00
osm0sis
ffd510aee5 Fix retaining disabled ROM apps through module updates in some scenarios
- KernelSU or APatch have completely hidden directories/files so would not get recreated
- for .apk files with a config.xml the config.xml would not get recreated due to the 0-size/hidden .apk
2024-03-04 13:48:16 -04:00
osm0sis
b30b43f2ae Fix app replacement messages during install/update 2024-03-03 23:47:36 -04:00
osm0sis
affe99b5ae Handle overlay APKs with config.xml entries correctly 2024-03-03 22:16:21 -04:00
Chris Renshaw
e2bb20b077 README: be painfully clear about where a Magisk module keeps its files 2024-03-02 22:57:11 -04:00
osm0sis
79052ff455 Separate common installation and boot-time scripts and source it 2024-03-02 22:49:46 -04:00
osm0sis
4ab07b71f8 migrate.sh: fix deprecated vndk property entry 2024-03-01 20:13:24 -04:00
osm0sis
34966f58a0 Don't hide CertifiedPropsOverlay config.xml by default to not break GSIs
- GSIs and possibly other ROMs use /system_ext/overlay/config/config.xml with overlay package names and options
- replacing/hiding either CertifiedPropsOverlay.apk or config.xml alone causes bootloops
2024-02-27 15:29:32 -04:00
Chris Renshaw
0299c76061 README: note GMS must not be on DenyList 2024-02-27 13:32:32 -04:00
osm0sis
163678c49a Add PifPrebuilt (com.goolag.pif) to default/example app replace list 2024-02-23 13:55:12 -04:00
Chris Renshaw
f61fd571e0 README: clarify caveat for format migration from cross-forks 2024-02-22 14:20:10 -04:00
Chris Renshaw
26979bd73e migrate.sh: ensure only one value match 2024-02-16 09:58:06 -04:00
Chris Renshaw
c19224b138 Correct comment 2024-02-16 09:50:43 -04:00
Chris Renshaw
ccb696d334 README: add other package names 2024-02-16 09:33:01 -04:00
Chris Renshaw
8014d71934 Consistent numbers 2024-02-14 10:01:49 -04:00
Chris Renshaw
52edfcfb7c README: use PixelFlasher thread UI Workflow post 2024-02-11 15:41:27 -04:00
Chris Renshaw
938ae86c8e README: Touch-ups 2024-02-08 23:14:21 -04:00
osm0sis
bdd846add6 Tidy scripts, clarify KernelSU/APatch hide files/directories 2024-02-08 00:08:57 -04:00
osm0sis
1a7c5103d1 verbose_logs is now verboseLogs
- differentiate all the ways from a BUILD_FIELD_ENTRY and a system.property_entry
- probably better this way in the long run
2024-02-07 22:53:13 -04:00
osm0sis
686af702dc README: improve Resources formatting 2024-02-07 22:19:36 -04:00
Chris Renshaw
18f8277f16 No CI for documentation changes 2024-02-07 21:28:23 -04:00
osm0sis
484ab2aa63 Documentation: fixes, and moar Resources! 2024-02-07 11:29:51 -04:00
osm0sis
87eb713cbd migrate.sh: be more verbose migrating from v4, catch another edge case 2024-02-04 21:57:42 -04:00
Chris Renshaw
fa418290b3 migrate.sh: optionally add advanced settings to json 2024-02-02 18:49:35 -04:00
osm0sis
608e60adbb Allow files on the app replace list 2024-02-02 16:46:59 -04:00
osm0sis
fae28159b9 Update AGP 2024-02-02 15:21:17 -04:00
osm0sis
71b40dcb09 Update gradle 2024-02-02 14:59:53 -04:00
Chris Renshaw
1f0c921773 Test Apple Silicon CI 2024-02-01 22:46:52 -04:00
Chris Renshaw
3b00a7249b README: add Banned Kernel troubleshooting 2024-02-01 11:56:07 -04:00
osm0sis
48014b9450 Revert "Hook uname to spoof kernel release version string"
This reverts commit 7997954f74.

Hook wasn't functional for intercepting the uname call despite many attempted methods, both on .gms and .gms.unstable

See: https://github.com/chiteroman/PlayIntegrityFix/issues/236
2024-02-01 09:37:52 -04:00
Chris Renshaw
3451dd72ec README: add FAQ 2024-01-31 12:14:55 -04:00
osm0sis
9cc8451c90 VERBOSE_LOGS is now verbose_logs
- differentiate advanced settings better from a Build field (all caps) or a System property (has .)
- match new advanced setting uname_release
2024-01-29 13:27:18 -04:00
osm0sis
7997954f74 Hook uname to spoof kernel release version string
Co-authored-by: chiteroman <98092901+chiteroman@users.noreply.github.com>
2024-01-29 13:15:11 -04:00
osm0sis
fc8e5108de Update default/example app replace list 2024-01-28 15:40:52 -04:00
Chris Renshaw
3ec6a4b039 Begin next development cycle 2024-01-25 15:03:42 -04:00
Chris Renshaw
5b9d0dfdd3 Changelog corrections 2024-01-25 14:36:30 -04:00
Chris Renshaw
278cbf1732 Update GitHub Actions again since https://github.com/actions/upload-artifact/issues/473 is fixed 2024-01-24 22:57:03 -04:00
osm0sis
594ac7c8ac Prepare v7 2024-01-24 14:22:23 -04:00
osm0sis
b8e68d059e Correct XInjectModule placement in replace list 2024-01-24 10:41:34 -04:00
osm0sis
198c2e5486 Fix ROM injection app replacement when using APatch 2024-01-23 12:31:36 -04:00
Chris Renshaw
919526bcd7 Add prop hack return codes for testing, tidy other functions 2024-01-23 00:56:47 -04:00
osm0sis
0b34f95282 Use app data dir to detect GMS package
Prevent injecting into unrelated apps because apps can use whatever process name. This effectively restores df20bdb but with null checks added to prevent crash.

Reference: topjohnwu/Magisk@07c22cc

Co-authored-by: chiteroman <98092901+chiteroman@users.noreply.github.com>
Co-authored-by: Wang Han <416810799@qq.com>
2024-01-22 19:34:23 -04:00
Chris Renshaw
63e4c571bf Hide adbd service state since DroidGuard looks at it
- not currently enforced, but play it safe and spoof it by default like with USB state
2024-01-21 00:50:27 -04:00
osm0sis
bdcfd283f1 Fix ROM injection app replacement when using KernelSU 2024-01-20 23:21:53 -04:00
osm0sis
dbd60afe68 migrate.sh: allow any filename to be specified as input file
- if none is provided it still falls back to looking for custom.pif.json in the current directory
2024-01-20 15:00:07 -04:00
osm0sis
e2cb4e1523 More logging
Co-authored-by: chiteroman <98092901+chiteroman@users.noreply.github.com>
2024-01-19 14:44:35 -04:00
osm0sis
5901844ce3 Add XiaomiEUInject-Stub to the default/example replace list 2024-01-19 09:46:54 -04:00
osm0sis
efb8ee930a Don't attempt to hack props if we don't have a context file 2024-01-18 16:56:45 -04:00
osm0sis
d36b35b7e9 Fix ROM injection app replacement on partitions other than /system 2024-01-18 14:27:55 -04:00
Chris Renshaw
4c08eb1e42 Begin next development cycle 2024-01-18 14:18:52 -04:00
osm0sis
2fa007afa3 Prepare v6 2024-01-17 16:13:20 -04:00
osm0sis
05c2474963 Fix Realme fingerprint scanners 2024-01-17 16:06:39 -04:00
Chris Renshaw
e0931c829d Reduce somewhat unnecessary extra Build field spoofing calls
Co-authored-by: chiteroman <98092901+chiteroman@users.noreply.github.com>
2024-01-16 20:28:28 -04:00
osm0sis
b57f46eed0 Revert "Fix seemingly unnecessary extra Build field spoofing calls"
This reverts commit 05927c60e1.

Seemingly necessary on some ROMs that do their own framework-level spoofing. May our logcats forgive us.
2024-01-16 14:44:29 -04:00
osm0sis
73d89d7a50 Clean up remaining .idea missing trailing newlines 2024-01-15 23:19:32 -04:00
osm0sis
475185c3ee Switch hooking method to Dobby
- Android 14 QPR2 (currently in Beta and due for Stable in March) breaks ShadowHook libc hooking needed for property spoofing
- there are currently no signs of life over at ShadowHook to resolve this despite my reporting it to them over a month ago

Co-authored-by: Nicholas Bissell <thefreeman193@hotmail.com>
Co-authored-by: chiteroman <98092901+chiteroman@users.noreply.github.com>
2024-01-15 23:16:21 -04:00
osm0sis
802c0a7617 Improve logging messages further 2024-01-15 17:18:26 -04:00
osm0sis
9a24cd6f23 Tidy JNI JSON sending/receiving code and logging 2024-01-15 17:05:26 -04:00
osm0sis
22e3a14a6f Refactor VERBOSE_LOGS parsing to directly pass level from Native to Java 2024-01-15 16:36:52 -04:00
osm0sis
24db525cf3 Add advanced Build classes field logging
Co-authored-by: Nicholas Bissell <thefreeman193@hotmail.com>
2024-01-13 14:09:29 -04:00
osm0sis
21a309dd12 More consistent replace file naming, retain custom through an update 2024-01-09 10:52:17 -04:00
osm0sis
05927c60e1 Fix seemingly unnecessary extra Build field spoofing calls
Co-authored-by: arda99 <arda99@noreply.xdaforums.com>
2024-01-08 21:36:34 -04:00
Chris Renshaw
008c0d0ada Add CI run number to zip filename 2024-01-08 20:57:35 -04:00
osm0sis
93ac718229 Support prop hacking on older Android 2024-01-08 16:44:26 -04:00
osm0sis
5aea2e877f README tweaks 2024-01-08 16:09:50 -04:00
osm0sis
d106e2a964 Allow customizable path replacement for conflicting custom ROM apps 2024-01-08 16:06:24 -04:00
osm0sis
a9630901b3 Reorganize slightly and add missing props 2024-01-08 14:15:58 -04:00
osm0sis
d7090f3f73 Use custom function to hack props without increasing prop change counter
- some apps were detecting tampered props from the increased prop_info serial counter using resetprop
- patching doesn't rely on magiskboot hexpatch so should work on KernelSU and APatch as well
- hopefully temporary until all root solutions adopt a patched system_properties repo to fix counters via resetprop
2024-01-08 13:55:55 -04:00
Chris Renshaw
3088f4b179 migrate.sh: remove all use of echo \n to be even more portable 2023-12-28 23:52:50 -04:00
Chris Renshaw
9673971b70 README: document VERBOSE_LOGS advanced logging levels 2023-12-28 20:10:19 -04:00
osm0sis
f6a9f855ef README: document manual migrate.sh execution 2023-12-28 13:28:31 -04:00
Chris Renshaw
edcb94e179 migrate.sh: add help, add force option, fix on shells without echo -e 2023-12-28 13:21:40 -04:00
osm0sis
a3cbed9a4e Clean up last remaining CR+LF 2023-12-27 23:32:40 -04:00
Chris Renshaw
e9b7289950 Begin next development cycle 2023-12-27 22:44:06 -04:00
Chris Renshaw
63fab9cca7 Fix Previous Changelogs link 2023-12-27 17:36:51 -04:00
48 changed files with 1584 additions and 25308 deletions

View File

@@ -1,38 +1,41 @@
name: Android CI
on:
workflow_dispatch:
push:
branches: [ "main" ]
branches: main
paths-ignore: '**.md'
pull_request:
branches: [ "main" ]
branches: main
paths-ignore: '**.md'
jobs:
build:
runs-on: ubuntu-latest
runs-on: macos-15
steps:
- name: Check out
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
submodules: "recursive"
submodules: 'recursive'
fetch-depth: 0
- name: Set up JDK 17
uses: actions/setup-java@v4
- name: Set up JDK
uses: actions/setup-java@v5
with:
distribution: 'temurin'
java-version: '17'
java-version: 21
- name: Grant execute permission for gradlew
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
with:
name: PlayIntegrityFork-CI
path: module/*
name: PlayIntegrityFork-CI_#${{ github.run_number }}
path: 'module/*'
compression-level: 9

15
.gitmodules vendored
View File

@@ -1,6 +1,9 @@
[submodule "libcxx"]
path = app/src/main/cpp/libcxx
url = https://github.com/topjohnwu/libcxx.git
[submodule "shadowhook"]
path = app/src/main/cpp/shadowhook
url = https://github.com/bytedance/android-inline-hook
[submodule "Dobby"]
path = app/src/main/cpp/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"]
path = app/src/main/cpp/json
url = https://github.com/nlohmann/json

2
.idea/compiler.xml generated
View File

@@ -3,4 +3,4 @@
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="17" />
</component>
</project>
</project>

View File

@@ -7,4 +7,4 @@
</entry>
</value>
</component>
</project>
</project>

2
.idea/gradle.xml generated
View File

@@ -16,4 +16,4 @@
</GradleProjectSettings>
</option>
</component>
</project>
</project>

View File

@@ -7,4 +7,4 @@
<option name="processComments" value="true" />
</inspection_tool>
</profile>
</component>
</component>

View File

@@ -3,4 +3,4 @@
<option name="PROJECT_PROFILE" value="Default" />
<option name="USE_PROJECT_PROFILE" value="false" />
</settings>
</component>
</component>

2
.idea/migrations.xml generated
View File

@@ -7,4 +7,4 @@
</set>
</option>
</component>
</project>
</project>

2
.idea/misc.xml generated
View File

@@ -6,4 +6,4 @@
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>
</project>

4
.idea/vcs.xml generated
View File

@@ -2,6 +2,6 @@
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
<mapping directory="$PROJECT_DIR$/app/src/main/cpp/libcxx" vcs="Git" />
<mapping directory="$PROJECT_DIR$/app/src/main/cpp/Dobby" vcs="Git" />
</component>
</project>
</project>

View File

@@ -1,17 +1,24 @@
## Custom Fork v5
- Allow spoofing literally any system property, supporting * lead wildcard to match multiple
- Remove all backwards compat cruft and deprecated entries
- Add log levels with VERBOSE_LOGS last json entry of 0, 1, 2, 3 or 100
- Spoof sys.usb.state to DroidGuard by default to hide USB Debugging
- Update example json for properties
- Add migration script to automatically upgrade old custom.pif.json during install/update (may also be run manually)
## Custom Fork v14
## Custom Fork v4
- Very verbose logging (for now)
- Allow spoofing literally any field from android.os.Build or android.os.Build.VERSION
- Add BUILD_ID and VNDK_VERSION support to keep cross-fork API compatibility
- Add exceptions for FIRST_API_VERSION (actually DEVICE_INITIAL_SDK_INT) and BUILD_ID (actually ID) for backwards API compatibility
- Add empty example.pif.json with reference link
- Fix GMS crashes if a null/bad value was read from json
- 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
###[Previous changelogs](https://github.com/osm0sis/PlayIntegrityFork/releases)
## Custom Fork v13
- Improve Action on KSU/APatch, KSU-Next, MMRL
- 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
- Improve autopif2 to populate TS's optional security_patch.txt
- Improve ROM overlay xml disabling support (YAAP)
- Improve autopif2 for wget2 on arm
_[Full changelogs](https://github.com/osm0sis/PlayIntegrityFork/releases)_

187
README.md
View File

@@ -1,86 +1,199 @@
# Play Integrity Fork
*PIF forked to bring back the custom.pif.json restore feature and develop more methodically*
*PIF forked to be more futureproof and develop more methodically*
[![GitHub release (latest by date)](https://img.shields.io/github/v/release/osm0sis/PlayIntegrityFork?label=Release&color=blue&style=flat)](https://github.com/osm0sis/PlayIntegrityFork/releases/latest)
[![GitHub Release Date](https://img.shields.io/github/release-date/osm0sis/PlayIntegrityFork?label=Release%20Date&color=brightgreen&style=flat)](https://github.com/osm0sis/PlayIntegrityFork/releases)
[![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)
A Zygisk module which fixes "ctsProfileMatch" (SafetyNet) and "MEETS_DEVICE_INTEGRITY" (Play Integrity).
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:
To use this module you must have one of the following (latest versions):
- Magisk with Zygisk enabled.
- KernelSU with [ZygiskNext](https://github.com/Dr-TSNG/ZygiskNext) module installed.
- [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) 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) 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) or [ReZygisk](https://github.com/PerformanC/ReZygisk) or [NeoZygisk](https://github.com/JingMatrix/NeoZygisk) module installed
## About module
It injects a classes.dex file to modify a few 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.
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.
The purpose of the module is to avoid hardware attestation.
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.
## About 'custom.pif.json' file
## Configuration
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 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.
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.
You can't use values from recent devices due them triggering full hardware backed attestation.
### About 'custom.pif.json' file
Older formatted custom.pif.json files from cross-forks and previous releases will be automatically migrated to the latest format.
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.
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>
<summary>Resources</summary>
<summary><strong>Resources</strong></summary>
- [How-To Guide - Info to help find build.prop files, then create and use a custom.pif.json](https://xdaforums.com/t/module-play-integrity-fix-safetynet-fix.4607985/post-89189572)
- [gen_pif_custom.sh - Script to generate a custom.pif.json from device dump build.prop files](https://xdaforums.com/t/tools-zips-scripts-osm0sis-odds-and-ends-multiple-devices-platforms.2239421/post-89173470)
- [UI Workflow Guide - Build, edit and test custom.pif.json using PixelFlasher on PC](https://xdaforums.com/t/module-play-integrity-fix-safetynet-fix.4607985/post-89189970)
- FAQ:
- [PIF FAQ](https://xdaforums.com/t/pif-faq.4653307/) - Frequently Asked Questions (READ FIRST!)
- Guides:
- [How-To Guide](https://xdaforums.com/t/module-play-integrity-fix-safetynet-fix.4607985/post-89189572) - Info to help find build.prop files, then manually create and use a custom.pif.json
- [Complete Noobs' Guide](https://xdaforums.com/t/how-to-search-find-your-own-fingerprints-noob-friendly-a-comprehensive-guide-w-tips-discussion-for-complete-noobs-from-one.4645816/) - A more in-depth basic explainer of the How-To Guide above
- [UI Workflow Guide](https://xdaforums.com/t/pixelflasher-a-gui-tool-for-flashing-updating-rooting-managing-pixel-phones.4415453/post-87412305) - Build/find, edit, and test custom.pif.json using PixelFlasher on PC
- [Tasker PIF Testing Helper](https://xdaforums.com/t/pif-testing-helper-tasker-profile-for-testing-fingerprints.4644827/) - Test custom.pif.json using Tasker on device
- Scripts:
- [gen_pif_custom.sh](https://xdaforums.com/t/tools-zips-scripts-osm0sis-odds-and-ends-multiple-devices-platforms.2239421/post-89173470) - Script to generate a custom.pif.json from device dump build.prop files
- [autopif.sh](https://xdaforums.com/t/module-play-integrity-fix-safetynet-fix.4607985/post-89233630) - Script to extract the latest working Xiaomi.eu public fingerprint (though frequently banned and may be banned for RCS use while otherwise passing) to test an initial setup
- [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) 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
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 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.
## Troubleshooting
### Failing BASIC verdict
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.
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:
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 integrity
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
Some modules which modify system can trigger DroidGuard detection, never hook GMS processes.
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)
### Failing DEVICE integrity (on KernelSU/KernelSU Next/APatch)
- Disable ZygiskNext
- Disable Zygisk Next
- Reboot
- Enable ZygiskNext
- Enable Zygisk Next
- Reboot again
### Play Protect/Store Certification and Google Wallet Tap To Pay Setup Security Requirements
### Failing DEVICE integrity (on custom kernel/ROM)
Follow these steps:
- 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
- You may also try a different custom kernel, or go back to the default kernel for your ROM, if available/possible
- Flash the module in Magisk/KernelSU
- Clear Google Wallet cache (if you have it)
- Clear Google Play Store cache and data
- Clear Google Play Services (com.google.android.gms) cache and data (Optionally skip clearing data and wait some time, ~24h, for it to resolve on its own)
### 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`
- 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
- 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
- Reflash the module in your root manager app
- Clear Google Play Store (com.android.vending) and, if present, Google Play Protect Service (com.google.android.odad) cache and data
- Reboot
Note clearing Google Play Services app ***data*** will then require you to reset any WearOS devices paired to your device.
### 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
Note: Clearing Google Play Services app ***data*** will then require you to reset any WearOS devices paired to your device.
### Read module logs
You can read module logs using this command directly after boot:
You can read module logs using one of these commands directly after boot:
```
adb shell "logcat | grep 'PIF'"
```
`adb shell "logcat | grep 'PIF/'"` or `su -c "logcat | grep 'PIF/'"`
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?
No.
[No...](#about-spoofing-advanced-settings)
## About Play Integrity, SafetyNet is deprecated
## About spoofing Advanced Settings
You can read more
here: [Play Integrity API Info - XDA Forums](https://xdaforums.com/t/info-play-integrity-api-replacement-for-safetynet.4479337/)
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>
<summary><strong>Details</strong></summary>
- 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; 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.
- 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.
- 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>
## 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 <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>
<summary><strong>Details</strong></summary>
- Manually opt-in by creating a file named scripts-only-mode in the module directory, either from a root prompt with `mkdir -p /data/adb/modules/playintegrityfix; touch /data/adb/modules/playintegrityfix/scripts-only-mode` or from a file explorer app, and then re/flashing the module. Scripts-only mode will remain enabled until this file is removed and the module is reflashed again.
- 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) 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>
## 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
Module scripts were adapted from those of kdrag0n/Displax's Universal SafetyNet Fix (USNF) module, please see the commit history of [Displax's USNF Fork](https://github.com/Displax/safetynet-fix/tree/dev/magisk) for proper attribution.
Forked from chiteroman's [Play Integrity Fix (PIF)](https://github.com/chiteroman/PlayIntegrityFix) (no longer online).
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,22 +4,38 @@ plugins {
android {
namespace = "es.chiteroman.playintegrityfix"
compileSdk = 34
ndkVersion = "26.1.10909125"
buildToolsVersion = "34.0.0"
compileSdk = 36
ndkVersion = "28.2.13676358"
buildToolsVersion = "36.0.0"
buildFeatures {
prefab = true
}
packaging {
jniLibs {
excludes += "**/liblog.so"
excludes += "**/libdobby.so"
}
}
defaultConfig {
applicationId = "es.chiteroman.playintegrityfix"
minSdk = 26
targetSdk = 34
targetSdk = 36
versionCode = 1
versionName = "1.0"
externalNativeBuild {
ndk {
jobs = Runtime.getRuntime().availableProcessors()
abiFilters += "armeabi-v7a"
abiFilters += "arm64-v8a"
cmake {
arguments += "-DANDROID_STL=none"
arguments += "-DCMAKE_BUILD_TYPE=Release"
cppFlags += "-std=c++23"
cppFlags += "-fno-exceptions"
cppFlags += "-fno-rtti"
cppFlags += "-fvisibility=hidden"
cppFlags += "-fvisibility-inlines-hidden"
}
}
}
@@ -33,23 +49,29 @@ android {
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
}
externalNativeBuild {
ndkBuild {
path = file("src/main/cpp/Android.mk")
cmake {
path = file("src/main/cpp/CMakeLists.txt")
version = "3.22.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/out/lib")
dependencies {
implementation("org.lsposed.libcxx:libcxx:28.1.13356709")
implementation("org.lsposed.hiddenapibypass:hiddenapibypass:6.1")
}
tasks.register("copyFiles") {
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 ->

View File

@@ -1,3 +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.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

View File

@@ -1,33 +0,0 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := zygisk
LOCAL_SRC_FILES := main.cpp
LOCAL_C_INCLUDES := $(LOCAL_PATH)
LOCAL_SRC_FILES += $(wildcard $(LOCAL_PATH)/shadowhook/shadowhook/src/main/cpp/*.c)
LOCAL_SRC_FILES += $(wildcard $(LOCAL_PATH)/shadowhook/shadowhook/src/main/cpp/common/*.c)
LOCAL_SRC_FILES += $(wildcard $(LOCAL_PATH)/shadowhook/shadowhook/src/main/cpp/third_party/xdl/*.c)
LOCAL_C_INCLUDES += $(LOCAL_PATH)/shadowhook/shadowhook/src/main/cpp
LOCAL_C_INCLUDES += $(LOCAL_PATH)/shadowhook/shadowhook/src/main/cpp/common
LOCAL_C_INCLUDES += $(LOCAL_PATH)/shadowhook/shadowhook/src/main/cpp/include
LOCAL_C_INCLUDES += $(LOCAL_PATH)/shadowhook/shadowhook/src/main/cpp/third_party/bsd
LOCAL_C_INCLUDES += $(LOCAL_PATH)/shadowhook/shadowhook/src/main/cpp/third_party/lss
LOCAL_C_INCLUDES += $(LOCAL_PATH)/shadowhook/shadowhook/src/main/cpp/third_party/xdl
ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
LOCAL_SRC_FILES += $(wildcard $(LOCAL_PATH)/shadowhook/shadowhook/src/main/cpp/arch/arm/*.c)
LOCAL_C_INCLUDES += $(LOCAL_PATH)/shadowhook/shadowhook/src/main/cpp/arch/arm
endif
ifeq ($(TARGET_ARCH_ABI),arm64-v8a)
LOCAL_SRC_FILES += $(wildcard $(LOCAL_PATH)/shadowhook/shadowhook/src/main/cpp/arch/arm64/*.c)
LOCAL_C_INCLUDES += $(LOCAL_PATH)/shadowhook/shadowhook/src/main/cpp/arch/arm64
endif
LOCAL_STATIC_LIBRARIES := libcxx
LOCAL_LDLIBS := -llog
include $(BUILD_SHARED_LIBRARY)
include $(LOCAL_PATH)/libcxx/Android.mk

View File

@@ -1,3 +0,0 @@
APP_STL := none
APP_CFLAGS := -Oz -fno-exceptions -fno-rtti -fvisibility=hidden -fvisibility-inlines-hidden
APP_CPPFLAGS := -std=c++20

View File

@@ -1,15 +1,15 @@
cmake_minimum_required(VERSION 3.22.1)
project(zygisk)
project(playintegrityfix)
include_directories(${CMAKE_SOURCE_DIR}/libcxx/include)
find_package(cxx REQUIRED CONFIG)
link_libraries(${CMAKE_SOURCE_DIR}/libcxx/${CMAKE_ANDROID_ARCH_ABI}.a)
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)
SET_OPTION(Plugin.Android.BionicLinkerUtil ON)
target_compile_features(${CMAKE_PROJECT_NAME} PRIVATE c_std_23 cxx_std_23)
target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE log)
target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE log dobby_static)

1
app/src/main/cpp/json Submodule

Submodule app/src/main/cpp/json added at 55f93686c0

File diff suppressed because it is too large Load Diff

View File

@@ -3,8 +3,8 @@
#include <unistd.h>
#include "zygisk.hpp"
#include "shadowhook.h"
#include "json.hpp"
#include "json/single_include/nlohmann/json.hpp"
#include "dobby.h"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, "PIF/Native", __VA_ARGS__)
@@ -13,7 +13,16 @@
#define JSON_FILE_PATH "/data/adb/modules/playintegrityfix/pif.json"
#define CUSTOM_JSON_FILE_PATH "/data/adb/modules/playintegrityfix/custom.pif.json"
static int VERBOSE_LOGS = 0;
#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 spoofVendingFinger = 0;
static int spoofVendingSdk = 0;
static std::map<std::string, std::string> jsonProps;
@@ -22,18 +31,12 @@ typedef void (*T_Callback)(void *, const char *, const char *, uint32_t);
static std::map<void *, T_Callback> callbacks;
static void modify_callback(void *cookie, const char *name, const char *value, uint32_t serial) {
if (cookie == nullptr || name == nullptr || value == nullptr || !callbacks.contains(cookie)) return;
const char *oldValue = value;
std::string prop(name);
// Spoof specific property values
if (prop == "sys.usb.state") {
value = "mtp";
}
if (jsonProps.count(prop)) {
// Exact property match
value = jsonProps[prop].c_str();
@@ -48,7 +51,7 @@ static void modify_callback(void *cookie, const char *name, const char *value, u
}
if (oldValue == value) {
if (VERBOSE_LOGS > 99) LOGD("[%s]: %s (unchanged)", name, value);
if (verboseLogs > 99) LOGD("[%s]: %s (unchanged)", name, oldValue);
} else {
LOGD("[%s]: %s -> %s", name, oldValue, value);
}
@@ -67,18 +70,14 @@ static void my_system_property_read_callback(const prop_info *pi, T_Callback cal
}
static void doHook() {
shadowhook_init(SHADOWHOOK_MODE_UNIQUE, false);
void *handle = shadowhook_hook_sym_name(
"libc.so",
"__system_property_read_callback",
reinterpret_cast<void *>(my_system_property_read_callback),
reinterpret_cast<void **>(&o_system_property_read_callback)
);
void *handle = DobbySymbolResolver(nullptr, "__system_property_read_callback");
if (handle == nullptr) {
LOGD("Couldn't find '__system_property_read_callback' handle");
return;
}
LOGD("Found '__system_property_read_callback' handle at %p", handle);
DobbyHook(handle, reinterpret_cast<dobby_dummy_func_t>(my_system_property_read_callback),
reinterpret_cast<dobby_dummy_func_t *>(&o_system_property_read_callback));
}
class PlayIntegrityFix : public zygisk::ModuleBase {
@@ -89,32 +88,43 @@ 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);
if (rawProcess) {
std::string_view process(rawProcess);
isGms = process.starts_with("com.google.android.gms");
isGmsUnstable = process.compare("com.google.android.gms.unstable") == 0;
// Prevent crash on apps with no data dir
if (rawDir == nullptr) {
env->ReleaseStringUTFChars(args->nice_name, rawProcess);
api->setOption(zygisk::DLCLOSE_MODULE_LIBRARY);
return;
}
pkgName = rawProcess;
std::string_view dir(rawDir);
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);
if (!isGms) {
api->setOption(zygisk::DLCLOSE_MODULE_LIBRARY);
return;
}
// We are in GMS now, force unmount
api->setOption(zygisk::FORCE_DENYLIST_UNMOUNT);
if (!isGmsUnstable) {
if (!isDroidGuardOrVending) {
api->setOption(zygisk::DLCLOSE_MODULE_LIBRARY);
return;
}
std::vector<char> jsonVector;
long dexSize = 0, jsonSize = 0;
int fd = api->connectCompanion();
read(fd, &dexSize, sizeof(long));
@@ -122,34 +132,34 @@ public:
if (dexSize < 1) {
close(fd);
LOGD("Couldn't read classes.dex");
LOGD("Couldn't read dex file");
api->setOption(zygisk::DLCLOSE_MODULE_LIBRARY);
return;
}
if (jsonSize < 1) {
close(fd);
LOGD("Couldn't read pif.json");
LOGD("Couldn't read json file");
api->setOption(zygisk::DLCLOSE_MODULE_LIBRARY);
return;
}
LOGD("Read from file descriptor for 'dex' -> %ld bytes", dexSize);
LOGD("Read from file descriptor for 'json' -> %ld bytes", jsonSize);
dexVector.resize(dexSize);
read(fd, dexVector.data(), dexSize);
std::vector<char> jsonVector(jsonSize);
jsonVector.resize(jsonSize);
read(fd, jsonVector.data(), jsonSize);
close(fd);
LOGD("Read from file descriptor file 'classes.dex' -> %ld bytes", dexSize);
LOGD("Read from file descriptor file 'pif.json' -> %ld bytes", jsonSize);
std::string data(jsonVector.cbegin(), jsonVector.cend());
json = nlohmann::json::parse(data, nullptr, false, true);
std::string jsonString(jsonVector.cbegin(), jsonVector.cend());
json = nlohmann::json::parse(jsonString, nullptr, false, true);
jsonVector.clear();
data.clear();
jsonString.clear();
}
void postAppSpecialize(const zygisk::AppSpecializeArgs *args) override {
@@ -157,9 +167,11 @@ public:
readJson();
doHook();
if (pkgName == VENDING_PACKAGE) spoofBuild = spoofProps = spoofProvider = spoofSignature = 0;
else spoofVendingFinger = spoofVendingSdk = 0;
inject();
if (spoofProps > 0) doHook();
if (spoofBuild + spoofProvider + spoofSignature + spoofVendingFinger + spoofVendingSdk > 0) inject();
dexVector.clear();
json.clear();
@@ -174,30 +186,103 @@ private:
JNIEnv *env = nullptr;
std::vector<char> dexVector;
nlohmann::json json;
std::string pkgName;
std::string vendingFingerprintValue;
void readJson() {
LOGD("JSON contains %d keys!", static_cast<int>(json.size()));
// Verbose logging if VERBOSE_LOGS with level number is last entry
if (json.contains("VERBOSE_LOGS")) {
if (!json["VERBOSE_LOGS"].is_null() && json["VERBOSE_LOGS"].is_string() && json["VERBOSE_LOGS"] != "") {
VERBOSE_LOGS = stoi(json["VERBOSE_LOGS"].get<std::string>());
if (VERBOSE_LOGS > 0) LOGD("Verbose logging (level %d) enabled!", VERBOSE_LOGS);
// Verbose logging level
if (json.contains("verboseLogs")) {
if (!json["verboseLogs"].is_null() && json["verboseLogs"].is_string() && json["verboseLogs"] != "") {
verboseLogs = stoi(json["verboseLogs"].get<std::string>());
if (verboseLogs > 0) LOGD("Verbose logging (level %d) enabled!", verboseLogs);
} else {
LOGD("Error parsing VERBOSE_LOGS!");
LOGD("Error parsing verboseLogs!");
}
json.erase("verboseLogs");
}
// Vending 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 (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) {
json.clear();
return;
}
// DroidGuard advanced spoofing settings
if (json.contains("spoofBuild")) {
if (!json["spoofBuild"].is_null() && json["spoofBuild"].is_string() && json["spoofBuild"] != "") {
spoofBuild = stoi(json["spoofBuild"].get<std::string>());
if (verboseLogs > 0) LOGD("Spoofing Build Fields %s!", (spoofBuild > 0) ? "enabled" : "disabled");
} else {
LOGD("Error parsing spoofBuild!");
}
json.erase("spoofBuild");
}
if (json.contains("spoofProps")) {
if (!json["spoofProps"].is_null() && json["spoofProps"].is_string() && json["spoofProps"] != "") {
spoofProps = stoi(json["spoofProps"].get<std::string>());
if (verboseLogs > 0) LOGD("Spoofing System Properties %s!", (spoofProps > 0) ? "enabled" : "disabled");
} else {
LOGD("Error parsing spoofProps!");
}
json.erase("spoofProps");
}
if (json.contains("spoofProvider")) {
if (!json["spoofProvider"].is_null() && json["spoofProvider"].is_string() && json["spoofProvider"] != "") {
spoofProvider = stoi(json["spoofProvider"].get<std::string>());
if (verboseLogs > 0) LOGD("Spoofing Keystore Provider %s!", (spoofProvider > 0) ? "enabled" : "disabled");
} else {
LOGD("Error parsing spoofProvider!");
}
json.erase("spoofProvider");
}
if (json.contains("spoofSignature")) {
if (!json["spoofSignature"].is_null() && json["spoofSignature"].is_string() && json["spoofSignature"] != "") {
spoofSignature = stoi(json["spoofSignature"].get<std::string>());
if (verboseLogs > 0) LOGD("Spoofing ROM Signature %s!", (spoofSignature > 0) ? "enabled" : "disabled");
} else {
LOGD("Error parsing spoofSignature!");
}
json.erase("spoofSignature");
}
std::vector<std::string> eraseKeys;
for (auto &jsonList: json.items()) {
if (VERBOSE_LOGS > 1) LOGD("Parsing %s...", jsonList.key().c_str());
if (verboseLogs > 1) LOGD("Parsing %s", jsonList.key().c_str());
if (jsonList.key().find_first_of("*.") != std::string::npos) {
// Name contains . or * (wildcard) so assume real property name
if (!jsonList.value().is_null() && jsonList.value().is_string()) {
if (jsonList.value() == "") {
LOGD("%s is empty, skipping...", jsonList.key().c_str());
LOGD("%s is empty, skipping", jsonList.key().c_str());
} else {
if (VERBOSE_LOGS > 0) LOGD("Adding '%s' to properties list", jsonList.key().c_str());
if (verboseLogs > 0) LOGD("Adding '%s' to properties list", jsonList.key().c_str());
jsonProps[jsonList.key()] = jsonList.value();
}
} else {
@@ -213,37 +298,51 @@ private:
}
void inject() {
LOGD("get 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 getSystemClassLoader = env->GetStaticMethodID(clClass, "getSystemClassLoader", "()Ljava/lang/ClassLoader;");
auto systemClassLoader = env->CallStaticObjectMethod(clClass, getSystemClassLoader);
LOGD("create class loader");
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 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("load class");
auto loadClass = env->GetMethodID(clClass, "loadClass",
"(Ljava/lang/String;)Ljava/lang/Class;");
auto entryClassName = env->NewStringUTF("es.chiteroman.playintegrityfix.EntryPoint");
LOGD("JNI %s: Loading module class", niceName);
auto loadClass = env->GetMethodID(clClass, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;");
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("read json");
auto readProps = env->GetStaticMethodID(entryClass, "readJson",
"(Ljava/lang/String;)V");
auto javaStr = env->NewStringUTF(json.dump().c_str());
env->CallStaticVoidMethod(entryClass, readProps, javaStr);
if (pkgName == VENDING_PACKAGE) {
LOGD("JNI %s: Calling EntryPointVending.init", niceName);
auto entryInit = env->GetStaticMethodID(entryClass, "init", "(IIILjava/lang/String;)V");
auto javaStr = env->NewStringUTF(vendingFingerprintValue.c_str());
env->CallStaticVoidMethod(entryClass, entryInit, verboseLogs, spoofVendingFinger, spoofVendingSdk, javaStr);
env->DeleteLocalRef(javaStr);
} else {
LOGD("JNI %s: Sending JSON", niceName);
auto receiveJson = env->GetStaticMethodID(entryClass, "receiveJson", "(Ljava/lang/String;)V");
auto javaStr = env->NewStringUTF(json.dump().c_str());
env->CallStaticVoidMethod(entryClass, receiveJson, javaStr);
LOGD("call init");
auto entryInit = env->GetStaticMethodID(entryClass, "init", "()V");
env->CallStaticVoidMethod(entryClass, entryInit);
LOGD("JNI %s: Calling EntryPoint.init", niceName);
auto entryInit = env->GetStaticMethodID(entryClass, "init", "(IIII)V");
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

@@ -0,0 +1,42 @@
package es.chiteroman.playintegrityfix;
import android.content.pm.PackageInfo;
import android.content.pm.Signature;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
public class CustomPackageInfoCreator implements Parcelable.Creator<PackageInfo> {
private final Parcelable.Creator<PackageInfo> originalCreator;
private final Signature spoofedSignature;
public CustomPackageInfoCreator(Parcelable.Creator<PackageInfo> originalCreator, Signature spoofedSignature) {
this.originalCreator = originalCreator;
this.spoofedSignature = spoofedSignature;
}
@Override
@SuppressWarnings("deprecation")
public PackageInfo createFromParcel(Parcel source) {
PackageInfo packageInfo = originalCreator.createFromParcel(source);
if (packageInfo.packageName.equals("android")) {
if (packageInfo.signatures != null && packageInfo.signatures.length > 0) {
packageInfo.signatures[0] = spoofedSignature;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
if (packageInfo.signingInfo != null) {
Signature[] signaturesArray = packageInfo.signingInfo.getApkContentsSigners();
if (signaturesArray != null && signaturesArray.length > 0) {
signaturesArray[0] = spoofedSignature;
}
}
}
}
return packageInfo;
}
@Override
public PackageInfo[] newArray(int size) {
return originalCreator.newArray(size);
}
}

View File

@@ -12,7 +12,10 @@ public final class CustomProvider extends Provider {
@Override
public synchronized Service getService(String type, String algorithm) {
EntryPoint.spoofDevice();
if (EntryPoint.getVerboseLogs() > 2) EntryPoint.LOG(String.format("Service: Caller type '%s' with algorithm '%s'", type, algorithm));
if (EntryPoint.getSpoofBuildEnabled() > 0) {
if (type.equals("KeyStore")) EntryPoint.spoofDevice();
}
return super.getService(type, algorithm);
}
}

View File

@@ -1,12 +1,21 @@
package es.chiteroman.playintegrityfix;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.Signature;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Base64;
import android.util.JsonReader;
import android.util.Log;
import org.lsposed.hiddenapibypass.HiddenApiBypass;
import java.io.IOException;
import java.io.StringReader;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.KeyStoreSpi;
@@ -17,15 +26,56 @@ import java.util.Map;
public final class EntryPoint {
private static Integer verboseLogs = 0;
private static Integer spoofBuildEnabled = 1;
private static final String signatureData = "MIIFyTCCA7GgAwIBAgIVALyxxl+zDS9SL68SzOr48309eAZyMA0GCSqGSIb3DQEBCwUAMHQxCzAJ\n" +
"BgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQw\n" +
"EgYDVQQKEwtHb29nbGUgSW5jLjEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDAg\n" +
"Fw0yMjExMDExODExMzVaGA8yMDUyMTEwMTE4MTEzNVowdDELMAkGA1UEBhMCVVMxEzARBgNVBAgT\n" +
"CkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50YWluIFZpZXcxFDASBgNVBAoTC0dvb2dsZSBJbmMu\n" +
"MRAwDgYDVQQLEwdBbmRyb2lkMRAwDgYDVQQDEwdBbmRyb2lkMIICIjANBgkqhkiG9w0BAQEFAAOC\n" +
"Ag8AMIICCgKCAgEAsqtalIy/nctKlrhd1UVoDffFGnDf9GLi0QQhsVoJkfF16vDDydZJOycG7/kQ\n" +
"ziRZhFdcoMrIYZzzw0ppBjsSe1AiWMuKXwTBaEtxN99S1xsJiW4/QMI6N6kMunydWRMsbJ6aAxi1\n" +
"lVq0bxSwr8Sg/8u9HGVivfdG8OpUM+qjuV5gey5xttNLK3BZDrAlco8RkJZryAD40flmJZrWXJmc\n" +
"r2HhJJUnqG4Z3MSziEgW1u1JnnY3f/BFdgYsA54SgdUGdQP3aqzSjIpGK01/vjrXvifHazSANjvl\n" +
"0AUE5i6AarMw2biEKB2ySUDp8idC5w12GpqDrhZ/QkW8yBSa87KbkMYXuRA2Gq1fYbQx3YJraw0U\n" +
"gZ4M3fFKpt6raxxM5j0sWHlULD7dAZMERvNESVrKG3tQ7B39WAD8QLGYc45DFEGOhKv5Fv8510h5\n" +
"sXK502IvGpI4FDwz2rbtAgJ0j+16db5wCSW5ThvNPhCheyciajc8dU1B5tJzZN/ksBpzne4Xf9gO\n" +
"LZ9ZU0+3Z5gHVvTS/YpxBFwiFpmL7dvGxew0cXGSsG5UTBlgr7i0SX0WhY4Djjo8IfPwrvvA0QaC\n" +
"FamdYXKqBsSHgEyXS9zgGIFPt2jWdhaS+sAa//5SXcWro0OdiKPuwEzLgj759ke1sHRnvO735dYn\n" +
"5whVbzlGyLBh3L0CAwEAAaNQME4wDAYDVR0TBAUwAwEB/zAdBgNVHQ4EFgQUU1eXQ7NoYKjvOQlh\n" +
"5V8jHQMoxA8wHwYDVR0jBBgwFoAUU1eXQ7NoYKjvOQlh5V8jHQMoxA8wDQYJKoZIhvcNAQELBQAD\n" +
"ggIBAHFIazRLs3itnZKllPnboSd6sHbzeJURKehx8GJPvIC+xWlwWyFO5+GHmgc3yh/SVd3Xja/k\n" +
"8Ud59WEYTjyJJWTw0Jygx37rHW7VGn2HDuy/x0D+els+S8HeLD1toPFMepjIXJn7nHLhtmzTPlDW\n" +
"DrhiaYsls/k5Izf89xYnI4euuOY2+1gsweJqFGfbznqyqy8xLyzoZ6bvBJtgeY+G3i/9Be14HseS\n" +
"Na4FvI1Oze/l2gUu1IXzN6DGWR/lxEyt+TncJfBGKbjafYrfSh3zsE4N3TU7BeOL5INirOMjre/j\n" +
"VgB1YQG5qLVaPoz6mdn75AbBBm5a5ahApLiKqzy/hP+1rWgw8Ikb7vbUqov/bnY3IlIU6XcPJTCD\n" +
"b9aRZQkStvYpQd82XTyxD/T0GgRLnUj5Uv6iZlikFx1KNj0YNS2T3gyvL++J9B0Y6gAkiG0EtNpl\n" +
"z7Pomsv5pVdmHVdKMjqWw5/6zYzVmu5cXFtR384Ti1qwML1xkD6TC3VIv88rKIEjrkY2c+v1frh9\n" +
"fRJ2OmzXmML9NgHTjEiJR2Ib2iNrMKxkuTIs9oxKZgrJtJKvdU9qJJKM5PnZuNuHhGs6A/9gt9Oc\n" +
"cetYeQvVSqeEmQluWfcunQn9C9Vwi2BJIiVJh4IdWZf5/e2PlSSQ9CJjz2bKI17pzdxOmjQfE0JS\n" +
"F7Xt\n";
private static final Map<String, String> map = new HashMap<>();
public static void init() {
spoofProvider();
spoofDevice();
public static Integer getVerboseLogs() {
return verboseLogs;
}
public static void readJson(String data) {
public static Integer getSpoofBuildEnabled() {
return spoofBuildEnabled;
}
public static void init(int logLevel, int spoofBuildVal, int spoofProviderVal, int spoofSignatureVal) {
verboseLogs = logLevel;
spoofBuildEnabled = spoofBuildVal;
if (verboseLogs > 99) logFields();
if (spoofProviderVal > 0) spoofProvider();
if (spoofBuildVal > 0) spoofDevice();
if (spoofSignatureVal > 0) spoofPackageManager();
}
public static void receiveJson(String data) {
try (JsonReader reader = new JsonReader(new StringReader(data))) {
reader.beginObject();
while (reader.hasNext()) {
@@ -68,13 +118,65 @@ public final class EntryPoint {
static void spoofDevice() {
for (String key : map.keySet()) {
// Verbose logging if VERBOSE_LOGS with level number is last entry
if (key.equals("VERBOSE_LOGS")) {
verboseLogs = Integer.parseInt(map.get("VERBOSE_LOGS"));
} else {
setField(key, map.get(key));
setField(key, map.get(key));
}
}
private static void spoofPackageManager() {
Signature spoofedSignature = new Signature(Base64.decode(signatureData, Base64.DEFAULT));
Parcelable.Creator<PackageInfo> originalCreator = PackageInfo.CREATOR;
Parcelable.Creator<PackageInfo> customCreator = new CustomPackageInfoCreator(originalCreator, spoofedSignature);
try {
Field creatorField = findField(PackageInfo.class, "CREATOR");
creatorField.setAccessible(true);
creatorField.set(null, customCreator);
} catch (Exception e) {
LOG("Couldn't replace PackageInfoCreator: " + e);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
HiddenApiBypass.addHiddenApiExemptions("Landroid/os/Parcel;", "Landroid/content/pm", "Landroid/app");
}
try {
Field cacheField = findField(PackageManager.class, "sPackageInfoCache");
cacheField.setAccessible(true);
Object cache = cacheField.get(null);
Method clearMethod = cache.getClass().getMethod("clear");
clearMethod.invoke(cache);
} catch (Exception e) {
LOG("Couldn't clear PackageInfoCache: " + e);
}
try {
Field creatorsField = findField(Parcel.class, "mCreators");
creatorsField.setAccessible(true);
Map<?, ?> mCreators = (Map<?, ?>) creatorsField.get(null);
mCreators.clear();
} catch (Exception e) {
LOG("Couldn't clear Parcel mCreators: " + e);
}
try {
Field creatorsField = findField(Parcel.class, "sPairedCreators");
creatorsField.setAccessible(true);
Map<?, ?> sPairedCreators = (Map<?, ?>) creatorsField.get(null);
sPairedCreators.clear();
} catch (Exception e) {
LOG("Couldn't clear Parcel sPairedCreators: " + e);
}
}
private static Field findField(Class<?> currentClass, String fieldName) throws NoSuchFieldException {
while (currentClass != null && !currentClass.equals(Object.class)) {
try {
return currentClass.getDeclaredField(fieldName);
} catch (NoSuchFieldException e) {
currentClass = currentClass.getSuperclass();
}
}
throw new NoSuchFieldException("Field '" + fieldName + "' not found in class hierarchy of " + currentClass.getName());
}
private static boolean classContainsField(Class className, String fieldName) {
@@ -86,7 +188,7 @@ public final class EntryPoint {
private static void setField(String name, String value) {
if (value.isEmpty()) {
LOG(String.format("%s is empty, skipping...", name));
LOG(String.format("%s is empty, skipping", name));
return;
}
@@ -141,7 +243,28 @@ public final class EntryPoint {
LOG(String.format("[%s]: %s -> %s", name, oldValue, value));
}
private static String logParseField(Field field) {
Object value = null;
String type = field.getType().getName();
String name = field.getName();
try {
value = field.get(null);
} catch (IllegalAccessException|NullPointerException e) {
return String.format("Couldn't access '%s' field value: " + e, name);
}
return String.format("<%s> %s: %s", type, name, String.valueOf(value));
}
private static void logFields() {
for (Field field : Build.class.getDeclaredFields()) {
LOG("Build " + logParseField(field));
}
for (Field field : Build.VERSION.class.getDeclaredFields()) {
LOG("Build.VERSION " + logParseField(field));
}
}
static void LOG(String msg) {
Log.d("PIF/Java", msg);
Log.d("PIF/Java:DG", msg);
}
}

View File

@@ -0,0 +1,62 @@
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 spoofVendingFinger, int spoofVendingSdk, String vendingFingerprintValue) {
// Only spoof FINGERPRINT to Play Store if not forcing Android <13 Play Integrity verdict
if (spoofVendingSdk < 1) {
if (spoofVendingFinger < 1) return;
String oldValue;
try {
Field field = Build.class.getDeclaredField("FINGERPRINT");
field.setAccessible(true);
oldValue = String.valueOf(field.get(null));
if (oldValue.equals(vendingFingerprintValue)) {
if (verboseLogs > 2) LOG(String.format("[FINGERPRINT]: %s (unchanged)", oldValue));
field.setAccessible(false);
return;
}
field.set(null, vendingFingerprintValue);
field.setAccessible(false);
LOG(String.format("[FINGERPRINT]: %s -> %s", oldValue, vendingFingerprintValue));
} catch (NoSuchFieldException e) {
LOG("FINGERPRINT field not found: " + e);
} catch (SecurityException | IllegalAccessException | IllegalArgumentException |
NullPointerException | ExceptionInInitializerError 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 {
id("com.android.application") version "8.2.0" apply false
id("com.android.application") version "8.13.0" apply false
}

View File

@@ -4,6 +4,8 @@
# any settings specified in this file.
# For more details on how to configure your build environment visit
# 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.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8

Binary file not shown.

View File

@@ -1,6 +1,7 @@
#Tue Oct 31 00:21:30 CET 2023
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-9.0.0-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

298
gradlew vendored
View File

@@ -1,7 +1,7 @@
#!/usr/bin/env sh
#!/bin/sh
#
# Copyright 2015 the original author or authors.
# Copyright © 2015 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -15,81 +15,115 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
#
##############################################################################
##
## Gradle start up script for UN*X
##
#
# Gradle start up script for POSIX generated by Gradle.
#
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
app_path=$0
# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# This is normally unused
# 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\n' "$PWD" ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
MAX_FD=maximum
warn () {
echo "$*"
}
} >&2
die () {
echo
echo "$*"
echo
exit 1
}
} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
case "$( uname )" in #(
CYGWIN* ) cygwin=true ;; #(
Darwin* ) darwin=true ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
CLASSPATH="\\\"\\\""
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
JAVACMD=$JAVA_HOME/jre/sh/java
else
JAVACMD="$JAVA_HOME/bin/java"
JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
@@ -98,88 +132,120 @@ Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
JAVACMD=java
if ! command -v java >/dev/null 2>&1
then
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=`expr $i + 1`
done
case $i in
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=`save "$@"`
# Collect all arguments for the java command, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done
fi
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command:
# * 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.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
"$@"
# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@"

183
gradlew.bat vendored
View File

@@ -1,89 +1,94 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@rem SPDX-License-Identifier: Apache-2.0
@rem
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
:execute
@rem Setup the command line
set CLASSPATH=
@rem Execute Gradle
"%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
if %ERRORLEVEL% equ 0 goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

View File

@@ -1 +1 @@
#MAGISK
#MAGISK

15
module/action.sh Normal file
View File

@@ -0,0 +1,15 @@
MODPATH="${0%/*}"
# ensure not running in busybox ash standalone shell
set +o standalone
unset ASH_STANDALONE
sh $MODPATH/autopif2.sh -s -m || exit 1
echo -e "\nDone!"
# 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

204
module/autopif2.sh Normal file
View File

@@ -0,0 +1,204 @@
#!/system/bin/sh
if [ "$USER" != "root" -a "$(whoami 2>/dev/null)" != "root" ]; then
echo "autopif2: need root permissions"; exit 1;
fi;
case "$HOME" in
*termux*) echo "autopif2: need su root environment"; exit 1;;
esac;
FORCE_TOP=1;
FORCE_DEPTH=1;
until [ -z "$1" ]; do
case "$1" in
-h|--help|help) echo "sh autopif2.sh [-a|-s] [-m] [-t #] [-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;;
-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;;
esac;
done;
echo "Pixel Beta pif.json generator script \
\n by osm0sis @ xda-developers";
case "$0" in
*.sh) DIR="$0";;
*) DIR="$(lsof -p $$ 2>/dev/null | grep -o '/.*autopif2.sh$')";;
esac;
DIR=$(dirname "$(readlink -f "$DIR")");
item() { echo "\n- $@"; }
die() { echo "\nError: $@, install busybox!"; exit 1; }
find_busybox() {
[ -n "$BUSYBOX" ] && return 0;
local path;
for path in /data/adb/modules/busybox-ndk/system/*/busybox /data/adb/magisk/busybox /data/adb/ksu/bin/busybox /data/adb/ap/bin/busybox; do
if [ -f "$path" ]; then
BUSYBOX="$path";
return 0;
fi;
done;
return 1;
}
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
die "wget broken";
else
wget() { $BUSYBOX wget "$@"; }
fi;
fi;
if date -D '%s' -d "$(date '+%s')" 2>&1 | grep -qE "bad date|invalid option"; then
if ! find_busybox; then
die "date broken";
else
date() { $BUSYBOX date "$@"; }
fi;
fi;
if ! echo "A\nB" | grep -m1 -A1 "A" | grep -q "B"; then
if ! find_busybox; then
die "grep broken";
else
grep() { $BUSYBOX grep "$@"; }
fi;
fi;
if [ "$DIR" = /data/adb/modules/playintegrityfix ]; then
DIR=$DIR/autopif2;
mkdir -p $DIR;
fi;
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 -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;
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;
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)";
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')";
echo "Beta Released: $BETA_REL_DATE \
\nEstimated Expiry: $BETA_EXP_DATE";
MODEL_LIST="$(grep -A1 'tr id=' PIXEL_OTA_HTML | grep 'td' | sed 's;.*<td>\(.*\)</td>;\1;')";
PRODUCT_LIST="$(grep -o 'ota/.*_beta' PIXEL_OTA_HTML | cut -d\/ -f2)";
OTA_LIST="$(grep 'ota/.*_beta' PIXEL_OTA_HTML | cut -d\" -f2)";
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() {
local list_count="$(echo "$MODEL_LIST" | wc -l)";
local list_rand="$((RANDOM % $list_count + 1))";
local IFS=$'\n';
set -- $MODEL_LIST;
MODEL="$(eval echo \${$list_rand})";
set -- $PRODUCT_LIST;
PRODUCT="$(eval echo \${$list_rand})";
set -- $OTA_LIST;
OTA="$(eval echo \${$list_rand})";
DEVICE="$(echo "$PRODUCT" | sed 's/_beta//')";
}
set_random_beta;
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 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
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;
fi;
item "Dumping values to minimal pif.json ...";
cat <<EOF | tee pif.json;
{
"MANUFACTURER": "Google",
"MODEL": "$MODEL",
"FINGERPRINT": "$FINGERPRINT",
"PRODUCT": "$PRODUCT",
"DEVICE": "$DEVICE",
"SECURITY_PATCH": "$SECURITY_PATCH",
"DEVICE_INITIAL_SDK_INT": "32"
}
EOF
for MIGRATE in migrate.sh /data/adb/modules/playintegrityfix/migrate.sh; do
[ -f "$MIGRATE" ] && break;
done;
if [ -f "$MIGRATE" ]; then
OLDJSON=/data/adb/modules/playintegrityfix/custom.pif.json;
if [ -f "$OLDJSON" ]; 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 spoofVendingFinger spoofVendingSdk verboseLogs";
for SETTING in $ADVSETTINGS; do
eval [ -z \"\$$SETTING\" ] \&\& $SETTING=$(grep_json "$SETTING" $OLDJSON);
eval TMPVAL=\$$SETTING;
[ -n "$TMPVAL" ] && sed -i "s;\($SETTING\": \"\).;\1$TMPVAL;" custom.pif.json;
done;
fi;
[ "$PATCH_COMMENT" ] && sed -i 's;"\*.security_patch";//"\*.security_patch";' custom.pif.json;
sed -i "s;};\n // Beta Released: $BETA_REL_DATE\n // Estimated Expiry: $BETA_EXP_DATE\n};" custom.pif.json;
cat custom.pif.json;
fi;
if [ "$DIR" = /data/adb/modules/playintegrityfix/autopif2 ]; then
if [ -f /data/adb/modules/playintegrityfix/migrate.sh ]; then
NEWNAME="custom.pif.json";
else
NEWNAME="pif.json";
fi;
if [ -f "../$NEWNAME" ]; then
item "Renaming old file to $NEWNAME.bak ...";
mv -fv ../$NEWNAME ../$NEWNAME.bak;
fi;
item "Installing new json ...";
cp -fv $NEWNAME ..;
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 -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 'system=' $TS_SECPAT && sed -i "s/system=.*/system=$(echo ${SECURITY_PATCH//-} | cut -c-6)/" $TS_SECPAT;
sed -i '$a\' $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;

84
module/common_func.sh Normal file
View File

@@ -0,0 +1,84 @@
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
# resetprop_hexpatch [-f|--force] <prop name> <new value>
resetprop_hexpatch() {
case "$1" in
-f|--force) local FORCE=1; shift;;
esac
local NAME="$1"
local NEWVALUE="$2"
local CURVALUE="$(resetprop "$NAME")"
[ ! "$NEWVALUE" -o ! "$CURVALUE" ] && return 1
[ "$NEWVALUE" = "$CURVALUE" -a ! "$FORCE" ] && return 2
local NEWLEN=${#NEWVALUE}
if [ -f /dev/__properties__ ]; then
local PROPFILE=/dev/__properties__
else
local PROPFILE="/dev/__properties__/$(resetprop -Z "$NAME")"
fi
[ ! -f "$PROPFILE" ] && return 3
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')"
printf "Patch '$NAME' to '$NEWVALUE' in '$PROPFILE' @ 0x%08x -> \n[0000??$NEWHEX]\n" $((NAMEOFFSET-96))
echo -ne "\x00\x00" \
| dd obs=1 count=2 seek=$((NAMEOFFSET-96)) conv=notrunc of="$PROPFILE"
echo -ne "$(printf "$NEWHEX" | sed -e 's/.\{2\}/&\\x/g' -e 's/^/\\x/' -e 's/\\x$//')" \
| dd obs=1 count=93 seek=$((NAMEOFFSET-93)) conv=notrunc of="$PROPFILE"
}
# resetprop_if_diff <prop name> <expected value>
resetprop_if_diff() {
local NAME="$1"
local EXPECTED="$2"
local CURRENT="$(resetprop "$NAME")"
[ -z "$CURRENT" ] || [ "$CURRENT" = "$EXPECTED" ] || $RESETPROP "$NAME" "$EXPECTED"
}
# resetprop_if_match <prop name> <value match string> <new value>
resetprop_if_match() {
local NAME="$1"
local CONTAINS="$2"
local VALUE="$3"
[[ "$(resetprop "$NAME")" = *"$CONTAINS"* ]] && $RESETPROP "$NAME" "$VALUE"
}
# stub for boot-time
if [ "$(getprop sys.boot_completed)" != "1" ]; then
ui_print() { return; }
fi

79
module/common_setup.sh Normal file
View File

@@ -0,0 +1,79 @@
# Remove any definitely conflicting modules that are installed
if [ -d /data/adb/modules/safetynet-fix ]; then
touch /data/adb/modules/safetynet-fix/remove
ui_print "! Universal SafetyNet Fix (USNF) module will be removed on next reboot"
fi
# Replace/hide conflicting custom ROM injection app folders/files to disable them
LIST=$MODPATH/example.app_replace.list
[ -f "$MODPATH/custom.app_replace.list" ] && LIST=$MODPATH/custom.app_replace.list
for APP in $(grep -v '^#' $LIST); do
if [ -e "$APP" ]; then
case $APP in
/system/*) ;;
*) PREFIX=/system;;
esac
HIDEPATH=$MODPATH$PREFIX$APP
if [ -d "$APP" ]; then
mkdir -p $HIDEPATH
if [ "$KSU" = "true" -o "$APATCH" = "true" ]; then
setfattr -n trusted.overlay.opaque -v y $HIDEPATH
else
touch $HIDEPATH/.replace
fi
else
mkdir -p $(dirname $HIDEPATH)
if [ "$KSU" = "true" -o "$APATCH" = "true" ]; then
mknod $HIDEPATH c 0 0
else
touch $HIDEPATH
fi
fi
case $APP in
*/overlay/*)
CFG=$(echo $APP | grep -oE '.*/overlay')/config/config.xml
if [ -f "$CFG" ]; then
if [ -d "$APP" ]; then
APK=$(readlink -f $APP/*.apk);
elif [[ "$APP" = *".apk" ]]; then
APK=$(readlink -f $APP);
fi
if [ -s "$APK" ]; then
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
mkdir -p $(dirname $HIDECFG)
cp -af $CFG $HIDECFG
fi
sed -i 's;<overlay \(package="'"$PKGNAME"'".*\) />;<!-- overlay \1 -->;' $HIDECFG
fi
fi
fi
;;
esac
if [[ -d "$APP" || "$APP" = *".apk" ]]; then
ui_print "! $(basename $APP .apk) ROM app disabled, please uninstall any user app versions/updates after next reboot"
[ "$HIDECFG" ] && ui_print "! + $PKGNAME entry commented out in copied overlay config"
fi
fi
done
# 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\]" || persistprop "$PROP" ""
done
fi
# 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

View File

@@ -1,32 +1,54 @@
# Error on < Android 8
if [ "$API" -lt 26 ]; then
abort "! You can't use this module on Android < 8.0"
# Allow a scripts-only mode for older Android (<10) which may not require the Zygisk components
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
[ -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/uninstall.sh
fi
# Remove/warn if conflicting modules are installed
if [ -d /data/adb/modules/safetynet-fix ]; then
touch /data/adb/modules/safetynet-fix/remove
ui_print "! Universal SafetyNet Fix (USNF) module will be removed on next reboot"
# Copy any disabled app files to updated module
if [ -d /data/adb/modules/playintegrityfix/system ]; then
ui_print "- Restoring disabled ROM apps configuration"
cp -afL /data/adb/modules/playintegrityfix/system $MODPATH
fi
# Copy any supported custom files to updated module
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
fi
done
# Warn if potentially conflicting modules are installed
if [ -d /data/adb/modules/MagiskHidePropsConf ]; then
ui_print "! MagiskHidePropsConfig (MHPC) module may cause issues with PIF"
fi
# Copy any custom.pif.json to updated module
if [ -f /data/adb/modules/playintegrityfix/custom.pif.json ]; then
ui_print "- Restoring custom.pif.json"
cp -af /data/adb/modules/playintegrityfix/custom.pif.json $MODPATH/custom.pif.json
# Run common tasks for installation and boot-time
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
ui_print " "
if [ -f "$MODPATH/custom.pif.json" ]; then
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 "- Running migration script on custom.pif.json:"
ui_print " "
chmod 755 $MODPATH/migrate.sh
sh $MODPATH/migrate.sh --install --force --advanced $MODPATH/custom.pif.json
ui_print " "
fi
fi
# Clean up any leftover files from previous deprecated methods
rm -f /data/data/com.google.android.gms/cache/pif.prop /data/data/com.google.android.gms/pif.prop
rm -f /data/data/com.google.android.gms/cache/pif.json /data/data/com.google.android.gms/pif.json
rm -f /data/data/com.google.android.gms/cache/pif.prop /data/data/com.google.android.gms/pif.prop \
/data/data/com.google.android.gms/cache/pif.json /data/data/com.google.android.gms/pif.json

View File

@@ -0,0 +1,25 @@
# Rename to custom.app_replace.list once customized
#
# Add conflicting custom ROM injection app folder/file paths to this list
# and they will be replaced/hidden systemlessly to disable them
# Xiaomi.eu
/product/app/XiaomiEUInject
/product/app/XiaomiEUInject-Stub
# EliteRoms
/system/app/EliteDevelopmentModule
/system/app/XInjectModule
# helluvaOS
/system_ext/app/helluvaProductDevice*
/system_ext/app/helluvaProductSecretStub
# hentaiOS
/system_ext/app/hentaiLewdbSVTDummy
# Evolution X
/system_ext/app/PifPrebuilt
# PixelOS, YAAP
/system_ext/overlay/CertifiedPropsOverlay.apk

View File

@@ -1,6 +1,8 @@
// Rename to custom.pif.json once completed
//
// See android.os.Build source for field value corresponding properties:
// These are the current suggested defaults but you may add as many other fields/properties as needed
//
// See android.os.Build source for all fields and field values' corresponding properties:
// https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/os/Build.java
{
@@ -22,5 +24,14 @@
// System Properties
"*.build.id": "", // for ro.build.id
"*.security_patch": "", // for ro.build.version.security_patch
"*api_level": "" // for 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"
}

13
module/killpi.sh Normal file
View 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;

View File

@@ -1,30 +1,56 @@
#!/bin/sh
N="
";
case "$1" in
install) INSTALL=1; shift;;
-h|--help|help) echo "sh migrate.sh [-f] [-o] [-a] [in-file] [out-file]"; exit 0;;
-i|--install|install) INSTALL=1; shift;;
*) echo "custom.pif.json migration script \
\n by osm0sis @ xda-developers \n";;
$N by osm0sis @ xda-developers $N";;
esac;
item() { echo "- $@"; }
die() { [ "$INSTALL" ] || echo "\n\n! $@"; exit 1; }
grep_get_json() { grep "$1" "$DIR/custom.pif.json" | cut -d\" -f4; }
grep_check_json() { grep -q "$1" "$DIR/custom.pif.json" && [ "$(grep_get_json "$1")" ]; }
die() { [ "$INSTALL" ] || echo "$N$N! $@"; exit 1; }
grep_get_json() {
local target="$FILE";
[ -n "$2" ] && target="$2";
eval set -- "$(cat "$target" | tr -d '\r\n' | grep -m1 -o "$1"'".*' | cut -d: -f2- | sed 's|//|#|g')";
echo "$1" | sed -e 's|"|\\\\\\"|g' -e 's|[,}]*$||';
}
grep_check_json() {
local target="$FILE";
[ -n "$2" ] && target="$2";
grep -q "$1" "$target" && [ "$(grep_get_json $1 "$target")" ];
}
until [ -z "$1" -o -f "$1" ]; do
case "$1" in
-f|--force|force) FORCE=1; shift;;
-o|--override|override) OVERRIDE=1; shift;;
-a|--advanced|advanced) ADVANCED=1; shift;;
*) die "Invalid argument/file not found: $1";;
esac;
done;
if [ -f "$1" ]; then
FILE="$1";
DIR="$1";
shift;
else
case "$0" in
*.sh) DIR="$0";;
*) DIR="$(lsof -p $$ 2>/dev/null | grep -o '/.*migrate.sh$')";;
*) DIR="$(lsof -p $$ 2>/dev/null | grep -o '/.*migrate.sh$')";;
esac;
fi;
DIR=$(dirname "$(readlink -f "$DIR")");
[ -z "$FILE" ] && FILE="$DIR/custom.pif.json";
[ -f "$DIR/custom.pif.json" ] || die "No custom.pif.json found";
OUT="$2";
[ -z "$OUT" ] && OUT="$DIR/custom.pif.json";
grep_check_json api_level && die "No migration required";
[ -f "$FILE" ] || die "No json file found";
grep_check_json api_level && [ ! "$FORCE" ] && die "No migration required";
[ "$INSTALL" ] || item "Parsing fields ...";
@@ -32,9 +58,13 @@ FPFIELDS="BRAND PRODUCT DEVICE RELEASE ID INCREMENTAL TYPE TAGS";
ALLFIELDS="MANUFACTURER MODEL FINGERPRINT $FPFIELDS SECURITY_PATCH DEVICE_INITIAL_SDK_INT";
for FIELD in $ALLFIELDS; do
eval $FIELD=\"$(grep_get_json \"$FIELD\")\";
eval $FIELD=\"$(grep_get_json $FIELD)\";
done;
if [ -n "$ID" ] && ! grep_check_json build.id; then
item 'Simple entry ID found, changing to ID field and "*.build.id" property ...';
fi;
if [ -z "$ID" ] && grep_check_json BUILD_ID; then
item 'Deprecated entry BUILD_ID found, changing to ID field and "*.build.id" property ...';
ID="$(grep_get_json BUILD_ID)";
@@ -45,48 +75,86 @@ if [ -n "$SECURITY_PATCH" ] && ! grep_check_json security_patch; then
fi;
if grep_check_json VNDK_VERSION; then
item 'Deprecated entry VNDK_VERSION found, changing to "*.vndk_version" property ...';
item 'Deprecated entry VNDK_VERSION found, changing to "*.vndk.version" property ...';
VNDK_VERSION="$(grep_get_json VNDK_VERSION)";
fi;
if [ -n "$DEVICE_INITIAL_SDK_INT" ] && ! grep_check_json api_level; then
item 'Simple entry DEVICE_INITIAL_SDK_INT found, changing to DEVICE_INITIAL_SDK_INT field and "*api_level" property ...';
fi;
if [ -z "$DEVICE_INITIAL_SDK_INT" ] && grep_check_json FIRST_API_LEVEL; then
item 'Deprecated entry FIRST_API_LEVEL found, changing to DEVICE_INITIAL_SDK_INT field and "*api_level" property ...';
DEVICE_INITIAL_SDK_INT="$(grep_get_json FIRST_API_LEVEL)";
fi;
if [ -z "$RELEASE" -o -z "$INCREMENTAL" -o -z "$TYPE" -o -z "$TAGS" ]; then
item "Missing default fields found, deriving from FINGERPRINT ...";
if [ -z "$RELEASE" -o -z "$INCREMENTAL" -o -z "$TYPE" -o -z "$TAGS" -o "$OVERRIDE" ]; then
if [ "$OVERRIDE" ]; then
item "Overriding values for fields derivable from FINGERPRINT ...";
else
item "Missing default fields found, deriving from FINGERPRINT ...";
fi;
IFS='/:' read F1 F2 F3 F4 F5 F6 F7 F8 <<EOF
$(grep_get_json FINGERPRINT)
EOF
i=1;
for FIELD in $FPFIELDS; do
eval [ -z "\$$FIELD" ] \&\& $FIELD=\"\$F$i\";
eval [ -z \"\$$FIELD\" -o \"$OVERRIDE\" ] \&\& $FIELD=\"\$F$i\";
i=$((i+1));
done;
fi;
if [ -z "$SECURITY_PATCH" -o "$SECURITY_PATCH" = "null" ]; then
item 'Missing required SECURITY_PATCH field and "*.security_patch" property value found, leaving empty ...';
unset SECURITY_PATCH;
fi;
if [ -z "$DEVICE_INITIAL_SDK_INT" -o "$DEVICE_INITIAL_SDK_INT" = "null" ]; then
item 'Missing required DEVICE_INITIAL_SDK_INT field and "*api_level" property value found, setting to 25 ...';
DEVICE_INITIAL_SDK_INT=25;
fi;
item "Renaming old file to custom.pif.json.bak ...";
mv -f "$DIR/custom.pif.json" "$DIR/custom.pif.json.bak";
ADVSETTINGS="spoofBuild spoofProps spoofProvider spoofSignature spoofVendingFinger spoofVendingSdk verboseLogs";
spoofBuild=1;
spoofProps=1;
spoofProvider=1;
spoofSignature=0;
spoofVendingFinger=0;
spoofVendingSdk=0;
verboseLogs=0;
if [ -f "$OUT" ]; then
item "Renaming old file to $(basename "$OUT").bak ...";
mv -f "$OUT" "$OUT.bak";
if grep -qE "verboseLogs|VERBOSE_LOGS" "$OUT.bak"; then
ADVANCED=1;
grep_check_json VERBOSE_LOGS "$OUT.bak" && verboseLogs="$(grep_get_json VERBOSE_LOGS "$OUT.bak")";
for SETTING in $ADVSETTINGS; do
eval grep_check_json $SETTING \"$OUT.bak\" \&\& $SETTING=\"$(grep_get_json $SETTING "$OUT.bak")\";
done;
grep -q '//"\*.security_patch"' "$OUT.bak" && SECURITY_COMMENT='//';
fi;
fi;
[ "$INSTALL" ] || item "Writing fields and properties to updated custom.pif.json ...";
[ "$ADVANCED" ] && item "Adding Advanced Settings entries ...";
(echo "{";
echo " // Build Fields";
for FIELD in $ALLFIELDS; do
eval echo '\ \ \ \ \"$FIELD\": \"'\$$FIELD'\",';
done;
echo -e "\n // System Properties";
echo "$N // System Properties";
echo ' "*.build.id": "'$ID'",';
echo ' "*.security_patch": "'$SECURITY_PATCH'",';
[ -z "$VNDK_VERSION" ] || echo ' "*.vndk_version": "'$VNDK_VERSION'",';
echo ' "*api_level": "'$DEVICE_INITIAL_SDK_INT'"';
echo "}") > "$DIR/custom.pif.json";
[ "$INSTALL" ] || cat "$DIR/custom.pif.json";
echo " $SECURITY_COMMENT"'"*.security_patch": "'$SECURITY_PATCH'",';
[ -z "$VNDK_VERSION" ] || echo ' "*.vndk.version": "'$VNDK_VERSION'",';
echo ' "*api_level": "'$DEVICE_INITIAL_SDK_INT'",';
if [ "$ADVANCED" ]; then
echo "$N // Advanced Settings";
for SETTING in $ADVSETTINGS; do
eval echo '\ \ \ \ \"$SETTING\": \"'\$$SETTING'\",';
done;
fi) | sed '$s/,/\n}/' > "$OUT";
[ "$INSTALL" ] || cat "$OUT";

View File

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

View File

@@ -1,43 +1,49 @@
# Remove Play Services from Magisk Denylist when set to enforcing
if magisk --denylist status; then
magisk --denylist rm com.google.android.gms
fi
MODPATH="${0%/*}"
. $MODPATH/common_func.sh
# Remove conflicting modules if installed
if [ -d /data/adb/modules/safetynet-fix ]; then
touch /data/adb/modules/safetynet-fix/remove
if [ -d "$MODPATH/zygisk" ]; then
# 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 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
resetprop_if_diff() {
local NAME=$1
local EXPECTED=$2
local CURRENT=$(resetprop $NAME)
[ -z "$CURRENT" ] || [ "$CURRENT" == "$EXPECTED" ] || resetprop $NAME $EXPECTED
}
resetprop_if_match() {
local NAME=$1
local CONTAINS=$2
local VALUE=$3
[[ "$(resetprop $NAME)" == *"$CONTAINS"* ]] && resetprop $NAME $VALUE
}
# RootBeer, Microsoft
resetprop_if_diff ro.build.tags release-keys
# Samsung
resetprop_if_diff ro.boot.warranty_bit 0
resetprop_if_diff ro.vendor.boot.warranty_bit 0
resetprop_if_diff ro.vendor.warranty_bit 0
resetprop_if_diff ro.warranty_bit 0
# Realme
resetprop_if_diff ro.boot.realmebootstate green
# OnePlus
resetprop_if_diff ro.is_ever_orange 0
# Microsoft
for PROP in $(resetprop | grep -oE 'ro.*.build.tags'); do
resetprop_if_diff $PROP release-keys
done
# Other
resetprop_if_diff ro.build.type user
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

View File

@@ -1,53 +1,49 @@
MODPATH="${0%/*}"
. $MODPATH/common_func.sh
# Conditional sensitive properties
resetprop_if_diff() {
local NAME=$1
local EXPECTED=$2
local CURRENT=$(resetprop $NAME)
[ -z "$CURRENT" ] || [ "$CURRENT" == "$EXPECTED" ] || resetprop $NAME $EXPECTED
}
resetprop_if_match() {
local NAME=$1
local CONTAINS=$2
local VALUE=$3
[[ "$(resetprop $NAME)" == *"$CONTAINS"* ]] && resetprop $NAME $VALUE
}
# Magisk recovery mode
resetprop_if_match ro.bootmode recovery unknown
# Magisk Recovery Mode
resetprop_if_match ro.boot.mode recovery unknown
resetprop_if_match ro.bootmode recovery unknown
resetprop_if_match vendor.boot.mode recovery unknown
# SELinux
if [ -n "$(resetprop ro.build.selinux)" ]; then
resetprop --delete ro.build.selinux
resetprop_if_diff ro.boot.selinux enforcing
# use delete since it can be 0 or 1 for enforcing depending on OEM
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
# use toybox to protect stat access time reading
if [ "$(toybox cat /sys/fs/selinux/enforce)" = "0" ]; then
chmod 640 /sys/fs/selinux/enforce
chmod 440 /sys/fs/selinux/policy
fi
# SafetyNet/Play Integrity
# Conditional late sensitive properties
# must be set after boot_completed for various OEMs
{
# late props which must be set after boot_completed for various OEMs
until [ "$(getprop sys.boot_completed)" == "1" ]; do
sleep 1
done
until [ "$(getprop sys.boot_completed)" = "1" ]; do
sleep 1
done
# Avoid breaking Realme fingerprint scanners
resetprop_if_diff ro.boot.flash.locked 1
# SafetyNet/Play Integrity + OEM
# avoid bootloop on some Xiaomi devices
resetprop_if_diff ro.secureboot.lockstate locked
# avoid breaking Realme fingerprint scanners
resetprop_if_diff ro.boot.flash.locked 1
resetprop_if_diff ro.boot.realme.lockstate 1
# avoid breaking Oppo fingerprint scanners
resetprop_if_diff ro.boot.vbmeta.device_state locked
# avoid breaking OnePlus display modes/fingerprint scanners
resetprop_if_diff vendor.boot.verifiedbootstate green
# avoid breaking OnePlus/Oppo fingerprint scanners on OOS/ColorOS 12+
resetprop_if_diff ro.boot.verifiedbootstate green
resetprop_if_diff ro.boot.veritymode enforcing
resetprop_if_diff vendor.boot.vbmeta.device_state locked
# Avoid breaking Oppo fingerprint scanners
resetprop_if_diff ro.boot.vbmeta.device_state locked
# Other
resetprop_if_diff sys.oem_unlock_allowed 0
# Avoid breaking OnePlus display modes/fingerprint scanners
resetprop_if_diff vendor.boot.verifiedbootstate green
# Avoid breaking OnePlus/Oppo display fingerprint scanners on OOS/ColorOS 12+
resetprop_if_diff ro.boot.verifiedbootstate green
resetprop_if_diff ro.boot.veritymode enforcing
resetprop_if_diff vendor.boot.vbmeta.device_state locked
}&

View File

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