Mini update

This commit is contained in:
chiteroman 2024-04-23 16:32:22 +02:00
parent 0287cfcd26
commit 9e2b59e72f
15 changed files with 55 additions and 142 deletions

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="17" />
<bytecodeTargetLevel target="21" />
</component>
</project>

View File

@ -5,7 +5,7 @@
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleJvm" value="#GRADLE_LOCAL_JAVA_HOME" />
<option name="gradleJvm" value="#JAVA_HOME" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<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_21" default="true" project-jdk-name="temurin-21" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">

View File

@ -5,21 +5,21 @@ plugins {
android {
namespace = "es.chiteroman.playintegrityfix"
compileSdk = 34
ndkVersion = "26.2.11394342"
ndkVersion = "26.3.11579264"
buildToolsVersion = "34.0.0"
buildFeatures {
prefab = true
}
defaultConfig {
applicationId = "es.chiteroman.playintegrityfix"
minSdk = 26
targetSdk = 34
versionCode = 15970
versionName = "v15.9.7"
versionCode = 15980
versionName = "v15.9.8"
multiDexEnabled = false
buildFeatures {
prefab = true
}
packaging {
jniLibs {
excludes += "**/liblog.so"
@ -47,7 +47,9 @@ android {
isMinifyEnabled = true
isShrinkResources = true
multiDexEnabled = false
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro"
)
}
}
@ -90,8 +92,10 @@ 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 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")
dexFile.copyTo(moduleFolder.resolve("classes.dex"), overwrite = true)

View File

@ -4,10 +4,12 @@ project(playintegrityfix)
find_package(cxx REQUIRED CONFIG)
link_libraries(log)
link_libraries(cxx::cxx)
add_library(${CMAKE_PROJECT_NAME} SHARED main.cpp)
add_subdirectory(Dobby)
target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE log dobby_static)
target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE dobby_static)

View File

@ -13,36 +13,40 @@
#define PIF_JSON_DEFAULT "/data/adb/modules/playintegrityfix/pif.json"
static std::string FIRST_API_LEVEL, SECURITY_PATCH, BUILD_ID;
static nlohmann::json json;
typedef void (*T_Callback)(void *, const char *, const char *, uint32_t);
static std::map<void *, T_Callback> callbacks;
static T_Callback o_callback = nullptr;
static void modify_callback(void *cookie, const char *name, const char *value, uint32_t serial) {
if (cookie == nullptr || name == nullptr || value == nullptr ||
!callbacks.contains(cookie))
return;
if (cookie == nullptr || name == nullptr || value == nullptr || o_callback == nullptr) return;
std::string_view prop(name);
if (prop.ends_with("security_patch")) {
if (!SECURITY_PATCH.empty()) {
value = SECURITY_PATCH.c_str();
if (json.contains("SECURITY_PATCH")) {
if (json["SECURITY_PATCH"].is_string()) {
value = json["SECURITY_PATCH"].get<std::string>().c_str();
}
}
} else if (prop.ends_with("api_level")) {
if (!FIRST_API_LEVEL.empty()) {
value = FIRST_API_LEVEL.c_str();
if (json.contains("FIRST_API_LEVEL")) {
if (json["FIRST_API_LEVEL"].is_number_integer()) {
value = std::to_string(json["FIRST_API_LEVEL"].get<int>()).c_str();
}
}
} else if (prop.ends_with("build.id")) {
if (!BUILD_ID.empty()) {
value = BUILD_ID.c_str();
if (json.contains("BUILD_ID")) {
if (json["BUILD_ID"].is_string()) {
value = json["BUILD_ID"].get<std::string>().c_str();
}
}
} else if (prop == "sys.usb.state") {
@ -54,7 +58,7 @@ static void modify_callback(void *cookie, const char *name, const char *value, u
LOGD("[%s]: %s", name, value);
}
return callbacks[cookie](cookie, name, value, serial);
return o_callback(cookie, name, value, serial);
}
static void (*o_system_property_read_callback)(const prop_info *, T_Callback, void *);
@ -64,7 +68,7 @@ my_system_property_read_callback(const prop_info *pi, T_Callback callback, void
if (pi == nullptr || callback == nullptr || cookie == nullptr) {
return o_system_property_read_callback(pi, callback, cookie);
}
callbacks[cookie] = callback;
o_callback = callback;
return o_system_property_read_callback(pi, modify_callback, cookie);
}
@ -134,8 +138,6 @@ public:
read(fd, jsonVector.data(), jsonSize);
json = nlohmann::json::parse(jsonVector, nullptr, false, true);
parseJson();
}
close(fd);
@ -166,7 +168,6 @@ private:
zygisk::Api *api = nullptr;
JNIEnv *env = nullptr;
std::vector<uint8_t> dexVector;
nlohmann::json json;
void injectDex() {
LOGD("get system classloader");
@ -195,71 +196,6 @@ private:
auto str = env->NewStringUTF(json.dump().c_str());
env->CallStaticVoidMethod(entryPointClass, entryInit, str);
}
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 :(");
}
}
};
static std::vector<uint8_t> readFile(const char *path) {

View File

@ -10,15 +10,12 @@ import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Date;
import java.util.Enumeration;
import java.util.Locale;
public final class CustomKeyStoreSpi extends KeyStoreSpi {
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";
public static volatile KeyStoreSpi keyStoreSpi;
public static volatile KeyStoreSpi keyStoreSpi = null;
@Override
public Key engineGetKey(String alias, char[] password) throws NoSuchAlgorithmException, UnrecoverableKeyException {
@ -28,41 +25,18 @@ public final class CustomKeyStoreSpi extends KeyStoreSpi {
@Override
public Certificate[] engineGetCertificateChain(String alias) {
boolean isDroidGuard = EntryPoint.isDroidGuard();
Certificate[] certificates = keyStoreSpi.engineGetCertificateChain(alias);
if (certificates[0] instanceof X509Certificate leaf) {
boolean attestationExtensions = leaf.getExtensionValue(EAT_OID) != null || leaf.getExtensionValue(ASN1_OID) != null || leaf.getExtensionValue(KNOX_OID) != null;
if (isDroidGuard && attestationExtensions) {
EntryPoint.LOG("DroidGuard and attestation extension detected! Throwing exception...");
for (StackTraceElement element : Thread.currentThread().getStackTrace()) {
if (element.getClassName().toLowerCase(Locale.US).contains("droidguard")) {
throw new UnsupportedOperationException();
}
}
return certificates;
return keyStoreSpi.engineGetCertificateChain(alias);
}
@Override
public Certificate engineGetCertificate(String alias) {
boolean isDroidGuard = EntryPoint.isDroidGuard();
Certificate certificate = keyStoreSpi.engineGetCertificate(alias);
if (certificate instanceof X509Certificate leaf) {
boolean attestationExtensions = leaf.getExtensionValue(EAT_OID) != null || leaf.getExtensionValue(ASN1_OID) != null || leaf.getExtensionValue(KNOX_OID) != null;
if (isDroidGuard && attestationExtensions) {
EntryPoint.LOG("DroidGuard and attestation extension detected! Throwing exception...");
throw new UnsupportedOperationException();
}
}
return certificate;
return keyStoreSpi.engineGetCertificate(alias);
}
@Override

View File

@ -10,9 +10,7 @@ import java.security.KeyStore;
import java.security.KeyStoreSpi;
import java.security.Provider;
import java.security.Security;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
public final class EntryPoint {
@ -82,10 +80,6 @@ public final class EntryPoint {
});
}
static boolean isDroidGuard() {
return Arrays.stream(Thread.currentThread().getStackTrace()).anyMatch(stackTraceElement -> stackTraceElement.getClassName().toLowerCase(Locale.US).contains("droidguard"));
}
private static Field getFieldByName(String name) {
Field field;

View File

@ -1,3 +1,6 @@
buildscript {
val agp_version by extra("8.3.2")
}
plugins {
id("com.android.application") version "8.3.1" apply false
id("com.android.application") version "8.3.2" apply false
}

View File

@ -1,7 +1,7 @@
#Wed Feb 07 18:13:12 CET 2024
#Thu Apr 18 12:59:17 CEST 2024
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
networkTimeout=10000
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

View File

@ -30,4 +30,4 @@ mount /data 2>/dev/null
[ $MAGISK_VER_CODE -lt 20400 ] && require_new_magisk
install_module
exit 0
exit 0

View File

@ -20,4 +20,4 @@ if [ -f "/data/adb/pif.json" ]; then
ui_print "- You are using custom fingerprint!"
ui_print "- If you fail DEVICE verdict, remove /data/adb/pif.json file"
ui_print "- If pif.json file doesn't exist, module will use default one"
fi
fi

View File

@ -1,7 +1,7 @@
id=playintegrityfix
name=Play Integrity Fix
version=v15.9.7
versionCode=15970
version=v15.9.8
versionCode=15980
author=chiteroman
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

View File

@ -8,4 +8,4 @@
"SECURITY_PATCH": "2016-07-01",
"ID": "MCC24.246-37",
"FIRST_API_LEVEL": 21
}
}

View File

@ -53,4 +53,4 @@ fi
resetprop_if_diff ro.boot.verifiedbootstate green
resetprop_if_diff ro.boot.veritymode enforcing
resetprop_if_diff vendor.boot.vbmeta.device_state locked
}&
}&