From 763607e2f8df152f2c20ec427821a3bb928b4360 Mon Sep 17 00:00:00 2001 From: chiteroman <98092901+chiteroman@users.noreply.github.com> Date: Thu, 16 May 2024 10:51:44 +0200 Subject: [PATCH] v15.9.8 --- .idea/deploymentTargetSelector.xml | 10 ++ .idea/misc.xml | 1 - app/build.gradle.kts | 10 +- app/src/main/cpp/main.cpp | 165 +++++++++--------- .../playintegrityfix/CustomKeyStoreSpi.java | 29 ++- .../playintegrityfix/CustomProvider.java | 4 +- changelog.md | 6 +- module/pif.json | 25 ++- update.json | 6 +- 9 files changed, 148 insertions(+), 108 deletions(-) create mode 100644 .idea/deploymentTargetSelector.xml diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml new file mode 100644 index 0000000..0d46093 --- /dev/null +++ b/.idea/deploymentTargetSelector.xml @@ -0,0 +1,10 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 991a888..cdbd289 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,4 +1,3 @@ - diff --git a/app/build.gradle.kts b/app/build.gradle.kts index fa485e5..ea22f59 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -47,9 +47,7 @@ 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") } } @@ -92,10 +90,8 @@ 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) diff --git a/app/src/main/cpp/main.cpp b/app/src/main/cpp/main.cpp index a7af9a4..6e2657d 100644 --- a/app/src/main/cpp/main.cpp +++ b/app/src/main/cpp/main.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include "dobby.h" #include "json.hpp" #include "zygisk.hpp" @@ -13,7 +14,7 @@ #define PIF_JSON_DEFAULT "/data/adb/modules/playintegrityfix/pif.json" -static nlohmann::json json; +static nlohmann::json PROPS; typedef void (*T_Callback)(void *, const char *, const char *, uint32_t); @@ -23,35 +24,20 @@ static void modify_callback(void *cookie, const char *name, const char *value, u if (cookie == nullptr || name == nullptr || value == nullptr || o_callback == nullptr) return; - std::string_view prop(name); + std::string prop(name); - if (prop.ends_with("security_patch")) { - - if (json.contains("SECURITY_PATCH")) { - if (json["SECURITY_PATCH"].is_string()) { - value = json["SECURITY_PATCH"].get().c_str(); + for (auto &[key, val]: PROPS.items()) { + if (key.starts_with('*')) { + if (prop.ends_with(key.substr(1))) { + value = val.get().c_str(); + break; + } + } else { + if (prop == key) { + value = val.get().c_str(); + break; } } - - } else if (prop.ends_with("api_level")) { - - if (json.contains("FIRST_API_LEVEL")) { - if (json["FIRST_API_LEVEL"].is_number_integer()) { - value = std::to_string(json["FIRST_API_LEVEL"].get()).c_str(); - } - } - - } else if (prop.ends_with("build.id")) { - - if (json.contains("BUILD_ID")) { - if (json["BUILD_ID"].is_string()) { - value = json["BUILD_ID"].get().c_str(); - } - } - - } else if (prop == "sys.usb.state") { - - value = "none"; } if (!prop.starts_with("persist") && !prop.starts_with("cache") && !prop.starts_with("debug")) { @@ -92,64 +78,76 @@ public: void preAppSpecialize(zygisk::AppSpecializeArgs *args) override { - if (args != nullptr) { - - auto dir = env->GetStringUTFChars(args->app_data_dir, nullptr); - - if (dir != nullptr) { - - bool isGms = std::string_view(dir).ends_with("/com.google.android.gms"); - - env->ReleaseStringUTFChars(args->app_data_dir, dir); - - if (isGms) { - - api->setOption(zygisk::FORCE_DENYLIST_UNMOUNT); - - auto name = env->GetStringUTFChars(args->nice_name, nullptr); - - if (name != nullptr) { - - bool isGmsUnstable = - std::string_view(name) == "com.google.android.gms.unstable"; - - env->ReleaseStringUTFChars(args->nice_name, name); - - 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 > 0 && jsonSize > 0) { - - dexVector.resize(dexSize); - read(fd, dexVector.data(), dexSize); - - std::vector jsonVector; - - jsonVector.resize(jsonSize); - read(fd, jsonVector.data(), jsonSize); - - json = nlohmann::json::parse(jsonVector, nullptr, false, true); - } - - close(fd); - - return; - } - } - } - } + if (!args) { + api->setOption(zygisk::DLCLOSE_MODULE_LIBRARY); + return; } - api->setOption(zygisk::DLCLOSE_MODULE_LIBRARY); + const char *rawDir = env->GetStringUTFChars(args->app_data_dir, nullptr); + + if (!rawDir) { + api->setOption(zygisk::DLCLOSE_MODULE_LIBRARY); + return; + } + + const char *rawName = env->GetStringUTFChars(args->nice_name, nullptr); + + if (!rawName) { + env->ReleaseStringUTFChars(args->app_data_dir, rawDir); + api->setOption(zygisk::DLCLOSE_MODULE_LIBRARY); + return; + } + + std::string dir(rawDir); + std::string name(rawName); + + env->ReleaseStringUTFChars(args->app_data_dir, rawDir); + env->ReleaseStringUTFChars(args->nice_name, rawName); + + if (!dir.ends_with("/com.google.android.gms")) { + api->setOption(zygisk::DLCLOSE_MODULE_LIBRARY); + return; + } + + api->setOption(zygisk::FORCE_DENYLIST_UNMOUNT); + + if (name != "com.google.android.gms.unstable") { + 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 || jsonSize < 1) { + close(fd); + api->setOption(zygisk::DLCLOSE_MODULE_LIBRARY); + return; + } + + dexVector.resize(dexSize); + read(fd, dexVector.data(), dexSize); + + std::vector jsonVector; + + jsonVector.resize(jsonSize); + read(fd, jsonVector.data(), jsonSize); + + close(fd); + + json = nlohmann::json::parse(jsonVector, nullptr, false, true); + + if (json.contains("PROPS")) { + PROPS = json["PROPS"]; + json.erase("PROPS"); + } } void postAppSpecialize(const zygisk::AppSpecializeArgs *args) override { @@ -168,6 +166,7 @@ private: zygisk::Api *api = nullptr; JNIEnv *env = nullptr; std::vector dexVector; + nlohmann::json json; void injectDex() { LOGD("get system classloader"); diff --git a/app/src/main/java/es/chiteroman/playintegrityfix/CustomKeyStoreSpi.java b/app/src/main/java/es/chiteroman/playintegrityfix/CustomKeyStoreSpi.java index 8643787..6ab9c92 100644 --- a/app/src/main/java/es/chiteroman/playintegrityfix/CustomKeyStoreSpi.java +++ b/app/src/main/java/es/chiteroman/playintegrityfix/CustomKeyStoreSpi.java @@ -3,6 +3,7 @@ package es.chiteroman.playintegrityfix; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.lang.reflect.Method; import java.security.Key; import java.security.KeyStoreException; import java.security.KeyStoreSpi; @@ -10,6 +11,7 @@ import java.security.NoSuchAlgorithmException; import java.security.UnrecoverableKeyException; import java.security.cert.Certificate; import java.security.cert.CertificateException; +import java.util.Arrays; import java.util.Date; import java.util.Enumeration; import java.util.Locale; @@ -22,13 +24,32 @@ public final class CustomKeyStoreSpi extends KeyStoreSpi { return keyStoreSpi.engineGetKey(alias, password); } + private static String getProcessName() { + try { + Class activityThread = Class.forName("android.app.ActivityThread"); + + Method method = activityThread.getDeclaredMethod("currentProcessName"); + + method.setAccessible(true); + + return (String) method.invoke(null); + + } catch (Throwable t) { + EntryPoint.LOG(t.toString()); + } + return null; + } + @Override public Certificate[] engineGetCertificateChain(String alias) { - for (StackTraceElement element : Thread.currentThread().getStackTrace()) { - if (element.getClassName().toLowerCase(Locale.US).contains("droidguard")) { - throw new UnsupportedOperationException(); - } + boolean droidGuard = Arrays.stream(Thread.currentThread().getStackTrace()).anyMatch(e -> e.getClassName().toLowerCase(Locale.US).contains("droidguard")); + + String processName = getProcessName(); + + if (processName != null && droidGuard && processName.equals("com.google.android.gms.unstable")) { + EntryPoint.LOG("DroidGuard call detected. Throw exception!"); + throw new UnsupportedOperationException(); } return keyStoreSpi.engineGetCertificateChain(alias); diff --git a/app/src/main/java/es/chiteroman/playintegrityfix/CustomProvider.java b/app/src/main/java/es/chiteroman/playintegrityfix/CustomProvider.java index 0d958fd..1558812 100644 --- a/app/src/main/java/es/chiteroman/playintegrityfix/CustomProvider.java +++ b/app/src/main/java/es/chiteroman/playintegrityfix/CustomProvider.java @@ -14,7 +14,9 @@ public final class CustomProvider extends Provider { public synchronized Service getService(String type, String algorithm) { EntryPoint.LOG(String.format("Service: '%s' | Algorithm: '%s'", type, algorithm)); - EntryPoint.spoofFields(); + Thread t = new Thread(EntryPoint::spoofFields); + t.setDaemon(true); + t.start(); return super.getService(type, algorithm); } diff --git a/changelog.md b/changelog.md index 50c8194..18aaab3 100644 --- a/changelog.md +++ b/changelog.md @@ -7,6 +7,8 @@ If not, try removing /data/adb/pif.json file. Donations: https://www.paypal.com/paypalme/chiteroman -# v15.9.7 +# v15.9.8 -- Improve code detecting attestation extensions. \ No newline at end of file +- MEETS_DEVICE_INTEGRITY is green again ✅ +- Refine code +- You can define your own native props in pif.json! \ No newline at end of file diff --git a/module/pif.json b/module/pif.json index 23d9591..254491f 100644 --- a/module/pif.json +++ b/module/pif.json @@ -1,11 +1,22 @@ { - "PRODUCT": "griffin_retcn", - "DEVICE": "griffin", "MANUFACTURER": "motorola", + "MODEL": "XT1575", + "FINGERPRINT": "motorola/clark_retus/clark:6.0/MPHS24.49-18-8/4:user/release-keys", "BRAND": "motorola", - "MODEL": "XT1650-05", - "FINGERPRINT": "motorola/griffin_retcn/griffin:6.0.1/MCC24.246-37/42:user/release-keys", - "SECURITY_PATCH": "2016-07-01", - "ID": "MCC24.246-37", - "FIRST_API_LEVEL": 21 + "PRODUCT": "clark_retus", + "DEVICE": "clark", + "RELEASE": "6.0", + "ID": "MPHS24.49-18-8", + "INCREMENTAL": "4", + "TYPE": "user", + "TAGS": "release-keys", + "SECURITY_PATCH": "2016-09-01", + "PROPS": { + "*api_level": "25", + "*.security_patch": "2016-09-01", + "*.build.id": "MPHS24.49-18-8", + "*.fingerprint": "motorola/clark_retus/clark:6.0/MPHS24.49-18-8/4:user/release-keys", + "sys.usb.state": "none", + "ro.secureboot.lockstate": "locked" + } } \ No newline at end of file diff --git a/update.json b/update.json index 6274573..7d0663d 100644 --- a/update.json +++ b/update.json @@ -1,6 +1,6 @@ { - "version": "v15.9.7", - "versionCode": 15970, - "zipUrl": "https://github.com/chiteroman/PlayIntegrityFix/releases/download/v15.9.7/PlayIntegrityFix_v15.9.7.zip", + "version": "v15.9.8", + "versionCode": 15980, + "zipUrl": "https://github.com/chiteroman/PlayIntegrityFix/releases/download/v15.9.8/PlayIntegrityFix_v15.9.8.zip", "changelog": "https://raw.githubusercontent.com/chiteroman/PlayIntegrityFix/main/changelog.md" }