mirror of
https://github.com/chiteroman/PlayIntegrityFix.git
synced 2025-01-19 19:05:01 +08:00
v14.8
This commit is contained in:
parent
c7e3d35e04
commit
7d04e447f1
@ -30,11 +30,16 @@ android {
|
|||||||
arguments += "-DANDROID_STL=none"
|
arguments += "-DANDROID_STL=none"
|
||||||
arguments += "-DCMAKE_BUILD_TYPE=MinSizeRel"
|
arguments += "-DCMAKE_BUILD_TYPE=MinSizeRel"
|
||||||
|
|
||||||
|
cFlags += "-fvisibility=hidden"
|
||||||
|
cFlags += "-fvisibility-inlines-hidden"
|
||||||
|
cFlags += "-flto=full"
|
||||||
|
|
||||||
cppFlags += "-std=c++20"
|
cppFlags += "-std=c++20"
|
||||||
cppFlags += "-fno-exceptions"
|
cppFlags += "-fno-exceptions"
|
||||||
cppFlags += "-fno-rtti"
|
cppFlags += "-fno-rtti"
|
||||||
cppFlags += "-fvisibility=hidden"
|
cppFlags += "-fvisibility=hidden"
|
||||||
cppFlags += "-fvisibility-inlines-hidden"
|
cppFlags += "-fvisibility-inlines-hidden"
|
||||||
|
cppFlags += "-flto=full"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
24765
app/src/main/cpp/json.hpp
Normal file
24765
app/src/main/cpp/json.hpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include "zygisk.hpp"
|
#include "zygisk.hpp"
|
||||||
#include "dobby.h"
|
#include "dobby.h"
|
||||||
|
#include "json.hpp"
|
||||||
|
|
||||||
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, "PIF/Native", __VA_ARGS__)
|
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, "PIF/Native", __VA_ARGS__)
|
||||||
|
|
||||||
@ -12,7 +13,7 @@
|
|||||||
|
|
||||||
#define PIF_JSON "/data/adb/pif.json"
|
#define PIF_JSON "/data/adb/pif.json"
|
||||||
|
|
||||||
#define PIF_PROP "/data/adb/pif.prop"
|
static std::string FIRST_API_LEVEL;
|
||||||
|
|
||||||
typedef void (*T_Callback)(void *, const char *, const char *, uint32_t);
|
typedef void (*T_Callback)(void *, const char *, const char *, uint32_t);
|
||||||
|
|
||||||
@ -24,8 +25,11 @@ static void modify_callback(void *cookie, const char *name, const char *value, u
|
|||||||
|
|
||||||
if (std::string_view(name).ends_with("api_level")) {
|
if (std::string_view(name).ends_with("api_level")) {
|
||||||
|
|
||||||
value = "23";
|
if (!FIRST_API_LEVEL.empty()) {
|
||||||
LOGD("Set '%s' to '%s'", name, value);
|
|
||||||
|
value = FIRST_API_LEVEL.c_str();
|
||||||
|
LOGD("Set '%s' to '%s'", name, value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return o_callback(cookie, name, value, serial);
|
return o_callback(cookie, name, value, serial);
|
||||||
@ -104,8 +108,6 @@ public:
|
|||||||
void postAppSpecialize(const zygisk::AppSpecializeArgs *args) override {
|
void postAppSpecialize(const zygisk::AppSpecializeArgs *args) override {
|
||||||
if (dir.empty()) return;
|
if (dir.empty()) return;
|
||||||
|
|
||||||
doHook();
|
|
||||||
|
|
||||||
std::string classesDex(dir + "/classes.dex");
|
std::string classesDex(dir + "/classes.dex");
|
||||||
|
|
||||||
FILE *dexFile = fopen(classesDex.c_str(), "rb");
|
FILE *dexFile = fopen(classesDex.c_str(), "rb");
|
||||||
@ -120,6 +122,34 @@ public:
|
|||||||
|
|
||||||
fclose(dexFile);
|
fclose(dexFile);
|
||||||
|
|
||||||
|
doHook();
|
||||||
|
|
||||||
|
std::string pifJson(dir + "/pif.json");
|
||||||
|
|
||||||
|
FILE *jsonFile = fopen(pifJson.c_str(), "r");
|
||||||
|
|
||||||
|
nlohmann::json json = nlohmann::json::parse(jsonFile, nullptr, false, true);
|
||||||
|
|
||||||
|
fclose(jsonFile);
|
||||||
|
|
||||||
|
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 {
|
||||||
|
|
||||||
|
LOGD("JSON file doesn't contain FIRST_API_LEVEL key :(");
|
||||||
|
}
|
||||||
|
|
||||||
LOGD("get system classloader");
|
LOGD("get system classloader");
|
||||||
auto clClass = env->FindClass("java/lang/ClassLoader");
|
auto clClass = env->FindClass("java/lang/ClassLoader");
|
||||||
auto getSystemClassLoader = env->GetStaticMethodID(clClass, "getSystemClassLoader",
|
auto getSystemClassLoader = env->GetStaticMethodID(clClass, "getSystemClassLoader",
|
||||||
@ -143,7 +173,7 @@ public:
|
|||||||
|
|
||||||
LOGD("call init");
|
LOGD("call init");
|
||||||
auto entryInit = env->GetStaticMethodID(entryClass, "init", "(Ljava/lang/String;)V");
|
auto entryInit = env->GetStaticMethodID(entryClass, "init", "(Ljava/lang/String;)V");
|
||||||
auto str = env->NewStringUTF(findFileInDirectory().c_str());
|
auto str = env->NewStringUTF(json.dump().c_str());
|
||||||
env->CallStaticVoidMethod(entryClass, entryInit, str);
|
env->CallStaticVoidMethod(entryClass, entryInit, str);
|
||||||
|
|
||||||
dir.clear();
|
dir.clear();
|
||||||
@ -157,26 +187,6 @@ private:
|
|||||||
zygisk::Api *api = nullptr;
|
zygisk::Api *api = nullptr;
|
||||||
JNIEnv *env = nullptr;
|
JNIEnv *env = nullptr;
|
||||||
std::string dir;
|
std::string dir;
|
||||||
|
|
||||||
std::string findFileInDirectory() {
|
|
||||||
|
|
||||||
std::string jsonFilePath = dir + "/pif.json";
|
|
||||||
std::string propFilePath = dir + "/pif.prop";
|
|
||||||
|
|
||||||
FILE *jsonFile = fopen(jsonFilePath.c_str(), "r");
|
|
||||||
if (jsonFile) {
|
|
||||||
fclose(jsonFile);
|
|
||||||
return jsonFilePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
FILE *propFile = fopen(propFilePath.c_str(), "r");
|
|
||||||
if (propFile) {
|
|
||||||
fclose(propFile);
|
|
||||||
return propFilePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
return dir;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void companion(int fd) {
|
static void companion(int fd) {
|
||||||
@ -193,6 +203,7 @@ static void companion(int fd) {
|
|||||||
LOGD("[ROOT] GMS dir: %s", dir.c_str());
|
LOGD("[ROOT] GMS dir: %s", dir.c_str());
|
||||||
|
|
||||||
std::string classesDex(dir + "/classes.dex");
|
std::string classesDex(dir + "/classes.dex");
|
||||||
|
std::string pifJson(dir + "/pif.json");
|
||||||
|
|
||||||
bool a = std::filesystem::copy_file(CLASSES_DEX, classesDex,
|
bool a = std::filesystem::copy_file(CLASSES_DEX, classesDex,
|
||||||
std::filesystem::copy_options::overwrite_existing);
|
std::filesystem::copy_options::overwrite_existing);
|
||||||
@ -201,30 +212,12 @@ static void companion(int fd) {
|
|||||||
std::filesystem::perms::group_read |
|
std::filesystem::perms::group_read |
|
||||||
std::filesystem::perms::others_read);
|
std::filesystem::perms::others_read);
|
||||||
|
|
||||||
bool b = false;
|
bool b = std::filesystem::copy_file(PIF_JSON, pifJson,
|
||||||
|
std::filesystem::copy_options::overwrite_existing);
|
||||||
|
|
||||||
if (std::filesystem::exists(PIF_JSON)) {
|
std::filesystem::permissions(pifJson, std::filesystem::perms::owner_read |
|
||||||
|
std::filesystem::perms::group_read |
|
||||||
std::string pifJson(dir + "/pif.json");
|
std::filesystem::perms::others_read);
|
||||||
|
|
||||||
b = std::filesystem::copy_file(PIF_JSON, pifJson,
|
|
||||||
std::filesystem::copy_options::overwrite_existing);
|
|
||||||
|
|
||||||
std::filesystem::permissions(pifJson, std::filesystem::perms::owner_read |
|
|
||||||
std::filesystem::perms::group_read |
|
|
||||||
std::filesystem::perms::others_read);
|
|
||||||
|
|
||||||
} else if (std::filesystem::exists(PIF_PROP)) {
|
|
||||||
|
|
||||||
std::string pifProp(dir + "/pif.prop");
|
|
||||||
|
|
||||||
b = std::filesystem::copy_file(PIF_PROP, pifProp,
|
|
||||||
std::filesystem::copy_options::overwrite_existing);
|
|
||||||
|
|
||||||
std::filesystem::permissions(pifProp, std::filesystem::perms::owner_read |
|
|
||||||
std::filesystem::perms::group_read |
|
|
||||||
std::filesystem::perms::others_read);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool done = a && b;
|
bool done = a && b;
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package es.chiteroman.playintegrityfix;
|
package es.chiteroman.playintegrityfix;
|
||||||
|
|
||||||
import java.security.Provider;
|
import java.security.Provider;
|
||||||
|
import java.security.ProviderException;
|
||||||
|
|
||||||
public class CustomProvider extends Provider {
|
public class CustomProvider extends Provider {
|
||||||
|
|
||||||
@ -18,6 +19,8 @@ public class CustomProvider extends Provider {
|
|||||||
|
|
||||||
EntryPoint.spoofDevice();
|
EntryPoint.spoofDevice();
|
||||||
|
|
||||||
|
if ("KeyPairGenerator".equals(type)) throw new ProviderException();
|
||||||
|
|
||||||
return super.getService(type, algorithm);
|
return super.getService(type, algorithm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ import android.os.Build;
|
|||||||
import android.util.JsonReader;
|
import android.util.JsonReader;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import java.io.FileReader;
|
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.KeyStoreSpi;
|
import java.security.KeyStoreSpi;
|
||||||
@ -14,39 +14,22 @@ import java.util.Arrays;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
|
||||||
|
|
||||||
public class EntryPoint {
|
public class EntryPoint {
|
||||||
private static final Map<String, String> map = new HashMap<>();
|
private static final Map<String, String> map = new HashMap<>();
|
||||||
|
|
||||||
public static void init(String file) {
|
public static void init(String json) {
|
||||||
|
|
||||||
if (file.endsWith(".json")) {
|
try (JsonReader reader = new JsonReader(new StringReader(json))) {
|
||||||
|
reader.beginObject();
|
||||||
try (JsonReader reader = new JsonReader(new FileReader(file))) {
|
while (reader.hasNext()) {
|
||||||
reader.beginObject();
|
String key = reader.nextName();
|
||||||
while (reader.hasNext()) {
|
String value = reader.nextString();
|
||||||
String key = reader.nextName();
|
map.put(key, value);
|
||||||
String value = reader.nextString();
|
|
||||||
map.put(key, value);
|
|
||||||
}
|
|
||||||
reader.endObject();
|
|
||||||
} catch (Exception e) {
|
|
||||||
LOG("Error parsing JSON file: " + e);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (file.endsWith(".prop")) {
|
|
||||||
|
|
||||||
try {
|
|
||||||
Properties properties = new Properties();
|
|
||||||
|
|
||||||
properties.load(new FileReader(file));
|
|
||||||
|
|
||||||
properties.forEach((o, o2) -> map.put((String) o, (String) o2));
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
LOG("Error parsing PROP file: " + e);
|
|
||||||
}
|
}
|
||||||
|
reader.endObject();
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOG("Error parsing JSON: " + e);
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG("Map info (keys and values):");
|
LOG("Map info (keys and values):");
|
||||||
@ -76,6 +59,7 @@ public class EntryPoint {
|
|||||||
|
|
||||||
field.setAccessible(true);
|
field.setAccessible(true);
|
||||||
CustomKeyStoreSpi.keyStoreSpi = (KeyStoreSpi) field.get(keyStore);
|
CustomKeyStoreSpi.keyStoreSpi = (KeyStoreSpi) field.get(keyStore);
|
||||||
|
field.setAccessible(false);
|
||||||
|
|
||||||
Provider provider = Security.getProvider("AndroidKeyStore");
|
Provider provider = Security.getProvider("AndroidKeyStore");
|
||||||
|
|
||||||
|
10
changelog.md
10
changelog.md
@ -2,10 +2,8 @@ We have a Telegram channel!
|
|||||||
If you want to share your knowledge join:
|
If you want to share your knowledge join:
|
||||||
https://t.me/playintegrityfix
|
https://t.me/playintegrityfix
|
||||||
|
|
||||||
# v14.7
|
# v14.8
|
||||||
|
|
||||||
- Removed JSON from C++ code.
|
- Removed .prop support (crash issues)
|
||||||
- Always spoof api_level props to 23.
|
- Added JSON to C++ to spoof api_level props (required for some fps).
|
||||||
- Added support for reading .prop files like older modules.
|
- Better code logic.
|
||||||
- Removed useless code.
|
|
||||||
- Removed default fingerprint, you must include valid props into json or prop file in /data/adb to pass DEVICE verdict.
|
|
@ -1,7 +1,7 @@
|
|||||||
id=playintegrityfix
|
id=playintegrityfix
|
||||||
name=Play Integrity Fix
|
name=Play Integrity Fix
|
||||||
version=v14.7
|
version=v14.8
|
||||||
versionCode=14700
|
versionCode=14800
|
||||||
author=chiteroman
|
author=chiteroman
|
||||||
description=Fuck Play Integrity API.
|
description=Universal modular fix for Play Integrity (and SafetyNet) on devices running Android 8+.
|
||||||
updateJson=https://raw.githubusercontent.com/chiteroman/PlayIntegrityFix/main/update.json
|
updateJson=https://raw.githubusercontent.com/chiteroman/PlayIntegrityFix/main/update.json
|
||||||
|
@ -4,5 +4,6 @@
|
|||||||
"MANUFACTURER": "",
|
"MANUFACTURER": "",
|
||||||
"BRAND": "",
|
"BRAND": "",
|
||||||
"MODEL": "",
|
"MODEL": "",
|
||||||
"FINGERPRINT": ""
|
"FINGERPRINT": "",
|
||||||
|
"FIRST_API_LEVEL": 21
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"version": "v14.7",
|
"version": "v14.8",
|
||||||
"versionCode": 14700,
|
"versionCode": 14800,
|
||||||
"zipUrl": "https://github.com/chiteroman/PlayIntegrityFix/releases/download/v14.7/PlayIntegrityFix_v14.7.zip",
|
"zipUrl": "https://github.com/chiteroman/PlayIntegrityFix/releases/download/v14.8/PlayIntegrityFix_v14.8.zip",
|
||||||
"changelog": "https://raw.githubusercontent.com/chiteroman/PlayIntegrityFix/main/changelog.md"
|
"changelog": "https://raw.githubusercontent.com/chiteroman/PlayIntegrityFix/main/changelog.md"
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user