From 3bf73ee1d2b0605a12333ded95da51c38b343d28 Mon Sep 17 00:00:00 2001 From: Didgeridoohan Date: Mon, 16 Apr 2018 00:05:33 +0200 Subject: [PATCH] v2.0.0-v6 --- META-INF/com/google/android/update-binary | 2 +- README.md | 80 ++- common/post-fs-data.sh | 117 ++--- common/prints.sh | 25 +- common/propsconf_conf | 70 +++ common/propsconf_late | 130 +++-- common/util_functions.sh | 565 ++++++++++++++++++++-- config.sh | 74 ++- module.prop | 6 +- system/binpath/props | Bin 27508 -> 32165 bytes 10 files changed, 872 insertions(+), 197 deletions(-) create mode 100644 common/propsconf_conf diff --git a/META-INF/com/google/android/update-binary b/META-INF/com/google/android/update-binary index f33f37a..54dd2d7 100755 --- a/META-INF/com/google/android/update-binary +++ b/META-INF/com/google/android/update-binary @@ -136,7 +136,7 @@ $POSTFSDATA && cp -af $INSTALLER/common/post-fs-data.sh $MODPATH/post-fs-data.sh # service mode scripts $LATESTARTSERVICE && cp -af $INSTALLER/common/service.sh $MODPATH/service.sh -# Module boot script placement and backup, etc +# Module script placement script_install ui_print "- Setting permissions" diff --git a/README.md b/README.md index 93ac0ff..399b9d2 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ ## Installation Install through the Magisk Manager Downloads section. Or, download the zip from the Manager or the [module support thread](https://forum.xda-developers.com/apps/magisk/module-magiskhide-props-config-simple-t3765199), and install through the Magisk Manager -> Modules, or from recovery. -The current release is always attached to the OP of the [module support thread](https://forum.xda-developers.com/apps/magisk/module-magiskhide-props-config-simple-t3765199). Any previous releases can also be found on [GitHub](https://github.com/Magisk-Modules-Repo/MagiskHide-Props-Config/releases). If downloading a release from GitHub, make sure to repackage the zip with all the module files and folders in the root of the zip. Otherwise it won't install (error: "not a Magisk zip"). +The current release is always attached to the OP of the [module support thread](https://forum.xda-developers.com/apps/magisk/module-magiskhide-props-config-simple-t3765199). Any previous releases can be found on [GitHub](https://github.com/Magisk-Modules-Repo/MagiskHide-Props-Config/releases). ## Usage @@ -17,7 +17,7 @@ After installing the module and rebooting, run the command `props` (as su) in a su props ``` -You can also run the command with options. Use -h or --help for details. +You can also run the command with options. Use -h for details. ## Spoofing device's fingerprint @@ -47,9 +47,9 @@ Google Nexus 6=google/shamu/shamu:7.1.1/N8I11B/4171878:user/release-keys ## Current fingerprints list version The fingerprints list will update without the need to update the entire module. Keep an eye on the [module support thread](https://forum.xda-developers.com/apps/magisk/module-magiskhide-props-config-simple-t3765199) for info. -Just run the `props` command and the list will be updated automatically. +Just run the `props` command and the list will be updated automatically. Use the -nw option to disable. -**_Current fingerprints list version - v5_** +**_Current fingerprints list version - v6_** ## Editing build.prop and default.prop @@ -61,20 +61,50 @@ By default, if MagiskHide detects certain sensitive prop values they will be cha - ro.debuggable (set to "0" by MagiskHide - sensitive value is "1") - ro.secure (set to "1" by MagiskHide - sensitive value is "0") - ro.build.type (set to "user" by MagiskHide - sensitive value is "userdebug") -- ro.build.tags (set to "release-keys" by MagiskHide - sensitive value is "test-keys") +- ro.build.tags (set to "release-keys" by MagiskHide - sensitive value is "test-keys" or "dev-keys") - ro.build.selinux (set to "0" by MagiskHide - sensitive value is "1") If, for some reason, you need one or more of these to be kept as their original value (one example would be resetting ro.build.type to userdebug since some ROMs need this to work properly), you can reset to the original value with this module. Keep in mind that this might trigger some apps looking for these prop values as a sign of your device being rooted. -You can also use this module to set these props to your preferred value with MagiskHide disabled. + +## Change/set custom prop values +It's quite easy to change prop values with Magisk. With this module it's even easier. Just enter the prop you want to change and the new value and the module does the rest, nice and systemless. Any changes that you've previously done directly to build.prop you can now do with this module instead. + + +## Prop script options +There are a couple of persistent options that you can set for the `props` script. These are currently "Colour" and "Fingerprints list check". The colour option disables or enables colours for the script, and the fingerprints list check option disables or enables automatic updating of the fingerprints list when the script starts. If the fingerprints list check is disabled, the list can be manually updated from within the script, under the "Device fingerprint" menu. + + +## Configuration file +You can use a configuration file to set your desired options, rather than running the `props` command. Download the [settings file](https://raw.githubusercontent.com/Magisk-Modules-Repo/MagiskHide-Props-Config/master/common/propsconf_conf) or extract it from the module zip (in the common folder), fill in the desired options (follow the instructions in the file), place it in /cache (or /data/cache if you're using an A/B device) and reboot. This can also be done directly at the first install (through Manager or recovery), before even rebooting your device. Instant settings. + + +## Device issues because of the module +In case of issues, if you've set a prop value that doesn't work on your device causing it not to boot, etc, don't worry. There are options. You can follow the advice in the [troubleshooting guide](https://www.didgeridoohan.com/magisk/Magisk#hn_Module_causing_issues_Magisk_functionality_bootloop_loss_of_root_etc) to remove or disable the module, or you can use the module's built-in options to reset all module settings to the defaults. + +Place a file named `reset_mhpc` in /cache (or /data/cache on A/B devices) and reboot. + +It is possible to use this in combination with the configuration file described above to keep device fingerprint or any other settings intact past the reset. Just make sure to remove any custom props that might have been causing issues from the configuration file. + + +## Certifying your device +If you're using a custom ROM, the chances of it being [perceived as uncertified by Google](https://www.xda-developers.com/google-blocks-gapps-uncertified-devices-custom-rom-whitelist/) are pretty high. If your ROM has a build date later than March 16 2018, this might mean that you can't even log into your Google account or use Gapps without [whitelisting your device with Google](https://www.google.com/android/uncertified/) first. + +Magisk, and this module, can help with that. + +Before setting up your device, install Magisk, this module and use the configuration file described above to pass the ctsProfile check. This should make your device be perceived as certified by Google and you can log into your Google account and use your device without having to whitelist it. Check [here](https://github.com/Magisk-Modules-Repo/MagiskHide-Props-Config/blob/master/common/prints.sh) for usable fingerprints (only use the part to the right of the equal sign). + +If you're having issues getting your device certified, take a look in the troubleshooting guide linked below. ## Miscellaneous MagiskHide issues -If you're having issues passing SafetyNet or otherwise getting MagiskHide to work, take a look in the [Magisk and MagiskHide Installation and Troubleshooting Guide](https://www.didgeridoohan.com/magisk). Lots of good info there (if I may say so myself)... +If you're having issues passing SafetyNet, getting your device certified, or otherwise getting MagiskHide to work, take a look in the [Magisk and MagiskHide Installation and Troubleshooting Guide](https://www.didgeridoohan.com/magisk). Lots of good info there (if I may say so myself)... + +But first: have you tried turning it off and on again? Toggling MagiskHide off and on usually works if MagiskHide has stopped working after an update of Magisk or your ROM. ## Support, etc -If you have questions, suggestions or are experiensing some kind of issue, visit the [module support thread](https://forum.xda-developers.com/apps/magisk/module-magiskhide-props-config-simple-t3765199) @XDA. +If you have questions, suggestions or are experiencing some kind of issue, visit the [module support thread](https://forum.xda-developers.com/apps/magisk/module-magiskhide-props-config-simple-t3765199) @ XDA. ### Logs, etc In case of issues, please provide the logs, saved in /cache, "propsconf.log" and "propsconf_last.log", together with a detailed description of your problem. Providing the output from terminal might also be useful. @@ -86,10 +116,20 @@ In case of issues, please provide the logs, saved in /cache, "propsconf.log" and ## Credits @topjohnwu @ XDA Developers, for Magisk -@Zackptg5 and @veez21 @ XDA Developers, for inspiration +@Zackptg5, @veez21 and @jenslody @ XDA Developers, for inspiration ## Changelog +### v2.0.0 +- Added a function for setting your own custom prop values. +- Added a function for setting values by configuration file. Useful if you want to make a ROM pass the ctsProfile check out of the box. +- Added a function for resetting the module by placing a specific file in /cache. Useful if a custom prop is causing issues. +- Added a function to set options for the props script. See the documentation for details. +- Added command option to not check online for new fingerprints list at start. Run `props` with the -h option for details. +- Restructured the fingerprints list menu. Sorted by manufacturer for easier access. +- New and updated fingerprints (lots), list v6. +- Minor fixes and improvements. + ### v1.2.1 - Fixed logic for checking the original prop values. - New fingerprints (Xiaomi Mi 5, ZTE Axon 7), list v4. @@ -110,20 +150,40 @@ In case of issues, please provide the logs, saved in /cache, "propsconf.log" and ## Current fingerprints list -### List v5   +### List v6   - Google Nexus 6 (7.1.1) +- Google Pixel (8.1.0) - Google Pixel 2 (P DP1) - Google Pixel 2 XL (8.1.0) +- HTC 10 (6.0.1) +- Huawei Mate 10 Pro (8.0.0) +- Motorola Moto G4 (7.0) +- Motorola Moto G5 (7.0) +- Motorola Moto G5 Plus (7.0) +- Nvidia Shield K1 (7.0) - OnePlus 3T (8.0.0) - OnePlus 5T (7.1.1) +- OnePlus 5T (8.0.0) - Samsung Galaxy Grand Prime (5.0.2) +- Samsung Galaxy Note 3 (7.1.1) - Samsung Galaxy Note 4 (6.0.1) +- Samsung Galaxy Note 5 (7.0) +- Samsung Galaxy S6 (5.0.2) - Samsung Galaxy S7 (7.0) +- Samsung Galaxy S7 Edge (7.0) +- Samsung Galaxy S8 Plus (7.0) - Samsung Galaxy S8 Plus (8.0.0) +- Sony Xperia X Performance (8.0.0) +- Sony Xperia XZ (8.0.0) - Sony Xperia XZ1 Compact (8.0.0) - Sony Xperia Z3 (6.0.1) +- Vodafone Smart Ultra 6 (5.1.1) - Xiaomi Mi 5 (7.0) - Xiaomi Mi 5S (7.0) - Xiaomi Mi 5S Plus (6.0.1) - Xiaomi Mi6 (7.1.1) +- Xiaomi Redmi 4X (6.0.1) +- Xiaomi Redmi Note 3 Pro (6.0.1) +- Xiaomi Redmi Note 4/4X (7.0) - ZTE Axon 7 (7.1.1) +- Zuk Z2 Pro (7.0) diff --git a/common/post-fs-data.sh b/common/post-fs-data.sh index bcdc3d5..f1d31e8 100644 --- a/common/post-fs-data.sh +++ b/common/post-fs-data.sh @@ -1,24 +1,19 @@ #!/system/bin/sh -# Please don't hardcode /magisk/modname/... ; instead, please use $MODDIR/... +# Please don't hardcode /magisk/modname/... ; instead, please use $MODPATH/... # This will make your scripts compatible even if Magisk change its mount point in the future -MODDIR=${0%/*} +MODPATH=${0%/*} # This script will be executed in post-fs-data mode # More info in the main Magisk thread # MagiskHide Props Config -# By Didgeridoohan @ XDA-Developers +# By Didgeridoohan @ XDA Developers # Variables -IMGPATH=$(dirname "$MODDIR") -LASTLOGFILE=/cache/propsconf_last.log -BIN=BIN_PLACEHOLDER -USNFLIST=USNF_PLACEHOLDER +IMGPATH=$(dirname "$MODPATH") # Load functions -. $MODDIR/util_functions.sh - -MODVERSION=$(echo $(get_file_value $MODDIR/module.prop "version=") | sed 's/-.*//') +. $MODPATH/util_functions.sh # Saves the previous log (if available) and creates a new one if [ -f "$LOGFILE" ]; then @@ -31,19 +26,17 @@ echo "**************** By Didgeridoohan ***************" >> $LOGFILE echo "***************************************************" >> $LOGFILE log_handler "Log start." -# Check for boot scripts, restore backup if deleted -if [ ! -f "$LATEFILE" ]; then - cp -af $MODDIR/propsconf_late $LATEFILE +# Check for boot scripts and restore backup if deleted, or if the resetfile is present +if [ ! -f "$LATEFILE" ] || [ -f "$RESETFILE" ]; then + cp -af $MODPATH/propsconf_late $LATEFILE chmod 755 $LATEFILE - log_handler "Boot script restored." + log_handler "Boot script restored/reset (${LATEFILE})." fi -# Update placeholders in util_functions.sh +# Update placeholders # Image path placeholder_update $LATEFILE IMGPATH IMG_PLACEHOLDER $IMGPATH -placeholder_update $MODDIR/system/$BIN/props IMGPATH IMG_PLACEHOLDER $IMGPATH -# Module version -placeholder_update $MODDIR/system/$BIN/props MODVERSION VER_PLACEHOLDER $MODVERSION +placeholder_update $MODPATH/system/$BIN/props IMGPATH IMG_PLACEHOLDER $IMGPATH # Check the reboot variable if [ "$(get_file_value $LATEFILE "REBOOTCHK=")" == 1 ]; then @@ -51,51 +44,30 @@ if [ "$(get_file_value $LATEFILE "REBOOTCHK=")" == 1 ]; then fi # Get the current values saved in propsconf_late -LATEDEBUGGABLE=$(get_file_value $LATEFILE "ORIGDEBUGGABLE=") -LATEFILEDEBUGGABLE=$(get_file_value $LATEFILE "FILEDEBUGGABLE=") -LATESECURE=$(get_file_value $LATEFILE "ORIGSECURE=") -LATEFILESECURE=$(get_file_value $LATEFILE "FILESECURE=") -LATETYPE=$(get_file_value $LATEFILE "ORIGTYPE=") -LATEFILETYPE=$(get_file_value $LATEFILE "FILETYPE=") -LATETAGS=$(get_file_value $LATEFILE "ORIGTAGS=") -LATEFILETAGS=$(get_file_value $LATEFILE "FILETAGS=") -LATESELINUX=$(get_file_value $LATEFILE "ORIGSELINUX=") -LATEFILESELINUX=$(get_file_value $LATEFILE "FILESELINUX=") -LATEFINGERPRINT=$(get_file_value $LATEFILE "ORIGFINGERPRINT=") +orig_values +latefile_values # Get default file values -FILEDEBUGGABLE=$(get_file_value /default.prop ro.debuggable) -FILESECURE=$(get_file_value /default.prop ro.secure) -FILETYPE=$(get_file_value /system/build.prop ro.build.type) -FILETAGS=$(get_file_value /system/build.prop ro.build.tags) -FILESELINUX=$(get_file_value /system/build.prop ro.build.selinux) +file_values # Save default file values in propsconf_late -sed -i "s/FILEDEBUGGABLE=$LATEFILEDEBUGGABLE/FILEDEBUGGABLE=$FILEDEBUGGABLE/" $LATEFILE -sed -i "s/FILESECURE=$LATEFILESECURE/FILESECURE=$FILESECURE/" $LATEFILE -sed -i "s/FILETYPE=$LATEFILETYPE/FILETYPE=$FILETYPE/" $LATEFILE -sed -i "s/FILETAGS=$LATEFILETAGS/FILETAGS=$FILETAGS/" $LATEFILE -sed -i "s/FILESELINUX=$LATEFILESELINUX/FILESELINUX=$FILESELINUX/" $LATEFILE +sed -i "s/FILEDEBUGGABLE=\"$LATEFILEDEBUGGABLE\"/FILEDEBUGGABLE=\"$FILEDEBUGGABLE\"/" $LATEFILE +sed -i "s/FILESECURE=\"$LATEFILESECURE\"/FILESECURE=\"$FILESECURE\"/" $LATEFILE +sed -i "s/FILETYPE=\"$LATEFILETYPE\"/FILETYPE=\"$FILETYPE\"/" $LATEFILE +sed -i "s/FILETAGS=\"$LATEFILETAGS\"/FILETAGS=\"$FILETAGS\"/" $LATEFILE +sed -i "s/FILESELINUX=\"$LATEFILESELINUX\"/FILESELINUX=\"$FILESELINUX\"/" $LATEFILE log_handler "Default file values saved to $LATEFILE." # Get the default prop values -ORIGDEBUGGABLE=$(resetprop ro.debuggable) -ORIGSECURE=$(resetprop ro.secure) -ORIGTYPE=$(resetprop ro.build.type) -ORIGTAGS=$(resetprop ro.build.tags) -ORIGSELINUX=$(resetprop ro.build.selinux) -ORIGFINGERPRINT=$(resetprop ro.build.fingerprint) -if [ ! "$ORIGFINGERPRINT" ]; then - ORIGFINGERPRINT=$(resetprop ro.bootimage.build.fingerprint) -fi +curr_values -# Save defatul prop values in propsconf_late -sed -i "s/ORIGDEBUGGABLE=$LATEDEBUGGABLE/ORIGDEBUGGABLE=$ORIGDEBUGGABLE/" $LATEFILE -sed -i "s/ORIGSECURE=$LATESECURE/ORIGSECURE=$ORIGSECURE/" $LATEFILE -sed -i "s/ORIGTYPE=$LATETYPE/ORIGTYPE=$ORIGTYPE/" $LATEFILE -sed -i "s/ORIGTAGS=$LATETAGS/ORIGTAGS=$ORIGTAGS/" $LATEFILE -sed -i "s/ORIGSELINUX=$LATESELINUX/ORIGSELINUX=$ORIGSELINUX/" $LATEFILE -sed -i "s@ORIGFINGERPRINT=$LATEFINGERPRINT@ORIGFINGERPRINT=$ORIGFINGERPRINT@" $LATEFILE +# Save default prop values in propsconf_late +sed -i "s/ORIGDEBUGGABLE=\"$ORIGDEBUGGABLE\"/ORIGDEBUGGABLE=\"$CURRDEBUGGABLE\"/" $LATEFILE +sed -i "s/ORIGSECURE=\"$ORIGSECURE\"/ORIGSECURE=\"$CURRSECURE\"/" $LATEFILE +sed -i "s/ORIGTYPE=\"$ORIGTYPE\"/ORIGTYPE=\"$CURRTYPE\"/" $LATEFILE +sed -i "s/ORIGTAGS=\"$ORIGTAGS\"/ORIGTAGS=\"$CURRTAGS\"/" $LATEFILE +sed -i "s/ORIGSELINUX=\"$ORIGSELINUX\"/ORIGSELINUX=\"$CURRSELINUX\"/" $LATEFILE +sed -i "s@ORIGFINGERPRINT=\"$ORIGFINGERPRINT\"@ORIGFINGERPRINT=\"$CURRFINGERPRINT\"@" $LATEFILE log_handler "Current prop values saved to $LATEFILE." # Checks for the Universal SafetyNet Fix module and similar modules editing the device fingerprint @@ -112,7 +84,7 @@ if [ "$PRINTMODULE" == "true" ]; then log_handler "Fingerprint modification disabled." else sed -i 's/FINGERPRINTENB=0/FINGERPRINTENB=1/' $LATEFILE - if [ "$(get_file_value $LATEFILE "FINGERPRINTENB=")" == 1 ]; then + if [ "$(get_file_value $LATEFILE "FINGERPRINTENB=")" == 1 ]; then log_handler "Fingerprint modification enabled." else log_handler "Fingerprint modification disabled." @@ -120,25 +92,16 @@ else fi # Check if original file values are safe -sed -i 's/FILESAFE=0/FILESAFE=1/' $LATEFILE -for V in $PROPSLIST; do - PROP=$(get_prop_type $V) - FILEPROP=$(echo "FILE$PROP" | tr '[:lower:]' '[:upper:]') - FILEVALUE=$(eval "echo \$$FILEPROP") - log_handler "Checking $FILEPROP=$FILEVALUE" - safe_props $V $FILEVALUE - if [ "$SAFE" == 0 ]; then - log_handler "Prop $V set to triggering value in prop file." - sed -i 's/FILESAFE=1/FILESAFE=0/' $LATEFILE - else - log_handler "Prop $V set to \"safe\" value in prop file." - fi -done +orig_safe +# Checks for configuration file +config_file + +# Edits build.prop if [ "$(get_file_value $LATEFILE "FILESAFE=")" == 0 ]; then # Checks if any other modules are using a local copy of build.prop BUILDMODULE=false - MODID=$(get_file_value $MODDIR/module.prop "id=") + MODID=$(get_file_value $MODPATH/module.prop "id=") for D in $(ls $IMGPATH); do if [ $D != "$MODID" ]; then if [ -f "$IMGPATH/$D/system/build.prop" ]; then @@ -157,7 +120,7 @@ if [ "$(get_file_value $LATEFILE "FILESAFE=")" == 0 ]; then # Copies the stock build.prop to the module. Only if set in propsconf_late. if [ "$(get_file_value $LATEFILE "BUILDPROPENB=")" == 1 ] && [ "$(get_file_value $LATEFILE "BUILDEDIT=")" == 1 ]; then log_handler "Build.prop editing enabled." - cp /system/build.prop $MODDIR/system/build.prop + cp /system/build.prop $MODPATH/system/build.prop log_handler "Stock build.prop copied from /system." # Edits the module copy of build.prop @@ -171,7 +134,7 @@ if [ "$(get_file_value $LATEFILE "FILESAFE=")" == 0 ]; then SEDTYPE=user fi if [ "$(get_file_value $LATEFILE "SETTYPE=")" == "true" ]; then - sed -i "s/ro.build.type=$FILETYPE/ro.build.type=$SEDTYPE/" $MODDIR/system/build.prop && log_handler "ro.build.type" + sed -i "s/ro.build.type=$FILETYPE/ro.build.type=$SEDTYPE/" $MODPATH/system/build.prop && log_handler "ro.build.type" fi if [ "$MODULETAGS" ]; then SEDTAGS=$MODULETAGS @@ -179,7 +142,7 @@ if [ "$(get_file_value $LATEFILE "FILESAFE=")" == 0 ]; then SEDTAGS=release-keys fi if [ "$(get_file_value $LATEFILE "SETTAGS=")" == "true" ]; then - sed -i "s/ro.build.tags=$FILETAGS/ro.build.tags=$SEDTAGS/" $MODDIR/system/build.prop && log_handler "ro.build.tags" + sed -i "s/ro.build.tags=$FILETAGS/ro.build.tags=$SEDTAGS/" $MODPATH/system/build.prop && log_handler "ro.build.tags" fi if [ "$MODULESELINUX" ]; then SEDSELINUX=$MODULESELINUX @@ -187,14 +150,14 @@ if [ "$(get_file_value $LATEFILE "FILESAFE=")" == 0 ]; then SEDSELINUX=0 fi if [ "$(get_file_value $LATEFILE "SETSELINUX=")" == "true" ]; then - sed -i "s/ro.build.selinux=$FILESELINUX/ro.build.selinux=$SEDSELINUX/" $MODDIR/system/build.prop && log_handler "ro.build.selinux" + sed -i "s/ro.build.selinux=$FILESELINUX/ro.build.selinux=$SEDSELINUX/" $MODPATH/system/build.prop && log_handler "ro.build.selinux" fi else - rm -f $MODDIR/system/build.prop + rm -f $MODPATH/system/build.prop log_handler "Build.prop editing disabled." fi else - rm -f $MODDIR/system/build.prop + rm -f $MODPATH/system/build.prop log_handler "Prop file editing disabled. All values ok." fi diff --git a/common/prints.sh b/common/prints.sh index cfc87d8..da8ce1e 100644 --- a/common/prints.sh +++ b/common/prints.sh @@ -1,9 +1,9 @@ #!/system/bin/sh # MagiskHide Props Config -# By Didgeridoohan @ XDA-Developers +# By Didgeridoohan @ XDA Developers -PRINTSV=5 +PRINTSV=6 PRINTSTRANSF=1 PRINTSFILE=/sdcard/printslist @@ -11,21 +11,42 @@ PRINTSFILE=/sdcard/printslist # Certified fingerprints PRINTSLIST=" Google Nexus 6 (7.1.1)=google/shamu/shamu:7.1.1/N8I11B/4171878:user/release-keys +Google Pixel (8.1.0)=google/sailfish/sailfish:8.1.0/OPM2.171019.029/4657601:user/release-keys Google Pixel 2 (P DP1)=google/walleye/walleye:P/PPP1.180208.014/4633861:user/release-keys Google Pixel 2 XL (8.1.0)=google/taimen/taimen:8.1.0/OPM1.171019.013/4474084:user/release-keys +HTC 10 (6.0.1)=htc/HTCOneM10vzw/htc_pmewl:6.0.1/MMB29M/774095.8:user/release-keys +Huawei Mate 10 Pro (8.0.0)=HUAWEI/BLA-L29/HWBLA:8.0.0/HUAWEIBLA-L29S/137(C432):user/release-keys +Motorola Moto G4 (7.0)=motorola/athene/athene:7.0/NPJS25.93-14-13/3:user/release-keys +Motorola Moto G5 (7.0)=motorola/cedric/cedric:7.0/NPPS25.137-15-11/11:user/release-keys +Motorola Moto G5 Plus (7.0)=motorola/potter_n/potter_n:7.0/NPNS25.137-33-11/11:user/release-keys +Nvidia Shield K1 (7.0)=nvidia/sb_na_wf/shieldtablet:7.0/NRD90M/1928188_1065.2559:user/release-keys OnePlus 3T (8.0.0)=OnePlus/OnePlus3/OnePlus3T:8.0.0/OPR6.170623.013/12041042:user/release-keys OnePlus 5T (7.1.1)=OnePlus/OnePlus5T/OnePlus5T:7.1.1/NMF26X/12152312:user/release-keys +OnePlus 5T (8.0.0)=OnePlus/OnePlus5T/OnePlus5T:8.0.0/OPR1.170623.032/02040656:user/release-keys Samsung Galaxy Grand Prime (5.0.2)=samsung/fortuna3gdtvvj/fortuna3gdtv:5.0.2/LRX22G/G530BTVJU1BPH4:user/release-keys +Samsung Galaxy Note 3 (7.1.1)=samsung/greatltexx/greatlte:7.1.1/NMF26X/N950FXXU1AQHA:user/release-keys Samsung Galaxy Note 4 (6.0.1)=samsung/trltexx/trlte:6.0.1/MMB29M/N910FXXS1DQH9:user/release-keys +Samsung Galaxy Note 5 (7.0)=samsung/nobleltejv/noblelte:7.0/NRD90M/N920CXXU3CQH6:user/release-keys +Samsung Galaxy S6 (5.0.2)=samsung/zerofltexx/zeroflte:5.0.2/LRX22G/G920FXXU1AOD4:user/release-keys Samsung Galaxy S7 (7.0)=samsung/heroltexx/herolte:7.0/NRD90M/G930FXXU2DRB6:user/release-keys +Samsung Galaxy S7 Edge (7.0)=samsung/hero2ltexx/hero2lte:7.0/NRD90M/G935FXXU2DRB6:user/release-keys +Samsung Galaxy S8 Plus (7.0)=samsung/dream2ltexx/dream2lte:7.0/NRD90M/G955FXXU1AQGB:user/release-keys Samsung Galaxy S8 Plus (8.0.0)=samsung/dream2ltexx/dream2lte:8.0.0/R16NW/G955FXXU1CRC7:user/release-keys +Sony Xperia X Performance (8.0.0)=Sony/F8131/F8131:8.0.0/41.3.A.2.99/1455830589:user/release-keys +Sony Xperia XZ (8.0.0)=Sony/F8331/F8331:8.0.0/41.3.A.2.99/1455830589:user/release-keys Sony Xperia XZ1 Compact (8.0.0)=Sony/G8441/G8441:8.0.0/47.1.A.12.119/1601781803:user/release-keys Sony Xperia Z3 (6.0.1)=Sony/D6633/D6633:6.0.1/23.5.A.1.291/2769308465:user/release-keys +Vodafone Smart Ultra 6 (5.1.1)=Vodafone/P839V55/P839V55:5.1.1/LMY47V/20161227.134319.15534:user/release-keys Xiaomi Mi 5 (7.0)=Xiaomi/gemini/gemini:7.0/NRD90M/V9.2.1.0.NAAMIEK:user/release-keys Xiaomi Mi 5S (7.0)=Xiaomi/capricorn/capricorn:7.0/NRD90M/V9.2.1.0.NAGMIEK:user/release-keys Xiaomi Mi 5S Plus (6.0.1)=Xiaomi/natrium/natrium:6.0.1/MXB48T/V8.5.2.0.MBGMIED:user/release-keys Xiaomi Mi 6 (7.1.1)=Xiaomi/sagit/sagit:7.1.1/NMF26X/V8.2.17.0.NCACNEC:user/release-keys +Xiaomi Mi 6 (8.0.0)=Xiaomi/sagit/sagit:8.0.0/OPR1.170623.027/V9.2.3.0.OCAMIEK:user/release-keys +Xiaomi Redmi 4X (6.0.1)==Xiaomi/santoni/santoni:6.0.1/MMB29M/V8.5.4.0.MAMCNED:user/release-keys. +Xiaomi Redmi Note 3 Pro (6.0.1)=Xiaomi/kenzo/kenzo:6.0.1/MMB29M/V8.2.1.0.MHOCNDL:user/release-keys +Xiaomi Redmi Note 4/4X (7.0)=xiaomi/mido/mido:7.0/NRD90M/V9.2.1.0.NCFMIEK:user/release-keys ZTE Axon 7 (7.1.1)=ZTE/P996A01_N/ailsa_ii:7.1.1/NMF26V/20171211.005949:user/release-keys +Zuk Z2 Pro (7.0)=ZUK/z2_row/z2_row:7.0/NRD90M/2.5.435_170525:user/release-keys " if [ -f "$PRINTSFILE" ]; then diff --git a/common/propsconf_conf b/common/propsconf_conf new file mode 100644 index 0000000..4a176a9 --- /dev/null +++ b/common/propsconf_conf @@ -0,0 +1,70 @@ +#!/system/bin/sh + +# MagiskHide Props Config +# By Didgeridoohan @ XDA Developers + +CONFFINGERPRINT="" + +CONFPROPFILES=false + +CONFDEBUGGABLE="" +CONFSECURE="" +CONFTYPE="" +CONFTAGS="" +CONFSELINUX="" + +CONFPROPS="" +PROPOPTION=replace + +CONFCOLOUR=enabled +CONFWEB=enabled + +# ================================================================= +# ========================== Instructions ========================= +# ================================================================= +# Set the above variables to the desired prop/configuration values. +# +# CONFFINGERPRINT should be set to the fingerprint of a ROM that passes +# the ctsProfile check. See the prints.sh file for usable prints, +# or the documentation for information on how to find one. +# +# CONFPROPFILES should be set to "true" if you want to mask the file +# values in build.prop and default.prop. For better root hiding. +# +# The MagiskHide prop variables can be set as follows: +# CONFDEBUGGABLE - 0 or 1 (set to "0" by MagiskHide - sensitive value is "1") +# CONFSECURE - 0 or 1 (set to "1" by MagiskHide - sensitive value is "0") +# CONFTYPE - user or userdebug (set to "user" by MagiskHide - sensitive value is "userdebug") +# CONFTAGS - release-keys or test-keys (set to "release-keys" by MagiskHide - sensitive value is "test-keys") +# CONFSELINUX - 0 or 1 (set to "0" by MagiskHide - sensitive value is "1") +# +# CONFPROPS should contain any custom props and the value you want the module to set. +# Any props you've previously edited in build.prop, and more, can be set like this. +# Add them to the PROPS variable according to the following example: +# CONFPROPS=" +# ro.sf.lcd_density=320 +# ro.config.media_vol_steps=30 +# net.tethering.noprovisioning=true +# " +# With PROPOPTION you can decide if the current custom prop list should +# be replaced, added to or preserved. Add the corresponding words "replace", +# "add", or "preserve". The default option is to replace the list. +# This option supersedes the preserve option described below, but only +# for the CONFPROPS variable. +# +# CONFCOLOUR and CONFWEB are the options for colour and automatic fingerprints +# list update. See the module documentation for more details. +# +# If any variables are left unset, that particular prop/configuration +# will be cleared and the device/MagiskHide default values will be used. +# If you want to keep any current module settings, add "preserve" to the variable. +# Example: +# CONFFINGERPRINT=preserve +# +# When placed in /cache, the module will load these values during boot and the +# configuration file will be deleted. Keep a backup of the file if you want to reuse it. +# +# For more information, see the documentation: +# https://github.com/Magisk-Modules-Repo/MagiskHide-Props-Config/blob/master/README.md +# and the support thread @ XDA Developers: +# https://forum.xda-developers.com/apps/magisk/module-magiskhide-props-config-simple-t3765199 \ No newline at end of file diff --git a/common/propsconf_late b/common/propsconf_late index 3325184..9fad973 100644 --- a/common/propsconf_late +++ b/common/propsconf_late @@ -1,7 +1,7 @@ #!/system/bin/sh # MagiskHide Props Config -# By Didgeridoohan @ XDA-Developers +# By Didgeridoohan @ XDA Developers # This is a script file for the Magisk module "MagiskHide Props Config" By Didgeridoohan @ XDA Developers. # DO NOT DELETE! @@ -9,12 +9,13 @@ # In that case, feel free to delete it. # Script version -SCRIPTV=1 +SCRIPTV=2 SETTRANSF=1 # Variables IMGPATH=IMG_PLACEHOLDER MODPATH=$IMGPATH/MagiskHidePropsConf + FINGERPRINTENB=1 PRINTEDIT=0 BUILDPROPENB=1 @@ -23,54 +24,84 @@ BUILDEDIT=0 DEFAULTEDIT=0 PROPCOUNT=0 PROPEDIT=0 +CUSTOMEDIT=0 REBOOTCHK=0 +OPTIONCOLOUR=1 +OPTIONWEB=1 + +# Function to clean up different files after the module has been uninstalled +cleanup() { + CACHELOC=CACHE_PLACEHOLDER + rm -f $CACHELOC/propsconf.log + rm -f $CACHELOC/propsconf_last.log + rm -f $CACHELOC/propsconf_conf + rm -f $CACHELOC/reset_mhpc + # Suicide. + rm $0 +} # Checks if the module is installed. Deletes itself if it isn't. -if [ -d "$MODPATH" ]; then +if [ -d "$MODPATH" ]; then # Checks if the module is set for removal - if [ -f "$MODPATH/remove" ]; then - # Suicide. - rm $0 + if [ -f "$MODPATH/remove" ]; then + # Cleanup + cleanup else # Load functions . $MODPATH/util_functions.sh log_handler "Running boot script." - if ! [ -f "$MODPATH/disable" ]; then + if [ -f "$MODPATH/disable" ]; then + log_handler "Module disabled." + else # ---Original values--- # default.prop - FILEDEBUGGABLE= - FILESECURE= + FILEDEBUGGABLE="" + FILESECURE="" # build.prop - FILETYPE= - FILETAGS= - FILESELINUX= + FILETYPE="" + FILETAGS="" + FILESELINUX="" # Prop values - ORIGDEBUGGABLE= - ORIGSECURE= - ORIGTYPE= - ORIGTAGS= - ORIGSELINUX= - ORIGFINGERPRINT= + ORIGDEBUGGABLE="" + ORIGSECURE="" + ORIGTYPE="" + ORIGTAGS="" + ORIGSELINUX="" + ORIGFINGERPRINT="" # ---Module values--- - MODULEDEBUGGABLE= - MODULESECURE= - MODULETYPE= - MODULETAGS= - MODULESELINUX= - MODULEFINGERPRINT= + MODULEDEBUGGABLE="" + MODULESECURE="" + MODULETYPE="" + MODULETAGS="" + MODULESELINUX="" + MODULEFINGERPRINT="" + + # ---Custom prop values--- + CUSTOMPROPS="" + + # ---MagiskHide sensitive props--- + REDEBUGGABLE=false + RESECURE=false + RETYPE=false + RETAGS=false + RESELINUX=false + + # ---Editing default.prop--- + SETDEBUGGABLE=false + SETSECURE=false + + # ---Editing build.prop--- + SETTYPE=false + SETTAGS=false + SETSELINUX=false # ---Setting/Changing props--- # Set/change MagiskHide sensitive props if [ "$PROPEDIT" == 1 ]; then log_handler "Changing sensitive props." - REDEBUGGABLE=false - RESECURE=false - RETYPE=false - RETAGS=false - RESELINUX=false if [ "$REDEBUGGABLE" == "true" ]; then resetprop -v ro.debuggable $MODULEDEBUGGABLE 2>> $LOGFILE fi @@ -87,37 +118,39 @@ if [ -d "$MODPATH" ]; then resetprop -v ro.build.selinux $MODULESELINUX 2>> $LOGFILE fi fi - # Set new fingerprint if [ "$FINGERPRINTENB" == 1 ] && [ "$PRINTEDIT" == 1 ]; then - REFINGERPRINT=false - if [ "$REFINGERPRINT" == "true" ]; then - log_handler "Changing fingerprint." - resetprop -v ro.build.fingerprint $MODULEFINGERPRINT 2>> $LOGFILE - resetprop -v ro.bootimage.build.fingerprint $MODULEFINGERPRINT 2>> $LOGFILE - fi + log_handler "Changing fingerprint." + resetprop -v ro.build.fingerprint $MODULEFINGERPRINT 2>> $LOGFILE + resetprop -v ro.bootimage.build.fingerprint $MODULEFINGERPRINT 2>> $LOGFILE fi - # Settings for default.prop editing - SETDEBUGGABLE=false - SETSECURE=false - # Edits default.prop + # ---Setting custom props--- + if [ "$CUSTOMEDIT" == 1 ]; then + log_handler "Writing custom props." + for ITEM in $CUSTOMPROPS; do + log_handler "Writing $(get_eq_left $ITEM)." + resetprop -v $(get_eq_left $ITEM) $(get_eq_right $ITEM) 2>> $LOGFILE + done + fi + + # ---Edits default.prop--- if [ "$DEFAULTEDIT" == 1 ] && [ "$FILESAFE" == 0 ]; then log_handler "Default.prop editing enabled." log_handler "Editing default.prop." mount -wo remount rootfs / if [ "$MODULEDEBUGGABLE" ]; then - SEDDEBUGGABLE=$MODULEDEBUGGABLE + SEDDEBUGGABLE="$MODULEDEBUGGABLE" else - SEDDEBUGGABLE=0 + SEDDEBUGGABLE="0" fi if [ "$SETDEBUGGABLE" == "true" ]; then sed -i "s/ro.debuggable=$FILEDEBUGGABLE/ro.debuggable=$SEDDEBUGGABLE/" /default.prop && log_handler "ro.debuggable" fi if [ "$MODULESECURE" ]; then - SEDSECURE=$MODULESECURE + SEDSECURE="$MODULESECURE" else - SEDSECURE=1 + SEDSECURE="1" fi if [ "$SETSECURE" == "true" ]; then sed -i "s/ro.secure=$FILESECURE/ro.secure=$SEDSECURE/" /default.prop && log_handler "ro.secure" @@ -126,15 +159,10 @@ if [ -d "$MODPATH" ]; then else log_handler "Default.prop editing disabled." fi - - # Settings for build.prop editing - SETTYPE=false - SETTAGS=false - SETSELINUX=false fi log_handler "Boot script finished.\n\n==================" fi else - # Suicide. - rm $0 + # Cleanup + cleanup fi diff --git a/common/util_functions.sh b/common/util_functions.sh index 426692e..cc367ac 100644 --- a/common/util_functions.sh +++ b/common/util_functions.sh @@ -1,20 +1,30 @@ #!/system/bin/sh # MagiskHide Props Config -# By Didgeridoohan @ XDA-Developers +# By Didgeridoohan @ XDA Developers # Variables +MODVERSION=VER_PLACEHOLDER +POSTFILE=$IMGPATH/.core/post-fs-data.d/propsconf_post LATEFILE=$IMGPATH/.core/service.d/propsconf_late -LOGFILE=/cache/propsconf.log +CACHELOC=CACHE_PLACEHOLDER +LOGFILE=$CACHELOC/propsconf.log +LASTLOGFILE=$CACHELOC/propsconf_last.log +CONFFILE=$CACHELOC/propsconf_conf +RESETFILE=$CACHELOC/reset_mhpc MAGISKLOC=/data/adb/magisk BBPATH=$MAGISKLOC/busybox PRINTSLOC=$MODPATH/prints.sh -PRINTSTMP=/cache/prints.sh +PRINTSTMP=$CACHELOC/prints.sh PRINTSWWW="https://raw.githubusercontent.com/Magisk-Modules-Repo/MagiskHide-Props-Config/master/common/prints.sh" +BIN=BIN_PLACEHOLDER +USNFLIST=USNF_PLACEHOLDER alias cat="$BBPATH cat" alias grep="$BBPATH grep" +alias printf="$BBPATH printf" alias resetprop="$MAGISKLOC/magisk resetprop" alias sed="$BBPATH sed" +alias sort="$BBPATH sort" alias tr="$BBPATH tr" alias wget="$BBPATH wget" @@ -46,7 +56,6 @@ log_print() { log_handler "$1" } - #Divider DIVIDER="${Y}=====================================${N}" @@ -68,7 +77,7 @@ menu_header() { # Finding file values get_file_value() { - cat $1 | grep $2 | sed 's/.*=//' + cat $1 | grep $2 | sed "s/.*$2//" | sed 's/\"//g' } # Find prop type @@ -76,29 +85,19 @@ get_prop_type() { echo $1 | sed 's/.*\.//' } -# Separate prop from value -safe_prop_name() { +# Get left side of = +get_eq_left() { echo $1 | sed 's/=.*//' } -safe_prop_value() { + +# Get right side of = +get_eq_right() { echo $1 | sed 's/.*=//' } -# Check safe values -safe_props() { - SAFE="" - if [ "$2" ]; then - for P in $SAFELIST; do - if [ "$(safe_prop_name $P)" == "$1" ]; then - if [ "$2" == "$(safe_prop_value $P)" ]; then - SAFE=1 - else - SAFE=0 - fi - break - fi - done - fi +# Get first word in string +get_first() { + echo $1 | sed 's/\ .*//' } # Updates placeholders @@ -106,12 +105,239 @@ placeholder_update() { FILEVALUE=$(get_file_value $1 "$2=") log_handler "Checking for '$3' in '$1'. Current value is '$FILEVALUE'." case $FILEVALUE in - *PLACEHOLDER*) sed -i "s@$2\=$3@$2\=$4@g" $1 + *PLACEHOLDER*) sed -i "s@${2}=${3}@${2}=${4}@g" $1 log_handler "Placeholder '$3' updated to '$4' in '$1'." ;; esac } +orig_check() { + PROPSTMPLIST=$PROPSLIST" + ro.build.fingerprint + " + ORIGLOAD=0 + for PROPTYPE in $PROPSTMPLIST; do + PROP=$(get_prop_type $PROPTYPE) + ORIGPROP=$(echo "ORIG${PROP}" | tr '[:lower:]' '[:upper:]') + ORIGVALUE=$(get_file_value $LATEFILE "${ORIGPROP}=") + if [ "$ORIGVALUE" ]; then + ORIGLOAD=1 + fi + done +} + +# Currently set values +curr_values() { + CURRDEBUGGABLE=$(resetprop ro.debuggable) + CURRSECURE=$(resetprop ro.secure) + CURRTYPE=$(resetprop ro.build.type) + CURRTAGS=$(resetprop ro.build.tags) + CURRSELINUX=$(resetprop ro.build.selinux) + CURRFINGERPRINT=$(resetprop ro.build.fingerprint) + if [ -z "$CURRFINGERPRINT" ]; then + CURRFINGERPRINT=$(resetprop ro.bootimage.build.fingerprint) + fi +} + +# Prop file values +file_values() { + FILEDEBUGGABLE=$(get_file_value /default.prop "ro.debuggable=") + FILESECURE=$(get_file_value /default.prop "ro.secure=") + FILETYPE=$(get_file_value /system/build.prop "ro.build.type=") + FILETAGS=$(get_file_value /system/build.prop "ro.build.tags=") + FILESELINUX=$(get_file_value /system/build.prop "ro.build.selinux=") +} + +# Latefile values +latefile_values() { + LATEFILEDEBUGGABLE=$(get_file_value $LATEFILE "FILEDEBUGGABLE=") + LATEFILESECURE=$(get_file_value $LATEFILE "FILESECURE=") + LATEFILETYPE=$(get_file_value $LATEFILE "FILETYPE=") + LATEFILETAGS=$(get_file_value $LATEFILE "FILETAGS=") + LATEFILESELINUX=$(get_file_value $LATEFILE "FILESELINUX=") +} + +# Original prop values +orig_values() { + ORIGDEBUGGABLE=$(get_file_value $LATEFILE "ORIGDEBUGGABLE=") + ORIGSECURE=$(get_file_value $LATEFILE "ORIGSECURE=") + ORIGTYPE=$(get_file_value $LATEFILE "ORIGTYPE=") + ORIGTAGS=$(get_file_value $LATEFILE "ORIGTAGS=") + ORIGSELINUX=$(get_file_value $LATEFILE "ORIGSELINUX=") + ORIGFINGERPRINT=$(get_file_value $LATEFILE "ORIGFINGERPRINT=") +} + +# Module values +module_values() { + MODULEDEBUGGABLE=$(get_file_value $LATEFILE "MODULEDEBUGGABLE=") + MODULESECURE=$(get_file_value $LATEFILE "MODULESECURE=") + MODULETYPE=$(get_file_value $LATEFILE "MODULETYPE=") + MODULETAGS=$(get_file_value $LATEFILE "MODULETAGS=") + MODULESELINUX=$(get_file_value $LATEFILE "MODULESELINUX=") + MODULEFINGERPRINT=$(get_file_value $LATEFILE "MODULEFINGERPRINT=") + CUSTOMPROPS=$(get_file_value $LATEFILE "CUSTOMPROPS=") +} + +# Run all value functions +all_values() { + # Currently set values + curr_values + # Prop file values + file_values + # Latefile values + latefile_values + # Original prop values + orig_values + # Module values + module_values +} + +after_change() { + # Update the reboot variable + reboot_chk + # Load all values + all_values + # Ask to reboot + reboot_fn "$1" +} + +after_change_file() { + # Update the reboot variable + reboot_chk + # Load all values + INPUT="" + all_values + # Ask to reboot + reboot_fn "$1" "$2" +} + +reboot_chk() { + sed -i 's/REBOOTCHK=0/REBOOTCHK=1/' $LATEFILE +} + +reset_fn() { + BUILDPROPENB=$(get_file_value $LATEFILE "BUILDPROPENB=") + FINGERPRINTENB=$(get_file_value $LATEFILE "FINGERPRINTENB=") + cp -af $MODPATH/propsconf_late $LATEFILE + if [ "$BUILDPROPENB" ] && [ -z "$BUILDPROPENB" == 1 ]; then + sed -i "s@BUILDPROPENB=1@BUILDPROPENB=$BUILDPROPENB@g" $LATEFILE + fi + if [ "$FINGERPRINTENB" ] && [ -z "$FINGERPRINTENB" == 1 ]; then + sed -i "s@FINGERPRINTENB=1@FINGERPRINTENB=$FINGERPRINTENB@g" $LATEFILE + fi + chmod 755 $LATEFILE + placeholder_update $LATEFILE IMGPATH IMG_PLACEHOLDER $IMGPATH + + # Update the reboot variable + reboot_chk + + # Update all prop value variables + all_values +} + +# Check if original file values are safe +orig_safe() { + sed -i 's/FILESAFE=0/FILESAFE=1/' $LATEFILE + for V in $PROPSLIST; do + PROP=$(get_prop_type $V) + FILEPROP=$(echo "FILE${PROP}" | tr '[:lower:]' '[:upper:]') + FILEVALUE=$(eval "echo \$$FILEPROP") + log_handler "Checking $FILEPROP=$FILEVALUE" + safe_props $V $FILEVALUE + if [ "$SAFE" == 0 ]; then + log_handler "Prop $V set to triggering value in prop file." + sed -i 's/FILESAFE=1/FILESAFE=0/' $LATEFILE + else + log_handler "Prop $V set to \"safe\" value in prop file." + fi + done +} + +# Checks for configuration file +config_file() { + if [ -f "$CONFFILE" ]; then + log_handler "Configuration file detected." + # Loads custom variables + . $CONFFILE + # Updates prop values (including fingerprint) + PROPSTMPLIST=$PROPSLIST" + ro.build.fingerprint + " + for PROPTYPE in $PROPSTMPLIST; do + CONFPROP=$(echo "CONF$(get_prop_type $PROPTYPE)" | tr '[:lower:]' '[:upper:]') + TMPPROP=$(eval "echo \$$CONFPROP") + if [ "$TMPPROP" ]; then + log_handler "Checking $PROPTYPE settings." + if [ "$TMPPROP" != "preserve" ]; then + if [ "$PROPTYPE" == "ro.build.fingerprint" ]; then + if [ "$(get_file_value $LATEFILE "FINGERPRINTENB=")" == 1 ]; then + change_print "$PROPTYPE" "$TMPPROP" "file" + fi + else + change_prop "$PROPTYPE" "$TMPPROP" "file" + fi + fi + else + if [ "$PROPTYPE" == "ro.build.fingerprint" ]; then + if [ "$(get_file_value $LATEFILE "FINGERPRINTENB=")" == 1 ]; then + reset_print "$PROPTYPE" "file" + fi + else + reset_prop "$PROPTYPE" "file" + fi + fi + done + + # Updates prop file editing + if [ "$(get_file_value $LATEFILE "FILESAFE=")" == 0 ]; then + if [ "$CONFPROPFILES" == "true" ]; then + edit_prop_files "file" "" " (configuration file)" + elif [ "$CONFPROPFILES" == "false" ]; then + reset_prop_files "file" "" " (configuration file)" + fi + fi + + # Updates custom props + if [ "$PROPOPTION" != "preserve" ]; then + if [ "$CONFPROPS" ]; then + if [ "$PROPOPTION" == "add" ] || [ "$PROPOPTION" == "replace" ]; then + if [ "$PROPOPTION" == "replace" ]; then + reset_all_custprop "file" + fi + for ITEM in $CONFPROPS; do + set_custprop "$(get_eq_left $ITEM)" "$(get_eq_right $ITEM)" "file" + done + fi + else + reset_all_custprop "file" + fi + fi + + # Updates options + OPTCCURR=$(get_file_value $LATEFILE "OPTIONCOLOUR=") + OPTWCURR=$(get_file_value $LATEFILE "OPTIONWEB=") + if [ "$CONFCOLOUR" == "enabled" ]; then + + sed -i "s@OPTIONCOLOUR=$OPTCCURR@OPTIONCOLOUR=1@" $LATEFILE + else + sed -i "s@OPTIONCOLOUR=$OPTCCURR@OPTIONCOLOUR=0" $LATEFILE + fi + log_handler "Colour $CONFCOLOUR." + if [ "$CONFWEB" == "enabled" ]; then + sed -i "s@OPTIONWEB=$OPTWCURR@OPTIONWEB=1@" $LATEFILE + else + sed -i "s@OPTIONWEB=$OPTWCURR@OPTIONWEB=0@" $LATEFILE + fi + log_handler "Automatic fingerprints list update $CONFWEB." + + # Deletes the configuration file + log_handler "Deleting configuration file." + rm -f $CONFFILE + fi +} + +# ======================== Fingerprint functions ======================== +# Checks and updates the prints list download_prints() { clear menu_header "Updating fingerprints list" @@ -126,7 +352,7 @@ download_prints() { # Updates list version in module.prop VERSIONTMP=$(get_file_value $MODPATH/module.prop "version=") sed -i "s/version=$VERSIONTMP/version=$MODVERSION-v$LISTVERSION/g" $MODPATH/module.prop - log_print "Updated list to v$LISTVERSION." + log_print "Updated list to v${LISTVERSION}." else rm -f $PRINTSTMP log_print "New fingerprints list requires module update." @@ -138,19 +364,282 @@ download_prints() { else log_print "No connection." fi + if [ "$1" == "manual" ]; then + sleep 2 + fi } -orig_check() { - PROPSTMPLIST=$PROPSLIST" - ro.build.fingerprint - " - ORIGLOAD=0 - for PROPTYPE in $PROPSTMPLIST; do - PROP=$(get_prop_type $PROPTYPE) - ORIGPROP=$(echo "ORIG$PROP" | tr '[:lower:]' '[:upper:]') - ORIGVALUE=$(get_file_value $LATEFILE "$ORIGPROP=") - if [ "$ORIGVALUE" ]; then - ORIGLOAD=1 - fi - done +# Reset the module fingerprint change +reset_print() { + log_handler "Resetting device fingerprint." + + SUBA=$(get_file_value $LATEFILE "MODULEFINGERPRINT=") + + # Saves new module value + sed -i "s@MODULEFINGERPRINT=\"$SUBA\"@MODULEFINGERPRINT=\"\"@" $LATEFILE + # Updates prop change variables in propsconf_late + sed -i 's/PRINTEDIT=1/PRINTEDIT=0/g' $LATEFILE + + if [ "$2" != "file" ]; then + after_change "$1" + fi } + +# Use fingerprint +change_print() { + log_handler "Changing device fingerprint to $2." + + SUBA=$(get_file_value $LATEFILE "MODULEFINGERPRINT=") + + # Saves new module value + sed -i "s@MODULEFINGERPRINT=\"$SUBA\"@MODULEFINGERPRINT=\"$2\"@" $LATEFILE + # Updates prop change variables in propsconf_late + sed -i 's/PRINTEDIT=0/PRINTEDIT=1/' $LATEFILE + + NEWFINGERPRINT="" + + if [ "$3" != "file" ]; then + after_change "$1" + fi +} + +# ======================== Props files functions ======================== +# Reset prop files +reset_prop_files() { + log_handler "Resetting prop files$3." + + # Changes file + for PROPTYPE in $PROPSLIST; do + log_handler "Disabling prop file editing for '$PROPTYPTE'." + PROP=$(get_prop_type $PROPTYPE) + FILEPROP=$(echo "FILE$PROP" | tr '[:lower:]' '[:upper:]') + SETPROP=$(echo "SET$PROP" | tr '[:lower:]' '[:upper:]') + + sed -i "s/$SETPROP=true/$SETPROP=false/" $LATEFILE + sed -i 's/BUILDEDIT=1/BUILDEDIT=0/' $LATEFILE + sed -i 's/DEFAULTEDIT=1/DEFAULTEDIT=0/' $LATEFILE + done + + if [ "$1" != "file" ]; then + after_change_file "$1" "$2" + fi +} + +# Editing prop files +edit_prop_files() { + log_handler "Modifying prop files$3." + + # Checks if editing prop files is enabled + if [ "$(get_file_value $LATEFILE "BUILDPROPENB=")" == 0 ]; then + log_handler "Editing build.prop is disabled. Only editing default.prop." + PROPSLIST=" + ro.debuggable + ro.secure + " + fi + + for PROPTYPE in $PROPSLIST; do + log_handler "Checking original file value for '$PROPTYPE'." + PROP=$(get_prop_type $PROPTYPE) + FILEPROP=$(echo "FILE$PROP" | tr '[:lower:]' '[:upper:]') + SETPROP=$(echo "SET$PROP" | tr '[:lower:]' '[:upper:]') + + # Check the original file value + PROPVALUE=$(get_file_value $LATEFILE "$FILEPROP=") + if [ -z "$PROPVALUE" ]; then + if [ "$PROPTYPE" == "ro.debuggable" ] || [ "$PROPTYPE" == "ro.secure" ]; then + PROPVALUE=$(get_file_value /default.prop "${PROPTYPE}=") + else + PROPVALUE=$(get_file_value /system/build.prop "${PROPTYPE}=") + fi + fi + + # Checks for default/set values + safe_props $PROPTYPE $PROPVALUE + + # Changes file only if necessary + if [ "$SAFE" == 0 ]; then + log_handler "Enabling prop file editing for '$PROPTYPE'." + sed -i "s/$SETPROP=false/$SETPROP=true/" $LATEFILE + elif [ "$SAFE" == 1 ]; then + log_handler "Prop file editing unnecessary for '$PROPTYPE'." + sed -i "s/$SETPROP=true/$SETPROP=false/" $LATEFILE + else + log_handler "Couldn't check safe value for '$PROPTYPE'." + fi + sed -i 's/DEFAULTEDIT=0/DEFAULTEDIT=1/' $LATEFILE + sed -i 's/BUILDEDIT=0/BUILDEDIT=1/' $LATEFILE + done + + if [ "$1" != "file" ]; then + after_change_file "$1" "$2" + fi +} + +# ======================== MagiskHide Props functions ======================== +# Check safe values +safe_props() { + SAFE="" + if [ "$2" ]; then + for P in $SAFELIST; do + if [ "$(get_eq_left $P)" == "$1" ]; then + if [ "$2" == "$(get_eq_right $P)" ]; then + SAFE=1 + else + SAFE=0 + fi + break + fi + done + fi +} + +# Find what prop value to change to +change_to() { + CHANGE="" + case "$1" in + ro.debuggable) if [ "$2" == 0 ]; then CHANGE=1; else CHANGE=0; fi + ;; + ro.secure) if [ "$2" == 0 ]; then CHANGE=1; else CHANGE=0; fi + ;; + ro.build.type) if [ "$2" == "userdebug" ]; then CHANGE="user"; else CHANGE="userdebug"; fi + ;; + ro.build.tags) if [ "$2" == "test-keys" ]; then CHANGE="release-keys"; else CHANGE="test-keys"; fi + ;; + ro.build.selinux) if [ "$2" == 0 ]; then CHANGE=1; else CHANGE=0; fi + ;; + esac +} + +# Reset the module prop change +reset_prop() { + # Sets variables + PROP=$(get_prop_type $1) + MODULEPROP=$(echo "MODULE${PROP}" | tr '[:lower:]' '[:upper:]') + REPROP=$(echo "RE${PROP}" | tr '[:lower:]' '[:upper:]') + SUBA=$(get_file_value $LATEFILE "${MODULEPROP}=") + + log_handler "Resetting $1 to default value." + + # Saves new module value + sed -i "s/$MODULEPROP=\"$SUBA\"/$MODULEPROP=\"\"/" $LATEFILE + # Changes prop + sed -i "s/$REPROP=true/$REPROP=false/" $LATEFILE + + # Updates prop change variable in propsconf_late + PROPCOUNT=$(get_file_value $LATEFILE "PROPCOUNT=") + if [ "$SUBA" ]; then + if [ "$PROPCOUNT" -gt 0 ]; then + PROPCOUNTP=$(($PROPCOUNT-1)) + sed -i "s/PROPCOUNT=$PROPCOUNT/PROPCOUNT=$PROPCOUNTP/" $LATEFILE + fi + if [ "$PROPCOUNT" == 0 ]; then + sed -i 's/PROPEDIT=1/PROPEDIT=0/' $LATEFILE + fi + fi + + if [ "$2" != "file" ]; then + after_change "$1" + fi +} + +# Use prop value +change_prop() { + # Sets variables + PROP=$(get_prop_type $1) + MODULEPROP=$(echo "MODULE${PROP}" | tr '[:lower:]' '[:upper:]') + REPROP=$(echo "RE${PROP}" | tr '[:lower:]' '[:upper:]') + SUBA=$(get_file_value $LATEFILE "${MODULEPROP}=") + + log_handler "Changing $1 to $2." + + # Saves new module value + sed -i "s/$MODULEPROP=\"$SUBA\"/$MODULEPROP=\"$2\"/" $LATEFILE + # Changes prop + sed -i "s/$REPROP=false/$REPROP=true/" $LATEFILE + + # Updates prop change variables in propsconf_late + if [ -z "$SUBA" ]; then + PROPCOUNT=$(get_file_value $LATEFILE "PROPCOUNT=") + PROPCOUNTP=$(($PROPCOUNT+1)) + sed -i "s/PROPCOUNT=$PROPCOUNT/PROPCOUNT=$PROPCOUNTP/" $LATEFILE + fi + sed -i 's/PROPEDIT=0/PROPEDIT=1/' $LATEFILE + + if [ "$3" != "file" ]; then + after_change "$1" + fi +} + +# Reset all module prop changes +reset_prop_all() { + log_handler "Resetting all props to default values." + + for PROPTYPE in $PROPSLIST; do + PROP=$(get_prop_type $PROPTYPE) + MODULEPROP=$(echo "MODULE${PROP}" | tr '[:lower:]' '[:upper:]') + REPROP=$(echo "RE${PROP}" | tr '[:lower:]' '[:upper:]') + SUBA=$(get_file_value $LATEFILE "${MODULEPROP}=") + + # Saves new module value + sed -i "s/$MODULEPROP=\"$SUBA\"/$MODULEPROP=\"\"/" $LATEFILE + # Changes prop + sed -i "s/$REPROP=true/$REPROP=false/" $LATEFILE + + # Updates prop change variables in propsconf_late + PROPCOUNT=$(get_file_value $LATEFILE "PROPCOUNT=") + sed -i "s/PROPCOUNT=$PROPCOUNT/PROPCOUNT=0/" $LATEFILE + sed -i 's/PROPEDIT=1/PROPEDIT=0/' $LATEFILE + done + + after_change "$1" +} + +# ======================== Custom Props functions ======================== +# Set custom prop value +set_custprop() { + if [ "$2" ]; then + CURRCUSTPROPS=$(get_file_value $LATEFILE "CUSTOMPROPS=") + TMPCUSTPROPS=$(echo "$CURRCUSTPROPS ${1}=${2}" | sed 's/^[ \t]*//') + SORTCUSTPROPS=$(echo $(printf '%s\n' $TMPCUSTPROPS | sort -u)) + + log_handler "Setting custom prop $1." + sed -i "s/CUSTOMPROPS=\"$CURRCUSTPROPS\"/CUSTOMPROPS=\"$SORTCUSTPROPS\"/" $LATEFILE + sed -i 's/CUSTOMEDIT=0/CUSTOMEDIT=1/' $LATEFILE + + if [ "$3" != "file" ]; then + after_change "$1" + fi + fi +} + +# Reset all custom prop values +reset_all_custprop() { + CURRCUSTPROPS=$(get_file_value $LATEFILE "CUSTOMPROPS=") + + log_handler "Resetting all custom props." + # Removing all custom props + sed -i "s/CUSTOMPROPS=\"$CURRCUSTPROPS\"/CUSTOMPROPS=\"\"/" $LATEFILE + sed -i 's/CUSTOMEDIT=1/CUSTOMEDIT=0/' $LATEFILE + + if [ "$1" != "file" ]; then + after_change "$1" + fi +} + +# Reset custom prop value +reset_custprop() { + CURRCUSTPROPS=$(get_file_value $LATEFILE "CUSTOMPROPS=") + + log_handler "Resetting custom props $1." + TMPCUSTPROPS=$(echo $CURRCUSTPROPS | sed "s/$1=$2//" | tr -s " " | sed 's/^[ \t]*//') + + # Removing all custom props + sed -i "s/CUSTOMPROPS=\"$CURRCUSTPROPS\"/CUSTOMPROPS=\"$TMPCUSTPROPS\"/" $LATEFILE + CURRCUSTPROPS=$(get_file_value $LATEFILE "CUSTOMPROPS=") + if [ -z "$CURRCUSTPROPS" ]; then + sed -i 's/CUSTOMEDIT=1/CUSTOMEDIT=0/' $LATEFILE + fi + + after_change "$1" +} \ No newline at end of file diff --git a/config.sh b/config.sh index 21d8853..3785e56 100644 --- a/config.sh +++ b/config.sh @@ -102,7 +102,7 @@ set_permissions() { # Finding file values get_file_value() { - cat $1 | grep $2 | sed 's/.*=//' + cat $1 | grep $2 | sed 's/.*=//' | sed 's/\"//g' } # Variables @@ -130,7 +130,12 @@ BUILDEDIT DEFAULTEDIT PROPCOUNT PROPEDIT +CUSTOMCHK REBOOTCHK +OPTIONCOLOUR +OPTIONWEB +" +PROPSETTINGSLIST=" FILEDEBUGGABLE FILESECURE FILETYPE @@ -148,6 +153,7 @@ MODULETYPE MODULETAGS MODULESELINUX MODULEFINGERPRINT +CUSTOMPROPS " PROPSLIST=" debuggable @@ -159,8 +165,7 @@ fingerprint " USNFLIST="xiaomi-safetynet-fix safetynet-fingerprint-fix" -# Places the boot script in service.d and puts a backup in the module folder -# Places util_functions.sh in the module folder +# Places various module scripts in their proper places script_placement() { ui_print "- Installing scripts" cp -af $INSTALLER/common/util_functions.sh $MODPATH/util_functions.sh @@ -172,18 +177,35 @@ script_placement() { elif [ "$SETTRANSF" -gt "$FILEV" ]; then ui_print "- Settings cleared (script updated)" else - ui_print "- Transfering settings from old script" + ui_print "- Script updated" + ui_print "- Transferring settings from old script" + # Prop settings + for ITEM in $SETTINGSLIST; do + SOLD=$(get_file_value $LATEFILE "${ITEM}=") + SNEW=$(get_file_value $UPDATELATEFILE "${ITEM}=") + if [ "$SOLD" ]; then + sed -i "s@${ITEM}=${SNEW}@${ITEM}=${SOLD}@" $UPDATELATEFILE + fi + done # Prop values - for S in $SETTINGSLIST; do - SOLD=$(get_file_value $LATEFILE "$S=") - SNEW=$(get_file_value $UPDATELATEFILE "$S=") - sed -i "s@$S\=$SNEW@$S\=$SOLD@g" $UPDATELATEFILE + for ITEM in $PROPSETTINGSLIST; do + SOLD=$(get_file_value $LATEFILE "${ITEM}=") + if [ "$SOLD" ]; then + sed -i "s@${ITEM}=\"\"@${ITEM}=\"${SOLD}\"@" $UPDATELATEFILE + fi done # Prop and file edits - for P in $PROPSLIST; do - REPROP=$(echo "RE$P" | tr '[:lower:]' '[:upper:]') - POLD=$(get_file_value $LATEFILE "$REPROP\=") - sed -i "s/$REPROP\=false/$REPROP\=$POLD/" $UPDATELATEFILE + for ITEM in $PROPSLIST; do + REPROP=$(echo "RE${ITEM}" | tr '[:lower:]' '[:upper:]') + SETPROP=$(echo "SET${ITEM}" | tr '[:lower:]' '[:upper:]') + REOLD=$(get_file_value $LATEFILE "${REPROP}=") + SETOLD=$(get_file_value $LATEFILE "${SETPROP}=") + if [ "$REOLD" ]; then + sed -i "s/${REPROP}=false/${REPROP}=${REOLD}/" $UPDATELATEFILE + fi + if [ "$SETOLD" ]; then + sed -i "s/${SETPROP}=false/${SETPROP}=${SETOLD}/" $UPDATELATEFILE + fi done fi cp -af $UPDATELATEFILE $LATEFILE @@ -197,7 +219,7 @@ script_placement() { placeholder_update() { FILEVALUE=$(get_file_value $1 "$2=") case $FILEVALUE in - *PLACEHOLDER*) sed -i "s@$2\=$3@$2\=\"$4\"@g" $1 + *PLACEHOLDER*) sed -i "s@${2}=${3}@${2}=\"${4}\"@g" $1 ;; esac } @@ -248,12 +270,34 @@ bin_check() { mv -f $MODPATH/system/binpath $MODPATH/system/$BIN } +# Check for A/B devices +ab_check() { + if [ -z $SLOT ]; then + CACHELOC=/cache + else + CACHELOC/data/cache + fi +} + +# Installs everything script_install() { build_prop_check usnf_check bin_check + ab_check script_placement ui_print "- Updating placeholders" - placeholder_update $MODPATH/post-fs-data.sh BIN BIN_PLACEHOLDER "$BIN" - placeholder_update $MODPATH/post-fs-data.sh USNFLIST USNF_PLACEHOLDER "$USNFLIST" + placeholder_update $LATEFILE CACHELOC CACHE_PLACEHOLDER "$CACHELOC" + placeholder_update $MODPATH/util_functions.sh BIN BIN_PLACEHOLDER "$BIN" + placeholder_update $MODPATH/util_functions.sh USNFLIST USNF_PLACEHOLDER "$USNFLIST" + placeholder_update $MODPATH/util_functions.sh CACHELOC CACHE_PLACEHOLDER "$CACHELOC" + MODVERSION=$(echo $(get_file_value $MODPATH/module.prop "version=") | sed 's/-.*//') + placeholder_update $MODPATH/util_functions.sh MODVERSION VER_PLACEHOLDER $MODVERSION + # Load module functions + . $MODPATH/util_functions.sh + # Checks original file values + file_values + orig_safe + # Checks for configuration file + config_file } diff --git a/module.prop b/module.prop index 460d4eb..bf46ba5 100644 --- a/module.prop +++ b/module.prop @@ -1,7 +1,7 @@ id=MagiskHidePropsConf name=MagiskHide Props Config -version=v1.2.1-v5 -versionCode=4 +version=v2.0.0-v6 +versionCode=5 author=Didgeridoohan -description=Change your device's fingerprint, to pass SafetyNet's CTS Profile check. Edit prop files for better root hiding. Set/reset prop values set by MagiskHide. +description=Change your device's fingerprint, to pass SafetyNet's CTS Profile check. Edit prop files for better root hiding. Set/reset prop values set by MagiskHide. Change any prop values easily. minMagisk=1500 diff --git a/system/binpath/props b/system/binpath/props index e53062bd33fba9c28764af8cf4965383fdad54e1..361e0089e8ff6e68b86a20801b3ad404319b0aa3 100644 GIT binary patch literal 32165 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