Skip to content

Commit

Permalink
Bring back spoofing fields in Java + code refine
Browse files Browse the repository at this point in the history
  • Loading branch information
chiteroman committed Aug 19, 2024
1 parent 94291f1 commit acca37b
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 34 deletions.
66 changes: 33 additions & 33 deletions app/src/main/cpp/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,8 @@ class PlayIntegrityFix : public zygisk::ModuleBase {
parseJSON();

if (trickyStore) {
LOGD("TrickyStore module installed and enabled, disabling spoofProps and spoofProvider");
LOGD("TrickyStore module installed and enabled, disabling spoofBuild (Java), spoofProps and spoofProvider");
spoofBuild = false;
spoofProps = false;
spoofProvider = false;
}
Expand All @@ -193,16 +194,18 @@ class PlayIntegrityFix : public zygisk::ModuleBase {
void postAppSpecialize(const zygisk::AppSpecializeArgs *args) override {
if (dexVector.empty()) return;

UpdateBuildFields();

cJSON_Delete(json);
if (spoofBuildZygisk) UpdateBuildFields();

if (spoofProps) doHook();
else api->setOption(zygisk::DLCLOSE_MODULE_LIBRARY);

if (spoofProvider || spoofSignature) injectDex();
if (spoofBuild || spoofProvider || spoofSignature) injectDex();
else
LOGD("Don't inject dex, spoofProvider and spoofSignature are false");
LOGD("Don't inject dex: spoofBuild (Java), spoofProvider and spoofSignature are false");

cJSON_Delete(json);
dexVector.clear();
dexVector.shrink_to_fit();
}

void preServerSpecialize(zygisk::ServerSpecializeArgs *args) override {
Expand All @@ -214,6 +217,8 @@ class PlayIntegrityFix : public zygisk::ModuleBase {
JNIEnv *env = nullptr;
std::vector<uint8_t> dexVector;
cJSON *json = nullptr;
bool spoofBuild = true;
bool spoofBuildZygisk = true;
bool spoofProps = true;
bool spoofProvider = true;
bool spoofSignature = false;
Expand All @@ -225,6 +230,9 @@ class PlayIntegrityFix : public zygisk::ModuleBase {
const cJSON *security_patch = cJSON_GetObjectItemCaseSensitive(json, "SECURITY_PATCH");
const cJSON *build_id = cJSON_GetObjectItemCaseSensitive(json, "ID");
const cJSON *isDebug = cJSON_GetObjectItemCaseSensitive(json, "DEBUG");
const cJSON *spoof_build = cJSON_GetObjectItemCaseSensitive(json, "spoofBuild");
const cJSON *spoof_build_zygisk = cJSON_GetObjectItemCaseSensitive(json,
"spoofBuildZygisk");
const cJSON *spoof_props = cJSON_GetObjectItemCaseSensitive(json, "spoofProps");
const cJSON *spoof_provider = cJSON_GetObjectItemCaseSensitive(json, "spoofProvider");
const cJSON *spoof_signature = cJSON_GetObjectItemCaseSensitive(json, "spoofSignature");
Expand All @@ -251,6 +259,16 @@ class PlayIntegrityFix : public zygisk::ModuleBase {
cJSON_DeleteItemFromObjectCaseSensitive(json, "DEBUG");
}

if (spoof_build && cJSON_IsBool(spoof_build)) {
spoofBuild = cJSON_IsTrue(spoof_build);
cJSON_DeleteItemFromObjectCaseSensitive(json, "spoofBuild");
}

if (spoof_build_zygisk && cJSON_IsBool(spoof_build_zygisk)) {
spoofBuildZygisk = cJSON_IsTrue(spoof_build_zygisk);
cJSON_DeleteItemFromObjectCaseSensitive(json, "spoofBuildZygisk");
}

if (spoof_props && cJSON_IsBool(spoof_props)) {
spoofProps = cJSON_IsTrue(spoof_props);
cJSON_DeleteItemFromObjectCaseSensitive(json, "spoofProps");
Expand Down Expand Up @@ -291,8 +309,15 @@ class PlayIntegrityFix : public zygisk::ModuleBase {
auto entryPointClass = (jclass) entryClassObj;

LOGD("call init");
auto entryInit = env->GetStaticMethodID(entryPointClass, "init", "(ZZ)V");
env->CallStaticVoidMethod(entryPointClass, entryInit, spoofProvider, spoofSignature);
auto entryInit = env->GetStaticMethodID(entryPointClass, "init", "(Ljava/lang/String;ZZ)V");
jstring jsonStr;
if (spoofBuild) {
jsonStr = env->NewStringUTF(cJSON_Print(json));
} else {
jsonStr = env->NewStringUTF("");
}
env->CallStaticVoidMethod(entryPointClass, entryInit, jsonStr, spoofProvider,
spoofSignature);
}

void UpdateBuildFields() {
Expand Down Expand Up @@ -329,31 +354,6 @@ class PlayIntegrityFix : public zygisk::ModuleBase {

LOGD("Set '%s' to '%s'", key, value);
}
} else if (cJSON_IsNumber(currentElement)) {
int value = currentElement->valueint;
jfieldID fieldID = env->GetStaticFieldID(buildClass, key, "I");

if (env->ExceptionCheck()) {
env->ExceptionClear();

fieldID = env->GetStaticFieldID(versionClass, key, "I");

if (env->ExceptionCheck()) {
env->ExceptionClear();
continue;
}
}

if (fieldID != nullptr) {
env->SetStaticIntField(buildClass, fieldID, value);

if (env->ExceptionCheck()) {
env->ExceptionClear();
continue;
}

LOGD("Set '%s' to '%d'", key, value);
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,10 @@ public CustomProvider(Provider provider) {
putAll(provider);
put("KeyStore.AndroidKeyStore", CustomKeyStoreSpi.class.getName());
}

@Override
public synchronized Service getService(String type, String algorithm) {
EntryPoint.spoofFields();
return super.getService(type, algorithm);
}
}
62 changes: 61 additions & 1 deletion app/src/main/java/es/chiteroman/playintegrityfix/EntryPoint.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
import android.util.Base64;
import android.util.Log;

import org.json.JSONObject;
import org.lsposed.hiddenapibypass.HiddenApiBypass;

import java.lang.reflect.Field;
Expand Down Expand Up @@ -134,7 +136,21 @@ private static Field findField(Class<?> currentClass, String fieldName) throws N
throw new NoSuchFieldException("Field '" + fieldName + "' not found in class hierarchy of " + Objects.requireNonNull(currentClass).getName());
}

public static void init(boolean spoofProvider, boolean spoofSignature) {
private static Field getBuildField(String name) {
Field field;
try {
field = Build.class.getField(name);
} catch (NoSuchFieldException e) {
try {
field = Build.VERSION.class.getField(name);
} catch (NoSuchFieldException ex) {
return null;
}
}
return field;
}

public static void init(String json, boolean spoofProvider, boolean spoofSignature) {
if (spoofProvider) {
spoofProvider();
} else {
Expand All @@ -146,5 +162,49 @@ public static void init(boolean spoofProvider, boolean spoofSignature) {
} else {
Log.i(TAG, "Don't spoof signature");
}

if (TextUtils.isEmpty(json)) {
Log.e(TAG, "Json is empty!");
return;
}

JSONObject jsonObject;
try {
jsonObject = new JSONObject(json);
} catch (Throwable t) {
Log.e(TAG, "init", t);
return;
}

jsonObject.keys().forEachRemaining(key -> {
Field field = getBuildField(key);
if (field == null) return;
field.setAccessible(true);
String value;
try {
value = jsonObject.getString(key);
} catch (Throwable t) {
Log.e(TAG, "init", t);
return;
}
map.putIfAbsent(field, value);
});

Log.i(TAG, "Parsed " + map.size() + " fields from JSON");

spoofFields();
}

public static void spoofFields() {
map.forEach((field, value) -> {
try {
String oldValue = (String) field.get(null);
if (value.equals(oldValue)) return;
field.set(null, value);
Log.i(TAG, "Set '" + field.getName() + "' to '" + value + "'");
} catch (Throwable t) {
Log.e(TAG, "spoofFields", t);
}
});
}
}
2 changes: 2 additions & 0 deletions module/pif.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
"PRODUCT": "akita_beta",
"SECURITY_PATCH": "2024-08-05",
"DEVICE_INITIAL_SDK_INT": 21,
"spoofBuild": true,
"spoofBuildZygisk": true,
"spoofProps": true,
"spoofProvider": true,
"spoofSignature": false
Expand Down

0 comments on commit acca37b

Please sign in to comment.