mirror of
https://github.com/chiteroman/PlayIntegrityFix.git
synced 2025-01-19 03:22:39 +02:00
v15.8
This commit is contained in:
parent
3753ee5ca7
commit
6a9f5f88a0
3
.idea/.gitignore
vendored
Normal file
3
.idea/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
@ -12,8 +12,8 @@ android {
|
|||||||
applicationId = "es.chiteroman.playintegrityfix"
|
applicationId = "es.chiteroman.playintegrityfix"
|
||||||
minSdk = 26
|
minSdk = 26
|
||||||
targetSdk = 34
|
targetSdk = 34
|
||||||
versionCode = 15702
|
versionCode = 15800
|
||||||
versionName = "v15.7.2"
|
versionName = "v15.8"
|
||||||
multiDexEnabled = false
|
multiDexEnabled = false
|
||||||
|
|
||||||
buildFeatures {
|
buildFeatures {
|
||||||
@ -30,14 +30,23 @@ android {
|
|||||||
externalNativeBuild {
|
externalNativeBuild {
|
||||||
cmake {
|
cmake {
|
||||||
arguments += "-DANDROID_STL=none"
|
arguments += "-DANDROID_STL=none"
|
||||||
arguments += "-DCMAKE_BUILD_TYPE=MinSizeRel"
|
arguments += "-DCMAKE_BUILD_TYPE=Release"
|
||||||
arguments += "-DPlugin.Android.BionicLinkerUtil=ON"
|
arguments += "-DPlugin.Android.BionicLinkerUtil=ON"
|
||||||
|
|
||||||
|
cFlags += "-fvisibility=hidden"
|
||||||
|
cFlags += "-fvisibility-inlines-hidden"
|
||||||
|
cFlags += "-flto"
|
||||||
|
cFlags += "-O3"
|
||||||
|
cFlags += "-mllvm -polly"
|
||||||
|
|
||||||
cppFlags += "-std=c++20"
|
cppFlags += "-std=c++20"
|
||||||
cppFlags += "-fno-exceptions"
|
cppFlags += "-fno-exceptions"
|
||||||
cppFlags += "-fno-rtti"
|
cppFlags += "-fno-rtti"
|
||||||
cppFlags += "-fvisibility=hidden"
|
cppFlags += "-fvisibility=hidden"
|
||||||
cppFlags += "-fvisibility-inlines-hidden"
|
cppFlags += "-fvisibility-inlines-hidden"
|
||||||
|
cppFlags += "-flto"
|
||||||
|
cppFlags += "-O3"
|
||||||
|
cppFlags += "-mllvm -polly"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,4 +10,4 @@ add_library(${CMAKE_PROJECT_NAME} SHARED main.cpp)
|
|||||||
|
|
||||||
add_subdirectory(Dobby)
|
add_subdirectory(Dobby)
|
||||||
|
|
||||||
target_link_libraries(${CMAKE_PROJECT_NAME} PUBLIC log dobby_static)
|
target_link_libraries(${CMAKE_PROJECT_NAME} log dobby_static)
|
@ -26,7 +26,7 @@ option(Plugin.SymbolResolver "Enable symbol resolver" ON)
|
|||||||
|
|
||||||
option(Plugin.ImportTableReplace "Enable import table replace " OFF)
|
option(Plugin.ImportTableReplace "Enable import table replace " OFF)
|
||||||
|
|
||||||
option(Plugin.Android.BionicLinkerUtil "Enable android bionic linker util" OFF)
|
option(Plugin.Android.BionicLinkerUtil "Enable android bionic linker util" ON)
|
||||||
|
|
||||||
option(DOBBY_BUILD_EXAMPLE "Build example" OFF)
|
option(DOBBY_BUILD_EXAMPLE "Build example" OFF)
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
#include <android/log.h>
|
#include <android/log.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <fstream>
|
||||||
|
#include <filesystem>
|
||||||
#include "dobby.h"
|
#include "dobby.h"
|
||||||
#include "json.hpp"
|
#include "json.hpp"
|
||||||
#include "zygisk.hpp"
|
#include "zygisk.hpp"
|
||||||
@ -108,6 +110,11 @@ public:
|
|||||||
|
|
||||||
auto name = env->GetStringUTFChars(args->nice_name, nullptr);
|
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";
|
bool isGmsUnstable = std::string_view(name) == "com.google.android.gms.unstable";
|
||||||
|
|
||||||
env->ReleaseStringUTFChars(args->nice_name, name);
|
env->ReleaseStringUTFChars(args->nice_name, name);
|
||||||
@ -151,16 +158,16 @@ public:
|
|||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
json = nlohmann::json::parse(jsonVector, nullptr, false, true);
|
json = nlohmann::json::parse(jsonVector, nullptr, false, true);
|
||||||
|
|
||||||
|
parseJson();
|
||||||
}
|
}
|
||||||
|
|
||||||
void postAppSpecialize(const zygisk::AppSpecializeArgs *args) override {
|
void postAppSpecialize(const zygisk::AppSpecializeArgs *args) override {
|
||||||
if (dexVector.empty() || json.empty()) return;
|
if (dexVector.empty() || json.empty()) return;
|
||||||
|
|
||||||
parseJson();
|
injectDex();
|
||||||
|
|
||||||
doHook();
|
doHook();
|
||||||
|
|
||||||
injectDex();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void preServerSpecialize(zygisk::ServerSpecializeArgs *args) override {
|
void preServerSpecialize(zygisk::ServerSpecializeArgs *args) override {
|
||||||
@ -274,31 +281,36 @@ static void companion(int fd) {
|
|||||||
|
|
||||||
std::vector<char> dexVector, jsonVector;
|
std::vector<char> dexVector, jsonVector;
|
||||||
|
|
||||||
FILE *dexFile = fopen(CLASSES_DEX, "rb");
|
std::ifstream dexFile(CLASSES_DEX, std::ios::binary);
|
||||||
|
|
||||||
if (dexFile) {
|
if (dexFile.is_open()) {
|
||||||
fseek(dexFile, 0, SEEK_END);
|
dexFile.seekg(0, std::ios::end);
|
||||||
dexSize = ftell(dexFile);
|
dexSize = dexFile.tellg();
|
||||||
fseek(dexFile, 0, SEEK_SET);
|
dexFile.seekg(0, std::ios::beg);
|
||||||
|
|
||||||
dexVector.resize(dexSize);
|
dexVector.resize(dexSize);
|
||||||
fread(dexVector.data(), 1, dexSize, dexFile);
|
dexFile.read(dexVector.data(), dexSize);
|
||||||
|
dexFile.close();
|
||||||
fclose(dexFile);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE *jsonFile = fopen(PIF_JSON, "rb");
|
std::ifstream jsonFile;
|
||||||
if (jsonFile == nullptr) jsonFile = fopen(PIF_JSON_DEFAULT, "rb");
|
|
||||||
|
|
||||||
if (jsonFile) {
|
if (std::filesystem::exists(PIF_JSON)) {
|
||||||
fseek(jsonFile, 0, SEEK_END);
|
jsonFile = std::ifstream(PIF_JSON);
|
||||||
jsonSize = ftell(jsonFile);
|
} else if (std::filesystem::exists(PIF_JSON_DEFAULT)) {
|
||||||
fseek(jsonFile, 0, SEEK_SET);
|
jsonFile = std::ifstream(PIF_JSON_DEFAULT);
|
||||||
|
} else {
|
||||||
|
LOGD("Couldn't open pif.json file. Did you remove it?");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (jsonFile.is_open()) {
|
||||||
|
jsonFile.seekg(0, std::ios::end);
|
||||||
|
jsonSize = jsonFile.tellg();
|
||||||
|
jsonFile.seekg(0, std::ios::beg);
|
||||||
|
|
||||||
jsonVector.resize(jsonSize);
|
jsonVector.resize(jsonSize);
|
||||||
fread(jsonVector.data(), 1, jsonSize, jsonFile);
|
jsonFile.read(jsonVector.data(), jsonSize);
|
||||||
|
jsonFile.close();
|
||||||
fclose(jsonFile);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
write(fd, &dexSize, sizeof(long));
|
write(fd, &dexSize, sizeof(long));
|
||||||
|
@ -10,12 +10,15 @@ 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 {
|
||||||
public static volatile KeyStoreSpi keyStoreSpi = null;
|
public static KeyStoreSpi keyStoreSpi = null;
|
||||||
|
private static final String EAT_OID = "1.3.6.1.4.1.11129.2.1.25";
|
||||||
|
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";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Key engineGetKey(String alias, char[] password) throws NoSuchAlgorithmException, UnrecoverableKeyException {
|
public Key engineGetKey(String alias, char[] password) throws NoSuchAlgorithmException, UnrecoverableKeyException {
|
||||||
@ -24,13 +27,21 @@ public final class CustomKeyStoreSpi extends KeyStoreSpi {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Certificate[] engineGetCertificateChain(String alias) {
|
public Certificate[] engineGetCertificateChain(String alias) {
|
||||||
for (StackTraceElement stackTraceElement : Thread.currentThread().getStackTrace()) {
|
Certificate[] certificates = keyStoreSpi.engineGetCertificateChain(alias);
|
||||||
if (stackTraceElement.getClassName().toLowerCase(Locale.US).contains("droidguard")) {
|
// This shouldn't happen...
|
||||||
EntryPoint.LOG("DroidGuard call certificate chain! Throw exception.");
|
if (certificates == null) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
// Is certificate chain ?
|
||||||
|
if (certificates.length > 1) {
|
||||||
|
if (certificates[0] instanceof X509Certificate x509Certificate) {
|
||||||
|
if (x509Certificate.getExtensionValue(EAT_OID) != null || x509Certificate.getExtensionValue(ASN1_OID) != null || x509Certificate.getExtensionValue(KNOX_OID) != null) {
|
||||||
|
EntryPoint.LOG("Certificate chain with dangerous extensions. Throw exception!");
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return keyStoreSpi.engineGetCertificateChain(alias);
|
}
|
||||||
|
return certificates;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -4,19 +4,17 @@ import java.security.Provider;
|
|||||||
|
|
||||||
public final class CustomProvider extends Provider {
|
public final class CustomProvider extends Provider {
|
||||||
|
|
||||||
public CustomProvider(Provider provider, boolean spoof) {
|
public CustomProvider(Provider provider) {
|
||||||
super(provider.getName(), provider.getVersion(), provider.getInfo());
|
super(provider.getName(), provider.getVersion(), provider.getInfo());
|
||||||
|
|
||||||
putAll(provider);
|
putAll(provider);
|
||||||
|
put("KeyStore.AndroidKeyStore", CustomKeyStoreSpi.class.getName());
|
||||||
if (spoof) put("KeyStore.AndroidKeyStore", CustomKeyStoreSpi.class.getName());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
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));
|
||||||
|
|
||||||
if ("AndroidKeyStore".equals(algorithm)) EntryPoint.spoofFields();
|
new Thread(EntryPoint::spoofFields).start();
|
||||||
|
|
||||||
return super.getService(type, algorithm);
|
return super.getService(type, algorithm);
|
||||||
}
|
}
|
||||||
|
@ -17,24 +17,21 @@ public final class EntryPoint {
|
|||||||
private static final Map<Field, String> map = new HashMap<>();
|
private static final Map<Field, String> map = new HashMap<>();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
boolean spoof = false;
|
|
||||||
try {
|
try {
|
||||||
KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
|
KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
|
||||||
|
Field keyStoreSpi = keyStore.getClass().getDeclaredField("keyStoreSpi");
|
||||||
|
|
||||||
Field field = keyStore.getClass().getDeclaredField("keyStoreSpi");
|
keyStoreSpi.setAccessible(true);
|
||||||
field.setAccessible(true);
|
|
||||||
|
|
||||||
CustomKeyStoreSpi.keyStoreSpi = (KeyStoreSpi) field.get(keyStore);
|
CustomKeyStoreSpi.keyStoreSpi = (KeyStoreSpi) keyStoreSpi.get(keyStore);
|
||||||
|
|
||||||
if (CustomKeyStoreSpi.keyStoreSpi != null) spoof = true;
|
|
||||||
|
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
LOG("Error spoofing AndroidKeyStore: " + t);
|
LOG("Couldn't get keyStoreSpi: " + t);
|
||||||
}
|
}
|
||||||
|
|
||||||
Provider provider = Security.getProvider("AndroidKeyStore");
|
Provider provider = Security.getProvider("AndroidKeyStore");
|
||||||
|
|
||||||
Provider customProvider = new CustomProvider(provider, spoof);
|
Provider customProvider = new CustomProvider(provider);
|
||||||
|
|
||||||
Security.removeProvider("AndroidKeyStore");
|
Security.removeProvider("AndroidKeyStore");
|
||||||
Security.insertProviderAt(customProvider, 1);
|
Security.insertProviderAt(customProvider, 1);
|
||||||
@ -74,10 +71,11 @@ public final class EntryPoint {
|
|||||||
map.forEach((field, s) -> {
|
map.forEach((field, s) -> {
|
||||||
try {
|
try {
|
||||||
if (s.equals(field.get(null))) return;
|
if (s.equals(field.get(null))) return;
|
||||||
|
field.setAccessible(true);
|
||||||
field.set(null, s);
|
field.set(null, s);
|
||||||
LOG("Set " + field.getName() + " field value: " + s);
|
LOG("Set " + field.getName() + " field value: " + s);
|
||||||
} catch (IllegalAccessException e) {
|
} catch (Throwable t) {
|
||||||
LOG("Couldn't access " + field.getName() + " value " + s + " | Exception: " + e);
|
LOG(t.toString());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
12
changelog.md
12
changelog.md
@ -6,13 +6,7 @@ Device verdict should pass by default.
|
|||||||
If not, try removing /data/adb/pif.json file.
|
If not, try removing /data/adb/pif.json file.
|
||||||
DO NOT REMOVE pif.json in module's folder!
|
DO NOT REMOVE pif.json in module's folder!
|
||||||
|
|
||||||
# v15.7.1
|
# v15.8
|
||||||
|
|
||||||
- Fix crash issue when JSON file have comments.
|
- Correctly detect attestation certificate chain and block it.
|
||||||
- Fix hooking in older Android versions.
|
- Misc improvements.
|
||||||
- Fix CTS profile / Device verdict failures in few devices due bad spoofing code.
|
|
||||||
- Fix spoofing Provider issue.
|
|
||||||
- Added post-fs-data.sh script.
|
|
||||||
- Using latest (compileable) version of Dobby.
|
|
||||||
- Using RikkaW libcxx prefab.
|
|
||||||
- Update Gradle.
|
|
@ -62,3 +62,18 @@ if [ -d "/system/app/EliteDevelopmentModule" ]; then
|
|||||||
|
|
||||||
ui_print "- EliteDevelopmentModule app removed."
|
ui_print "- EliteDevelopmentModule app removed."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ -f "/data/adb/pif.json" ]; then
|
||||||
|
mv -f "/data/adb/pif.json" "/data/adb/pif.json.old"
|
||||||
|
ui_print "- Backup old pif.json file"
|
||||||
|
ui_print "- Module will use the default one"
|
||||||
|
ui_print "- If you want to use your custom fingerprint, remove .old extension"
|
||||||
|
fi
|
||||||
|
|
||||||
|
ui_print "! If you don't pass DEVICE verdict after install (and reboot)"
|
||||||
|
ui_print "! Check kernel release name (In Shell run: 'uname -r')"
|
||||||
|
ui_print "! Google banned few strings in kernel to avoid users using custom kernels"
|
||||||
|
ui_print "! Try to use stock kernel or not banned one"
|
||||||
|
ui_print "! Kernels with 'bad' strings like 'lineageos' are banned!"
|
||||||
|
ui_print "! Check official XDA post to know more about this"
|
||||||
|
ui_print "! If you are using stock ROM without custom kernel just ignore this"
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
id=playintegrityfix
|
id=playintegrityfix
|
||||||
name=Play Integrity Fix
|
name=Play Integrity Fix
|
||||||
version=v15.7.2
|
version=v15.8
|
||||||
versionCode=15702
|
versionCode=15800
|
||||||
author=chiteroman
|
author=chiteroman
|
||||||
description=Universal modular fix for Play Integrity (and SafetyNet) on devices running Android 8+.
|
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
|
||||||
|
@ -17,21 +17,20 @@ resetprop_if_diff() {
|
|||||||
[ -z "$CURRENT" ] || [ "$CURRENT" = "$EXPECTED" ] || resetprop "$NAME" "$EXPECTED"
|
[ -z "$CURRENT" ] || [ "$CURRENT" = "$EXPECTED" ] || resetprop "$NAME" "$EXPECTED"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Conditional early sensitive properties
|
|
||||||
|
|
||||||
# Samsung
|
|
||||||
resetprop_if_diff ro.boot.warranty_bit 0
|
|
||||||
resetprop_if_diff ro.vendor.boot.warranty_bit 0
|
|
||||||
resetprop_if_diff ro.vendor.warranty_bit 0
|
|
||||||
resetprop_if_diff ro.warranty_bit 0
|
|
||||||
|
|
||||||
# OnePlus
|
|
||||||
resetprop_if_diff ro.is_ever_orange 0
|
|
||||||
|
|
||||||
# Microsoft, RootBeer
|
|
||||||
resetprop_if_diff ro.build.tags release-keys
|
resetprop_if_diff ro.build.tags release-keys
|
||||||
|
|
||||||
# Other
|
resetprop_if_diff ro.boot.warranty_bit 0
|
||||||
|
|
||||||
|
resetprop_if_diff ro.vendor.boot.warranty_bit 0
|
||||||
|
|
||||||
|
resetprop_if_diff ro.vendor.warranty_bit 0
|
||||||
|
|
||||||
|
resetprop_if_diff ro.warranty_bit 0
|
||||||
|
|
||||||
|
resetprop_if_diff ro.is_ever_orange 0
|
||||||
|
|
||||||
resetprop_if_diff ro.build.type user
|
resetprop_if_diff ro.build.type user
|
||||||
|
|
||||||
resetprop_if_diff ro.debuggable 0
|
resetprop_if_diff ro.debuggable 0
|
||||||
|
|
||||||
resetprop_if_diff ro.secure 1
|
resetprop_if_diff ro.secure 1
|
||||||
|
@ -22,43 +22,33 @@ resetprop_if_match ro.boot.mode recovery unknown
|
|||||||
resetprop_if_match vendor.boot.mode recovery unknown
|
resetprop_if_match vendor.boot.mode recovery unknown
|
||||||
|
|
||||||
# SELinux
|
# 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
|
if [ -n "$(resetprop ro.build.selinux)" ]; then
|
||||||
resetprop --delete ro.build.selinux
|
resetprop --delete ro.build.selinux
|
||||||
fi
|
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
|
if [ "$(toybox cat /sys/fs/selinux/enforce)" = "0" ]; then
|
||||||
chmod 640 /sys/fs/selinux/enforce
|
chmod 640 /sys/fs/selinux/enforce
|
||||||
chmod 440 /sys/fs/selinux/policy
|
chmod 440 /sys/fs/selinux/policy
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Conditional late sensitive properties
|
# Late props which must be set after boot_completed
|
||||||
|
|
||||||
# SafetyNet/Play Integrity
|
|
||||||
{
|
{
|
||||||
# must be set after boot_completed for various OEMs
|
|
||||||
until [ "$(getprop sys.boot_completed)" = "1" ]; do
|
until [ "$(getprop sys.boot_completed)" = "1" ]; do
|
||||||
sleep 1
|
sleep 1
|
||||||
done
|
done
|
||||||
|
|
||||||
# avoid breaking Realme fingerprint scanners
|
|
||||||
resetprop_if_diff ro.boot.flash.locked 1
|
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
|
resetprop_if_diff ro.boot.vbmeta.device_state locked
|
||||||
|
|
||||||
# avoid breaking OnePlus display modes/fingerprint scanners
|
resetprop_if_diff ro.boot.verifiedbootstate green
|
||||||
|
|
||||||
|
resetprop_if_diff ro.boot.veritymode enforcing
|
||||||
|
|
||||||
resetprop_if_diff vendor.boot.verifiedbootstate green
|
resetprop_if_diff vendor.boot.verifiedbootstate green
|
||||||
|
|
||||||
# avoid breaking OnePlus/Oppo display fingerprint scanners on OOS/ColorOS 12+
|
|
||||||
resetprop_if_diff ro.boot.verifiedbootstate green
|
|
||||||
resetprop_if_diff ro.boot.veritymode enforcing
|
|
||||||
resetprop_if_diff vendor.boot.vbmeta.device_state locked
|
resetprop_if_diff vendor.boot.vbmeta.device_state locked
|
||||||
|
|
||||||
# Xiaomi
|
|
||||||
resetprop_if_diff ro.secureboot.lockstate locked
|
|
||||||
|
|
||||||
# Realme
|
|
||||||
resetprop_if_diff ro.boot.realmebootstate green
|
|
||||||
}&
|
}&
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"version": "v15.7.2",
|
"version": "v15.8",
|
||||||
"versionCode": 15702,
|
"versionCode": 15800,
|
||||||
"zipUrl": "https://github.com/chiteroman/PlayIntegrityFix/releases/download/v15.7.2/PlayIntegrityFix_v15.7.2.zip",
|
"zipUrl": "https://github.com/chiteroman/PlayIntegrityFix/releases/download/v15.8/PlayIntegrityFix_v15.8.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