From a5b2422a788088281b4772cf7f6f5393f6d8bfc3 Mon Sep 17 00:00:00 2001 From: chiteroman <98092901+chiteroman@users.noreply.github.com> Date: Tue, 9 Jul 2024 01:18:29 +0200 Subject: [PATCH] v16.6-beta - Import few code from osm0sis fork - Add support for parsing system props in json - Use service.sh of Shamiko - Update fingerprint to fix RCS - Other improvements --- .idea/misc.xml | 3 +- app/build.gradle.kts | 2 +- app/src/main/cpp/main.cpp | 101 +++++++++++------ .../com/google/android/updater-script | 2 +- module/customize.sh | 52 +++++++-- module/module.prop | 4 +- module/pif.json | 104 ++++++++++++++++-- module/post-fs-data.sh | 32 ------ module/service.sh | 87 +++++++-------- 9 files changed, 247 insertions(+), 140 deletions(-) diff --git a/.idea/misc.xml b/.idea/misc.xml index 31d4edd..991a888 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,6 +1,7 @@ + - + diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 7284f57..81f6e41 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -17,7 +17,7 @@ android { minSdk = 26 targetSdk = 34 versionCode = 16500 - versionName = "v16.5" + versionName = "v16.6" multiDexEnabled = false packaging { diff --git a/app/src/main/cpp/main.cpp b/app/src/main/cpp/main.cpp index 3b5ea06..ed5873e 100644 --- a/app/src/main/cpp/main.cpp +++ b/app/src/main/cpp/main.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include "dobby.h" #include "json.hpp" #include "zygisk.hpp" @@ -40,53 +41,44 @@ static ssize_t xwrite(int fd, void *buffer, size_t count) { return total; } -static nlohmann::json json; +static int verboseLogs = 0; + +static std::map props; typedef void (*T_Callback)(void *, const char *, const char *, uint32_t); -static T_Callback o_callback = nullptr; +static std::map callbacks; static void modify_callback(void *cookie, const char *name, const char *value, uint32_t serial) { - if (cookie == nullptr || name == nullptr || value == nullptr || o_callback == nullptr) return; + if (cookie == nullptr || name == nullptr || value == nullptr || + !callbacks.contains(cookie)) + return; std::string_view prop(name); - if (prop.ends_with("api_level") && json.contains("DEVICE_INITIAL_SDK_INT") && - !json["DEVICE_INITIAL_SDK_INT"].empty()) { + if (prop == "init.svc.adbd") { + value = "stopped"; + } else if (prop == "sys.usb.state") { + value = "mtp"; + } - if (json["DEVICE_INITIAL_SDK_INT"].is_string()) { - value = json["DEVICE_INITIAL_SDK_INT"].get().c_str(); - } else if (json["DEVICE_INITIAL_SDK_INT"].is_number_integer()) { - value = std::to_string(json["DEVICE_INITIAL_SDK_INT"].get()).c_str(); - } - - } else if (prop.ends_with(".build.id") && json.contains("ID") && !json["ID"].empty()) { - - if (json["ID"].is_string()) { - value = json["ID"].get().c_str(); - } - - } else if (prop.ends_with(".security_patch") && json.contains("SECURITY_PATCH") && - !json["SECURITY_PATCH"].empty()) { - - if (json["SECURITY_PATCH"].is_string()) { - value = json["SECURITY_PATCH"].get().c_str(); - } - - } else if (prop.ends_with(".mod_device") && json.contains("PRODUCT") && - !json["PRODUCT"].empty()) { - - if (json["PRODUCT"].is_string()) { - value = json["PRODUCT"].get().c_str(); + if (props.contains(name)) { + value = props[name].c_str(); + if (verboseLogs > 49) LOGD("[%s]: %s", name, value); + } else { + for (const auto &item: props) { + if (item.first.starts_with("*") && prop.ends_with(item.first.substr(1))) { + value = item.second.c_str(); + if (verboseLogs > 49) LOGD("[%s]: %s", name, value); + break; + } } } - if (!prop.starts_with("cache") && !prop.starts_with("debug") && !prop.starts_with("persist")) { - LOGD("[%s]: %s", name, value); - } + if (verboseLogs > 99) LOGD("[%s]: %s", name, value); - return o_callback(cookie, name, value, serial); + return callbacks[cookie](cookie, name, value, serial); } static void (*o_system_property_read_callback)(const prop_info *, T_Callback, void *); @@ -96,7 +88,7 @@ my_system_property_read_callback(const prop_info *pi, T_Callback callback, void if (pi == nullptr || callback == nullptr || cookie == nullptr) { return o_system_property_read_callback(pi, callback, cookie); } - o_callback = callback; + callbacks[cookie] = callback; return o_system_property_read_callback(pi, modify_callback, cookie); } @@ -185,6 +177,8 @@ public: LOGD("Dex file size: %d", dexSize); LOGD("Json file size: %d", jsonSize); + + parseJSON(); } void postAppSpecialize(const zygisk::AppSpecializeArgs *args) override { @@ -203,6 +197,45 @@ private: zygisk::Api *api = nullptr; JNIEnv *env = nullptr; std::vector dexVector; + nlohmann::json json; + + void parseJSON() { + if (json.empty()) return; + + if (json.contains("verboseLogs") && !json["verboseLogs"].empty()) { + if (json["verboseLogs"].is_string()) { + verboseLogs = std::stoi(json["verboseLogs"].get()); + } else if (json["verboseLogs"].is_number_integer()) { + verboseLogs = json["verboseLogs"].get(); + } + json.erase("verboseLogs"); + } + + if (verboseLogs > 0) LOGD("Verbose logging (level %d) enabled", verboseLogs); + + std::vector removeKeys; + + // Java fields are always uppercase, system props are always lowercase + for (const auto &item: json.items()) { + if (std::all_of(item.key().cbegin(), item.key().cend(), [](unsigned char c) { + return c == '_' || (std::isalpha(c) && std::isupper(c)); + })) { + // Java field + if (verboseLogs > 99) LOGD("Skip Java field: %s", item.key().c_str()); + continue; + } + // System prop + if (item.value().is_string()) { + props.insert({item.key(), item.value().get()}); + if (verboseLogs > 99) LOGD("Got system prop: %s", item.key().c_str()); + } + removeKeys.push_back(item.key()); + } + + LOGD("Loaded %d props to spoof", props.size()); + + for (const auto &item: removeKeys) json.erase(item); + } void injectDex() { LOGD("get system classloader"); diff --git a/module/META-INF/com/google/android/updater-script b/module/META-INF/com/google/android/updater-script index 492be83..11d5c96 100644 --- a/module/META-INF/com/google/android/updater-script +++ b/module/META-INF/com/google/android/updater-script @@ -1 +1 @@ -#MAGISK \ No newline at end of file +#MAGISK diff --git a/module/customize.sh b/module/customize.sh index 091f935..ef235da 100644 --- a/module/customize.sh +++ b/module/customize.sh @@ -1,22 +1,56 @@ -# Error on < Android 8. +# Error on < Android 8 if [ "$API" -lt 26 ]; then abort "- !!! You can't use this module on Android < 8.0" fi -# safetynet-fix module is obsolete and it's incompatible with PIF. -if [ -d /data/adb/modules/safetynet-fix ]; then - rm -rf /data/adb/modules/safetynet-fix - rm -f /data/adb/SNFix.dex - ui_print "! safetynet-fix module will be removed. Do NOT install it again along PIF." +# safetynet-fix module is obsolete and it's incompatible with PIF +if [ -d "/data/adb/modules/safetynet-fix" ]; then + touch "/data/adb/modules/safetynet-fix/remove" + ui_print "! safetynet-fix module removed. Do NOT install it again along PIF" fi -# MagiskHidePropsConf module is obsolete in Android 8+ but it shouldn't give issues. -if [ -d /data/adb/modules/MagiskHidePropsConf ]; then +# playcurl must be removed when flashing PIF +if [ -d "/data/adb/modules/playcurl" ]; then + touch "/data/adb/modules/playcurl/remove" + ui_print "! playcurl module removed!" +fi + +# MagiskHidePropsConf module is obsolete in Android 8+ but it shouldn't give issues +if [ -d "/data/adb/modules/MagiskHidePropsConf" ]; then ui_print "! WARNING, MagiskHidePropsConf module may cause issues with PIF." fi # Check custom fingerprint if [ -f "/data/adb/pif.json" ]; then mv -f "/data/adb/pif.json" "/data/adb/pif.json.old" - ui_print "- Backup old pif.json" + ui_print "- Backup custom pif.json" +fi + +REMOVE=" +/system/product/app/XiaomiEUInject +/system/product/app/XiaomiEUInject-Stub +/system/system/app/EliteDevelopmentModule +/system/system/app/XInjectModule +/system/system_ext/app/hentaiLewdbSVTDummy +/system/system_ext/app/PifPrebuilt +/system/system_ext/overlay/CertifiedPropsOverlay.apk +" + +if [ "$KSU" = "true" -o "$APATCH" = "true" ]; then + ui_print "- KernelSU/APatch detected, conflicting apps will be automatically removed" +else + ui_print "- Magisk detected, removing conflicting apps one by one :(" + echo "$REMOVE" | grep -v '^$' | while read -r line; do + if [ -d "$line" ]; then + mkdir -p "${MODPATH}${line}" + touch "${MODPATH}${line}/.replace" + ui_print "- Removed dir: $line" + elif [ -f "$line" ]; then + dir=$(dirname "$line") + filename=$(basename "$line") + mkdir -p "${MODPATH}${dir}" + touch "${MODPATH}${dir}/${filename}" + ui_print "- Removed file: $line" + fi + done fi diff --git a/module/module.prop b/module/module.prop index 66be188..257e133 100644 --- a/module/module.prop +++ b/module/module.prop @@ -1,7 +1,7 @@ id=playintegrityfix name=Play Integrity Fix -version=v16.5 -versionCode=16500 +version=v16.6 +versionCode=16600 author=chiteroman description=Universal modular fix for Play Integrity (and SafetyNet) on devices running Android 8-15 updateJson=https://raw.githubusercontent.com/chiteroman/PlayIntegrityFix/main/update.json diff --git a/module/pif.json b/module/pif.json index 81d5f6b..f6f60ca 100644 --- a/module/pif.json +++ b/module/pif.json @@ -1,15 +1,95 @@ { - "ID": "OPM1.171019.011", - "PRODUCT": "sailfish", - "DEVICE": "sailfish", - "BOARD": "", - "MANUFACTURER": "Google", "BRAND": "google", - "MODEL": "Pixel", - "HARDWARE": "", - "INCREMENTAL": "4448085", - "RELEASE": "8.1.0", - "SECURITY_PATCH": "2017-12-05", - "DEVICE_INITIAL_SDK_INT": 24, - "FINGERPRINT": "google/sailfish/sailfish:8.1.0/OPM1.171019.011/4448085:user/release-keys" + "DEVICE": "husky", + "FINGERPRINT": "google/husky_beta/husky:15/AP31.240517.022/11948202:user/release-keys", + "ID": "AP31.240517.022", + "MANUFACTURER": "Google", + "MODEL": "Pixel 8 Pro", + "PRODUCT": "husky_beta", + "SECURITY_PATCH": "2024-06-05", + "*.security_patch": "2024-06-05", + "*api_level": "24", + "dalvik.vm.appimageformat": "lz4", + "dalvik.vm.dex2oat-Xms": "64m", + "dalvik.vm.dex2oat-Xmx": "512m", + "dalvik.vm.dex2oat-max-image-block-size": "524288", + "dalvik.vm.dex2oat-minidebuginfo": "true", + "dalvik.vm.dex2oat-resolve-startup-strings": "true", + "dalvik.vm.dexopt.secondary": "true", + "dalvik.vm.dexopt.thermal-cutoff": "2", + "dalvik.vm.image-dex2oat-Xms": "64m", + "dalvik.vm.image-dex2oat-Xmx": "64m", + "dalvik.vm.madvise.artfile.size": "4294967295", + "dalvik.vm.madvise.odexfile.size": "104857600", + "dalvik.vm.madvise.vdexfile.size": "104857600", + "dalvik.vm.minidebuginfo": "true", + "dalvik.vm.usap_pool_enabled": "false", + "dalvik.vm.usap_pool_refill_delay_ms": "3000", + "dalvik.vm.usap_pool_size_max": "3", + "dalvik.vm.usap_pool_size_min": "1", + "dalvik.vm.usap_refill_threshold": "1", + "dalvik.vm.useartservice": "true", + "dalvik.vm.usejit": "true", + "debug.atrace.tags.enableflags": "0", + "net.bt.name": "Android", + "persist.settings.large_screen_opt.enabled": "false", + "persist.traced.enable": "1", + "pm.dexopt.ab-ota": "speed-profile", + "pm.dexopt.bg-dexopt": "speed-profile", + "pm.dexopt.boot-after-mainline-update": "verify", + "pm.dexopt.boot-after-ota": "verify", + "pm.dexopt.cmdline": "verify", + "pm.dexopt.first-boot": "verify", + "pm.dexopt.inactive": "verify", + "pm.dexopt.install": "speed-profile", + "pm.dexopt.install-bulk": "speed-profile", + "pm.dexopt.install-bulk-downgraded": "verify", + "pm.dexopt.install-bulk-secondary": "verify", + "pm.dexopt.install-bulk-secondary-downgraded": "verify", + "pm.dexopt.install-fast": "skip", + "pm.dexopt.post-boot": "verify", + "pm.dexopt.shared": "speed", + "ro.actionable_compatible_property.enabled": "true", + "ro.adb.secure": "1", + "ro.allow.mock.location": "0", + "ro.apex.updatable": "true", + "ro.build.date": "Mon Jun 10 17:11:45 UTC 2024", + "ro.build.date.utc": "1718039505", + "ro.build.description": "husky_beta-user 15 AP31.240517.022 11948202 release-keys", + "ro.build.display.id": "AP31.240517.022", + "ro.build.flavor": "husky_beta-user", + "ro.build.host": "r-5ed19c9f6e4ddbc5-v0mt", + "ro.build.user": "android-build", + "ro.build.version.all_codenames": "REL", + "ro.build.version.codename": "REL", + "ro.build.version.known_codenames": "Base,Base11,Cupcake,Donut,Eclair,Eclair01,EclairMr1,Froyo,Gingerbread,GingerbreadMr1,Honeycomb,HoneycombMr1,HoneycombMr2,IceCreamSandwich,IceCreamSandwichMr1,JellyBean,JellyBeanMr1,JellyBeanMr2,Kitkat,KitkatWatch,Lollipop,LollipopMr1,M,N,NMr1,O,OMr1,P,Q,R,S,Sv2,Tiramisu,UpsideDownCake,VanillaIceCream", + "ro.build.version.min_supported_target_sdk": "28", + "ro.build.version.preview_sdk": "0", + "ro.build.version.preview_sdk_fingerprint": "REL", + "ro.build.version.release_or_codename": "15", + "ro.build.version.release_or_preview_display": "15", + "ro.camerax.extensions.enabled": "true", + "ro.dalvik.vm.native.bridge": "0", + "ro.debuggable": "0", + "ro.force.debuggable": "0", + "ro.hotword.detection_service_required": "true", + "ro.launcher.blur.appLaunch": "0", + "ro.llndk.api_level": "202404", + "ro.postinstall.fstab.prefix": "/system", + "ro.product.cpu.abi": "arm64-v8a", + "ro.product.locale": "en-US", + "ro.secure": "1", + "ro.system.build.date": "Mon Jun 10 17:11:45 UTC 2024", + "ro.system.build.date.utc": "1718039505", + "ro.system.build.id": "AP31.240517.022", + "ro.system.build.tags": "release-keys", + "ro.system.build.type": "user", + "ro.system.build.version.incremental": "11948202", + "ro.system.build.version.release": "15", + "ro.system.build.version.release_or_codename": "15", + "ro.system.product.cpu.abilist": "arm64-v8a", + "ro.system.product.cpu.abilist64": "arm64-v8a", + "ro.treble.enabled": "true", + "security.perf_harden": "1", + "verboseLogs": 100 } diff --git a/module/post-fs-data.sh b/module/post-fs-data.sh index dd92da4..9da99f2 100644 --- a/module/post-fs-data.sh +++ b/module/post-fs-data.sh @@ -2,35 +2,3 @@ if magisk --denylist status; then magisk --denylist rm com.google.android.gms fi - -# Remove safetynet-fix module if installed -if [ -d /data/adb/modules/safetynet-fix ]; then - rm -rf /data/adb/modules/safetynet-fix - rm -rf /data/adb/SNFix.dex -fi - -resetprop_if_diff() { - local NAME="$1" - local EXPECTED="$2" - local CURRENT="$(resetprop "$NAME")" - - [ -z "$CURRENT" ] || [ "$CURRENT" = "$EXPECTED" ] || resetprop "$NAME" "$EXPECTED" -} - -resetprop_if_diff ro.build.tags release-keys - -resetprop_if_diff ro.boot.warranty_bit 0 - -resetprop_if_diff ro.vendor.boot.warranty_bit 0 - -resetprop_if_diff ro.vendor.warranty_bit 0 - -resetprop_if_diff ro.warranty_bit 0 - -resetprop_if_diff ro.is_ever_orange 0 - -resetprop_if_diff ro.build.type user - -resetprop_if_diff ro.debuggable 0 - -resetprop_if_diff ro.secure 1 diff --git a/module/service.sh b/module/service.sh index 58b10bb..f60b0ae 100644 --- a/module/service.sh +++ b/module/service.sh @@ -1,56 +1,47 @@ -# Conditional sensitive properties +#!/system/bin/sh -resetprop_if_diff() { - local NAME="$1" - local EXPECTED="$2" - local CURRENT="$(resetprop "$NAME")" - - [ -z "$CURRENT" ] || [ "$CURRENT" = "$EXPECTED" ] || resetprop "$NAME" "$EXPECTED" +check_reset_prop() { + local NAME=$1 + local EXPECTED=$2 + local VALUE=$(resetprop $NAME) + [ -z $VALUE ] || [ $VALUE = $EXPECTED ] || resetprop $NAME $EXPECTED } -resetprop_if_match() { - local NAME="$1" - local CONTAINS="$2" - local VALUE="$3" - - [[ "$(resetprop "$NAME")" = *"$CONTAINS"* ]] && resetprop "$NAME" "$VALUE" +contains_reset_prop() { + local NAME=$1 + local CONTAINS=$2 + local NEWVAL=$3 + [[ "$(resetprop $NAME)" = *"$CONTAINS"* ]] && resetprop $NAME $NEWVAL } -# Magisk recovery mode -resetprop_if_match ro.bootmode recovery unknown -resetprop_if_match ro.boot.mode recovery unknown -resetprop_if_match vendor.boot.mode recovery unknown +resetprop -w sys.boot_completed 0 -# SELinux -resetprop_if_diff ro.boot.selinux enforcing -# use delete since it can be 0 or 1 for enforcing depending on OEM -if [ -n "$(resetprop ro.build.selinux)" ]; then - resetprop --delete ro.build.selinux -fi +check_reset_prop "ro.boot.vbmeta.device_state" "locked" +check_reset_prop "ro.boot.verifiedbootstate" "green" +check_reset_prop "ro.boot.flash.locked" "1" +check_reset_prop "ro.boot.veritymode" "enforcing" +check_reset_prop "ro.boot.warranty_bit" "0" +check_reset_prop "ro.warranty_bit" "0" +check_reset_prop "ro.debuggable" "0" +check_reset_prop "ro.force.debuggable" "0" +check_reset_prop "ro.secure" "1" +check_reset_prop "ro.adb.secure" "1" +check_reset_prop "ro.build.type" "user" +check_reset_prop "ro.build.tags" "release-keys" +check_reset_prop "ro.vendor.boot.warranty_bit" "0" +check_reset_prop "ro.vendor.warranty_bit" "0" +check_reset_prop "vendor.boot.vbmeta.device_state" "locked" +check_reset_prop "vendor.boot.verifiedbootstate" "green" +check_reset_prop "sys.oem_unlock_allowed" "0" -# use toybox to protect *stat* access time reading -if [ "$(toybox cat /sys/fs/selinux/enforce)" = "0" ]; then - chmod 640 /sys/fs/selinux/enforce - chmod 440 /sys/fs/selinux/policy -fi +# MIUI specific +check_reset_prop "ro.secureboot.lockstate" "locked" -# 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 - resetprop_if_diff ro.boot.flash.locked 1 - - # SafetyNet/Play Integrity | Avoid breaking Oppo fingerprint scanners - resetprop_if_diff ro.boot.vbmeta.device_state locked - - # SafetyNet/Play Integrity | Avoid breaking OnePlus display modes/fingerprint scanners - resetprop_if_diff vendor.boot.verifiedbootstate green - - # SafetyNet/Play Integrity | Avoid breaking OnePlus display modes/fingerprint scanners on OOS 12 - resetprop_if_diff ro.boot.verifiedbootstate green - resetprop_if_diff ro.boot.veritymode enforcing - resetprop_if_diff vendor.boot.vbmeta.device_state locked -}& \ No newline at end of file +# Realme specific +check_reset_prop "ro.boot.realmebootstate" "green" +check_reset_prop "ro.boot.realme.lockstate" "1" + +# Hide that we booted from recovery when magisk is in recovery mode +contains_reset_prop "ro.bootmode" "recovery" "unknown" +contains_reset_prop "ro.boot.bootmode" "recovery" "unknown" +contains_reset_prop "vendor.boot.bootmode" "recovery" "unknown"