[ASUS ZenFone 8] bnsmb:
To change a file (or directory) in one of the read-only mounted filesystems in the Android OS Magisk can be used.

(see How to change files in the directory /system with Magisk and How to make files in /system writable )

But this method only works for files in the directories /system, /vendor, /product, or /system_ext.

In current Android OS implementations there are a lot of other directories on read-only filesystems with files that must be changed or replaced to change the behaviour of Android.

For example on some Android implementations the boot animation is in the file /my_product/media/bootanimation/bootanimation.zip. The standard mechanism to change a file on a read-only mounted filesystem via Magisk can not be used to replace this file with another file.

But Magisk also supports executing scripts while booting the phone (see How to run a script at every boot using Magisk)

And the Magisk init scripts in the directory /data/adb/post-fs-data.d are executed early in the boot process. Therefor we can create a Magisk init script to replace any file with another file using the same method Magisk is using (that is a "mount -o bind ..." ):

Note

All commands in this Howto must be done by the user root.

Example

To replace the boot animation with another one copy the ZIP file with the new boot animation to the directory /data/adb (or any other read-write mounted directory available early in the boot process), e.g:

ASUS_I006D:/data # ls -l /data/adb/Earth_bootanimation.zip
-rw-r--r-- 1 u0_a130 media_rw 13227720 2022-04-16 10:58 /data/adb/Earth_bootanimation.zip
ASUS_I006D:/data #

Make sure that the owner, group, permissions, and SELinux contexts for the file are okay using these commands:

# get the owner, group, permissions, and SELinux context of the file to replace
#
ls -lZ /system/media/bootanimation.zip
-rw-r--r-- 1 root root u:object_r:system_file:s0 4109852 2009-01-01 01:00 /system/media/bootanimation.zip

# correct the config for the new file
#
chown root:root /data/adb/Earth_bootanimation.zip

chmod 0644 /data/adb/Earth_bootanimation.zip

chcon -v u:object_r:system_file:s0 /data/adb/Earth_bootanimation.zip

Result:

ASUS_I006D:/data # ls -ldZ /data/adb/Earth_bootanimation.zip
-rw-r--r-- 1 root root u:object_r:system_file:s0 13227720 2022-04-16 10:58 /data/adb/Earth_bootanimation.zip
ASUS_I006D:/data #

Now create a Magisk init script to replace the file via bind mount:

echo "mount -o bind /data/adb/Earth_bootanimation.zip /system/media/bootanimation.zip " >/data/adb/post-fs-data.d/change_bootanimation.sh
chmod 755 /data/adb/post-fs-data.d/change_bootanimation.sh

That's it .. Reboot the phone and enjoy the new animation.

To remove the new animation just delete the script /data/adb/post-fs-data.d/change_bootanimation.sh and reboot the phone.

The same method can be used to replace a complete directory using these steps:

e.g. to make the directory /odm/etc writable do:

#
# create the new directory
#
mkdir /data/adb/odm_etc

#
# copy the existing files in /odm/etc to the new directory
#
cd /odm/etc && find . | cpio -pdum /data/adb/odm_etc

#
# create the Magisk init script to replace /odm/etc with the new directory /data/adb/odm_etc
#
echo "# make /odm writable
mount -o bind /data/adb/odm_etc /odm/etc
" >/data/adb/post-fs-data.d/make_odm_etc_writable
chmod 0755 /data/adb/post-fs-data.d/make_odm_etc_writable

Now reboot the phone and check the result:

ASUS_I006D:/ #
ASUS_I006D:/ # ls -l /odm/etc
total 15
-rw-r--r-- 1 root root 4961 2009-01-01 01:00 NOTICE.xml.gz
-rw------- 1 root root 1136 2009-01-01 01:00 build.prop
-r--r--r-- 1 root root 0 2009-01-01 01:00 fs_config_dirs
-r--r--r-- 1 root root 0 2009-01-01 01:00 fs_config_files
-rw-r--r-- 1 root root 0 2009-01-01 01:00 group
-rw-r--r-- 1 root root 0 2009-01-01 01:00 passwd
drwxr-xr-x 2 root root 3452 2023-01-18 16:30 selinux
ASUS_I006D:/ #

#
# create a new file in the directory used to replace /odm/etc
#
ASUS_I006D:/ # touch /data/adb/odm_etc/test.$$

ASUS_I006D:/ # ls -l /data/adb/odm_etc/test.$$
-rw-r--r-- 1 root root 0 2023-01-18 16:41 /data/adb/odm_etc/test.4597
ASUS_I006D:/ #

#
# check the contents of the directory /odm/etc
#
ASUS_I006D:/ # ls -l /odm/etc/test.$$
-rw-r--r-- 1 root root 0 2023-01-18 16:41 //odm/etc/test.4597
ASUS_I006D:/ #

To replace files that are used by user apps, make sure that the file that is to replace the original file is readable by any user. I recommend creating the new files in the directory /data/local/tmp - the file system for this directory supports all permissions for Linux files and is readable by any user.

Caution

I'm sure there is a reason why this feature is not implemented for all directories by default in Magisk

And, for example, if you make the directory /odm/etc writable using the method described above Android will complain after the next reboot with an error message that something is wrong with your phone.

Therefor please use with care! If possible only use this approach to make single files writable.

Trouble Shooting

If it looks like the "new" file is not used or something else went wrong, but the phone still boots into the Android system, this could be due to an incorrect SELinux context. To find this kind of error, look for the name of the replaced file in the output of logcat with grep.

To check if an error is caused by an invalid SELinux context you can temporary disable SELinux:

# get the current SELinux mode (0 = disabled = permissive , 1 = enabled)
#
ASUS_I006D:/ $ getenforce
Enforcing
ASUS_I006D:/ $

# temporary disable SELinux
#
ASUS_I006D:/ $ su - -c "setenforce 0"
ASUS_I006D:/ $

# check the result
#
ASUS_I006D:/ $ getenforce
Permissive
ASUS_I006D:/ $

To enable SELinux again use the command setenforce with the parameter "1" or reboot the phone. For files that are used early in the boot process the command to disable SELinux temporary should be in a script in /data/adb/post-fs-data.d.

In case the phone does not boot anymore after replacing a file or directory using this method:

Reboot the phone from a recovery with adb support (like TWRP) and delete the script in /data/adb/post-fs-data to fix the error

Notes

Files or directories that are used by Android before the Magisk init scripts are executed can not be changed using this method. These files must be replaced by changing the files in the ramdisk on the boot partition (see How to change files in the boot image using Magisk and How to trigger an action when a property is changed )

There are various Magisk Modules available in the internet to replace the animation that use this technique

To test a boot animation while the Android OS is running do:

mount -o bind /data/adb/bootanimation_android12.zip /system/media/bootanimation.zip
bootanimation

Update 24.06.2023/bs

See the post https://xdaforums.com/t/how-to-change-any-file-or-directory-using-magisk.4543103/#post-88679517 below in this thread for using an overlayfs to make files read-write.

Update 11.07.2023 /bs

Added more details about how to configure the SELinux context for the new file

Update 18.03.2024 /bs

Added a hint about the recommended directory to be used for new files