mirror of
https://github.com/chiteroman/PlayIntegrityFix.git
synced 2025-01-19 03:22:39 +02:00
v15.9.5
This commit is contained in:
parent
8e239aade9
commit
972bf318cb
@ -1,3 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="jbr-17" project-jdk-type="JavaSDK">
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="jbr-17" project-jdk-type="JavaSDK">
|
||||||
|
47
README.md
47
README.md
@ -1,15 +1,46 @@
|
|||||||
# Play Integrity Fix
|
# Play Integrity Fix
|
||||||
|
|
||||||
This module attempts to fix Play Integrity verdicts to get a certified device on bootloader unlocked devices.
|
This module tries to fix Play Integrity and SafetyNet verdicts to get a valid attestation.
|
||||||
|
|
||||||
Device verdict should pass by default.
|
You will need root and Zygisk, so you must choose ONE of this three setups:
|
||||||
If not, try removing /data/adb/pif.json file.
|
|
||||||
DO NOT REMOVE pif.json in module's folder!
|
|
||||||
|
|
||||||
Wiki: https://github.com/chiteroman/PlayIntegrityFix/wiki
|
- [Magisk](https://github.com/topjohnwu/Magisk) with Zygisk enabled.
|
||||||
|
- [KernelSU](https://github.com/tiann/KernelSU) with [ZygiskNext](https://github.com/Dr-TSNG/ZygiskNext) module installed.
|
||||||
|
- [APatch](https://github.com/bmax121/APatch) with [ZygiskNext](https://github.com/Dr-TSNG/ZygiskNext) module installed.
|
||||||
|
|
||||||
XDA post: https://xdaforums.com/t/module-play-integrity-fix-safetynet-fix.4607985/
|
After flashing and reboot your device, you can check PI and SN using these apps:
|
||||||
|
|
||||||
Telegram group: https://t.me/playintegrityfix
|
- Play Integrity -> https://play.google.com/store/apps/details?id=gr.nikolasspyr.integritycheck
|
||||||
|
- SafetyNet -> https://play.google.com/store/apps/details?id=rikka.safetynetchecker
|
||||||
|
|
||||||
Donations: https://www.paypal.com/paypalme/chiteroman
|
NOTE: if you get an error message about a limit, you need to use another app, this is because a lot of users are requesting an attestation.
|
||||||
|
|
||||||
|
NOTE: SafetyNet is obsolete, more info here: https://developer.android.com/privacy-and-security/safetynet/deprecation-timeline
|
||||||
|
|
||||||
|
Also, if you are using custom rom or custom kernel, be sure that your kernel name isn't blacklisted, you can check it running ```uname -r``` command. This is a list of banned strings: https://xdaforums.com/t/module-play-integrity-fix-safetynet-fix.4607985/post-89308909
|
||||||
|
|
||||||
|
After requesting an attestation in Play Integrity API you should get this result:
|
||||||
|
|
||||||
|
- MEETS_BASIC_INTEGRITY ✅
|
||||||
|
- MEETS_DEVICE_INTEGRITY ✅
|
||||||
|
- MEETS_STRONG_INTEGRITY ❌
|
||||||
|
- MEETS_VIRTUAL_INTEGRITY ❌
|
||||||
|
|
||||||
|
You can know more about verdicts in this post: https://xdaforums.com/t/info-play-integrity-api-replacement-for-safetynet.4479337/
|
||||||
|
|
||||||
|
And in SafetyNet you should get this:
|
||||||
|
|
||||||
|
- basicIntegrity: true
|
||||||
|
- ctsProfileMatch: true
|
||||||
|
- evaluationType: BASIC
|
||||||
|
|
||||||
|
NOTE: Strong verdict is impossible to pass on unlocked bootloader devices, there are few devices and "exploits" which will allow you to pass it, but, in normal conditions, this verdict will be green only if you are using stock ROM and locked bootloader. The old posts talking about Strong pass was an "exploit" in Google servers, obviously, now it's patched.
|
||||||
|
|
||||||
|
FAQ: https://xdaforums.com/t/pif-faq.4653307/
|
||||||
|
|
||||||
|
## Download
|
||||||
|
https://github.com/chiteroman/PlayIntegrityFix/releases/latest
|
||||||
|
|
||||||
|
## Donations
|
||||||
|
|
||||||
|
[PayPal](https://www.paypal.com/paypalme/chiteroman)
|
@ -12,10 +12,14 @@ android {
|
|||||||
applicationId = "es.chiteroman.playintegrityfix"
|
applicationId = "es.chiteroman.playintegrityfix"
|
||||||
minSdk = 26
|
minSdk = 26
|
||||||
targetSdk = 34
|
targetSdk = 34
|
||||||
versionCode = 15940
|
versionCode = 15950
|
||||||
versionName = "v15.9.4"
|
versionName = "v15.9.5"
|
||||||
multiDexEnabled = false
|
multiDexEnabled = false
|
||||||
|
|
||||||
|
buildFeatures {
|
||||||
|
prefab = true
|
||||||
|
}
|
||||||
|
|
||||||
packaging {
|
packaging {
|
||||||
jniLibs {
|
jniLibs {
|
||||||
excludes += "**/liblog.so"
|
excludes += "**/liblog.so"
|
||||||
@ -25,8 +29,8 @@ android {
|
|||||||
|
|
||||||
externalNativeBuild {
|
externalNativeBuild {
|
||||||
cmake {
|
cmake {
|
||||||
arguments += "-DANDROID_STL=c++_static"
|
arguments += "-DANDROID_STL=none"
|
||||||
arguments += "-DCMAKE_BUILD_TYPE=Release"
|
arguments += "-DCMAKE_BUILD_TYPE=MinSizeRel"
|
||||||
arguments += "-DPlugin.Android.BionicLinkerUtil=ON"
|
arguments += "-DPlugin.Android.BionicLinkerUtil=ON"
|
||||||
|
|
||||||
cppFlags += "-std=c++20"
|
cppFlags += "-std=c++20"
|
||||||
@ -34,7 +38,6 @@ android {
|
|||||||
cppFlags += "-fno-rtti"
|
cppFlags += "-fno-rtti"
|
||||||
cppFlags += "-fvisibility=hidden"
|
cppFlags += "-fvisibility=hidden"
|
||||||
cppFlags += "-fvisibility-inlines-hidden"
|
cppFlags += "-fvisibility-inlines-hidden"
|
||||||
cppFlags += "-flto"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -61,6 +64,10 @@ android {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation("dev.rikka.ndk.thirdparty:cxx:1.2.0")
|
||||||
|
}
|
||||||
|
|
||||||
tasks.register("updateModuleProp") {
|
tasks.register("updateModuleProp") {
|
||||||
doLast {
|
doLast {
|
||||||
val versionName = project.android.defaultConfig.versionName
|
val versionName = project.android.defaultConfig.versionName
|
||||||
@ -84,7 +91,7 @@ tasks.register("copyFiles") {
|
|||||||
doLast {
|
doLast {
|
||||||
val moduleFolder = project.rootDir.resolve("module")
|
val moduleFolder = project.rootDir.resolve("module")
|
||||||
val dexFile = project.layout.buildDirectory.get().asFile.resolve("intermediates/dex/release/minifyReleaseWithR8/classes.dex")
|
val dexFile = project.layout.buildDirectory.get().asFile.resolve("intermediates/dex/release/minifyReleaseWithR8/classes.dex")
|
||||||
val soDir = project.layout.buildDirectory.get().asFile.resolve("intermediates/stripped_native_libs/release/out/lib")
|
val soDir = project.layout.buildDirectory.get().asFile.resolve("intermediates/stripped_native_libs/release/stripReleaseDebugSymbols/out/lib")
|
||||||
|
|
||||||
dexFile.copyTo(moduleFolder.resolve("classes.dex"), overwrite = true)
|
dexFile.copyTo(moduleFolder.resolve("classes.dex"), overwrite = true)
|
||||||
|
|
||||||
|
@ -2,6 +2,10 @@ cmake_minimum_required(VERSION 3.22.1)
|
|||||||
|
|
||||||
project(playintegrityfix)
|
project(playintegrityfix)
|
||||||
|
|
||||||
|
find_package(cxx REQUIRED CONFIG)
|
||||||
|
|
||||||
|
link_libraries(cxx::cxx)
|
||||||
|
|
||||||
add_library(${CMAKE_PROJECT_NAME} SHARED main.cpp)
|
add_library(${CMAKE_PROJECT_NAME} SHARED main.cpp)
|
||||||
|
|
||||||
add_subdirectory(Dobby)
|
add_subdirectory(Dobby)
|
||||||
|
@ -17,11 +17,13 @@ static std::string FIRST_API_LEVEL, SECURITY_PATCH, BUILD_ID;
|
|||||||
|
|
||||||
typedef void (*T_Callback)(void *, const char *, const char *, uint32_t);
|
typedef void (*T_Callback)(void *, const char *, const char *, uint32_t);
|
||||||
|
|
||||||
static T_Callback o_callback = nullptr;
|
static std::map<void *, T_Callback> callbacks;
|
||||||
|
|
||||||
static void modify_callback(void *cookie, const char *name, const char *value, uint32_t serial) {
|
static void modify_callback(void *cookie, const char *name, const char *value, uint32_t serial) {
|
||||||
|
|
||||||
if (cookie == nullptr || name == nullptr || value == nullptr || o_callback == nullptr) return;
|
if (cookie == nullptr || name == nullptr || value == nullptr ||
|
||||||
|
!callbacks.contains(cookie))
|
||||||
|
return;
|
||||||
|
|
||||||
std::string_view prop(name);
|
std::string_view prop(name);
|
||||||
|
|
||||||
@ -52,7 +54,7 @@ static void modify_callback(void *cookie, const char *name, const char *value, u
|
|||||||
LOGD("[%s]: %s", name, value);
|
LOGD("[%s]: %s", name, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
return o_callback(cookie, name, value, serial);
|
return callbacks[cookie](cookie, name, value, serial);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void (*o_system_property_read_callback)(const prop_info *, T_Callback, void *);
|
static void (*o_system_property_read_callback)(const prop_info *, T_Callback, void *);
|
||||||
@ -62,19 +64,19 @@ my_system_property_read_callback(const prop_info *pi, T_Callback callback, void
|
|||||||
if (pi == nullptr || callback == nullptr || cookie == nullptr) {
|
if (pi == nullptr || callback == nullptr || cookie == nullptr) {
|
||||||
return o_system_property_read_callback(pi, callback, cookie);
|
return o_system_property_read_callback(pi, callback, cookie);
|
||||||
}
|
}
|
||||||
o_callback = callback;
|
callbacks[cookie] = callback;
|
||||||
return o_system_property_read_callback(pi, modify_callback, cookie);
|
return o_system_property_read_callback(pi, modify_callback, cookie);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void doHook() {
|
static void doHook() {
|
||||||
void *handle = DobbySymbolResolver("libc.so", "__system_property_read_callback");
|
void *handle = DobbySymbolResolver(nullptr, "__system_property_read_callback");
|
||||||
if (handle == nullptr) {
|
if (handle == nullptr) {
|
||||||
LOGD("Couldn't hook '__system_property_read_callback'. Report to @chiteroman");
|
LOGD("Couldn't hook __system_property_read_callback");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
DobbyHook(handle, (void *) my_system_property_read_callback,
|
DobbyHook(handle, (void *) my_system_property_read_callback,
|
||||||
(void **) &o_system_property_read_callback);
|
(void **) &o_system_property_read_callback);
|
||||||
LOGD("Found and hooked '__system_property_read_callback' at %p", handle);
|
LOGD("Found and hooked __system_property_read_callback at %p", handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
class PlayIntegrityFix : public zygisk::ModuleBase {
|
class PlayIntegrityFix : public zygisk::ModuleBase {
|
||||||
@ -86,77 +88,71 @@ public:
|
|||||||
|
|
||||||
void preAppSpecialize(zygisk::AppSpecializeArgs *args) override {
|
void preAppSpecialize(zygisk::AppSpecializeArgs *args) override {
|
||||||
|
|
||||||
auto dir = env->GetStringUTFChars(args->app_data_dir, nullptr);
|
const char *dir, *name;
|
||||||
|
bool isGms, isGmsUnstable;
|
||||||
|
|
||||||
if (dir == nullptr) {
|
if (!args) goto exit;
|
||||||
api->setOption(zygisk::DLCLOSE_MODULE_LIBRARY);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isGms = std::string_view(dir).ends_with("/com.google.android.gms");
|
dir = env->GetStringUTFChars(args->app_data_dir, nullptr);
|
||||||
|
|
||||||
|
if (!dir) goto exit;
|
||||||
|
|
||||||
|
isGms = std::string_view(dir).ends_with("/com.google.android.gms");
|
||||||
|
|
||||||
env->ReleaseStringUTFChars(args->app_data_dir, dir);
|
env->ReleaseStringUTFChars(args->app_data_dir, dir);
|
||||||
|
|
||||||
if (!isGms) {
|
if (isGms) {
|
||||||
api->setOption(zygisk::DLCLOSE_MODULE_LIBRARY);
|
name = env->GetStringUTFChars(args->nice_name, nullptr);
|
||||||
return;
|
|
||||||
|
if (!name) goto exit;
|
||||||
|
|
||||||
|
isGmsUnstable = strcmp(name, "com.google.android.gms.unstable") == 0;
|
||||||
|
|
||||||
|
if (isGmsUnstable) {
|
||||||
|
|
||||||
|
long dexSize = 0, jsonSize = 0;
|
||||||
|
|
||||||
|
int fd = api->connectCompanion();
|
||||||
|
|
||||||
|
read(fd, &dexSize, sizeof(long));
|
||||||
|
read(fd, &jsonSize, sizeof(long));
|
||||||
|
|
||||||
|
LOGD("Dex file size: %ld", dexSize);
|
||||||
|
LOGD("Json file size: %ld", jsonSize);
|
||||||
|
|
||||||
|
if (dexSize < 1 || jsonSize < 1) {
|
||||||
|
close(fd);
|
||||||
|
LOGD("Invalid files!");
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
dexVector.resize(dexSize);
|
||||||
|
read(fd, dexVector.data(), dexSize);
|
||||||
|
|
||||||
|
std::vector<uint8_t> jsonVector;
|
||||||
|
|
||||||
|
jsonVector.resize(jsonSize);
|
||||||
|
read(fd, jsonVector.data(), jsonSize);
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
json = nlohmann::json::parse(jsonVector, nullptr, false, true);
|
||||||
|
|
||||||
|
parseJson();
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
api->setOption(zygisk::FORCE_DENYLIST_UNMOUNT);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
api->setOption(zygisk::FORCE_DENYLIST_UNMOUNT);
|
exit:
|
||||||
|
api->setOption(zygisk::DLCLOSE_MODULE_LIBRARY);
|
||||||
auto name = env->GetStringUTFChars(args->nice_name, nullptr);
|
|
||||||
|
|
||||||
if (name == nullptr) {
|
|
||||||
api->setOption(zygisk::DLCLOSE_MODULE_LIBRARY);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isGmsUnstable = std::string_view(name) == "com.google.android.gms.unstable";
|
|
||||||
|
|
||||||
env->ReleaseStringUTFChars(args->nice_name, name);
|
|
||||||
|
|
||||||
if (!isGmsUnstable) {
|
|
||||||
api->setOption(zygisk::DLCLOSE_MODULE_LIBRARY);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
long dexSize = 0, jsonSize = 0;
|
|
||||||
|
|
||||||
int fd = api->connectCompanion();
|
|
||||||
|
|
||||||
read(fd, &dexSize, sizeof(long));
|
|
||||||
read(fd, &jsonSize, sizeof(long));
|
|
||||||
|
|
||||||
LOGD("Dex file size: %ld", dexSize);
|
|
||||||
LOGD("Json file size: %ld", jsonSize);
|
|
||||||
|
|
||||||
if (dexSize < 1) {
|
|
||||||
close(fd);
|
|
||||||
LOGD("Dex file empty!");
|
|
||||||
api->setOption(zygisk::DLCLOSE_MODULE_LIBRARY);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
dexVector.resize(dexSize);
|
|
||||||
read(fd, dexVector.data(), dexSize);
|
|
||||||
|
|
||||||
if (jsonSize < 1) {
|
|
||||||
close(fd);
|
|
||||||
LOGD("JSON file not found!");
|
|
||||||
api->setOption(zygisk::DLCLOSE_MODULE_LIBRARY);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<uint8_t> jsonVector;
|
|
||||||
|
|
||||||
jsonVector.resize(jsonSize);
|
|
||||||
read(fd, jsonVector.data(), jsonSize);
|
|
||||||
|
|
||||||
close(fd);
|
|
||||||
|
|
||||||
json = nlohmann::json::parse(jsonVector, nullptr, false, true);
|
|
||||||
|
|
||||||
parseJson();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void postAppSpecialize(const zygisk::AppSpecializeArgs *args) override {
|
void postAppSpecialize(const zygisk::AppSpecializeArgs *args) override {
|
||||||
|
@ -10,15 +10,12 @@ import java.security.NoSuchAlgorithmException;
|
|||||||
import java.security.UnrecoverableKeyException;
|
import java.security.UnrecoverableKeyException;
|
||||||
import java.security.cert.Certificate;
|
import java.security.cert.Certificate;
|
||||||
import java.security.cert.CertificateException;
|
import java.security.cert.CertificateException;
|
||||||
import java.security.cert.X509Certificate;
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
public final class CustomKeyStoreSpi extends KeyStoreSpi {
|
public final class CustomKeyStoreSpi extends KeyStoreSpi {
|
||||||
private static final String EAT_OID = "1.3.6.1.4.1.11129.2.1.25";
|
public static volatile KeyStoreSpi keyStoreSpi;
|
||||||
private static final String ASN1_OID = "1.3.6.1.4.1.11129.2.1.17";
|
|
||||||
private static final String KNOX_OID = "1.3.6.1.4.1.236.11.3.23.7";
|
|
||||||
public static volatile KeyStoreSpi keyStoreSpi = null;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Key engineGetKey(String alias, char[] password) throws NoSuchAlgorithmException, UnrecoverableKeyException {
|
public Key engineGetKey(String alias, char[] password) throws NoSuchAlgorithmException, UnrecoverableKeyException {
|
||||||
@ -27,24 +24,15 @@ public final class CustomKeyStoreSpi extends KeyStoreSpi {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Certificate[] engineGetCertificateChain(String alias) {
|
public Certificate[] engineGetCertificateChain(String alias) {
|
||||||
Certificate[] certificates = keyStoreSpi.engineGetCertificateChain(alias);
|
|
||||||
|
|
||||||
// If certificate array is null, throw exception
|
for (StackTraceElement stackTraceElement : Thread.currentThread().getStackTrace()) {
|
||||||
// This shouldn't happen...
|
if (stackTraceElement.getClassName().toLowerCase(Locale.US).contains("droidguard")) {
|
||||||
if (certificates == null) {
|
EntryPoint.LOG("engineGetCertificateChain invoked by DroidGuard!");
|
||||||
EntryPoint.LOG("Certificate chain is null!");
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
// If leaf certificate has attestation extensions, throw exception!
|
|
||||||
if (certificates[0] instanceof X509Certificate x509Certificate) {
|
|
||||||
if (x509Certificate.getExtensionValue(EAT_OID) != null || x509Certificate.getExtensionValue(ASN1_OID) != null || x509Certificate.getExtensionValue(KNOX_OID) != null) {
|
|
||||||
EntryPoint.LOG("Leaf certificate with attestation extensions. Throw exception!");
|
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return certificates;
|
return keyStoreSpi.engineGetCertificateChain(alias);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -14,7 +14,7 @@ public final class CustomProvider extends Provider {
|
|||||||
public synchronized Service getService(String type, String algorithm) {
|
public synchronized Service getService(String type, String algorithm) {
|
||||||
EntryPoint.LOG(String.format("Service: '%s' | Algorithm: '%s'", type, algorithm));
|
EntryPoint.LOG(String.format("Service: '%s' | Algorithm: '%s'", type, algorithm));
|
||||||
|
|
||||||
new Thread(EntryPoint::spoofFields).start();
|
EntryPoint.spoofFields();
|
||||||
|
|
||||||
return super.getService(type, algorithm);
|
return super.getService(type, algorithm);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,3 @@
|
|||||||
buildscript {
|
|
||||||
val agp_version by extra("8.2.2")
|
|
||||||
}
|
|
||||||
plugins {
|
plugins {
|
||||||
id("com.android.application") version "8.2.2" apply false
|
id("com.android.application") version "8.3.0" apply false
|
||||||
}
|
}
|
12
changelog.md
12
changelog.md
@ -1,10 +1,14 @@
|
|||||||
We have a Telegram group!
|
Telegram channel:
|
||||||
If you want to share your knowledge join:
|
|
||||||
https://t.me/playintegrityfix
|
https://t.me/playintegrityfix
|
||||||
|
|
||||||
Device verdict should pass by default.
|
Device verdict should pass by default.
|
||||||
If not, try removing /data/adb/pif.json file.
|
If not, try removing /data/adb/pif.json file.
|
||||||
|
|
||||||
# v15.9.4
|
Donations:
|
||||||
|
https://www.paypal.com/paypalme/chiteroman
|
||||||
|
|
||||||
- Misc improvements.
|
# v15.9.5
|
||||||
|
|
||||||
|
- Strip libraries and reduce their size.
|
||||||
|
- Fix attestation not passing on some devices.
|
||||||
|
- Do not auto remove conflict apps, users should remove them manually.
|
@ -22,9 +22,7 @@ if [ -f "/data/adb/pif.json" ]; then
|
|||||||
ui_print "- If pif.json file doesn't exist, module will use default one"
|
ui_print "- If pif.json file doesn't exist, module will use default one"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
ui_print "- Removing conflict apps..."
|
# Conflict apps
|
||||||
|
|
||||||
# Remove conflict apps
|
|
||||||
APPS="
|
APPS="
|
||||||
/system/app/EliteDevelopmentModule
|
/system/app/EliteDevelopmentModule
|
||||||
/system/app/XInjectModule
|
/system/app/XInjectModule
|
||||||
@ -35,16 +33,7 @@ APPS="
|
|||||||
"
|
"
|
||||||
|
|
||||||
for app in $APPS; do
|
for app in $APPS; do
|
||||||
if [ -d "$app" ]; then
|
if [ -d "$app" ]; then
|
||||||
directory="$MODPATH$app"
|
ui_print "- ${app##*/} app found! You should uninstall it manually!"
|
||||||
[ -d "$directory" ] || mkdir -p "$directory"
|
fi
|
||||||
if [ "$KSU" = "true" ] || [ "$APATCH" = "true" ]; then
|
|
||||||
mknod $directory c 0 0
|
|
||||||
else
|
|
||||||
touch $directory/.replace
|
|
||||||
fi
|
|
||||||
ui_print "- ${app##*/} app removed"
|
|
||||||
else
|
|
||||||
ui_print "- ${app##*/} app doesn't exist, skip"
|
|
||||||
fi
|
|
||||||
done
|
done
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
id=playintegrityfix
|
id=playintegrityfix
|
||||||
name=Play Integrity Fix
|
name=Play Integrity Fix
|
||||||
version=v15.9.4
|
version=v15.9.5
|
||||||
versionCode=15940
|
versionCode=15950
|
||||||
author=chiteroman
|
author=chiteroman
|
||||||
description=Universal modular fix for Play Integrity (and SafetyNet) on devices running Android 8-14.
|
description=Universal modular fix for Play Integrity (and SafetyNet) on devices running Android 8-14.
|
||||||
updateJson=https://raw.githubusercontent.com/chiteroman/PlayIntegrityFix/main/update.json
|
updateJson=https://raw.githubusercontent.com/chiteroman/PlayIntegrityFix/main/update.json
|
||||||
|
@ -36,25 +36,21 @@ fi
|
|||||||
|
|
||||||
# Late props which must be set after boot_completed
|
# Late props which must be set after boot_completed
|
||||||
{
|
{
|
||||||
until [ "$(getprop sys.boot_completed)" = "1" ]; do
|
until [[ "$(getprop sys.boot_completed)" == "1" ]]; do
|
||||||
sleep 1
|
sleep 1
|
||||||
done
|
done
|
||||||
|
|
||||||
resetprop_if_diff ro.boot.flash.locked 1
|
# SafetyNet/Play Integrity | Avoid breaking Realme fingerprint scanners
|
||||||
|
resetprop ro.boot.flash.locked 1
|
||||||
|
|
||||||
resetprop_if_diff ro.boot.vbmeta.device_state locked
|
# SafetyNet/Play Integrity | Avoid breaking Oppo fingerprint scanners
|
||||||
|
resetprop ro.boot.vbmeta.device_state locked
|
||||||
|
|
||||||
resetprop_if_diff ro.boot.verifiedbootstate green
|
# SafetyNet/Play Integrity | Avoid breaking OnePlus display modes/fingerprint scanners
|
||||||
|
resetprop vendor.boot.verifiedbootstate green
|
||||||
|
|
||||||
resetprop_if_diff ro.boot.veritymode enforcing
|
# SafetyNet/Play Integrity | Avoid breaking OnePlus display modes/fingerprint scanners on OOS 12
|
||||||
|
resetprop ro.boot.verifiedbootstate green
|
||||||
resetprop_if_diff vendor.boot.verifiedbootstate green
|
resetprop ro.boot.veritymode enforcing
|
||||||
|
resetprop vendor.boot.vbmeta.device_state locked
|
||||||
resetprop_if_diff vendor.boot.vbmeta.device_state locked
|
|
||||||
|
|
||||||
resetprop_if_diff ro.crypto.state encrypted
|
|
||||||
|
|
||||||
resetprop_if_diff ro.secureboot.lockstate locked
|
|
||||||
|
|
||||||
resetprop_if_diff ro.boot.realmebootstate green
|
|
||||||
}&
|
}&
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"version": "v15.9.4",
|
"version": "v15.9.5",
|
||||||
"versionCode": 15940,
|
"versionCode": 15950,
|
||||||
"zipUrl": "https://github.com/chiteroman/PlayIntegrityFix/releases/download/v15.9.4/PlayIntegrityFix_v15.9.4.zip",
|
"zipUrl": "https://github.com/chiteroman/PlayIntegrityFix/releases/download/v15.9.5/PlayIntegrityFix_v15.9.5.zip",
|
||||||
"changelog": "https://raw.githubusercontent.com/chiteroman/PlayIntegrityFix/main/changelog.md"
|
"changelog": "https://raw.githubusercontent.com/chiteroman/PlayIntegrityFix/main/changelog.md"
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user