Custom props!

This commit is contained in:
chiteroman 2023-11-25 17:31:37 +01:00
parent 27c00e2ce7
commit edffde9b1a
No known key found for this signature in database
GPG Key ID: 15FF53015D426D8E
7 changed files with 24804 additions and 49 deletions

View File

@ -28,7 +28,7 @@ It injects a classes.dex file to modify few fields in android.os.Build class. Al
it creates a hook to modify system properties. it creates a hook to modify system properties.
The purpose of the module is to avoid a hardware attestation. The purpose of the module is to avoid a hardware attestation.
## About 'pif.prop' file ## About 'pif.json' file
You can modify this file to spoof android.os.Build fields in GMS unstable process and try to pass Device verdict. You can modify this file to spoof android.os.Build fields in GMS unstable process and try to pass Device verdict.
You can't use values from recent devices due this devices must use a hardware attestation. You can't use values from recent devices due this devices must use a hardware attestation.

24689
app/src/main/cpp/json.hpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,18 +1,19 @@
#include <android/log.h> #include <android/log.h>
#include <sys/system_properties.h> #include <sys/system_properties.h>
#include <unistd.h> #include <unistd.h>
#include <string_view> #include <fstream>
#include <map>
#include <vector>
#include "zygisk.hpp" #include "zygisk.hpp"
#include "dobby.h" #include "dobby.h"
#include "json.hpp"
#define DEX_FILE_PATH "/data/adb/modules/playintegrityfix/classes.dex"
#define PROP_FILE_PATH "/data/adb/modules/playintegrityfix/pif.json"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, "PIF/Native", __VA_ARGS__) #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, "PIF/Native", __VA_ARGS__)
#define FIRST_API_LEVEL "25" static std::string FIRST_API_LEVEL, SECURITY_PATCH;
#define SECURITY_PATCH "2017-08-05"
typedef void (*T_Callback)(void *, const char *, const char *, uint32_t); typedef void (*T_Callback)(void *, const char *, const char *, uint32_t);
@ -27,10 +28,18 @@ static void modify_callback(void *cookie, const char *name, const char *value, u
std::string_view prop(name); std::string_view prop(name);
if (prop.ends_with("api_level")) { if (prop.ends_with("api_level")) {
value = FIRST_API_LEVEL; if (FIRST_API_LEVEL == "NULL") {
value = nullptr;
} else {
value = FIRST_API_LEVEL.c_str();
}
LOGD("[%s] -> %s", name, value); LOGD("[%s] -> %s", name, value);
} else if (prop.ends_with("security_patch")) { } else if (prop.ends_with("security_patch")) {
value = SECURITY_PATCH; if (SECURITY_PATCH == "NULL") {
value = nullptr;
} else {
value = SECURITY_PATCH.c_str();
}
LOGD("[%s] -> %s", name, value); LOGD("[%s] -> %s", name, value);
} }
@ -90,23 +99,44 @@ public:
return; return;
} }
ssize_t size;
char buffer[10000];
int fd = api->connectCompanion(); int fd = api->connectCompanion();
long size; size = read(fd, buffer, sizeof(buffer));
char buffer[1024];
while ((size = read(fd, buffer, sizeof(buffer))) > 0) { if (size > 0) {
moduleDex.insert(moduleDex.end(), buffer, buffer + size); moduleDex.insert(moduleDex.end(), buffer, buffer + size);
} else {
LOGD("Couldn't load classes.dex file in memory");
close(fd);
api->setOption(zygisk::DLCLOSE_MODULE_LIBRARY);
return;
}
lseek(fd, 0, SEEK_SET);
size = read(fd, buffer, sizeof(buffer));
if (size > 0) {
jsonStr.insert(jsonStr.end(), buffer, buffer + size);
} else {
LOGD("Couldn't load pif.json file in memory");
} }
close(fd); close(fd);
LOGD("Received from socket %lu bytes!", moduleDex.size()); LOGD("Received 'classes.dex' file from socket: %d bytes",
static_cast<int>(moduleDex.size()));
LOGD("Received 'pif.json' file from socket: %d bytes", static_cast<int>(jsonStr.size()));
} }
void postAppSpecialize(const zygisk::AppSpecializeArgs *args) override { void postAppSpecialize(const zygisk::AppSpecializeArgs *args) override {
if (moduleDex.empty()) return; if (moduleDex.empty()) return;
readJson();
inject(); inject();
doHook(); doHook();
@ -120,6 +150,21 @@ private:
zygisk::Api *api = nullptr; zygisk::Api *api = nullptr;
JNIEnv *env = nullptr; JNIEnv *env = nullptr;
std::vector<char> moduleDex; std::vector<char> moduleDex;
std::string jsonStr;
void readJson() {
nlohmann::json json = nlohmann::json::parse(jsonStr, nullptr, false);
auto getStringFromJson = [&json](const std::string &key) {
return json.contains(key) && !json[key].is_null() ? json[key].get<std::string>()
: "NULL";
};
SECURITY_PATCH = getStringFromJson("SECURITY_PATCH");
FIRST_API_LEVEL = getStringFromJson("FIRST_API_LEVEL");
json.clear();
}
void inject() { void inject() {
LOGD("get system classloader"); LOGD("get system classloader");
@ -144,34 +189,34 @@ private:
auto entryClass = (jclass) entryClassObj; auto entryClass = (jclass) entryClassObj;
LOGD("read json");
auto readProps = env->GetStaticMethodID(entryClass, "readJson",
"(Ljava/lang/String;)V");
auto javaStr = env->NewStringUTF(jsonStr.c_str());
env->CallStaticVoidMethod(entryClass, readProps, javaStr);
LOGD("call init"); LOGD("call init");
auto entryInit = env->GetStaticMethodID(entryClass, "init", "()V"); auto entryInit = env->GetStaticMethodID(entryClass, "init", "()V");
env->CallStaticVoidMethod(entryClass, entryInit); env->CallStaticVoidMethod(entryClass, entryInit);
moduleDex.clear(); moduleDex.clear();
jsonStr.clear();
} }
}; };
static void companion(int fd) { static void companion(int fd) {
FILE *file = fopen("/data/adb/modules/playintegrityfix/classes.dex", "rb"); std::ifstream dex(DEX_FILE_PATH, std::ios::binary);
std::ifstream prop(PROP_FILE_PATH);
if (file == nullptr) { std::vector<char> dexVector((std::istreambuf_iterator<char>(dex)),
write(fd, nullptr, 0); std::istreambuf_iterator<char>());
return;
}
fseek(file, 0, SEEK_END); std::vector<char> propVector((std::istreambuf_iterator<char>(prop)),
long size = ftell(file); std::istreambuf_iterator<char>());
fseek(file, 0, SEEK_SET);
std::vector<char> vector(size); write(fd, dexVector.data(), dexVector.size());
fread(vector.data(), 1, size, file); lseek(fd, 0, SEEK_SET);
write(fd, propVector.data(), propVector.size());
fclose(file);
write(fd, vector.data(), size);
vector.clear();
} }
REGISTER_ZYGISK_MODULE(PlayIntegrityFix) REGISTER_ZYGISK_MODULE(PlayIntegrityFix)

