mirror of
https://github.com/chiteroman/PlayIntegrityFix.git
synced 2025-01-19 03:22:39 +02:00
v15.7.2
This commit is contained in:
parent
0dd66bfe1d
commit
1f6fadf058
@ -12,8 +12,8 @@ android {
|
|||||||
applicationId = "es.chiteroman.playintegrityfix"
|
applicationId = "es.chiteroman.playintegrityfix"
|
||||||
minSdk = 26
|
minSdk = 26
|
||||||
targetSdk = 34
|
targetSdk = 34
|
||||||
versionCode = 15701
|
versionCode = 15702
|
||||||
versionName = "v15.7.1"
|
versionName = "v15.7.2"
|
||||||
multiDexEnabled = false
|
multiDexEnabled = false
|
||||||
|
|
||||||
buildFeatures {
|
buildFeatures {
|
||||||
|
@ -16,11 +16,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
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return o_callback(cookie, name, value, serial);
|
return callbacks[cookie](cookie, name, value, serial);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void (*o_system_property_read_callback)(const void *, T_Callback, void *);
|
static void (*o_system_property_read_callback)(const void *, T_Callback, void *);
|
||||||
@ -62,12 +64,12 @@ my_system_property_read_callback(const void *pi, T_Callback callback, void *cook
|
|||||||
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'. Report to @chiteroman");
|
||||||
return;
|
return;
|
||||||
|
@ -15,7 +15,7 @@ import java.util.Enumeration;
|
|||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
public final class CustomKeyStoreSpi extends KeyStoreSpi {
|
public final class CustomKeyStoreSpi extends KeyStoreSpi {
|
||||||
public static volatile KeyStoreSpi keyStoreSpi;
|
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 {
|
||||||
|
@ -4,19 +4,19 @@ import java.security.Provider;
|
|||||||
|
|
||||||
public final class CustomProvider extends Provider {
|
public final class CustomProvider extends Provider {
|
||||||
|
|
||||||
public CustomProvider(Provider provider) {
|
public CustomProvider(Provider provider, boolean spoof) {
|
||||||
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));
|
||||||
|
|
||||||
EntryPoint.spoofFields();
|
if ("AndroidKeyStore".equals(algorithm)) EntryPoint.spoofFields();
|
||||||
|
|
||||||
return super.getService(type, algorithm);
|
return super.getService(type, algorithm);
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@ 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");
|
||||||
|
|
||||||
@ -24,13 +25,16 @@ public final class EntryPoint {
|
|||||||
field.setAccessible(true);
|
field.setAccessible(true);
|
||||||
|
|
||||||
CustomKeyStoreSpi.keyStoreSpi = (KeyStoreSpi) field.get(keyStore);
|
CustomKeyStoreSpi.keyStoreSpi = (KeyStoreSpi) field.get(keyStore);
|
||||||
|
|
||||||
|
if (CustomKeyStoreSpi.keyStoreSpi != null) spoof = true;
|
||||||
|
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
LOG("Error spoofing AndroidKeyStore: " + t);
|
LOG("Error spoofing AndroidKeyStore: " + t);
|
||||||
}
|
}
|
||||||
|
|
||||||
Provider provider = Security.getProvider("AndroidKeyStore");
|
Provider provider = Security.getProvider("AndroidKeyStore");
|
||||||
|
|
||||||
Provider customProvider = new CustomProvider(provider);
|
Provider customProvider = new CustomProvider(provider, spoof);
|
||||||
|
|
||||||
Security.removeProvider("AndroidKeyStore");
|
Security.removeProvider("AndroidKeyStore");
|
||||||
Security.insertProviderAt(customProvider, 1);
|
Security.insertProviderAt(customProvider, 1);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
id=playintegrityfix
|
id=playintegrityfix
|
||||||
name=Play Integrity Fix
|
name=Play Integrity Fix
|
||||||
version=v15.7.1
|
version=v15.7.2
|
||||||
versionCode=15701
|
versionCode=15702
|
||||||
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+.
|
||||||
updateJson=https://raw.githubusercontent.com/chiteroman/PlayIntegrityFix/main/update.json
|
updateJson=https://raw.githubusercontent.com/chiteroman/PlayIntegrityFix/main/update.json
|
||||||
|
@ -8,3 +8,30 @@ if [ -d /data/adb/modules/safetynet-fix ]; then
|
|||||||
rm -rf /data/adb/modules/safetynet-fix
|
rm -rf /data/adb/modules/safetynet-fix
|
||||||
rm -rf /data/adb/SNFix.dex
|
rm -rf /data/adb/SNFix.dex
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
resetprop_if_diff() {
|
||||||
|
local NAME="$1"
|
||||||
|
local EXPECTED="$2"
|
||||||
|
local CURRENT="$(resetprop "$NAME")"
|
||||||
|
|
||||||
|
[ -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
|
||||||
|
|
||||||
|
# Other
|
||||||
|
resetprop_if_diff ro.build.type user
|
||||||
|
resetprop_if_diff ro.debuggable 0
|
||||||
|
resetprop_if_diff ro.secure 1
|
||||||
|
@ -1,19 +1,19 @@
|
|||||||
# Conditional sensitive properties
|
# Conditional sensitive properties
|
||||||
|
|
||||||
resetprop_if_diff() {
|
resetprop_if_diff() {
|
||||||
local NAME=$1
|
local NAME="$1"
|
||||||
local EXPECTED=$2
|
local EXPECTED="$2"
|
||||||
local CURRENT=$(resetprop $NAME)
|
local CURRENT="$(resetprop "$NAME")"
|
||||||
|
|
||||||
[ -z "$CURRENT" ] || [ "$CURRENT" == "$EXPECTED" ] || resetprop $NAME $EXPECTED
|
[ -z "$CURRENT" ] || [ "$CURRENT" = "$EXPECTED" ] || resetprop "$NAME" "$EXPECTED"
|
||||||
}
|
}
|
||||||
|
|
||||||
resetprop_if_match() {
|
resetprop_if_match() {
|
||||||
local NAME=$1
|
local NAME="$1"
|
||||||
local CONTAINS=$2
|
local CONTAINS="$2"
|
||||||
local VALUE=$3
|
local VALUE="$3"
|
||||||
|
|
||||||
[[ "$(resetprop $NAME)" == *"$CONTAINS"* ]] && resetprop $NAME $VALUE
|
[[ "$(resetprop "$NAME")" = *"$CONTAINS"* ]] && resetprop "$NAME" "$VALUE"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Magisk recovery mode
|
# Magisk recovery mode
|
||||||
@ -32,34 +32,15 @@ if [ "$(toybox cat /sys/fs/selinux/enforce)" == "0" ]; then
|
|||||||
chmod 440 /sys/fs/selinux/policy
|
chmod 440 /sys/fs/selinux/policy
|
||||||
fi
|
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
|
until [ "$(getprop sys.boot_completed)" = "1" ]; do
|
||||||
sleep 1
|
sleep 1
|
||||||
done
|
done
|
||||||
|
|
||||||
# RootBeer, Microsoft
|
|
||||||
resetprop_if_diff ro.build.tags release-keys
|
|
||||||
|
|
||||||
# Samsung
|
|
||||||
resetprop_if_diff ro.boot.warranty_bit 0
|
|
||||||
resetprop_if_diff ro.vendor.boot.warranty_bit 0
|
|
||||||
resetprop_if_diff ro.vendor.warranty_bit 0
|
|
||||||
resetprop_if_diff ro.warranty_bit 0
|
|
||||||
|
|
||||||
# Xiaomi
|
|
||||||
resetprop_if_diff ro.secureboot.lockstate locked
|
|
||||||
|
|
||||||
# Realme
|
|
||||||
resetprop_if_diff ro.boot.realmebootstate green
|
|
||||||
|
|
||||||
# OnePlus
|
|
||||||
resetprop_if_diff ro.is_ever_orange 0
|
|
||||||
|
|
||||||
# Other
|
|
||||||
resetprop_if_diff ro.build.type user
|
|
||||||
resetprop_if_diff ro.debuggable 0
|
|
||||||
resetprop_if_diff ro.secure 1
|
|
||||||
|
|
||||||
# avoid breaking Realme fingerprint scanners
|
# 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
|
resetprop_if_diff ro.boot.realme.lockstate 1
|
||||||
@ -74,3 +55,10 @@ resetprop_if_diff vendor.boot.verifiedbootstate green
|
|||||||
resetprop_if_diff ro.boot.verifiedbootstate green
|
resetprop_if_diff ro.boot.verifiedbootstate green
|
||||||
resetprop_if_diff ro.boot.veritymode enforcing
|
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
|
||||||
|
}&
|
||||||
|
Loading…
Reference in New Issue
Block a user