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 spoofProps = 1;
|
||||||
static int spoofProvider = 1;
|
static int spoofProvider = 1;
|
||||||
static int spoofSignature = 0;
|
static int spoofSignature = 0;
|
||||||
|
static int spoofVendingFingerprint = 0;
|
||||||
static int spoofVendingSdk = 0;
|
static int spoofVendingSdk = 0;
|
||||||
|
|
||||||
static std::map<std::string, std::string> jsonProps;
|
static std::map<std::string, std::string> jsonProps;
|
||||||
@@ -166,10 +167,10 @@ public:
|
|||||||
readJson();
|
readJson();
|
||||||
|
|
||||||
if (pkgName == VENDING_PACKAGE) spoofProps = spoofBuild = spoofProvider = spoofSignature = 0;
|
if (pkgName == VENDING_PACKAGE) spoofProps = spoofBuild = spoofProvider = spoofSignature = 0;
|
||||||
else spoofVendingSdk = 0;
|
else spoofVendingFingerprint = spoofVendingSdk = 0;
|
||||||
|
|
||||||
if (spoofProps > 0) doHook();
|
if (spoofProps > 0) doHook();
|
||||||
if (spoofBuild + spoofProvider + spoofSignature + spoofVendingSdk > 0) inject();
|
if (spoofBuild + spoofProvider + spoofSignature + spoofVendingFingerprint + spoofVendingSdk > 0) inject();
|
||||||
|
|
||||||
dexVector.clear();
|
dexVector.clear();
|
||||||
json.clear();
|
json.clear();
|
||||||
@@ -185,6 +186,7 @@ private:
|
|||||||
std::vector<char> dexVector;
|
std::vector<char> dexVector;
|
||||||
nlohmann::json json;
|
nlohmann::json json;
|
||||||
std::string pkgName;
|
std::string pkgName;
|
||||||
|
std::string spoofFingerprintValue = "";
|
||||||
|
|
||||||
void readJson() {
|
void readJson() {
|
||||||
LOGD("JSON contains %d keys!", static_cast<int>(json.size()));
|
LOGD("JSON contains %d keys!", static_cast<int>(json.size()));
|
||||||
@@ -210,6 +212,17 @@ private:
|
|||||||
}
|
}
|
||||||
json.erase("spoofVendingSdk");
|
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) {
|
if (pkgName == VENDING_PACKAGE) {
|
||||||
json.clear();
|
json.clear();
|
||||||
return;
|
return;
|
||||||
@@ -299,8 +312,9 @@ private:
|
|||||||
|
|
||||||
if (pkgName == VENDING_PACKAGE) {
|
if (pkgName == VENDING_PACKAGE) {
|
||||||
LOGD("JNI %s: Calling EntryPointVending.init", niceName);
|
LOGD("JNI %s: Calling EntryPointVending.init", niceName);
|
||||||
auto entryInit = env->GetStaticMethodID(entryClass, "init", "(II)V");
|
auto entryInit = env->GetStaticMethodID(entryClass, "init", "(IIILjava/lang/String;)V");
|
||||||
env->CallStaticVoidMethod(entryClass, entryInit, verboseLogs, spoofVendingSdk);
|
auto javaStr = env->NewStringUTF(spoofFingerprintValue.c_str());
|
||||||
|
env->CallStaticVoidMethod(entryClass, entryInit, verboseLogs, spoofVendingFingerprint, spoofVendingSdk, javaStr);
|
||||||
} else {
|
} else {
|
||||||
LOGD("JNI %s: Sending JSON", niceName);
|
LOGD("JNI %s: Sending JSON", niceName);
|
||||||
auto receiveJson = env->GetStaticMethodID(entryClass, "receiveJson", "(Ljava/lang/String;)V");
|
auto receiveJson = env->GetStaticMethodID(entryClass, "receiveJson", "(Ljava/lang/String;)V");
|
||||||
|
|||||||
@@ -12,29 +12,51 @@ public final class EntryPointVending {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("DefaultLocale")
|
@SuppressLint("DefaultLocale")
|
||||||
public static void init(int verboseLogs, int spoofVendingSdk) {
|
public static void init(int verboseLogs, int spoofVendingFingerprint, int spoofVendingSdk, String spoofFingerprintValue) {
|
||||||
if (spoofVendingSdk < 1) return;
|
if (spoofVendingSdk < 1){
|
||||||
int requestSdk = spoofVendingSdk == 1 ? 32 : spoofVendingSdk;
|
// Only spoof FINGERPRINT to Play Store if not forcing legacy verdict
|
||||||
int targetSdk = Math.min(Build.VERSION.SDK_INT, requestSdk);
|
if (spoofVendingFingerprint < 1) return;
|
||||||
int oldValue;
|
String oldValue;
|
||||||
try {
|
try {
|
||||||
Field field = Build.VERSION.class.getDeclaredField("SDK_INT");
|
Field field = Build.class.getDeclaredField("FINGERPRINT");
|
||||||
field.setAccessible(true);
|
field.setAccessible(true);
|
||||||
oldValue = field.getInt(null);
|
oldValue = String.valueOf(field.get(null));
|
||||||
if (oldValue == targetSdk) {
|
if (oldValue.equals(spoofFingerprintValue)) {
|
||||||
if (verboseLogs > 2) LOG(String.format("[SDK_INT]: %d (unchanged)", oldValue));
|
if (verboseLogs > 2) LOG(String.format("[FINGERPRINT]: %s (unchanged)", oldValue));
|
||||||
|
field.setAccessible(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
field.set(null, spoofFingerprintValue);
|
||||||
field.setAccessible(false);
|
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
|
if [ -n "$ARGS" ]; then
|
||||||
grep_json() { [ -f "$2" ] && grep -m1 "$1" $2 | cut -d\" -f4; }
|
grep_json() { [ -f "$2" ] && grep -m1 "$1" $2 | cut -d\" -f4; }
|
||||||
verboseLogs=$(grep_json "VERBOSE_LOGS" $OLDJSON);
|
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
|
for SETTING in $ADVSETTINGS; do
|
||||||
eval [ -z \"\$$SETTING\" ] \&\& $SETTING=$(grep_json "$SETTING" $OLDJSON);
|
eval [ -z \"\$$SETTING\" ] \&\& $SETTING=$(grep_json "$SETTING" $OLDJSON);
|
||||||
eval TMPVAL=\$$SETTING;
|
eval TMPVAL=\$$SETTING;
|
||||||
|
|||||||
@@ -31,6 +31,7 @@
|
|||||||
"spoofProps": "1",
|
"spoofProps": "1",
|
||||||
"spoofProvider": "1",
|
"spoofProvider": "1",
|
||||||
"spoofSignature": "0",
|
"spoofSignature": "0",
|
||||||
|
"spoofVendingFingerprint": "0",
|
||||||
"spoofVendingSdk": "0",
|
"spoofVendingSdk": "0",
|
||||||
"verboseLogs": "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;
|
DEVICE_INITIAL_SDK_INT=25;
|
||||||
fi;
|
fi;
|
||||||
|
|
||||||
ADVSETTINGS="spoofBuild spoofProps spoofProvider spoofSignature spoofVendingSdk verboseLogs";
|
ADVSETTINGS="spoofBuild spoofProps spoofProvider spoofSignature spoofVendingFingerprint spoofVendingSdk verboseLogs";
|
||||||
|
|
||||||
spoofBuild=1;
|
spoofBuild=1;
|
||||||
spoofProps=1;
|
spoofProps=1;
|
||||||
spoofProvider=1;
|
spoofProvider=1;
|
||||||
spoofSignature=0;
|
spoofSignature=0;
|
||||||
|
spoofVendingFingerprint=0;
|
||||||
spoofVendingSdk=0;
|
spoofVendingSdk=0;
|
||||||
verboseLogs=0;
|
verboseLogs=0;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user