View File

@ -1,29 +1,40 @@
package es.chiteroman.playintegrityfix; package es.chiteroman.playintegrityfix;
import android.os.Build; import android.os.Build;
import android.util.JsonReader;
import android.util.Log; import android.util.Log;
import java.io.IOException;
import java.io.StringReader;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.security.KeyStore; import java.security.KeyStore;
import java.security.KeyStoreException; import java.security.KeyStoreException;
import java.security.KeyStoreSpi; import java.security.KeyStoreSpi;
import java.security.Provider; import java.security.Provider;
import java.security.Security; import java.security.Security;
import java.util.HashMap;
import java.util.Map;
public final class EntryPoint { public final class EntryPoint {
private static final String PRODUCT = "sailfish"; private static final Map<String, String> map = new HashMap<>();
private static final String DEVICE = "sailfish";
private static final String MANUFACTURER = "Google";
private static final String BRAND = "google";
private static final String MODEL = "Pixel";
private static final String FINGERPRINT = "google/sailfish/sailfish:7.1.2/NZH54D/4146044:user/release-keys";
private static final String SECURITY_PATCH = "2017-08-05";
public static void init() { public static void init() {
spoofProvider(); spoofProvider();
spoofDevice(); spoofDevice();
} }
public static void readJson(String data) {
try (JsonReader reader = new JsonReader(new StringReader(data))) {
reader.beginObject();
while (reader.hasNext()) {
map.put(reader.nextName(), reader.nextString());
}
reader.endObject();
} catch (IOException e) {
LOG("Couldn't read JSON from Zygisk: " + e);
}
}
private static void spoofProvider() { private static void spoofProvider() {
final String KEYSTORE = "AndroidKeyStore"; final String KEYSTORE = "AndroidKeyStore";
@ -52,13 +63,15 @@ public final class EntryPoint {
} }
static void spoofDevice() { static void spoofDevice() {
setProp("PRODUCT", PRODUCT); if (map.isEmpty()) return;
setProp("DEVICE", DEVICE);
setProp("MANUFACTURER", MANUFACTURER); setProp("PRODUCT", map.get("PRODUCT"));
setProp("BRAND", BRAND); setProp("DEVICE", map.get("DEVICE"));
setProp("MODEL", MODEL); setProp("MANUFACTURER", map.get("MANUFACTURER"));
setProp("FINGERPRINT", FINGERPRINT); setProp("BRAND", map.get("BRAND"));
setVersionProp("SECURITY_PATCH", SECURITY_PATCH); setProp("MODEL", map.get("MODEL"));
setProp("FINGERPRINT", map.get("FINGERPRINT"));
setVersionProp("SECURITY_PATCH", map.get("SECURITY_PATCH"));
} }
private static void setProp(String name, String value) { private static void setProp(String name, String value) {

View File

@ -10,8 +10,7 @@ https://t.me/playintegrityfix
If you want an undetectable resetprop, use Kitsune Magisk. If you want an undetectable resetprop, use Kitsune Magisk.
If you want to spoof your own props, modify the props in source code and build by yourself. If you want to spoof your own props, modify the props in source code and build by yourself.
Or you can use unstable build, you can download in GitHub repo.
Should work and don't crash nothing. Should work and don't crash nothing.
Maybe in a future I do a custom spoof version... But I won't release it as stable build.
I recommend to clear GMS data and cache before reboot. I recommend to clear GMS data and cache before reboot.

View File

@ -1,7 +1,6 @@
id=playintegrityfix id=playintegrityfix
name=Play Integrity Fix name=Play Integrity Fix
version=v13.7 version=v1.1-PROPS
versionCode=137 versionCode=1
author=chiteroman author=chiteroman
description=Fix CTS profile (SafetyNet) and DEVICE verdict (Play Integrity). description=Fix CTS profile (SafetyNet) and DEVICE verdict (Play Integrity).
updateJson=https://raw.githubusercontent.com/chiteroman/PlayIntegrityFix/main/update.json

10
module/pif.json Normal file
View File

@ -0,0 +1,10 @@
{
"PRODUCT": "taimen",
"DEVICE": "taimen",
"MANUFACTURER": "Google",
"BRAND": "google",
"MODEL": "Pixel 2 XL",
"FINGERPRINT": "google/taimen/taimen:8.1.0/OPM4.171019.021.R1/4833808:user/release-keys",
"SECURITY_PATCH": "2018-07-05",
"FIRST_API_LEVEL": "25"
}