mirror of
https://github.com/chiteroman/PlayIntegrityFix.git
synced 2025-01-18 19:12:38 +02:00
Bring back spoofing fields in Java + code refine
This commit is contained in:
parent
94291f16e0
commit
acca37b3be
@ -184,7 +184,8 @@ public:
|
|||||||
parseJSON();
|
parseJSON();
|
||||||
|
|
||||||
if (trickyStore) {
|
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;
|
spoofProps = false;
|
||||||
spoofProvider = false;
|
spoofProvider = false;
|
||||||
}
|
}
|
||||||
@ -193,16 +194,18 @@ public:
|
|||||||
void postAppSpecialize(const zygisk::AppSpecializeArgs *args) override {
|
void postAppSpecialize(const zygisk::AppSpecializeArgs *args) override {
|
||||||
if (dexVector.empty()) return;
|
if (dexVector.empty()) return;
|
||||||
|
|
||||||
UpdateBuildFields();
|
if (spoofBuildZygisk) UpdateBuildFields();
|
||||||
|
|
||||||
cJSON_Delete(json);
|
|
||||||
|
|
||||||
if (spoofProps) doHook();
|
if (spoofProps) doHook();
|
||||||
else api->setOption(zygisk::DLCLOSE_MODULE_LIBRARY);
|
else api->setOption(zygisk::DLCLOSE_MODULE_LIBRARY);
|
||||||
|
|
||||||
if (spoofProvider || spoofSignature) injectDex();
|
if (spoofBuild || spoofProvider || spoofSignature) injectDex();
|
||||||
else
|
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 {
|
void preServerSpecialize(zygisk::ServerSpecializeArgs *args) override {
|
||||||
@ -214,6 +217,8 @@ private:
|
|||||||
JNIEnv *env = nullptr;
|
JNIEnv *env = nullptr;
|
||||||
std::vector<uint8_t> dexVector;
|
std::vector<uint8_t> dexVector;
|
||||||
cJSON *json = nullptr;
|
cJSON *json = nullptr;
|
||||||
|
bool spoofBuild = true;
|
||||||
|
bool spoofBuildZygisk = true;
|
||||||
bool spoofProps = true;
|
bool spoofProps = true;
|
||||||
bool spoofProvider = true;
|
bool spoofProvider = true;
|
||||||
bool spoofSignature = false;
|
bool spoofSignature = false;
|
||||||
@ -225,6 +230,9 @@ private:
|
|||||||
const cJSON *security_patch = cJSON_GetObjectItemCaseSensitive(json, "SECURITY_PATCH");
|
const cJSON *security_patch = cJSON_GetObjectItemCaseSensitive(json, "SECURITY_PATCH");
|
||||||
const cJSON *build_id = cJSON_GetObjectItemCaseSensitive(json, "ID");
|
const cJSON *build_id = cJSON_GetObjectItemCaseSensitive(json, "ID");
|
||||||
const cJSON *isDebug = cJSON_GetObjectItemCaseSensitive(json, "DEBUG");
|
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_props = cJSON_GetObjectItemCaseSensitive(json, "spoofProps");
|
||||||
const cJSON *spoof_provider = cJSON_GetObjectItemCaseSensitive(json, "spoofProvider");
|
const cJSON *spoof_provider = cJSON_GetObjectItemCaseSensitive(json, "spoofProvider");
|
||||||
const cJSON *spoof_signature = cJSON_GetObjectItemCaseSensitive(json, "spoofSignature");
|
const cJSON *spoof_signature = cJSON_GetObjectItemCaseSensitive(json, "spoofSignature");
|
||||||
@ -251,6 +259,16 @@ private:
|
|||||||
cJSON_DeleteItemFromObjectCaseSensitive(json, "DEBUG");
|
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)) {
|
if (spoof_props && cJSON_IsBool(spoof_props)) {
|
||||||
spoofProps = cJSON_IsTrue(spoof_props);
|
spoofProps = cJSON_IsTrue(spoof_props);
|
||||||
cJSON_DeleteItemFromObjectCaseSensitive(json, "spoofProps");
|
cJSON_DeleteItemFromObjectCaseSensitive(json, "spoofProps");
|
||||||
@ -291,8 +309,15 @@ private:
|
|||||||
auto entryPointClass = (jclass) entryClassObj;
|
auto entryPointClass = (jclass) entryClassObj;
|
||||||
|
|
||||||
LOGD("call init");
|
LOGD("call init");
|
||||||
auto entryInit = env->GetStaticMethodID(entryPointClass, "init", "(ZZ)V");
|
auto entryInit = env->GetStaticMethodID(entryPointClass, "init", "(Ljava/lang/String;ZZ)V");
|
||||||
env->CallStaticVoidMethod(entryPointClass, entryInit, spoofProvider, spoofSignature);
|
jstring jsonStr;
|
||||||
|
if (spoofBuild) {
|
||||||
|
jsonStr = env->NewStringUTF(cJSON_Print(json));
|
||||||
|
} else {
|
||||||
|
jsonStr = env->NewStringUTF("");
|
||||||
|
}
|
||||||
|
env->CallStaticVoidMethod(entryPointClass, entryInit, jsonStr, spoofProvider,
|
||||||
|
spoofSignature);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateBuildFields() {
|
void UpdateBuildFields() {
|
||||||
@ -329,31 +354,6 @@ private:
|
|||||||
|
|
||||||
LOGD("Set '%s' to '%s'", key, value);
|
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);
|
putAll(provider);
|
||||||
put("KeyStore.AndroidKeyStore", CustomKeyStoreSpi.class.getName());
|
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.Build;
|
||||||
import android.os.Parcel;
|
import android.os.Parcel;
|
||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
|
import android.text.TextUtils;
|
||||||
import android.util.Base64;
|
import android.util.Base64;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import org.json.JSONObject;
|
||||||
import org.lsposed.hiddenapibypass.HiddenApiBypass;
|
import org.lsposed.hiddenapibypass.HiddenApiBypass;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
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());
|
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) {
|
if (spoofProvider) {
|
||||||
spoofProvider();
|
spoofProvider();
|
||||||
} else {
|
} else {
|
||||||
@ -146,5 +162,49 @@ public final class EntryPoint {
|
|||||||
} else {
|
} else {
|
||||||
Log.i(TAG, "Don't spoof signature");
|
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",
|
"PRODUCT": "akita_beta",
|
||||||
"SECURITY_PATCH": "2024-08-05",
|
"SECURITY_PATCH": "2024-08-05",
|
||||||
"DEVICE_INITIAL_SDK_INT": 21,
|
"DEVICE_INITIAL_SDK_INT": 21,
|
||||||
|
"spoofBuild": true,
|
||||||
|
"spoofBuildZygisk": true,
|
||||||
"spoofProps": true,
|
"spoofProps": true,
|
||||||
"spoofProvider": true,
|
"spoofProvider": true,
|
||||||
"spoofSignature": false
|
"spoofSignature": false
|
||||||
|
Loading…
Reference in New Issue
Block a user