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"
}