mirror of
https://github.com/chiteroman/PlayIntegrityFix.git
synced 2025-01-19 02:52:20 +08:00
Bring back spoofing fields in Java + code refine
This commit is contained in:
parent
94291f16e0
commit
acca37b3be
@ -184,7 +184,8 @@ public:
|
||||
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;
|
||||
}
|
||||
@ -193,16 +194,18 @@ public:
|
||||
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 {
|
||||
@ -214,6 +217,8 @@ private:
|
||||
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;
|
||||
@ -225,6 +230,9 @@ private:
|
||||
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");
|
||||
@ -251,6 +259,16 @@ private:
|
||||
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");
|
||||
@ -291,8 +309,15 @@ private:
|
||||
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() {
|
||||
@ -329,31 +354,6 @@ private:
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,4 +9,10 @@ public final class CustomProvider extends 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);
|
||||
}
|
||||
}
|
||||
|
@ -6,9 +6,11 @@ import android.content.pm.Signature;
|
||||
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;
|
||||
@ -134,7 +136,21 @@ public final class EntryPoint {
|
||||
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 {
|
||||
@ -146,5 +162,49 @@ public final class EntryPoint {
|
||||
} 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);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user