You've already forked PlayIntegrityFork
mirror of
https://github.com/osm0sis/PlayIntegrityFork.git
synced 2025-09-06 06:37:06 +00:00
Add advanced setting spoofVendingFingerprint (#38)
spoofVendingFingerprint = 0 / 1 When 0, no impact on Vending When 1, same FINGERPRINT from custom.pif.json is injected into Vending Unless spoofVendingSdk is enabled also, in which case FINGERPRINT is not injected since it's not used
This commit is contained in:
@@ -20,6 +20,7 @@ static int spoofBuild = 1;
|
||||
static int spoofProps = 1;
|
||||
static int spoofProvider = 1;
|
||||
static int spoofSignature = 0;
|
||||
static int spoofVendingFingerprint = 0;
|
||||
static int spoofVendingSdk = 0;
|
||||
|
||||
static std::map<std::string, std::string> jsonProps;
|
||||
@@ -166,10 +167,10 @@ public:
|
||||
readJson();
|
||||
|
||||
if (pkgName == VENDING_PACKAGE) spoofProps = spoofBuild = spoofProvider = spoofSignature = 0;
|
||||
else spoofVendingSdk = 0;
|
||||
else spoofVendingFingerprint = spoofVendingSdk = 0;
|
||||
|
||||
if (spoofProps > 0) doHook();
|
||||
if (spoofBuild + spoofProvider + spoofSignature + spoofVendingSdk > 0) inject();
|
||||
if (spoofBuild + spoofProvider + spoofSignature + spoofVendingFingerprint + spoofVendingSdk > 0) inject();
|
||||
|
||||
dexVector.clear();
|
||||
json.clear();
|
||||
@@ -185,6 +186,7 @@ private:
|
||||
std::vector<char> dexVector;
|
||||
nlohmann::json json;
|
||||
std::string pkgName;
|
||||
std::string spoofFingerprintValue = "";
|
||||
|
||||
void readJson() {
|
||||
LOGD("JSON contains %d keys!", static_cast<int>(json.size()));
|
||||
@@ -210,6 +212,17 @@ private:
|
||||
}
|
||||
json.erase("spoofVendingSdk");
|
||||
}
|
||||
if (json.contains("spoofVendingFingerprint")) {
|
||||
if (!json["spoofVendingFingerprint"].is_null() && json["spoofVendingFingerprint"].is_string() && json["spoofVendingFingerprint"] != "" &&
|
||||
json.contains("FINGERPRINT") && !json["FINGERPRINT"].is_null() && json["FINGERPRINT"].is_string() && json["FINGERPRINT"] != "") {
|
||||
spoofVendingFingerprint = stoi(json["spoofVendingFingerprint"].get<std::string>());
|
||||
spoofFingerprintValue = json["FINGERPRINT"].get<std::string>();
|
||||
if (verboseLogs > 0) LOGD("Spoofing Fingerprint in Play Store %s!", (spoofVendingFingerprint > 0) ? "enabled" : "disabled");
|
||||
} else {
|
||||
LOGD("Error parsing spoofVendingFingerprint or FINGERPRINT field!");
|
||||
}
|
||||
json.erase("spoofVendingFingerprint");
|
||||
}
|
||||
if (pkgName == VENDING_PACKAGE) {
|
||||
json.clear();
|
||||
return;
|
||||
@@ -299,8 +312,9 @@ private:
|
||||
|
||||
if (pkgName == VENDING_PACKAGE) {
|
||||
LOGD("JNI %s: Calling EntryPointVending.init", niceName);
|
||||
auto entryInit = env->GetStaticMethodID(entryClass, "init", "(II)V");
|
||||
env->CallStaticVoidMethod(entryClass, entryInit, verboseLogs, spoofVendingSdk);
|
||||
auto entryInit = env->GetStaticMethodID(entryClass, "init", "(IIILjava/lang/String;)V");
|
||||
auto javaStr = env->NewStringUTF(spoofFingerprintValue.c_str());
|
||||
env->CallStaticVoidMethod(entryClass, entryInit, verboseLogs, spoofVendingFingerprint, spoofVendingSdk, javaStr);
|
||||
} else {
|
||||
LOGD("JNI %s: Sending JSON", niceName);
|
||||
auto receiveJson = env->GetStaticMethodID(entryClass, "receiveJson", "(Ljava/lang/String;)V");
|
||||
|
||||
@@ -12,29 +12,51 @@ public final class EntryPointVending {
|
||||
}
|
||||
|
||||
@SuppressLint("DefaultLocale")
|
||||
public static void init(int verboseLogs, int spoofVendingSdk) {
|
||||
if (spoofVendingSdk < 1) return;
|
||||
int requestSdk = spoofVendingSdk == 1 ? 32 : spoofVendingSdk;
|
||||
int targetSdk = Math.min(Build.VERSION.SDK_INT, requestSdk);
|
||||
int oldValue;
|
||||
try {
|
||||
Field field = Build.VERSION.class.getDeclaredField("SDK_INT");
|
||||
field.setAccessible(true);
|
||||
oldValue = field.getInt(null);
|
||||
if (oldValue == targetSdk) {
|
||||
if (verboseLogs > 2) LOG(String.format("[SDK_INT]: %d (unchanged)", oldValue));
|
||||
public static void init(int verboseLogs, int spoofVendingFingerprint, int spoofVendingSdk, String spoofFingerprintValue) {
|
||||
if (spoofVendingSdk < 1){
|
||||
// Only spoof FINGERPRINT to Play Store if not forcing legacy verdict
|
||||
if (spoofVendingFingerprint < 1) return;
|
||||
String oldValue;
|
||||
try {
|
||||
Field field = Build.class.getDeclaredField("FINGERPRINT");
|
||||
field.setAccessible(true);
|
||||
oldValue = String.valueOf(field.get(null));
|
||||
if (oldValue.equals(spoofFingerprintValue)) {
|
||||
if (verboseLogs > 2) LOG(String.format("[FINGERPRINT]: %s (unchanged)", oldValue));
|
||||
field.setAccessible(false);
|
||||
return;
|
||||
}
|
||||
field.set(null, spoofFingerprintValue);
|
||||
field.setAccessible(false);
|
||||
return;
|
||||
LOG(String.format("[FINGERPRINT]: %s -> %s", oldValue, spoofFingerprintValue));
|
||||
} catch (NoSuchFieldException e) {
|
||||
LOG("FINGERPRINT field not found: " + e);
|
||||
} catch (SecurityException | IllegalAccessException | IllegalArgumentException |
|
||||
NullPointerException | ExceptionInInitializerError e) {
|
||||
LOG("FINGERPRINT field not accessible: " + e);
|
||||
}
|
||||
} else {
|
||||
int requestSdk = spoofVendingSdk == 1 ? 32 : spoofVendingSdk;
|
||||
int targetSdk = Math.min(Build.VERSION.SDK_INT, requestSdk);
|
||||
int oldValue;
|
||||
try {
|
||||
Field field = Build.VERSION.class.getDeclaredField("SDK_INT");
|
||||
field.setAccessible(true);
|
||||
oldValue = field.getInt(null);
|
||||
if (oldValue == targetSdk) {
|
||||
if (verboseLogs > 2) LOG(String.format("[SDK_INT]: %d (unchanged)", oldValue));
|
||||
field.setAccessible(false);
|
||||
return;
|
||||
}
|
||||
field.set(null, targetSdk);
|
||||
field.setAccessible(false);
|
||||
LOG(String.format("[SDK_INT]: %d -> %d", oldValue, targetSdk));
|
||||
} catch (NoSuchFieldException e) {
|
||||
LOG("SDK_INT field not found: " + e);
|
||||
} catch (SecurityException | IllegalAccessException | IllegalArgumentException |
|
||||
NullPointerException | ExceptionInInitializerError e) {
|
||||
LOG("SDK_INT field not accessible: " + e);
|
||||
}
|
||||
field.set(null, targetSdk);
|
||||
field.setAccessible(false);
|
||||
LOG(String.format("[SDK_INT]: %d -> %d", oldValue, targetSdk));
|
||||
} catch (NoSuchFieldException e) {
|
||||
LOG("SDK_INT field not found: " + e);
|
||||
} catch (SecurityException | IllegalAccessException | IllegalArgumentException |
|
||||
NullPointerException | ExceptionInInitializerError e) {
|
||||
LOG("SDK_INT field not accessible: " + e);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -162,7 +162,7 @@ if [ -f "$MIGRATE" ]; then
|
||||
if [ -n "$ARGS" ]; then
|
||||
grep_json() { [ -f "$2" ] && grep -m1 "$1" $2 | cut -d\" -f4; }
|
||||
verboseLogs=$(grep_json "VERBOSE_LOGS" $OLDJSON);
|
||||
ADVSETTINGS="spoofBuild spoofProps spoofProvider spoofSignature spoofVendingSdk verboseLogs";
|
||||
ADVSETTINGS="spoofBuild spoofProps spoofProvider spoofSignature spoofVendingFingerprint spoofVendingSdk verboseLogs";
|
||||
for SETTING in $ADVSETTINGS; do
|
||||
eval [ -z \"\$$SETTING\" ] \&\& $SETTING=$(grep_json "$SETTING" $OLDJSON);
|
||||
eval TMPVAL=\$$SETTING;
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
"spoofProps": "1",
|
||||
"spoofProvider": "1",
|
||||
"spoofSignature": "0",
|
||||
"spoofVendingFingerprint": "0",
|
||||
"spoofVendingSdk": "0",
|
||||
"verboseLogs": "0"
|
||||
}
|
||||
|
||||
@@ -114,12 +114,13 @@ if [ -z "$DEVICE_INITIAL_SDK_INT" -o "$DEVICE_INITIAL_SDK_INT" = "null" ]; then
|
||||
DEVICE_INITIAL_SDK_INT=25;
|
||||
fi;
|
||||
|
||||
ADVSETTINGS="spoofBuild spoofProps spoofProvider spoofSignature spoofVendingSdk verboseLogs";
|
||||
ADVSETTINGS="spoofBuild spoofProps spoofProvider spoofSignature spoofVendingFingerprint spoofVendingSdk verboseLogs";
|
||||
|
||||
spoofBuild=1;
|
||||
spoofProps=1;
|
||||
spoofProvider=1;
|
||||
spoofSignature=0;
|
||||
spoofVendingFingerprint=0;
|
||||
spoofVendingSdk=0;
|
||||
verboseLogs=0;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user