Skip to content

Commit

Permalink
v15.7.1
Browse files Browse the repository at this point in the history
  • Loading branch information
chiteroman committed Feb 7, 2024
1 parent bdef429 commit 0dd66bf
Show file tree
Hide file tree
Showing 12 changed files with 227 additions and 48 deletions.
6 changes: 6 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ android {
applicationId = "es.chiteroman.playintegrityfix"
minSdk = 26
targetSdk = 34
versionCode = 15700
versionName = "v15.7"
versionCode = 15701
versionName = "v15.7.1"
multiDexEnabled = false

buildFeatures {
Expand Down
62 changes: 62 additions & 0 deletions app/src/main/cpp/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,68 @@ class PlayIntegrityFix : public zygisk::ModuleBase {
}

void parseJson() {
if (json.contains("FIRST_API_LEVEL")) {

if (json["FIRST_API_LEVEL"].is_number_integer()) {

FIRST_API_LEVEL = std::to_string(json["FIRST_API_LEVEL"].get<int>());

} else if (json["FIRST_API_LEVEL"].is_string()) {

FIRST_API_LEVEL = json["FIRST_API_LEVEL"].get<std::string>();
}

json.erase("FIRST_API_LEVEL");

} else if (json.contains("DEVICE_INITIAL_SDK_INT")) {

if (json["DEVICE_INITIAL_SDK_INT"].is_number_integer()) {

FIRST_API_LEVEL = std::to_string(json["DEVICE_INITIAL_SDK_INT"].get<int>());

} else if (json["DEVICE_INITIAL_SDK_INT"].is_string()) {

FIRST_API_LEVEL = json["DEVICE_INITIAL_SDK_INT"].get<std::string>();
}

} else {

LOGD("JSON file doesn't contain FIRST_API_LEVEL or DEVICE_INITIAL_SDK_INT keys :(");
}

if (json.contains("SECURITY_PATCH")) {

if (json["SECURITY_PATCH"].is_string()) {

SECURITY_PATCH = json["SECURITY_PATCH"].get<std::string>();
}

} else {

LOGD("JSON file doesn't contain SECURITY_PATCH key :(");
}

if (json.contains("ID")) {

if (json["ID"].is_string()) {

BUILD_ID = json["ID"].get<std::string>();
}

} else if (json.contains("BUILD_ID")) {

if (json["BUILD_ID"].is_string()) {

BUILD_ID = json["BUILD_ID"].get<std::string>();
}

json["ID"] = BUILD_ID;
json.erase("BUILD_ID");

} else {

LOGD("JSON file doesn't contain ID/BUILD_ID keys :(");
}
}
};

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package es.chiteroman.playintegrityfix;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.Key;
import java.security.KeyStoreException;
import java.security.KeyStoreSpi;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.util.Date;
import java.util.Enumeration;
import java.util.Locale;

public final class CustomKeyStoreSpi extends KeyStoreSpi {
public static volatile KeyStoreSpi keyStoreSpi;

@Override
public Key engineGetKey(String alias, char[] password) throws NoSuchAlgorithmException, UnrecoverableKeyException {
return keyStoreSpi.engineGetKey(alias, password);
}

@Override
public Certificate[] engineGetCertificateChain(String alias) {
for (StackTraceElement stackTraceElement : Thread.currentThread().getStackTrace()) {
if (stackTraceElement.getClassName().toLowerCase(Locale.US).contains("droidguard")) {
EntryPoint.LOG("DroidGuard call certificate chain! Throw exception.");
throw new UnsupportedOperationException();
}
}
return keyStoreSpi.engineGetCertificateChain(alias);
}

@Override
public Certificate engineGetCertificate(String alias) {
return keyStoreSpi.engineGetCertificate(alias);
}

@Override
public Date engineGetCreationDate(String alias) {
return keyStoreSpi.engineGetCreationDate(alias);
}

@Override
public void engineSetKeyEntry(String alias, Key key, char[] password, Certificate[] chain) throws KeyStoreException {
keyStoreSpi.engineSetKeyEntry(alias, key, password, chain);
}

@Override
public void engineSetKeyEntry(String alias, byte[] key, Certificate[] chain) throws KeyStoreException {
keyStoreSpi.engineSetKeyEntry(alias, key, chain);
}

@Override
public void engineSetCertificateEntry(String alias, Certificate cert) throws KeyStoreException {
keyStoreSpi.engineSetCertificateEntry(alias, cert);
}

@Override
public void engineDeleteEntry(String alias) throws KeyStoreException {
keyStoreSpi.engineDeleteEntry(alias);
}

@Override
public Enumeration<String> engineAliases() {
return keyStoreSpi.engineAliases();
}

@Override
public boolean engineContainsAlias(String alias) {
return keyStoreSpi.engineContainsAlias(alias);
}

@Override
public int engineSize() {
return keyStoreSpi.engineSize();
}

@Override
public boolean engineIsKeyEntry(String alias) {
return keyStoreSpi.engineIsKeyEntry(alias);
}

@Override
public boolean engineIsCertificateEntry(String alias) {
return keyStoreSpi.engineIsCertificateEntry(alias);
}

@Override
public String engineGetCertificateAlias(Certificate cert) {
return keyStoreSpi.engineGetCertificateAlias(cert);
}

@Override
public void engineStore(OutputStream stream, char[] password) throws CertificateException, IOException, NoSuchAlgorithmException {
keyStoreSpi.engineStore(stream, password);
}

@Override
public void engineLoad(InputStream stream, char[] password) throws CertificateException, IOException, NoSuchAlgorithmException {
keyStoreSpi.engineLoad(stream, password);
}
}
Original file line number Diff line number Diff line change
@@ -1,27 +1,22 @@
package es.chiteroman.playintegrityfix;

import java.security.Provider;
import java.security.ProviderException;

public final class CustomProvider extends Provider {

public CustomProvider(Provider provider) {
super(provider.getName(), provider.getVersion(), provider.getInfo());

putAll(provider);

put("KeyStore.AndroidKeyStore", CustomKeyStoreSpi.class.getName());
}

@Override
public synchronized Service getService(String type, String algorithm) {
EntryPoint.spoofFields();

EntryPoint.LOG(String.format("Service: '%s' | Algorithm: '%s'", type, algorithm));

if ("AndroidKeyStore".equals(algorithm)) {
Service service = super.getService(type, algorithm);
EntryPoint.LOG(service.toString());
throw new ProviderException();
}
EntryPoint.spoofFields();

return super.getService(type, algorithm);
}
Expand Down
13 changes: 13 additions & 0 deletions app/src/main/java/es/chiteroman/playintegrityfix/EntryPoint.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import org.json.JSONObject;

import java.lang.reflect.Field;
import java.security.KeyStore;
import java.security.KeyStoreSpi;
import java.security.Provider;
import java.security.Security;
import java.util.HashMap;
Expand All @@ -15,6 +17,17 @@ public final class EntryPoint {
private static final Map<Field, String> map = new HashMap<>();

static {
try {
KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");

Field field = keyStore.getClass().getDeclaredField("keyStoreSpi");
field.setAccessible(true);

CustomKeyStoreSpi.keyStoreSpi = (KeyStoreSpi) field.get(keyStore);
} catch (Throwable t) {
LOG("Error spoofing AndroidKeyStore: " + t);
}

Provider provider = Security.getProvider("AndroidKeyStore");

Provider customProvider = new CustomProvider(provider);
Expand Down
19 changes: 12 additions & 7 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,17 @@ We have a Telegram group!
If you want to share your knowledge join:
https://t.me/playintegrityfix

# v15.6

- Fix bootloop issue in modern devices.
- Move code logic to C.
- Minor improvements.

Device verdict should pass by default.
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

- Fix crash issue when JSON file have comments.
- Fix hooking in older Android versions.
- 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.
Binary file modified gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
16 changes: 7 additions & 9 deletions gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
#Wed Feb 07 09:57:46 CET 2024
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionSha256Sum=9d926787066a081739e8200858338b4a69e837c3a821a33aca9db09dd4a41026
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
#Wed Feb 07 18:13:12 CET 2024
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
networkTimeout=10000
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
29 changes: 12 additions & 17 deletions gradlew
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,10 @@ done
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit

# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'

# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
Expand Down Expand Up @@ -131,29 +133,26 @@ location of your Java installation."
fi
else
JAVACMD=java
if ! command -v java >/dev/null 2>&1
then
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
fi

# Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
# shellcheck disable=SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
# shellcheck disable=SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
Expand Down Expand Up @@ -198,15 +197,11 @@ if "$cygwin" || "$msys" ; then
done
fi


# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'

# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, 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.
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded.

set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
Expand Down
4 changes: 2 additions & 2 deletions module/module.prop
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
id=playintegrityfix
name=Play Integrity Fix
version=v15.7
versionCode=15700
version=v15.7.1
versionCode=15701
author=chiteroman
description=Universal modular fix for Play Integrity (and SafetyNet) on devices running Android 8+.
updateJson=https://raw.githubusercontent.com/chiteroman/PlayIntegrityFix/main/update.json
6 changes: 3 additions & 3 deletions update.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"version": "v15.6",
"versionCode": 15600,
"zipUrl": "https://github.com/chiteroman/PlayIntegrityFix/releases/download/v15.6/PlayIntegrityFix_v15.6.zip",
"version": "v15.7.1",
"versionCode": 15701,
"zipUrl": "https://github.com/chiteroman/PlayIntegrityFix/releases/download/v15.7/PlayIntegrityFix_v15.7.1.zip",
"changelog": "https://raw.githubusercontent.com/chiteroman/PlayIntegrityFix/main/changelog.md"
}

0 comments on commit 0dd66bf

Please sign in to comment.