177 Commits

Author SHA1 Message Date
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
35 changed files with 794 additions and 25047 deletions

View File

@@ -1,6 +1,7 @@
name: Android CI
on:
workflow_dispatch:
push:
branches: main
paths-ignore: '**.md'
@@ -11,7 +12,7 @@ on:
jobs:
build:
runs-on: macos-14
runs-on: macos-15
steps:
- name: Check out
@@ -30,7 +31,7 @@ jobs:
run: chmod +x gradlew
- name: Build with Gradle
run: ./gradlew assembleRelease
run: ./gradlew --warning-mode all assembleRelease
- name: Upload CI module zip as artifact zip
uses: actions/upload-artifact@v4

5
.gitmodules vendored
View File

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

View File

@@ -1,16 +1,23 @@
## Custom Fork v9
- Improve migrate script handling of some formatting edge cases
- Add migrate script manual option to override all values using the fingerprint values
- Add an opt-in scripts-only-mode for Android <10 ROMs
- Add autopif script to allow extracting the latest Xiaomi.eu custom.pif.json values
- Add killgms script to allow manual DroidGuard process killing
## Custom Fork v13
## Custom Fork v8
- Rename VERBOSE_LOGS to verboseLogs to better differentiate Advanced Settings from Build Fields or System Properties
- Improve replace list to also allow file paths replacing/hiding systemlessly
- Improve migration script and add optional verboseLogs entry to output
- Improve replace list to automatically comment out any overlay APK config.xml entries systemlessly
- Update default/example app replace list for more ROM spoof injection methods
- Fix retaining disabled ROM apps through module updates in some scenarios
- Improve Action on KSU/APatch, KSU-Next, MMRL
- Improve autopif2 to ignore Preview builds by default
- Remove unnecessary adb props spoof
- Add all known opt-out props for PPU/PIH variants/hybrids
- Add new verified boot error props deletion
- Update killgms to killpi by adding vending
- Improve autopif2 to populate TS's optional security_patch.txt
- Improve ROM overlay xml disabling support
- Improve autopif2 for wget2 on arm
- Improve Action to use Platform Preview builds
## Custom Fork v12
- Improve autopif2 to generate from Pixel Beta point releases
- Improve autopif2 to catch more broken environments
- Improve migrate parsing lines with comments
- Update default app replace list for helluvaOS
- Fix retaining replaced non-system ROM apps on KSU/APatch
- Add autopif2 --strong for initial setup with TS
- Add skipping prop deletion to avoid app detections if skipdelprop file exists
_[Previous changelogs](https://github.com/osm0sis/PlayIntegrityFork/releases)_

View File

@@ -6,27 +6,26 @@
[![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 Android <13 "deviceRecognitionVerdict" with the Play Integrity API.
To use this module you must have one of the following (latest versions):
- [Magisk](https://github.com/topjohnwu/Magisk) with Zygisk enabled (and Enforce DenyList enabled if NOT also using [Shamiko](https://github.com/LSPosed/LSPosed.github.io/releases) or [Zygisk Assistant](https://github.com/snake-4/Zygisk-Assistant), for best results)
- [Magisk](https://github.com/topjohnwu/Magisk) with Zygisk enabled (and Enforce DenyList enabled if NOT also using [Shamiko](https://github.com/LSPosed/LSPosed.github.io/releases) or [Zygisk Assistant](https://github.com/snake-4/Zygisk-Assistant) or [NoHello](https://github.com/MhmRdd/NoHello), for best results)
- [KernelSU](https://github.com/tiann/KernelSU) with [Zygisk Next](https://github.com/Dr-TSNG/ZygiskNext) module installed
- [KernelSU Next](https://github.com/KernelSU-Next/KernelSU-Next) with [Zygisk Next](https://github.com/Dr-TSNG/ZygiskNext) module installed
- [APatch](https://github.com/bmax121/APatch) with [Zygisk Next](https://github.com/Dr-TSNG/ZygiskNext) module installed
## About module
It injects a classes.dex file to modify fields in the android.os.Build class. Also, it creates a hook in the native code to modify system properties. These are spoofed only to Google Play Services' DroidGuard (SafetyNet/Play Integrity) service.
The purpose of the module is to avoid hardware attestation.
It injects a classes.dex file to modify fields in the android.os.Build class. Also, it creates a hook in the native code to modify system properties. These are spoofed only to Google Play Services' DroidGuard (Play Integrity) service.
## About 'custom.pif.json' file
You can fill out the included template [example.pif.json](https://raw.githubusercontent.com/osm0sis/PlayIntegrityFork/main/module/example.pif.json) from the module directory (/data/adb/modules/playintegrityfix) then rename it to custom.pif.json to spoof custom values to the GMS unstable process. It will be used instead of any included pif.json (none included currently).
Note this is just a template with the current suggested defaults, but with this fork you can include as few or as many android.os.Build class fields and Android system properties as needed to pass DEVICE verdict now and in the future if the enforced checks by Play Integrity change.
Note this is just a template with the current suggested default entries, but with this fork you can include as few or as many android.os.Build class fields and Android system properties as needed to pass DEVICE verdict now and in the future if the enforced checks by Play Integrity change.
As a general rule you can't use values from recent devices due to them only being allowed with full hardware backed attestation. A script to extract the latest Xiaomi.eu public fingerprint is included with the module; see the autopif section below for usage and caveats, and see the Resources below for information and scripts to help find a working private fingerprint.
As a general rule you can't use values from recent devices due to them only being allowed with full hardware backed attestation. A script to extract the latest Pixel Beta fingerprint is included with the module; see the autopif2 section below for usage and caveats, and see the Resources below for information and scripts to help find a working private fingerprint.
Older formatted custom.pif.json files from cross-forks and previous releases will be automatically migrated to the latest format. Simply ensure the filename is custom.pif.json and place it in the module directory before upgrading.
@@ -46,37 +45,44 @@ A migration may also be performed manually with `sh migrate.sh` and custom.pif.j
- 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
- [pif-test-json-file.sh](https://xdaforums.com/t/tools-zips-scripts-osm0sis-odds-and-ends-multiple-devices-platforms.2239421/post-89482876) - Script to automate generating and testing json files to attempt to find working fingerprints
- [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) from the module directory (/data/adb/modules/playintegrityfix) then rename it to custom.app_replace.list to systemlessly replace any additional conflicting custom ROM spoof injection app paths to disable them.
## About 'autopif.sh' and 'killgms.sh' script files
## About 'autopif2.sh' and 'killpi.sh' script files
There's intentionally no custom./pif.json in my fork by default, because the goal remains to be futureproof, and including something that could/will be banned and obsolete the next day would be contrary to that goal. If you don't care to have your own private fingerprint to use or don't have time to look for one currently then simply run the extraction script from a root prompt with `sh autopif.sh` in the module directory (/data/adb/playintegrityfix/), or from a file explorer app that supports script execution.
There's intentionally no pif.json in the module because the goal remains to be futureproof, and including something that may be banned and obsolete within days would be contrary to that goal. If you don't care to have your own private fingerprint to use or don't have time to look for one currently (since very few remain) then simply run the generation script from a root manager app that supports the module Action button, a root prompt with `sh autopif2.sh --preview` in the module directory (/data/adb/modules/playintegrityfix), or from a file explorer app that supports script execution. For arm/x86 devices wget2 is required but may be installed via [addon module](https://xdaforums.com/t/tools-zips-scripts-osm0sis-odds-and-ends-multiple-devices-platforms.2239421/post-89991315).
The autopif script extracts the latest working Xiaomi.eu fingerprint (though frequently banned and may be banned for RCS use while otherwise passing Play Integrity and SafetyNet) to test an initial setup.
The autopif2 script generates a random device fingerprint from the latest Pixel Beta, ideally only to test an initial setup, since they expire roughly every 6 weeks from the Pixel Beta release date (dates included in the generated fingerprint), and the public mass-used ones from other modules or ROMs may also get banned or may be banned for RCS use while otherwise passing Play Integrity in that time. Notable advanced commandline options are: `-p` or `--preview` forces not to ignore Android Platform Preview builds (Developer Previews and Betas); and `-d #` or `--depth #` chooses the depth to crawl down the QPR Betas list when there are multiple active Betas, e.g. when QPR2 is concurrent with QPR1 the default value of 1 would get the first listed (QPR2) and `-d 2` would force it to get the second listed (QPR1).
The killgms script forces the Google Play Services DroidGuard process (com.google.android.gms.unstable) to end, making it restart with the next attestation attempt; useful for testing out different private fingerprints without requiring a reboot in between.
The killpi script forces the Google Play Services DroidGuard (com.google.android.gms.unstable) and Play Store (com.android.vending) processes to end, making them restart with the next attestation attempt; useful for testing out different fingerprints without requiring a reboot in between.
## Troubleshooting
Make sure Google Play Services (com.google.android.gms) is NOT on the Magisk DenyList if Enforce DenyList is enabled since this interferes with the module; the module does prevent this using scripts but it only happens once during each reboot.
Note: The below verdicts are all referring to the Android <13 deviceRecognitionVerdict Play Integrity API, not the Android 13+ deviceRecognitionVerdict (which relies on locked bootloader checks to pass even DEVICE verdict).
### Failing BASIC verdict
If you are failing basicIntegrity (SafetyNet) or MEETS_BASIC_INTEGRITY (Play Integrity) something is wrong in your setup. Recommended steps in order to find the problem:
If you are failing MEETS_BASIC_INTEGRITY something is wrong in your setup. Recommended steps in order to find the problem:
- Disable all modules except this one
- Try a different (ideally known working) custom.pif.json
Note: Some modules which modify system (e.g. Xposed) can trigger DroidGuard detections, as can any which hook GMS processes (e.g. custom fonts).
### Failing DEVICE verdict (on KernelSU/APatch)
### Failing DEVICE verdict (on KernelSU/KernelSU Next/APatch)
- Disable Zygisk Next
- Reboot
@@ -92,7 +98,8 @@ Note: Some modules which modify system (e.g. Xposed) can trigger DroidGuard dete
### Failing DEVICE verdict (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 you to update to it without requiring a data wipe
- If the output shows the ROM is signed with the AOSP testkey then inform your ROM maintainer to start signing their builds with a private key for their next build and ideally also provide a ROM signature migration build to allow users to update to it without requiring a data wipe
- 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 and/or Google Wallet Tap To Pay Setup Security Requirements
@@ -115,15 +122,30 @@ Add a "verboseLogs" entry with a value of "0", "1", "2", "3" or "100" to your cu
## Can this module pass MEETS_STRONG_INTEGRITY?
No.
No...
## About Play Integrity (SafetyNet is deprecated)
## About spoofing Advanced Settings
[Play Integrity API](https://xdaforums.com/t/info-play-integrity-api-replacement-for-safetynet.4479337/) - FAQ/information about PI (Play Integrity) replacing SN (SafetyNet)
The advanced spoofing options add granular control over what exactly gets spoofed, allowing one to disable the parts that may conflict with other kinds of spoofing modules, and provide an option to work around the testkey ROM ban for those needing that feature. See more in the Details area below.
<details>
<summary><strong>Details</strong></summary>
- Adding the Advanced Settings entries is best done using the migration script with the `sh migrate.sh --force --advanced` or `sh migrate.sh -f -a` command. They may also be added on initial setups using the `sh autopif2.sh --advanced --preview` or `sh autopif2.sh -a -p` command or configured directly for Tricky Store to achieve <A13 STRONG or A13+ DEVICE or STRONG integrity (see below) with the `sh autopif2.sh --strong --preview` or `sh autopif2.sh -s -p` command. Other than for the "verboseLogs" entry (see above), they are all 0 (disabled) or 1 (enabled).
- The "spoofBuild" entry (default 1) controls spoofing the Build Fields from the fingerprint; the "spoofProps" entry (default 1) controls spoofing the System Properties from the fingerprint; the "spoofProvider" entry (default 1) controls spoofing the Keystore Provider; the "spoofSignature" entry (default 0) controls spoofing the ROM Signature, and the "spoofVendingSdk" entry (default 0) controls spoofing ROM SDK_INT/sdkVersion 32 to the Play Store (com.android.vending) to force Play Integrity to use the <A13 verdicts.
- Leaving spoofVendingSdk enabled is NOT recommended, it [will break](https://github.com/osm0sis/PlayIntegrityFork/pull/30) the behavior of the Play Store to some extent (back gesture/navbar button for all, account sign-in and downloads for higher original ROM SDK_INT) and could have other unintended effects like incorrect app variants being served, crashes, etc. One possible use case is with the [spoofVendingSdk QSTile](https://xdaforums.com/t/tricky-store-bootloader-keybox-spoofing.4683446/post-90118016) Tasker App to quickly toggle it on only as needed, then toggle it off again afterward.
- For spoofing locked bootloader and attempting to pass Play Integrity <A13 STRONG or A13+ DEVICE or STRONG verdict I only recommend using the latest official [Tricky Store](https://github.com/5ec1cff/TrickyStore) build.
- Note: Using Tricky Store to achieve <A13 STRONG or A13+ DEVICE or STRONG integrity (with an unrevoked hardware keybox.xml) requires the Advanced Settings "spoofProvider" disabled and the "*.security_patch" entry commented out (unless spoofing a matching OS Patch Level with system= or all= in Tricky Store's security_patch.txt; autopif2 will do this automatically if security_patch.txt exists in the Tricky Store directory), but to achieve <A13 DEVICE integrity (with Tricky Store default AOSP software keybox.xml) requires at least "spoofProps" enabled, and some fingerprints may also require "spoofProvider". More known working private fingerprints can achieve <A13 DEVICE/STRONG integrity on more devices using these Advanced Settings in conjunction with Tricky Store than was possible with Tricky Store alone since they require fingerprint props spoofing.
</details>
## About Scripts-only mode
An advanced mode intended for older Android <10 stock ROMs or those with stock-like values, (and some other rare special cases,) since they generally only need a few prop changes to pass Play Integrity DEVICE verdict. Due to this the majority of the previous information does not apply to or contradicts that of Scripts-only mode, so to avoid confusion it's contained in the Details area below.
An advanced feature intended for older Android <10 ROMs, mostly stock ROMs or those with stock-like values, (and some other rare special cases), since they generally only need a few prop changes to pass Play Integrity <A13 DEVICE verdict. Due to this the majority of the previous information does not apply to or contradicts that of Scripts-only mode, so to avoid confusion it's contained in the Details area below.
<details>
<summary><strong>Details</strong></summary>
@@ -136,6 +158,20 @@ An advanced mode intended for older Android <10 stock ROMs or those with stock-l
</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 scripts adapted from those of Displax's forked Universal SafetyNet Fix (USNF MOD) module; please see the commit history of [Displax's USNF MOD](https://github.com/Displax/safetynet-fix/tree/dev/magisk) for proper attribution.

View File

@@ -4,9 +4,9 @@ plugins {
android {
namespace = "es.chiteroman.playintegrityfix"
compileSdk = 34
ndkVersion = "26.3.11579264"
buildToolsVersion = "34.0.0"
compileSdk = 36
ndkVersion = "28.1.13356709"
buildToolsVersion = "36.0.0"
buildFeatures {
prefab = true
@@ -22,7 +22,7 @@ android {
defaultConfig {
applicationId = "es.chiteroman.playintegrityfix"
minSdk = 26
targetSdk = 34
targetSdk = 36
versionCode = 1
versionName = "1.0"
@@ -62,15 +62,16 @@ android {
}
dependencies {
implementation("dev.rikka.ndk.thirdparty:cxx:1.2.0")
implementation("org.lsposed.libcxx:libcxx:28.1.13356709")
implementation("org.lsposed.hiddenapibypass:hiddenapibypass:6.1")
}
tasks.register("copyFiles") {
doLast {
val moduleFolder = project.rootDir.resolve("module")
val dexFile = project.layout.buildDirectory.get().asFile.resolve("intermediates/dex/release/minifyReleaseWithR8/classes.dex")
val soDir = project.layout.buildDirectory.get().asFile.resolve("intermediates/stripped_native_libs/release/stripReleaseDebugSymbols/out/lib")
val moduleFolder = project.rootDir.resolve("module")
val dexFile = project.layout.buildDirectory.get().asFile.resolve("intermediates/dex/release/minifyReleaseWithR8/classes.dex")
val soDir = project.layout.buildDirectory.get().asFile.resolve("intermediates/stripped_native_libs/release/stripReleaseDebugSymbols/out/lib")
doLast {
dexFile.copyTo(moduleFolder.resolve("classes.dex"), overwrite = true)
soDir.walk().filter { it.isFile && it.extension == "so" }.forEach { soFile ->

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,6 +1,6 @@
cmake_minimum_required(VERSION 3.22.1)
project(zygisk)
project(playintegrityfix)
find_package(cxx REQUIRED CONFIG)

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,7 +3,7 @@
#include <unistd.h>
#include "zygisk.hpp"
#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__)
@@ -12,8 +12,15 @@
#define JSON_FILE_PATH "/data/adb/modules/playintegrityfix/pif.json"
#define CUSTOM_JSON_FILE_PATH "/data/adb/modules/playintegrityfix/custom.pif.json"
#define VENDING_PACKAGE "com.android.vending"
#define DROIDGUARD_PACKAGE "com.google.android.gms.unstable"
static int verboseLogs = 0;
static int spoofBuild = 1;
static int spoofProps = 1;
static int spoofProvider = 1;
static int spoofSignature = 0;
static int spoofVendingSdk = 0;
static std::map<std::string, std::string> jsonProps;
@@ -28,13 +35,6 @@ static void modify_callback(void *cookie, const char *name, const char *value, u
std::string prop(name);
// Spoof specific property values
if (prop == "init.svc.adbd") {
value = "stopped";
} else if (prop == "sys.usb.state") {
value = "mtp";
}
if (jsonProps.count(prop)) {
// Exact property match
value = jsonProps[prop].c_str();
@@ -86,7 +86,7 @@ public:
}
void preAppSpecialize(zygisk::AppSpecializeArgs *args) override {
bool isGms = false, isGmsUnstable = false;
bool isGms = false, isDroidGuardOrVending = false;
auto rawProcess = env->GetStringUTFChars(args->nice_name, nullptr);
auto rawDir = env->GetStringUTFChars(args->app_data_dir, nullptr);
@@ -98,11 +98,11 @@ public:
return;
}
std::string_view process(rawProcess);
pkgName = rawProcess;
std::string_view dir(rawDir);
isGms = dir.ends_with("/com.google.android.gms");
isGmsUnstable = process == "com.google.android.gms.unstable";
isGms = dir.ends_with("/com.google.android.gms") || dir.ends_with("/com.android.vending");
isDroidGuardOrVending = pkgName == DROIDGUARD_PACKAGE || pkgName == VENDING_PACKAGE;
env->ReleaseStringUTFChars(args->nice_name, rawProcess);
env->ReleaseStringUTFChars(args->app_data_dir, rawDir);
@@ -115,7 +115,7 @@ public:
// We are in GMS now, force unmount
api->setOption(zygisk::FORCE_DENYLIST_UNMOUNT);
if (!isGmsUnstable) {
if (!isDroidGuardOrVending) {
api->setOption(zygisk::DLCLOSE_MODULE_LIBRARY);
return;
}
@@ -164,8 +164,12 @@ public:
if (dexVector.empty() || json.empty()) return;
readJson();
doHook();
inject();
if (pkgName == VENDING_PACKAGE) spoofProps = spoofBuild = spoofProvider = spoofSignature = 0;
else spoofVendingSdk = 0;
if (spoofProps > 0) doHook();
if (spoofBuild + spoofProvider + spoofSignature + spoofVendingSdk > 0) inject();
dexVector.clear();
json.clear();
@@ -180,11 +184,12 @@ private:
JNIEnv *env = nullptr;
std::vector<char> dexVector;
nlohmann::json json;
std::string pkgName;
void readJson() {
LOGD("JSON contains %d keys!", static_cast<int>(json.size()));
// Verbose logging if verboseLogs with level number is present
// 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>());
@@ -195,6 +200,57 @@ private:
json.erase("verboseLogs");
}
// Advanced spoofing settings
if (json.contains("spoofVendingSdk")) {
if (!json["spoofVendingSdk"].is_null() && json["spoofVendingSdk"].is_string() && json["spoofVendingSdk"] != "") {
spoofVendingSdk = stoi(json["spoofVendingSdk"].get<std::string>());
if (verboseLogs > 0) LOGD("Spoofing SDK Level in Play Store %s!", (spoofVendingSdk > 0) ? "enabled" : "disabled");
} else {
LOGD("Error parsing spoofVendingSdk!");
}
json.erase("spoofVendingSdk");
}
if (pkgName == VENDING_PACKAGE) {
json.clear();
return;
}
if (json.contains("spoofBuild")) {
if (!json["spoofBuild"].is_null() && json["spoofBuild"].is_string() && json["spoofBuild"] != "") {
spoofBuild = stoi(json["spoofBuild"].get<std::string>());
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 (verboseLogs > 1) LOGD("Parsing %s", jsonList.key().c_str());
@@ -220,32 +276,41 @@ private:
}
void inject() {
LOGD("JNI: Getting system classloader");
const char* niceName = pkgName == VENDING_PACKAGE ? "PS" : "DG";
LOGD("JNI %s: Getting system classloader", niceName);
auto clClass = env->FindClass("java/lang/ClassLoader");
auto getSystemClassLoader = env->GetStaticMethodID(clClass, "getSystemClassLoader", "()Ljava/lang/ClassLoader;");
auto systemClassLoader = env->CallStaticObjectMethod(clClass, getSystemClassLoader);
LOGD("JNI: Creating module classloader");
LOGD("JNI %s: Creating module classloader", niceName);
auto dexClClass = env->FindClass("dalvik/system/InMemoryDexClassLoader");
auto dexClInit = env->GetMethodID(dexClClass, "<init>", "(Ljava/nio/ByteBuffer;Ljava/lang/ClassLoader;)V");
auto buffer = env->NewDirectByteBuffer(dexVector.data(), static_cast<jlong>(dexVector.size()));
auto dexCl = env->NewObject(dexClClass, dexClInit, buffer, systemClassLoader);
LOGD("JNI: Loading module class");
LOGD("JNI %s: Loading module class", niceName);
auto loadClass = env->GetMethodID(clClass, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;");
auto entryClassName = env->NewStringUTF("es.chiteroman.playintegrityfix.EntryPoint");
const char* className = pkgName == VENDING_PACKAGE ? "es.chiteroman.playintegrityfix.EntryPointVending" : "es.chiteroman.playintegrityfix.EntryPoint";
auto entryClassName = env->NewStringUTF(className);
auto entryClassObj = env->CallObjectMethod(dexCl, loadClass, entryClassName);
auto entryClass = (jclass) entryClassObj;
LOGD("JNI: Sending JSON");
auto receiveJson = env->GetStaticMethodID(entryClass, "receiveJson", "(Ljava/lang/String;)V");
auto javaStr = env->NewStringUTF(json.dump().c_str());
env->CallStaticVoidMethod(entryClass, receiveJson, javaStr);
if (pkgName == VENDING_PACKAGE) {
LOGD("JNI %s: Calling EntryPointVending.init", niceName);
auto entryInit = env->GetStaticMethodID(entryClass, "init", "(II)V");
env->CallStaticVoidMethod(entryClass, entryInit, verboseLogs, spoofVendingSdk);
} else {
LOGD("JNI %s: Sending JSON", niceName);
auto receiveJson = env->GetStaticMethodID(entryClass, "receiveJson", "(Ljava/lang/String;)V");
auto javaStr = env->NewStringUTF(json.dump().c_str());
env->CallStaticVoidMethod(entryClass, receiveJson, javaStr);
LOGD("JNI: Calling init");
auto entryInit = env->GetStaticMethodID(entryClass, "init", "(I)V");
env->CallStaticVoidMethod(entryClass, entryInit, verboseLogs);
LOGD("JNI %s: Calling EntryPoint.init", niceName);
auto entryInit = env->GetStaticMethodID(entryClass, "init", "(IIII)V");
env->CallStaticVoidMethod(entryClass, entryInit, verboseLogs, spoofBuild, spoofProvider, spoofSignature);
}
}
};

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

@@ -13,7 +13,9 @@ public final class CustomProvider extends Provider {
@Override
public synchronized Service getService(String type, String algorithm) {
if (EntryPoint.getVerboseLogs() > 2) EntryPoint.LOG(String.format("Service: Caller type '%s' with algorithm '%s'", type, algorithm));
if (type.equals("KeyStore")) EntryPoint.spoofDevice();
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,6 +26,35 @@ 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<>();
@@ -24,11 +62,17 @@ public final class EntryPoint {
return verboseLogs;
}
public static void init(int level) {
verboseLogs = level;
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();
spoofProvider();
spoofDevice();
if (spoofProviderVal > 0) spoofProvider();
if (spoofBuildVal > 0) spoofDevice();
if (spoofSignatureVal > 0) spoofPackageManager();
}
public static void receiveJson(String data) {
@@ -78,6 +122,63 @@ public final class EntryPoint {
}
}
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) {
for (Field field : className.getDeclaredFields()) {
if (field.getName().equals(fieldName)) return true;
@@ -164,6 +265,6 @@ public final class EntryPoint {
}
static void LOG(String msg) {
Log.d("PIF/Java", msg);
Log.d("PIF/Java:DG", msg);
}
}

View File

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

View File

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

Binary file not shown.

View File

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

10
gradlew vendored
View File

@@ -15,6 +15,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
#
##############################################################################
#
@@ -84,7 +86,7 @@ done
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
@@ -112,7 +114,7 @@ case "$( uname )" in #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
CLASSPATH="\\\"\\\""
# Determine the Java command to use to start the JVM.
@@ -203,7 +205,7 @@ fi
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
@@ -211,7 +213,7 @@ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
"$@"
# Stop when "xargs" is not available.

6
gradlew.bat vendored
View File

@@ -13,6 +13,8 @@
@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 ##########################################################################
@@ -68,11 +70,11 @@ goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
set CLASSPATH=
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
:end
@rem End local scope for the variables with windows NT shell

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 -a -m -p || 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

View File

@@ -1,105 +0,0 @@
#!/system/bin/sh
if [ "$USER" != "root" -o "$(whoami 2>/dev/null)" != "root" ]; then
echo "autopif: need root permissions";
exit 1;
fi;
echo "Xiaomi.eu pif.json extractor script \
\n by osm0sis @ xda-developers";
case "$0" in
*.sh) DIR="$0";;
*) DIR="$(lsof -p $$ 2>/dev/null | grep -o '/.*autopif.sh$')";;
esac;
DIR=$(dirname "$(readlink -f "$DIR")");
if ! which wget >/dev/null || grep -q "wget-curl" $(which wget); then
if [ -f /data/adb/magisk/busybox ]; then
wget() { /data/adb/magisk/busybox wget "$@"; }
elif [ -f /data/adb/ksu/bin/busybox ]; then
wget() { /data/adb/ksu/bin/busybox wget "$@"; }
elif [ -f /data/adb/ap/bin/busybox ]; then
wget() { /data/adb/ap/bin/busybox wget "$@"; }
else
echo "Error: wget not found, install busybox!";
exit 1;
fi;
fi;
item() { echo "\n- $@"; }
if [ "$DIR" = /data/adb/modules/playintegrityfix ]; then
DIR=$DIR/autopif;
mkdir -p $DIR;
fi;
cd "$DIR";
if [ ! -f apktool_2.0.3-dexed.jar ]; then
item "Downloading Apktool ...";
wget --no-check-certificate -O apktool_2.0.3-dexed.jar https://github.com/osm0sis/APK-Patcher/raw/master/tools/apktool_2.0.3-dexed.jar 2>&1 || exit 1;
fi;
item "Finding latest APK from RSS feed ...";
APKURL=$(wget -q -O - --no-check-certificate https://sourceforge.net/projects/xiaomi-eu-multilang-miui-roms/rss?path=/xiaomi.eu/Xiaomi.eu-app | grep -o '<link>.*' | head -n 2 | tail -n 1 | sed 's;<link>\(.*\)</link>;\1;g');
APKNAME=$(echo $APKURL | sed 's;.*/\(.*\)/download;\1;g');
echo "$APKNAME";
if [ ! -f $APKNAME ]; then
item "Downloading $APKNAME ...";
wget --no-check-certificate -O $APKNAME $APKURL 2>&1 || exit 1;
fi;
OUT=$(basename $APKNAME .apk);
if [ ! -d $OUT ]; then
item "Extracting APK files with Apktool ...";
DALVIKVM=dalvikvm;
if echo "$PREFIX" | grep -q "termux"; then
if [ "$TERMUX_VERSION" ]; then
if grep -q "apex" $PREFIX/bin/dalvikvm; then
DALVIKVM=$PREFIX/bin/dalvikvm;
else
echo 'Error: Outdated Termux packages, run "pkg upgrade" from a user prompt!';
exit 1;
fi;
else
echo "Error: Play Store Termux not supported, use GitHub/F-Droid Termux!";
exit 1;
fi;
fi;
$DALVIKVM -Xnoimage-dex2oat -cp apktool_2.0.3-dexed.jar brut.apktool.Main d -f --no-src -p $OUT -o $OUT $APKNAME || exit 1;
fi;
item "Converting inject_fields.xml to pif.json ...";
(echo '{';
grep -o '<field.*' $OUT/res/xml/inject_fields.xml | sed 's;.*name=\(".*"\) type.* value=\(".*"\).*; \1: \2,;g';
echo ' "FIRST_API_LEVEL": "25",' ) | sed '$s/,/\n}/' | tee pif.json;
if [ -f /data/adb/modules/playintegrityfix/migrate.sh ]; then
if [ -f /data/adb/modules/playintegrityfix/custom.pif.json ]; then
grep -qE "verboseLogs|VERBOSE_LOGS" /data/adb/modules/playintegrityfix/custom.pif.json && ARGS="-a";
fi;
item "Converting pif.json to custom.pif.json with migrate.sh:";
rm -f custom.pif.json;
sh /data/adb/modules/playintegrityfix/migrate.sh -i $ARGS pif.json;
cat custom.pif.json;
fi;
if [ "$DIR" = /data/adb/modules/playintegrityfix/autopif ]; 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 ..;
fi;
if [ -f /data/adb/modules/playintegrityfix/killgms.sh ]; then
item "Killing any running GMS DroidGuard process ...";
sh /data/adb/modules/playintegrityfix/killgms.sh 2>&1;
fi;

203
module/autopif2.sh Normal file
View File

@@ -0,0 +1,203 @@
#!/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_DEPTH=1;
until [ -z "$1" ]; do
case "$1" in
-h|--help|help) echo "sh autopif2.sh [-a|-s] [-m] [-p] [-d #]"; exit 0;;
-a|--advanced|advanced) ARGS="-a"; shift;;
-s|--strong|strong) ARGS="-a"; PATCH_COMMENT=1; spoofProvider=0; shift;;
-m|--match|match) FORCE_MATCH=1; shift;;
-p|--preview|preview) FORCE_PREVIEW=1; shift;;
-d|--depth|depth) echo "$2" | grep -q '^[1-9]$' || exit 1; FORCE_DEPTH=$2; shift 2;;
*) break;;
esac;
done;
echo "Pixel Beta pif.json generator script \
\n by osm0sis @ xda-developers";
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 -n1) 2>&1 || exit 1;
if grep -qE 'Developer Preview|tooltip>.*preview program' PIXEL_LATEST_HTML && [ ! "$FORCE_PREVIEW" ]; then
wget -q -O PIXEL_BETA_HTML --no-check-certificate $(grep -o 'https://developer.android.com/about/versions/.*[0-9]"' PIXEL_VERSIONS_HTML | sort -ru | cut -d\" -f1 | head -n2 | tail -n1) 2>&1 || exit 1;
else
TITLE="Preview ";
mv -f PIXEL_LATEST_HTML PIXEL_BETA_HTML;
fi;
wget -q -O PIXEL_OTA_HTML --no-check-certificate https://developer.android.com$(grep -o 'href=".*download-ota.*"' PIXEL_BETA_HTML | cut -d\" -f2 | head -n$FORCE_DEPTH | tail -n1) 2>&1 || exit 1;
echo "$(grep -m1 -oE 'tooltip>Android .*[0-9]' PIXEL_OTA_HTML | cut -d\> -f2) $TITLE$(grep -oE 'tooltip>QPR.* Beta' PIXEL_OTA_HTML | cut -d\> -f2 | head -n$FORCE_DEPTH | tail -n1)";
BETA_REL_DATE="$(date -D '%B %e, %Y' -d "$(grep -m1 -A1 'Release date' PIXEL_OTA_HTML | tail -n1 | sed 's;.*<td>\(.*\)</td>.*;\1;')" '+%Y-%m-%d')";
BETA_EXP_DATE="$(date -D '%s' -d "$(($(date -D '%Y-%m-%d' -d "$BETA_REL_DATE" '+%s') + 60 * 60 * 24 * 7 * 6))" '+%Y-%m-%d')";
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
echo "\nError: Failed to extract information from metadata!";
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 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 -q 'all=' $TS_SECPAT && sed -i "s/all=.*/all=$SECURITY_PATCH/" $TS_SECPAT;
grep -q 'system=' $TS_SECPAT && sed -i "s/system=.*/system=$(echo ${SECURITY_PATCH//-} | cut -c-6)/" $TS_SECPAT;
cat $TS_SECPAT;
fi;
if [ -f /data/adb/modules/playintegrityfix/killpi.sh ]; then
item "Killing any running GMS DroidGuard/Play Store processes ...";
sh /data/adb/modules/playintegrityfix/killpi.sh 2>&1 || true;
fi;
fi;

View File

@@ -1,3 +1,32 @@
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
@@ -18,7 +47,7 @@ resetprop_hexpatch() {
local PROPFILE="/dev/__properties__/$(resetprop -Z "$NAME")"
fi
[ ! -f "$PROPFILE" ] && return 3
local NAMEOFFSET=$(echo $(strings -t d "$PROPFILE" | grep "$NAME") | cut -d ' ' -f 1)
local NAMEOFFSET=$(echo $(strings -t d "$PROPFILE" | grep "$NAME") | cut -d\ -f1)
#<hex 2-byte change counter><flags byte><hex length of prop value><prop value + nul padding to 92 bytes><prop name>
local NEWHEX="$(printf '%02x' "$NEWLEN")$(printf "$NEWVALUE" | od -A n -t x1 -v | tr -d ' \n')$(printf "%$((92-NEWLEN))s" | sed 's/ /00/g')"
@@ -37,7 +66,7 @@ resetprop_if_diff() {
local EXPECTED="$2"
local CURRENT="$(resetprop "$NAME")"
[ -z "$CURRENT" ] || [ "$CURRENT" = "$EXPECTED" ] || resetprop_hexpatch "$NAME" "$EXPECTED"
[ -z "$CURRENT" ] || [ "$CURRENT" = "$EXPECTED" ] || $RESETPROP "$NAME" "$EXPECTED"
}
# resetprop_if_match <prop name> <value match string> <new value>
@@ -46,7 +75,7 @@ resetprop_if_match() {
local CONTAINS="$2"
local VALUE="$3"
[[ "$(resetprop "$NAME")" = *"$CONTAINS"* ]] && resetprop_hexpatch "$NAME" "$VALUE"
[[ "$(resetprop "$NAME")" = *"$CONTAINS"* ]] && $RESETPROP "$NAME" "$VALUE"
}
# stub for boot-time

View File

@@ -39,7 +39,7 @@ for APP in $(grep -v '^#' $LIST); do
APK=$(readlink -f $APP);
fi
if [ -s "$APK" ]; then
PKGNAME=$(unzip -p $APK AndroidManifest.xml | tr -d '\0' | grep -oE '[[:alnum:].-_]+\*http' | cut -d\* -f1)
PKGNAME=$(unzip -p $APK AndroidManifest.xml | tr -d '\0' | grep -oE 'android.*overlay' | strings | tr -d '\n' | sed -e 's/^android//' -e 's/application//' -e 's;*http.*res/android;;' -e 's/manifest//' -e 's/overlay$//' | grep -oE '[[:alnum:].-_].*overlay' | cut -d\ -f2)
if [ "$PKGNAME" ] && grep -q "overlay package=\"$PKGNAME" $CFG; then
HIDECFG=$MODPATH$PREFIX$CFG
if [ ! -f "$HIDECFG" ]; then
@@ -59,9 +59,21 @@ for APP in $(grep -v '^#' $LIST); do
fi
done
# Work around AOSPA PropImitationHooks conflict when their persist props don't exist
if [ -n "$(resetprop ro.aospa.version)" ]; then
for PROP in persist.sys.pihooks.first_api_level persist.sys.pihooks.security_patch; do
resetprop | grep -q "\[$PROP\]" || resetprop -n -p "$PROP" "";
done;
fi;
# 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

@@ -3,21 +3,24 @@ if [ -f /data/adb/modules/playintegrityfix/scripts-only-mode ]; then
ui_print "! Installing global scripts only; Zygisk attestation fallback and device spoofing disabled"
touch $MODPATH/scripts-only-mode
sed -i 's/\(description=\)\(.*\)/\1[Scripts-only mode] \2/' $MODPATH/module.prop
rm -rf $MODPATH/autopif.sh $MODPATH/classes.dex $MODPATH/common_setup.sh \
[ -f /data/adb/modules/playintegrityfix/uninstall.sh ] && sh /data/adb/modules/playintegrityfix/uninstall.sh
rm -rf $MODPATH/action.sh $MODPATH/autopif2.sh $MODPATH/classes.dex $MODPATH/common_setup.sh \
$MODPATH/custom.pif.json $MODPATH/example.app_replace.list $MODPATH/example.pif.json \
$MODPATH/killgms.sh $MODPATH/migrate.sh $MODPATH/zygisk \
$MODPATH/migrate.sh $MODPATH/pif.json $MODPATH/zygisk \
/data/adb/modules/playintegrityfix/custom.app_replace.list \
/data/adb/modules/playintegrityfix/custom.pif.json /data/adb/modules/playintegrityfix/system
/data/adb/modules/playintegrityfix/custom.pif.json \
/data/adb/modules/playintegrityfix/system \
/data/adb/modules/playintegrityfix/uninstall.sh
fi
# Copy any disabled app files to updated module
if [ -d /data/adb/modules/playintegrityfix/system ]; then
ui_print "- Restoring disabled ROM apps configuration"
cp -arf /data/adb/modules/playintegrityfix/system $MODPATH
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; do
for FILE in custom.app_replace.list custom.pif.json skipdelprop uninstall.sh; do
if [ -f "/data/adb/modules/playintegrityfix/$FILE" ]; then
ui_print "- Restoring $FILE"
cp -af /data/adb/modules/playintegrityfix/$FILE $MODPATH/$FILE
@@ -30,14 +33,17 @@ if [ -d /data/adb/modules/MagiskHidePropsConf ]; then
fi
# Run common tasks for installation and boot-time
[ -d "$MODPATH/zygisk" ] && . $MODPATH/common_setup.sh
if [ -d "$MODPATH/zygisk" ]; then
. $MODPATH/common_func.sh
. $MODPATH/common_setup.sh
fi
# Migrate custom.pif.json to latest defaults if needed
if [ -f "$MODPATH/custom.pif.json" ] && ! grep -q "api_level" $MODPATH/custom.pif.json; then
ui_print "- Running migration script on custom.pif.json:"
ui_print " "
chmod 755 $MODPATH/migrate.sh
sh $MODPATH/migrate.sh install $MODPATH/custom.pif.json
sh $MODPATH/migrate.sh --install --advanced $MODPATH/custom.pif.json
ui_print " "
fi

View File

@@ -11,11 +11,13 @@
/system/app/EliteDevelopmentModule
/system/app/XInjectModule
# hentaiOS
# helluvaOS, hentaiOS
/system_ext/app/helluvaProductDevice*
/system_ext/app/helluvaProductSecretStub
/system_ext/app/hentaiLewdbSVTDummy
# Evolution X
/system_ext/app/PifPrebuilt
# PixelOS
# PixelOS, YAAP
/system_ext/overlay/CertifiedPropsOverlay.apk

View File

@@ -2,7 +2,7 @@
//
// These are the current suggested defaults but you may add as many other fields/properties as needed
//
// See android.os.Build source for all field values' corresponding properties:
// 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
{
@@ -24,5 +24,13 @@
// System Properties
"*.build.id": "", // for ro.build.id
"*.security_patch": "", // for ro.build.version.security_patch
"*api_level": "" // for ro.board.api_level, ro.board.first_api_level, ro.product.first_api_level and ro.vendor.api_level
"*api_level": "", // for ro.board.api_level, ro.board.first_api_level, ro.product.first_api_level and ro.vendor.api_level
// Advanced Settings
"spoofBuild": "1",
"spoofProps": "1",
"spoofProvider": "1",
"spoofSignature": "0",
"spoofVendingSdk": "0",
"verboseLogs": "0"
}

View File

@@ -1,12 +0,0 @@
#!/system/bin/sh
# killgms.sh by osm0sis @ xda-developers
#
# Kill the Google Play services DroidGuard process
# (com.google.android.gms.unstable)
if [ "$USER" != "root" -o "$(whoami 2>/dev/null)" != "root" ]; then
echo "killgms: need root permissions";
exit 1;
fi;
killall -v com.google.android.gms.unstable;

13
module/killpi.sh Normal file
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,13 +1,10 @@
#!/bin/sh
case "$1" in
-h|--help|help) echo "sh migrate.sh [-f] [-o] [-a] [in-file] [out-file]"; exit 0;;
esac;
N="
";
case "$1" in
-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";;
@@ -15,18 +12,26 @@ esac;
item() { echo "- $@"; }
die() { [ "$INSTALL" ] || echo "$N$N! $@"; exit 1; }
grep_get_json() { eval set -- "$(cat "$FILE" | tr -d '\r\n' | grep -m1 -o "$1"'".*' | cut -d: -f2-)"; echo "$1" | sed -e 's|"|\\\\\\"|g' -e 's|[,}]*$||'; }
grep_check_json() { grep -q "$1" "$FILE" && [ "$(grep_get_json $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")" ];
}
case "$1" in
-f|--force|force) FORCE=1; shift;;
esac;
case "$1" in
-o|--override|override) OVERRIDE=1; shift;;
esac;
case "$1" in
-a|--advanced|advanced) ADVANCED=1; shift;;
esac;
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";
@@ -109,10 +114,26 @@ if [ -z "$DEVICE_INITIAL_SDK_INT" -o "$DEVICE_INITIAL_SDK_INT" = "null" ]; then
DEVICE_INITIAL_SDK_INT=25;
fi;
ADVSETTINGS="spoofBuild spoofProps spoofProvider spoofSignature spoofVendingSdk verboseLogs";
spoofBuild=1;
spoofProps=1;
spoofProvider=1;
spoofSignature=0;
spoofVendingSdk=0;
verboseLogs=0;
if [ -f "$OUT" ]; then
item "Renaming old file to $(basename "$OUT").bak ...";
mv -f "$OUT" "$OUT.bak";
grep -qE "verboseLogs|VERBOSE_LOGS" "$OUT.bak" && ADVANCED=1;
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 ...";
@@ -124,12 +145,14 @@ for FIELD in $ALLFIELDS; do
done;
echo "$N // System Properties";
echo ' "*.build.id": "'$ID'",';
echo ' "*.security_patch": "'$SECURITY_PATCH'",';
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";
echo ' "verboseLogs": "0",';
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=v9
versionCode=90000
version=v13
versionCode=130001
author=osm0sis & chiteroman @ xda-developers
description=Fix CTS profile (SafetyNet) and DEVICE verdict (Play Integrity)
description=Fix <A13 DEVICE (Play Integrity) verdict
updateJson=https://raw.githubusercontent.com/osm0sis/PlayIntegrityFork/main/update.json

View File

@@ -2,15 +2,17 @@ MODPATH="${0%/*}"
. $MODPATH/common_func.sh
if [ -d "$MODPATH/zygisk" ]; then
# Remove Play Services from Magisk DenyList when set to Enforce in normal mode
# Remove Play Services and Play Store from Magisk DenyList when set to Enforce in normal mode
if magisk --denylist status; then
magisk --denylist rm com.google.android.gms
magisk --denylist rm com.android.vending
fi
# Run common tasks for installation and boot-time
. $MODPATH/common_setup.sh
else
# Add Play Services DroidGuard process to Magisk DenyList for better results in scripts-only mode
# Add Play Services DroidGuard and Play Store processes to Magisk DenyList for better results in scripts-only mode
magisk --denylist add com.google.android.gms com.google.android.gms.unstable
magisk --denylist add com.android.vending
fi
# Conditional early sensitive properties
@@ -21,9 +23,6 @@ resetprop_if_diff ro.vendor.boot.warranty_bit 0
resetprop_if_diff ro.vendor.warranty_bit 0
resetprop_if_diff ro.warranty_bit 0
# Xiaomi
resetprop_if_diff ro.secureboot.lockstate locked
# Realme
resetprop_if_diff ro.boot.realmebootstate green
@@ -31,9 +30,20 @@ resetprop_if_diff ro.boot.realmebootstate green
resetprop_if_diff ro.is_ever_orange 0
# Microsoft
resetprop_if_diff ro.build.tags release-keys
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

@@ -3,18 +3,18 @@ MODPATH="${0%/*}"
# Conditional sensitive properties
# 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
resetprop_if_diff ro.boot.selinux enforcing
# use delete since it can be 0 or 1 for enforcing depending on OEM
if [ -n "$(resetprop ro.build.selinux)" ]; then
resetprop --delete ro.build.selinux
if ! $SKIPDELPROP; then
delprop_if_exist ro.build.selinux
fi
# use toybox to protect *stat* access time reading
# 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
@@ -22,25 +22,28 @@ fi
# Conditional late sensitive properties
# SafetyNet/Play Integrity
# must be set after boot_completed for various OEMs
{
# 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
resetprop_if_diff ro.boot.realme.lockstate 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 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": "v9",
"versionCode": 90000,
"zipUrl": "https://github.com/osm0sis/PlayIntegrityFork/releases/download/v9/PlayIntegrityFork-v9.zip",
"version": "v13",
"versionCode": 130000,
"zipUrl": "https://github.com/osm0sis/PlayIntegrityFork/releases/download/v13/PlayIntegrityFork-v13.zip",
"changelog": "https://raw.githubusercontent.com/osm0sis/PlayIntegrityFork/main/CHANGELOG.md"
}