diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..26d33521af10bcc7fd8cea344038eaaeb78d0ef5 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000000000000000000000000000000000000..b589d56e9f285d8cfdc6c270853a5d439021a278 --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="CompilerConfiguration"> + <bytecodeTargetLevel target="17" /> + </component> +</project> \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000000000000000000000000000000000000..6d890505686cbe08ef947ab55a100426a0f4befe --- /dev/null +++ b/.idea/gradle.xml @@ -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> \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000000000000000000000000000000000000..146ab09b7c50daf1f04814fccb913b8d87302176 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -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> \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000000000000000000000000000000000000..0ad17cbd33a2f389d524bc4bfef9c52e1f7ab490 --- /dev/null +++ b/.idea/misc.xml @@ -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> \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000000000000000000000000000000000000..35eb1ddfbbc029bcab630581847471d7f238ec53 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="VcsDirectoryMappings"> + <mapping directory="" vcs="Git" /> + </component> +</project> \ No newline at end of file diff --git a/app/build.gradle.kts b/app/build.gradle.kts index e6e4b14ab33661800d7378a265cfc24f8b3bf9fa..ca05e7cef04f011a3c21fc2fefeccef3ff0ff9e2 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -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") } \ No newline at end of file diff --git a/app/src/main/cpp/main.cpp b/app/src/main/cpp/main.cpp index ba44e6682cfaaa30fb78a6a7422356113c7f7814..b4e98ebb121188629ffece0911476beddae47c41 100644 --- a/app/src/main/cpp/main.cpp +++ b/app/src/main/cpp/main.cpp @@ -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; - - long jsonSize = 0; - char *jsonBuffer = nullptr; - - FILE *dex = fopen(DEX_FILE_PATH, "rb"); - - if (dex) { - fseek(dex, 0, SEEK_END); - dexSize = ftell(dex); - fseek(dex, 0, SEEK_SET); - - dexBuffer = static_cast<char *>(calloc(1, dexSize)); - fread(dexBuffer, 1, dexSize, dex); + std::ifstream dex(DEX_FILE_PATH, std::ios::binary); + std::ifstream json(JSON_FILE_PATH); - 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); - } + 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>()); - write(fd, &dexSize, sizeof(long)); - write(fd, dexBuffer, dexSize); + int dexSize = static_cast<int>(dexVector.size()); + int jsonSize = static_cast<int>(jsonVector.size()); - write(fd, &jsonSize, sizeof(long)); - write(fd, jsonBuffer, jsonSize); + write(fd, &dexSize, sizeof(int)); + write(fd, &jsonSize, sizeof(int)); - free(dexBuffer); - free(jsonBuffer); + write(fd, dexVector.data(), dexSize); + write(fd, jsonVector.data(), jsonSize); } REGISTER_ZYGISK_MODULE(PlayIntegrityFix) diff --git a/module/bin/arm64-v8a/resetprop b/module/bin/arm64-v8a/resetprop deleted file mode 100644 index 513fdefd1c67b438d2dd61caf904aeed67ee7d03..0000000000000000000000000000000000000000 Binary files a/module/bin/arm64-v8a/resetprop and /dev/null differ diff --git a/module/bin/armeabi-v7a/resetprop b/module/bin/armeabi-v7a/resetprop deleted file mode 100644 index dad18cdf35b470b6265de032760597c0c46c13c6..0000000000000000000000000000000000000000 Binary files a/module/bin/armeabi-v7a/resetprop and /dev/null differ diff --git a/module/customize.sh b/module/customize.sh index a6d50c03f8933c8b4577a6137e392594638fe0fe..ea07489a7ba1af816d49d85475895fd1a3f883bb 100644 --- a/module/customize.sh +++ b/module/customize.sh @@ -7,12 +7,4 @@ fi 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" \ No newline at end of file +fi \ No newline at end of file diff --git a/module/module.prop b/module/module.prop index 6c77468862f694207e932a3ac32f584c64f5ddba..a1ae94f72f6dcaf812aef319f716add300eb0f9a 100644 --- a/module/module.prop +++ b/module/module.prop @@ -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 \ No newline at end of file diff --git a/module/service.sh b/module/service.sh index e032ef2e502bc60176adcc591fc696cc8b1e7b39..307ea1c4db23dd498f167b5d5bcdb39813b3e5e7 100644 --- a/module/service.sh +++ b/module/service.sh @@ -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 }& diff --git a/module/system.prop b/module/system.prop new file mode 100644 index 0000000000000000000000000000000000000000..a1dfa579717e72d2c153efab7baa052b402857e3 --- /dev/null +++ b/module/system.prop @@ -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