New version for custom spoof!

This commit is contained in:
chiteroman 2023-11-27 17:25:34 +01:00
parent a728533ed6
commit 4dcf53b340
No known key found for this signature in database
GPG Key ID: 15FF53015D426D8E
14 changed files with 136 additions and 136 deletions

3
.idea/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml

6
.idea/compiler.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="17" />
</component>
</project>

19
.idea/gradle.xml Normal file
View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="testRunner" value="GRADLE" />
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleJvm" value="jbr-17" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
</set>
</option>
</GradleProjectSettings>
</option>
</component>
</project>

View File

@ -0,0 +1,10 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="SpellCheckingInspection" enabled="false" level="TYPO" enabled_by_default="false">
<option name="processCode" value="true" />
<option name="processLiterals" value="true" />
<option name="processComments" value="true" />
</inspection_tool>
</profile>
</component>

10
.idea/misc.xml Normal file
View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="jbr-17" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>

6
.idea/vcs.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

View File

@ -45,20 +45,24 @@ android {
}
tasks.register("copyFiles") {
val moduleFolder = project.rootDir.resolve("module")
val dexFile = project.buildDir.resolve("intermediates/dex/release/minifyReleaseWithR8/classes.dex")
val soDir = project.buildDir.resolve("intermediates/stripped_native_libs/release/out/lib")
doLast {
val moduleFolder = project.rootDir.resolve("module")
val dexFile = project.buildDir.resolve("intermediates/dex/release/minifyReleaseWithR8/classes.dex")
val soDir = project.buildDir.resolve("intermediates/stripped_native_libs/release/out/lib")
dexFile.copyTo(moduleFolder.resolve("classes.dex"), overwrite = true)
dexFile.copyTo(moduleFolder.resolve("classes.dex"), overwrite = true)
soDir.walk().filter { it.isFile && it.extension == "so" }.forEach { soFile ->
val abiFolder = soFile.parentFile.name
val destination = moduleFolder.resolve("zygisk/$abiFolder.so")
soFile.copyTo(destination, overwrite = true)
soDir.walk().filter { it.isFile && it.extension == "so" }.forEach { soFile ->
val abiFolder = soFile.parentFile.name
val destination = moduleFolder.resolve("zygisk/$abiFolder.so")
soFile.copyTo(destination, overwrite = true)
}
}
}
tasks.register<Zip>("zip") {
dependsOn("copyFiles")
archiveFileName.set("PlayIntegrityFix.zip")
destinationDirectory.set(project.rootDir.resolve("out"))
@ -66,7 +70,5 @@ tasks.register<Zip>("zip") {
}
afterEvaluate {
tasks.named("assembleRelease") {
dependsOn("copyFiles", "zip")
}
tasks["assembleRelease"].finalizedBy("copyFiles", "zip")
}

View File

@ -1,6 +1,7 @@
#include <android/log.h>
#include <sys/system_properties.h>
#include <unistd.h>
#include <fstream>
#include "zygisk.hpp"
#include "shadowhook.h"
@ -79,15 +80,13 @@ public:
}
void preAppSpecialize(zygisk::AppSpecializeArgs *args) override {
bool isGms = false;
bool isGmsUnstable = false;
auto rawProcess = env->GetStringUTFChars(args->nice_name, nullptr);
if (rawProcess) {
std::string_view process(rawProcess);
isGms = process.starts_with("com.google.android.gms");
isGmsUnstable = process.compare("com.google.android.gms.unstable") == 0;
}
std::string_view process(rawProcess);
bool isGms = process.starts_with("com.google.android.gms");
bool isGmsUnstable = process.compare("com.google.android.gms.unstable") == 0;
env->ReleaseStringUTFChars(args->nice_name, rawProcess);
if (!isGms) {
@ -102,56 +101,51 @@ public:
return;
}
long size = 0;
int dexSize = 0;
int jsonSize = 0;
int fd = api->connectCompanion();
read(fd, &size, sizeof(long));
read(fd, &dexSize, sizeof(int));
read(fd, &jsonSize, sizeof(int));
if (size < 1) {
if (dexSize < 1) {
close(fd);
LOGD("Couldn't read from file descriptor 'classes.dex' file!");
LOGD("Couldn't read classes.dex");
api->setOption(zygisk::DLCLOSE_MODULE_LIBRARY);
return;
}
dexVector.resize(size);
read(fd, dexVector.data(), size);
size = 0;
read(fd, &size, sizeof(long));
if (size < 1) {
if (jsonSize < 1) {
close(fd);
LOGD("Couldn't read from file descriptor 'pif.json' file!");
LOGD("Couldn't read pif.json");
api->setOption(zygisk::DLCLOSE_MODULE_LIBRARY);
return;
}
propVector.resize(size);
dexVector.resize(dexSize);
jsonVector.resize(jsonSize);
read(fd, propVector.data(), size);
read(fd, dexVector.data(), dexSize);
read(fd, jsonVector.data(), jsonSize);
close(fd);
LOGD("Read from file descriptor file 'classes.dex' -> %d bytes",
static_cast<int>(dexVector.size()));
LOGD("Read from file descriptor file 'pif.json' -> %d bytes",
static_cast<int>(propVector.size()));
LOGD("Read from file descriptor file 'classes.dex' -> %d bytes", dexSize);
LOGD("Read from file descriptor file 'pif.json' -> %d bytes", jsonSize);
}
void postAppSpecialize(const zygisk::AppSpecializeArgs *args) override {
if (dexVector.empty() || propVector.empty()) return;
if (dexVector.empty() || jsonVector.empty()) return;
readJson();
inject();
doHook();
inject();
dexVector.clear();
propVector.clear();
jsonVector.clear();
}
void preServerSpecialize(zygisk::ServerSpecializeArgs *args) override {
@ -161,10 +155,10 @@ public:
private:
zygisk::Api *api = nullptr;
JNIEnv *env = nullptr;
std::vector<char> dexVector, propVector;
std::vector<char> dexVector, jsonVector;
void readJson() {
std::string data(propVector.cbegin(), propVector.cend());
std::string data(jsonVector.cbegin(), jsonVector.cend());
nlohmann::json json = nlohmann::json::parse(data, nullptr, false, true);
if (json.contains("SECURITY_PATCH")) {
@ -220,7 +214,7 @@ private:
LOGD("read json");
auto readProps = env->GetStaticMethodID(entryClass, "readJson",
"(Ljava/lang/String;)V");
std::string data(propVector.cbegin(), propVector.cend());
std::string data(jsonVector.cbegin(), jsonVector.cend());
auto javaStr = env->NewStringUTF(data.c_str());
env->CallStaticVoidMethod(entryClass, readProps, javaStr);
@ -231,46 +225,22 @@ private:
};
static void companion(int fd) {
long dexSize = 0;
char *dexBuffer = nullptr;
std::ifstream dex(DEX_FILE_PATH, std::ios::binary);
std::ifstream json(JSON_FILE_PATH);
long jsonSize = 0;
char *jsonBuffer = nullptr;
std::vector<char> dexVector((std::istreambuf_iterator<char>(dex)),
std::istreambuf_iterator<char>());
std::vector<char> jsonVector((std::istreambuf_iterator<char>(json)),
std::istreambuf_iterator<char>());
FILE *dex = fopen(DEX_FILE_PATH, "rb");
int dexSize = static_cast<int>(dexVector.size());
int jsonSize = static_cast<int>(jsonVector.size());
if (dex) {
fseek(dex, 0, SEEK_END);
dexSize = ftell(dex);
fseek(dex, 0, SEEK_SET);
write(fd, &dexSize, sizeof(int));
write(fd, &jsonSize, sizeof(int));
dexBuffer = static_cast<char *>(calloc(1, dexSize));
fread(dexBuffer, 1, dexSize, dex);
fclose(dex);
}
FILE *json = fopen(JSON_FILE_PATH, "r");
if (json) {
fseek(json, 0, SEEK_END);
jsonSize = ftell(json);
fseek(json, 0, SEEK_SET);
jsonBuffer = static_cast<char *>(calloc(1, jsonSize));
fread(jsonBuffer, 1, jsonSize, json);
fclose(json);
}
write(fd, &dexSize, sizeof(long));
write(fd, dexBuffer, dexSize);
write(fd, &jsonSize, sizeof(long));
write(fd, jsonBuffer, jsonSize);
free(dexBuffer);
free(jsonBuffer);
write(fd, dexVector.data(), dexSize);
write(fd, jsonVector.data(), jsonSize);
}
REGISTER_ZYGISK_MODULE(PlayIntegrityFix)

Binary file not shown.

Binary file not shown.

View File

@ -8,11 +8,3 @@ if [ -d "/data/adb/modules/safetynet-fix" ]; then
touch "/data/adb/modules/safetynet-fix/remove"
ui_print "- 'safetynet-fix' module will be removed in next reboot."
fi
# Use custom resetprop only in Android 10+
if [ "$API" -gt 28 ]; then
mv -f "$MODPATH/bin/$ABI/resetprop" "$MODPATH"
ui_print "- Using custom resetprop to avoid detections."
fi
rm -rf "$MODPATH/bin"

View File

@ -1,7 +1,7 @@
id=playintegrityfix
name=Play Integrity Fix
version=v13.8-beta
versionCode=137
version=PROPS-v2.0
versionCode=2000
author=chiteroman
description=Fix CTS profile (SafetyNet) and DEVICE verdict (Play Integrity).
updateJson=https://raw.githubusercontent.com/chiteroman/PlayIntegrityFix/main/update.json

View File

@ -1,27 +1,12 @@
# Sensitive properties
RESETPROP="${0%/*}/resetprop"
if [ -e "$RESETPROP" ]; then
chmod 755 $RESETPROP
else
RESETPROP="resetprop"
fi
check_resetprop() {
local NAME=$1
local EXPECTED=$2
local VALUE=$(resetprop $NAME)
[ -z $VALUE ] || [ $VALUE = $EXPECTED ] || $RESETPROP -n $NAME $EXPECTED
}
maybe_set_prop() {
local prop="$1"
local contains="$2"
local value="$3"
if [[ "$(getprop "$prop")" == *"$contains"* ]]; then
$RESETPROP -n "$prop" "$value"
resetprop "$prop" "$value"
fi
}
@ -31,9 +16,7 @@ maybe_set_prop ro.boot.mode recovery unknown
maybe_set_prop vendor.boot.mode recovery unknown
# Hiding SELinux | Permissive status
if [ -n "$(getprop ro.build.selinux)" ]; then
$RESETPROP --delete ro.build.selinux
fi
resetprop --delete ro.build.selinux
# Hiding SELinux | Use toybox to protect *stat* access time reading
if [[ "$(toybox cat /sys/fs/selinux/enforce)" == "0" ]]; then
@ -41,40 +24,23 @@ if [[ "$(toybox cat /sys/fs/selinux/enforce)" == "0" ]]; then
chmod 440 /sys/fs/selinux/policy
fi
# Reset props after boot completed to avoid breaking some weird devices/ROMs...
# Late props which must be set after boot_completed
{
until [[ "$(getprop sys.boot_completed)" == "1" ]]; do
sleep 1
done
# SafetyNet/Play Integrity | Avoid breaking Realme fingerprint scanners
check_resetprop ro.boot.flash.locked 1
resetprop ro.boot.flash.locked 1
# SafetyNet/Play Integrity | Avoid breaking Oppo fingerprint scanners
check_resetprop ro.boot.vbmeta.device_state locked
resetprop ro.boot.vbmeta.device_state locked
# SafetyNet/Play Integrity | Avoid breaking OnePlus display modes/fingerprint scanners
check_resetprop vendor.boot.verifiedbootstate green
resetprop vendor.boot.verifiedbootstate green
# SafetyNet/Play Integrity | Avoid breaking OnePlus display modes/fingerprint scanners on OOS 12
check_resetprop ro.boot.verifiedbootstate green
check_resetprop ro.boot.veritymode enforcing
check_resetprop vendor.boot.vbmeta.device_state locked
# RootBeer, Microsoft
check_resetprop ro.build.tags release-keys
# Samsung
check_resetprop ro.boot.warranty_bit 0
check_resetprop ro.vendor.boot.warranty_bit 0
check_resetprop ro.vendor.warranty_bit 0
check_resetprop ro.warranty_bit 0
# OnePlus
check_resetprop ro.is_ever_orange 0
# Other
check_resetprop ro.build.type user
check_resetprop ro.debuggable 0
check_resetprop ro.secure 1
resetprop ro.boot.verifiedbootstate green
resetprop ro.boot.veritymode enforcing
resetprop vendor.boot.vbmeta.device_state locked
}&

16
module/system.prop Normal file
View File

@ -0,0 +1,16 @@
# RootBeer, Microsoft
ro.build.tags=release-keys
# Samsung
ro.boot.warranty_bit=0
ro.vendor.boot.warranty_bit=0
ro.vendor.warranty_bit=0
ro.warranty_bit=0
# OnePlus
ro.is_ever_orange=0
# Other
ro.build.type=user
ro.debuggable=0
ro.secure=1