Skip to content

Commit

Permalink
New version!
Browse files Browse the repository at this point in the history
  • Loading branch information
chiteroman committed Dec 5, 2023
1 parent 692f342 commit 4bbbb16
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 124 deletions.
18 changes: 5 additions & 13 deletions app/src/main/cpp/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ static void modify_callback(void *cookie, const char *name, const char *value, u
}
}

LOGD("[%s]: %s", name, value);
if (!prop.starts_with("cache") && !prop.starts_with("debug")) LOGD("[%s]: %s", name, value);

return o_callback(cookie, name, value, serial);
}
Expand Down Expand Up @@ -129,9 +129,7 @@ class PlayIntegrityFix : public zygisk::ModuleBase {
LOGD("JSON contains %d keys!", static_cast<int>(json.size()));

if (json.contains("SECURITY_PATCH")) {
if (json["SECURITY_PATCH"].is_null()) {
LOGD("Key SECURITY_PATCH is null!");
} else if (json["SECURITY_PATCH"].is_string()) {
if (json["SECURITY_PATCH"].is_string()) {
SECURITY_PATCH = json["SECURITY_PATCH"].get<std::string>();
} else {
LOGD("Error parsing SECURITY_PATCH!");
Expand All @@ -141,9 +139,7 @@ class PlayIntegrityFix : public zygisk::ModuleBase {
}

if (json.contains("FIRST_API_LEVEL")) {
if (json["FIRST_API_LEVEL"].is_null()) {
LOGD("Key FIRST_API_LEVEL is null!");
} else if (json["FIRST_API_LEVEL"].is_string()) {
if (json["FIRST_API_LEVEL"].is_string()) {
FIRST_API_LEVEL = json["FIRST_API_LEVEL"].get<std::string>();
} else {
LOGD("Error parsing FIRST_API_LEVEL!");
Expand All @@ -153,9 +149,7 @@ class PlayIntegrityFix : public zygisk::ModuleBase {
}

if (json.contains("BUILD_ID")) {
if (json["BUILD_ID"].is_null()) {
LOGD("Key BUILD_ID is null!");
} else if (json["BUILD_ID"].is_string()) {
if (json["BUILD_ID"].is_string()) {
BUILD_ID = json["BUILD_ID"].get<std::string>();
} else {
LOGD("Error parsing BUILD_ID!");
Expand All @@ -165,9 +159,7 @@ class PlayIntegrityFix : public zygisk::ModuleBase {
}

if (json.contains("VNDK_VERSION")) {
if (json["VNDK_VERSION"].is_null()) {
LOGD("Key VNDK_VERSION is null!");
} else if (json["VNDK_VERSION"].is_string()) {
if (json["VNDK_VERSION"].is_string()) {
VNDK_VERSION = json["VNDK_VERSION"].get<std::string>();
} else {
LOGD("Error parsing VNDK_VERSION!");
Expand Down
219 changes: 110 additions & 109 deletions app/src/main/java/es/chiteroman/playintegrityfix/EntryPoint.java
Original file line number Diff line number Diff line change
@@ -1,110 +1,111 @@
package es.chiteroman.playintegrityfix;

import android.os.Build;
import android.util.JsonReader;
import android.util.Log;

import java.io.IOException;
import java.io.StringReader;
import java.lang.reflect.Field;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.KeyStoreSpi;
import java.security.Provider;
import java.security.Security;
import java.util.HashMap;
import java.util.Map;

public final class EntryPoint {
private static final Map<String, String> map = new HashMap<>();

public static void init(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);
return;
}
spoofProvider();
spoofDevice();
}

private static void spoofProvider() {
final String KEYSTORE = "AndroidKeyStore";

try {
Provider provider = Security.getProvider(KEYSTORE);
KeyStore keyStore = KeyStore.getInstance(KEYSTORE);

Field f = keyStore.getClass().getDeclaredField("keyStoreSpi");
f.setAccessible(true);
CustomKeyStoreSpi.keyStoreSpi = (KeyStoreSpi) f.get(keyStore);
f.setAccessible(false);

CustomProvider customProvider = new CustomProvider(provider);
Security.removeProvider(KEYSTORE);
Security.insertProviderAt(customProvider, 1);

LOG("Spoof KeyStoreSpi and Provider done!");

} catch (KeyStoreException e) {
LOG("Couldn't find KeyStore: " + e);
} catch (NoSuchFieldException e) {
LOG("Couldn't find field: " + e);
} catch (IllegalAccessException e) {
LOG("Couldn't change access of field: " + e);
}
}

static void spoofDevice() {
setProp("PRODUCT", map.get("PRODUCT"));
setProp("DEVICE", map.get("DEVICE"));
setProp("MANUFACTURER", map.get("MANUFACTURER"));
setProp("BRAND", map.get("BRAND"));
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) {
if (name == null || value == null || name.isEmpty() || value.isEmpty()) return;
try {
Field field = Build.class.getDeclaredField(name);
field.setAccessible(true);
String oldValue = (String) field.get(null);
field.set(null, value);
field.setAccessible(false);
if (value.equals(oldValue)) return;
LOG(String.format("[%s]: %s -> %s", name, oldValue, value));
} catch (NoSuchFieldException e) {
LOG(String.format("Couldn't find '%s' field name.", name));
} catch (IllegalAccessException e) {
LOG(String.format("Couldn't modify '%s' field value.", name));
}
}

private static void setVersionProp(String name, String value) {
if (name == null || value == null || name.isEmpty() || value.isEmpty()) return;
try {
Field field = Build.VERSION.class.getDeclaredField(name);
field.setAccessible(true);
String oldValue = (String) field.get(null);
field.set(null, value);
field.setAccessible(false);
if (value.equals(oldValue)) return;
LOG(String.format("[%s]: %s -> %s", name, oldValue, value));
} catch (NoSuchFieldException e) {
LOG(String.format("Couldn't find '%s' field name.", name));
} catch (IllegalAccessException e) {
LOG(String.format("Couldn't modify '%s' field value.", name));
}
}

static void LOG(String msg) {
Log.d("PIF/Java", msg);
}
package es.chiteroman.playintegrityfix;

import android.os.Build;
import android.util.JsonReader;
import android.util.Log;

import java.io.IOException;
import java.io.StringReader;
import java.lang.reflect.Field;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.KeyStoreSpi;
import java.security.Provider;
import java.security.Security;
import java.util.HashMap;
import java.util.Map;

public final class EntryPoint {
private static final Map<String, String> map = new HashMap<>();

public static void init(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);
return;
}
spoofProvider();
spoofDevice();
}

private static void spoofProvider() {
final String KEYSTORE = "AndroidKeyStore";

try {
Provider provider = Security.getProvider(KEYSTORE);
KeyStore keyStore = KeyStore.getInstance(KEYSTORE);

Field f = keyStore.getClass().getDeclaredField("keyStoreSpi");
f.setAccessible(true);
CustomKeyStoreSpi.keyStoreSpi = (KeyStoreSpi) f.get(keyStore);
f.setAccessible(false);

CustomProvider customProvider = new CustomProvider(provider);
Security.removeProvider(KEYSTORE);
Security.insertProviderAt(customProvider, 1);

LOG("Spoof KeyStoreSpi and Provider done!");

} catch (KeyStoreException e) {
LOG("Couldn't find KeyStore: " + e);
} catch (NoSuchFieldException e) {
LOG("Couldn't find field: " + e);
} catch (IllegalAccessException e) {
LOG("Couldn't change access of field: " + e);
}
}

static void spoofDevice() {
setProp("PRODUCT", map.get("PRODUCT"));
setProp("DEVICE", map.get("DEVICE"));
setProp("MANUFACTURER", map.get("MANUFACTURER"));
setProp("BRAND", map.get("BRAND"));
setProp("MODEL", map.get("MODEL"));
setProp("FINGERPRINT", map.get("FINGERPRINT"));
setProp("ID", map.get("BUILD_ID"));
setVersionProp("SECURITY_PATCH", map.get("SECURITY_PATCH"));
}

private static void setProp(String name, String value) {
if (name == null || value == null || name.isEmpty() || value.isEmpty()) return;
try {
Field field = Build.class.getDeclaredField(name);
field.setAccessible(true);
String oldValue = (String) field.get(null);
field.set(null, value);
field.setAccessible(false);
if (value.equals(oldValue)) return;
LOG(String.format("[%s]: %s -> %s", name, oldValue, value));
} catch (NoSuchFieldException e) {
LOG(String.format("Couldn't find '%s' field name.", name));
} catch (IllegalAccessException e) {
LOG(String.format("Couldn't modify '%s' field value.", name));
}
}

private static void setVersionProp(String name, String value) {
if (name == null || value == null || name.isEmpty() || value.isEmpty()) return;
try {
Field field = Build.VERSION.class.getDeclaredField(name);
field.setAccessible(true);
String oldValue = (String) field.get(null);
field.set(null, value);
field.setAccessible(false);
if (value.equals(oldValue)) return;
LOG(String.format("[%s]: %s -> %s", name, oldValue, value));
} catch (NoSuchFieldException e) {
LOG(String.format("Couldn't find '%s' field name.", name));
} catch (IllegalAccessException e) {
LOG(String.format("Couldn't modify '%s' field value.", name));
}
}

static void LOG(String msg) {
Log.d("PIF/Java", msg);
}
}
2 changes: 1 addition & 1 deletion module/module.prop
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ name=Play Integrity Fix (DEV)
version=v1
versionCode=1
author=chiteroman
description=Fuck Play Integrity API for yourself.
description=Fuck Play Integrity API by yourself.
updateJson=https://raw.githubusercontent.com/chiteroman/PlayIntegrityFix/dev/update.json
2 changes: 1 addition & 1 deletion module/pif.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@
"FIRST_API_LEVEL": "",
"BUILD_ID": "",
"VNDK_VERSION": ""
}
}
Binary file modified out/PlayIntegrityFix.zip
Binary file not shown.

0 comments on commit 4bbbb16

Please sign in to comment.