Bring back spoofing fields in Java + code refine

This commit is contained in:
chiteroman 2024-08-19 13:13:48 +02:00
parent 94291f16e0
commit acca37b3be
No known key found for this signature in database
4 changed files with 102 additions and 34 deletions

View File

@ -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);
}
}
}
}

View File

@ -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);
}
}

View File

@ -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);
}
});
}
}

View File

@ -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