[ZIP - Dual Installer] Dynamic Installer Stable 4.8-b [ Android 10+ or earlier ]

Search This thread

BlassGO

Senior Member
Jan 19, 2021
161
383
20210222_103348.jpg

SUPPORT: TELEGRAM CHANNEL - TELEGRAM GROUP - SUPPORT ME

ABOUT THIS:
With this you can make Automatic Installers (.ZIP flash files) for All Android devices without limitations (Supports an installation from Recovery or can be used to create a Magisk module)

By default the installer mounts the partitions as RW (Read/Write) and creates its own environment (Busybox + Bash) to work even if your installation environment is not the most suitable

Although the name "Dynamic Installer" can be confusing, the installer is not exclusive for devices with Dynamic Partitions, it supports devices with old and new partitions.


Compatibility:
  • ARM/ARM64​
General Features:
  • Fully shell script based (Open source)​
  • It can mount main partitions as RW (/system_root, /system, /system_ext, /vendor, /product, /odm)​
  • Supports /apex mounting (dalvikvm support included)​
  • Supports old and new partitions​
  • Support for a Dual installation (Recovery or Magisk)​
  • It has many useful actions that make it easy to mount partitions, edit/patch files or install ROMs​
  • It has many other special features for patching smali JARs/APKs, XML editing, running JARs directly and more.​
  • It has 4 types of execution (ZIP for Recovery or Magisk, Just load from Recovery Terminal or Termux)​
  • It runs with BASH instead of ASH, DASH​
  • Support for addons and more​

Default Variables:
Bash:
$TMP: The value of this variable contains the temp directory (A directory that only exists during execution, you can use it to store temporary contents)

$BOOTMODE: This value will be "true" only if the device is already booted (or "false")

$chipname: The value of this variable can be "snapdragon/exynos/mediatek/kirin/unisoc" depending on the chipset of the device

$installzip: The value of this variable contains the path of your ZIP (that the user is installing)

$is64bit: The value of this variable will be "true" only if the device is 64-bit (or "false")

$API: The value of this variable contains the API number (of the Android version) of the device

$slot: Contains the Active Slot (_a or _b) if the device has A/B partitions (It can be refreshed with "getarch" )

$dynamic_partitions: The value of this variable will be "true" if the device has a Dynamic Partitions (or "false")

$virtual_partitions: The value of this variable will be "true" if the device has a Virtual Dynamic Partitions (or "false")

${n}: Allows creating new lines within a string ( Example: paragraph=" First line ${n} Second line ${n} Third line " )

$encrypted: It will be "true" only if the device has encrypted Internal Memory (or "false")

$di_version: The complete current version of Dynamic Installer

$main_version: The main version of the Dynamic Installer (Only include whole numbers or decimals, without the -b -b2 -b3 ... variant extensions)

$CUSTOM_SETUP: If the installation is conventional (Recovery or Magisk) it is set by default to 0, if Test Mode is being used it is set to 1 and finally, if it is an externally managed installation such as KernelSU, it is set to 2.

Updater-Script configs
PATH: META-INF/com/google/android/updater-script

Here you will find some lines that start with "setdefault" (These conditions affect even if you make a Magisk module)

  • setdefault devices (code name/Model of supported devices or off)
If you want the installer to only run on specific devices you can replace "off" with the code name or Model of the supported devices (Use ":" to separate them)
Bash:
#By default
setdefault devices off

#For example to only supports Galaxy A51
#Check using one code name
setdefault devices "a51"

#Check using two code names
setdefault devices "a51:a51nsxx"

#Check Galaxy A51 but with Models
setdefault devices "SM-A515F:SM-A515FN"

#For example to only supports Pixel 4 XL and Pixel 2
setdefault devices "Pixel 2:Pixel 4 XL"

#Or a Mix
#For example to only supports Pixel 4 XL/Pixel 2 and Galaxy A51
setdefault devices "a51:a51nsxx:Pixel 2:Pixel 4 XL"
  • setdefault apex_mount ( on or off)
You can change the "off" to "on" to allow mounting of /apex, (this could cause a very slow mounting with mount_all action), activate it only if necessary (When you want to use actions like apktool / sign / run_jar that require dalvikvm from Recovery)
Bash:
#By default
setdefault apex_mount off

#To allow /apex mount using /system/apex and /system_ext/apex
setdefault apex_mount on

  • setdefault import_addons (on or off)
If you activate it all files with extension .sh within META-INF/addons will be imported before execution, this way you can load several plugins for your main script

NOTE: The import will respect an alphabetical (a.sh, b.sh, c.sh, ...) or numerical (1.sh, 2.sh, 3.sh, ...) order
Bash:
#By default
setdefault import_addons off

#To import all META-INF/addons/*.sh
setdefault import_addons on

  • setdefault magisk_support ( on / off / force)
To enable, disable or force the Magisk space:
  1. on = Automatically switch between updater-script (Device not booted) or customize.sh (Device already booted). Dual installation, two possible execution scripts.
  2. off = Never use the Magisk space, so the updater-script will always be used in any case of installation (Device already booted or not booted)
  3. force = Always use the Magisk space, so the customize.sh will always be used for any installation case (Device already booted or not booted)

NOTE: When magisk_support is set to "off", it is understood that any references to magisk modules, such as $MODPATH, will not be available even if the ZIP is installed from the Magisk App.
Bash:
#By default
setdefault magisk_support on

#To use updater-script instead of customize.sh
#(Device already Booted)
setdefault magisk_support off

#To use customize.sh instead of updater-script 
#(Device NOT Booted - Recovery)
setdefault magisk_support force

  • setdefault extraction_speed (default or custom value)
Allows you to change the extraction speed (MB/s) only when using these actions: update/update_zip/write_raw_image
Bash:
#By default
setdefault extraction_speed default

#To use 5MB / s in the supported actions
#Use "M" for Megabytes
setdefault extraction_speed 5M

  • setdefault ensure_root (on or off)
If set to "off", mount_all will allow Read-Only systems (Even if you can't make edits internally, you can still mount read-only, otherwise, with "on", the installation would be aborted)
Bash:
#By default
setdefault ensure_root on

#To allow RO systems
setdefault ensure_root off

  • setdefault permissions (0:0:0755:0644 or custom value)
Allows you to change the default permissions for folders/files used by ALL Dynamic Installer functions (It means that any function that interacts with files or folders will use these permissions in the result)

Format = User ID : Group ID : Folder permissions : File permissions

Bash:
#By default
setdefault permissions "0:0:0755:0644"

#To use 0755 in Folders and 0777 in Files
setdefault permissions "0 : 0 : 0755 : 0777"

Pre-introduction to Addons
The contents inside META-INF/addons are extracted automatically in the installation, to refer to the path use $addons variable

Plugins here
Bash:
::If you have META-INF/addons/myfile.txt
#To print this file
#You don't need to extract it
fprint "$addons/myfile.txt"

Pre-introduction to Actions
Some of these actions support specific extensions as follows:
  • _addon: If you add "_addon" to the end of each supported action it will take the files directly from "META-INF/addons" folder inside the zip
Bash:
#META-INF/addons/Example.txt
update_file_addon "Example.txt" /system/build.prop
  • _zip: If you add "_zip" at the end of each supported action it will take the files directly from the ZIP, you can include paths with folders
Bash:
#To use "folder/Example.txt" file inside the ZIP
update_file_zip "folder/Example.txt" /system/build.prop
  • If this extension isnt included in the action, it will work as an external command to the zip
Bash:
update_file "/sdcard/Example.txt" /system/build.prop
How does it work?
  • update-binary It is the script that creates the proper environment and executes the entire ZIP
  • zbin contains all the necessary plugins
  • updater-script It is the script that is executed only if the ZIP is installed from Recovery (or when the device is not booted in general)
  • customize.sh It is the script that is executed only if the ZIP is installed from the Magisk App (or when the device is already booted in general)

Test MODE
The "Test Mode" allows you to test most actions of the Dynamic Installer using the Termux App for Android or some Custom Recovery Terminal (with this you can practice)
20220104_152849.jpg


To use it, extract this folder:

  • META-INF/zbin
Also this file:
  • META-INF/addons/extra.zip
To your internal memory: /sdcard

Execution in Termux (ROOT):

Bash:
#First method
su
cd /sdcard/zbin
. ./setup

#Second method
su
. /sdcard/zbin/setup /sdcard/zbin

Execution in Custom Recovery Terminal:
Bash:
#First method
cd /sdcard/zbin
. ./setup

#Second method
. /sdcard/zbin/setup /sdcard/zbin

Now you can test some actions:
Bash:
update_file_string "ro.product.system.model= TEST" /sdcard/build.prop

apktool --help

Magisk SPACE
NOTE: You can use all the additional functions of the Dynamic Installer during the installation by Magisk

SPACE: META-INF/com/google/android/magisk

In this space you can configure the script and the information of your Magisk module, but the format of the script is totally free, do not rely too much on the existing formats for magisk modules

The magisk modules use a "$MODPATH" variable which is where you must direct all the files to be applied

For example to just extract contents of your ZIP in "$MODPATH/system" (This will apply the changes to /system after reboot)
Bash:
package_extract_dir "FolderInsideZIP" "$MODPATH/system"

KernelSU Support
NOTE: You can use all the additional functions of the Dynamic Installer during the installation by KSU

SPACE: META-INF/com/google/android/magisk

The same Magisk space is used, in this space you can configure the Script or special additional Scripts like service.sh. The format of the main script (customize.sh) is totally free, do not rely too much on the existing formats for Magisk/KSU modules.

Before continuing, it is important to understand the problems and what were the solutions implemented from v4.8+


PROBLEMS:
  • Unlike Magisk Modules, the customize.sh and module.prop files must be strictly in the ROOT of the ZIP, since their reading is static and is not managed by the installer itself. This makes it impossible for these files to be obtained from the Magisk Space implemented in the Dynamic Installer.
  • Unlike Magisk Modules, the execution of the ZIP is not controlled by the "META-INF/com/google/android/update-binary" file, which is the main requirement to load the Dynamic Installer, KSU transfers this logic to the Manager itself. which directly executes "customize.sh" from the root of the ZIP.
SOLUTIONS:
  • Add a module.prop in the root of the ZIP from which the module information such as Name, Author, Description, ... will be read only for an installation with the KSU manager.
  • Add a customize.sh in the root of the ZIP that calls the update-binary of the Dynamic Installer allowing its conventional execution only for an installation with the KSU manager.

Okay, now it is easier to understand the role played by these two files that must be added to the ROOT of any module based on the Dynamic Installer v4.8+ that wants to support KernelSU or other external Managers different from Magisk.

DOWNLOAD

So, your final ZIP should look something like this:
Code:
META-INF
customize.sh
module.prop

In this module.prop configure the information of the module you want for an installation by KernelSU, and in "META-INF/com/google/android/magisk/module.prop" the information you want for an installation by Magisk.


EXTRA:
The KSU modules use a "$MODPATH" variable which is where you must direct all the files to be applied

For example to just extract contents of your ZIP in "$MODPATH/system" (This will apply the changes to /system after reboot)
Bash:
package_extract_dir "FolderInsideZIP" "$MODPATH/system"

REPLACE NATIVE FUNCTIONS
By default all the Native functions of the Dynamic Installer and some Native Variables are in Read/Only to prevent them from being altered by imported shell scripts, however there is a way to allow their substitution from your script: off_readonly

NOTE: off_readonly is interpreted during the installation of the ZIP, so it doesn't work from Test Mode
Bash:
#off_readonly "function name" "function name" "..."
off_readonly ui_print update_file

#Now you can use your custom functions
ui_print() {
   echo My custom ui_print function
}

update_file() {
   echo My custom update_file function
}

#For some Native Variables like $TMP
off_readonly TMP TMPDIR

#New values
TMP="My custom value"
TMPDIR="My custom value"

TMP2
This variable ($TMP2) is generated by using start_tmp function and ends with end_tmp, the value contains a new temporary path that disappears after installation

Multiple spaces can be generated and finished the same number of times in different periods
Bash:
start_tmp
Space1="$TMP2"

start_tmp
Space2="$TMP2"

start_tmp
Space3="$TMP2"

#U need to finish ALL dynamic spaces
#end_tmp will be remove the created temp directory based on the order of creation

end_tmp
end_tmp
end_tmp

BUGS:
  • The functions to decompile/compile APKs use an experimental apktool build that CANNOT process images, so dont try to process a full complex APKs! Only smali editions

CREDITS TO:

  • Me @BlassGO ( Creator of Dynamic Installer)
  • @osm0sis ( Traditional installer functionalities in shell code)
  • @topjohnwu ( Some very cool functions in shell code)
  • @munjeni for superrepack and superunpack (Best tools to manipulate SUPER images)
  • @lebigmac cuz I used his project systemrw as a base to made my super_rw function for Dynamic Installer
  • 3arthur6 for its binary 7zip for the experimental Z variants of the DI


MORE EXPLANATIONS
AND DOWNLOADS
IN THE NEXT POSTS
 
Last edited:

BlassGO

Senior Member
Jan 19, 2021
161
383

ALL ACTIONS
-----------------------------------
ABORT / END:
  • abort "Text" "Text" "..."
Print an optional message and then terminate the whole installation as failed
Bash:
abort "There was a problem, stopping installation!"

  • end "Text" "Text" "..."
Print an optional message and then terminate the whole installation but without failure alert
Bash:
end "Nothing to do..."
-----------------------------------
VARIABLES / SUB-PROCESSES:
How to play with variables and sub-processes
  • MyVar="Text"
Assign a textual value to a variable (MyVar)

NOTE: There is a distinction between uppercase and lowercase for the name of the variables ("a" and "A" can be used as two different variables)

WARNING: The name of the variable must always start with alphabetic characters or the "_" character (A or __A is valid), it cannot start with numbers ( 90 or 90__MyVar it's not valid), fulfilling this start condition, the rest of the name can have both numeric characters, alphabetic characters or "_" character ( MyVar__90 is valid), the number of times you want
Bash:
a="Ole"
A="Just test"
A10="a b c d e"
__A="1 2 3 4 5"
__B__="W e l c o m e !"
_ABC_1_2_3="-------------------------"

  • $MyVar / ${MyVar} / $(sub-process)
The "$" symbol is used to invoke variables or create sub-processes

By default, values for both Variables and Actions are taken as literal text
Bash:
MyVar="W e l c o m e !"

#It will literally print "MyVar"
ui_print "MyVar"

But with the symbol "$" it is possible to make that text be interpreted, instead of being taken as something literal
Bash:
__B__="W e l c o m e !"

MyVar="$__B__"

#It will be print "W e l c o m e !"
ui_print "$MyVar"

For variables, sometimes it is necessary to limit the text that should be interpreted, for this use curly brackets ${MyVar}
Bash:
MyVar="W e l c o m e "

ui_print "${MyVar}Blass!"

Finally, some available Actions can return text, being possible to include this text as a value for a Variable or another Action. For this the symbol "$" is used, followed by a grouping with parentheses $(action)

Bash:
#The "string" action will return "welcome" in uppercase "WELCOME" and this will be the printed text
#Result: WELCOME Blass!
ui_print "$(string upper "welcome") Blass!"

#Same for Variables
Result="$(string upper "welcome") Blass!"
ui_print "$Result"
-----------------------------------
LOGIC OF EXPRESSIONS:
As in many programming languages, the use of logical connectors is supported
  • Action/Expression && Action/Expression && Action/Expression ...
"&&" allows to join several expressions/actions, it is interpreted as "and", the whole line will end without error, if and only if, all expressions/actions end without any error

NOTE: If the previous action/expression ends in error, the next expression/action will not even be executed
Bash:
exist "/system/build.prop" && exist "/system/ole" && exist "/system/a"

  • Action/Expression || Action/Expression || Action/Expression ...
"||" allows to join several possible expressions/actions, it is interpreted as "or", the whole line will end without error, if any of the actions/expressions end without error (It is not necessary for all of them to do, but at least one must be satisfactory)

NOTE: If the previous action/expression completes without error, the next expression/action will not even be executed
Bash:
exist "/system/build.prop" || exist "/system/ole" || exist "/system/a"

  • (Action/Expression && Action/Expression) || (Action/Expression && Action/Expression) ...
"()" parentheses allow multiple Actions/Expressions to be grouped together, making them form a new Expression

NOTE: The grouped actions/expressions will be executed in a separate space, that is, they will not be able to alter values in your main script
Bash:
(exist "/system/build.prop" && exist "/system/ole") || (exist "/system/huh" && exist "/system/a")

  • not Action/Expression
"not" allows to negate any expression/action, making its operation inverse, that is, if the expression/action ends with an error, it will be interpreted inversely as successful, and if it ends without error, it will be interpreted inversely as failed.

You can use either "not" or "!", they are the same

NOTE: "not" only affects each individual action/expression, new actions/expressions joined with "&&" or "||" will not be affected by the negation

WARNING: When negating a grouping "()" it is important to understand that also the connectors "&&" and "||" are inverted, that is, "&&" in negation becomes "||" and vice versa
Bash:
not exist "/system/build.prop" && not exist "/system/ole" && not exist "/system/a"

#Using grouping it is possible to avoid repetitive use of "not"
#Note the change of "&&" to "||"  to preserve the logic of the previous example
not (exist "/system/build.prop" || exist "/system/ole" || exist "/system/a")
-----------------------------------
MOUNT:
  • mount_all
It will mount the main partitions automatically (/system_root, /system, /system_ext, /vendor, /product, /odm , /apex only if setdefault apex_mount enabled)

  • try_mount "part" "part" "part" "..."
Mount specific partitions (By default in Read/Write if possible or Read/Only)

NOTE: For /system_root, /system_ext, /system, /vendor, /product, /odm or /apex use mount_all

-read-write (-rw) = To only mount partitions in Read/Write

-read-only (-ro) = To only mount partitions in Read/Only

-remount (-re) = Unmount partitions before mounting

-express (-e) = This does a superficial find of the partition, avoiding a long waiting time in case that partition does not exist

-name (-n) = Specify a name to find the partition to mount instead of the automatic name (For A/B devices, if the slot is not specified, the active slot will be used by default)

-file (-f) = Mount a file (only .IMG RAW supported) / Or specify a partition (block) to mount
Bash:
#Read/Write if possible or RO
try_mount /cache /optics /prism /odm /vendor

#Only Read/Write
try_mount -rw /optics /prism

#Only Read/Only
try_mount -ro /optics /prism

#Unmount before mount
try_mount -remount /optics /prism

#Specifying custom name to find the Partition Block to Mount
try_mount -name "system" /test

#For A/B? Its the same
#Supports A/B by default with common names
#Use Active Slot by default
try_mount -name "vendor" /test
#Or optionally specify a slot
try_mount -name "vendor_b" /test

#Don't look for the partition block for long time
try_mount -express /system

#Specifying a FILE to mount instead of partition
try_mount -file "/sdcard/system.img" /test

#Specifying a block to mount
try_mount -file "/dev/block/dm-0" /system_root

#Mix
try_mount -remount -rw /optics /prism
try_mount -express -name "vendor" /mnt/vendor
try_mount -ro -file "/sdcard/vendor.img" /mnt/vendor

#Mount subpartition of SUPER image (.img RAW)
try_mount -file "/sdcard/super.img" -name "system" /mnt/system_inside_SUPER

#Mount subpartition of SUPER image (.img RAW)
#A/B super.img need the slot to mount
try_mount -file "/sdcard/super.img" -name "system_a" /mnt/system_inside_SUPER

  • apex_mount ".apex/.capex File or Folder"
To mount Android Pony Express (APEX) files or folders in /apex space

NOTE: Supports .apex and New Android 12 .capex File formats

Bash:
#Mount APEX File
#/system/apex/com.android.runtime.apex
apex_mount "/system/apex/com.android.runtime.apex"

#Mount APEX Folder
#/system/apex/com.android.runtime
apex_mount "/system/apex/com.android.runtime"

  • umount_all
Unmount ALL mounted partitions with mount_all / auto_mount_partitions, ALL mounted partitions with try_mount and ALL mounted partitions with apex_mount

  • find_block "Block name"
In case you need to get the exact block of a partition (Supports A/B by default)

NOTE: By default if a partition block isnt found, it will stop after 5 seconds to avoid an infinite loop

-express (-e) = This does a superficial find of the partition, avoiding a long waiting time in case that partition does not exist

-time (-t) = Does a full find but only for a limited time


Bash:
#For example to get real system block
#In this example it will return "/dev/block/dm-0"
find_block "system"

#For A/B? Its the same
#Supports A/B by default with common names
find_block "system"

#Fast find
find_block -e system

#Find with limited time
find_block -t 5 system

  • is_same_mount "FOLDER" "FOLDER"
Check if two folders are linked to the same partition (For example /system and /system_ext use the same partition in most devices)

NOTE: Both folders must be mounted

Bash:
if is_same_mount "/system" "/system_ext"; then
   ui_print "/system_ext is inside the system partition"
else
   ui_print "/system_ext must have a separate partition"
fi
-----------------------------------
EXTRACT:
  • package_extract_dir "Folder inside ZIP" "Destination Folder"
You can extract contents of a whole folder within the ZIP to an external path

NOTE: You can define a third argument with the path of an external ZIP, this ZIP will be used instead of the current installation ZIP
Bash:
package_extract_dir "Folder" /system

#Extracting from an external ZIP
package_extract_dir "Folder" /system "/sdcard/External.zip"
  • package_extract_file "Fully File path Inside ZIP" "Fully Dest path outside ZIP"
You can extract a single file from the ZIP to an external path (You can rename the resulting file) or you can get it directly as Text if u want

NOTE: You can define a third argument with the path of an external ZIP, this ZIP will be used instead of the current installation ZIP
Bash:
#Extract to an external path
package_extract_file "Folder/file.txt" /system/test.txt

#Just get the File content directly as Text
#If you dont add a destination path
content=$(package_extract_file "Folder/file.txt")

#Extracting from an external ZIP
package_extract_file "Folder/file.txt" /system/test.txt "/sdcard/External.zip"
-----------------------------------
WIPES:
  • wipe "Common Partition name"
To wipe any section like system, vendor, product, odm, data, dalvik, cache

data = Wipe /data but IGNORE /data/media (Internal storage)

userdata = Fully /data wipe

Bash:
#To wipe /system
wipe system

#To wipe /data but WITHOUT Internal Storage
wipe data

#To wipe ALL /data
wipe userdata

#To wipe dalvik-cache
wipe dalvik

#To wipe cache
wipe cache

#Mix
#To wipe /data /system /vendor /product /cache
wipe data cache system vendor product
-----------------------------------
USER SELECTION:
  • Simple selection (Yes or No)
Bash:
if $yes; then
   #Action if the user presses the volume up button
   package_extract_dir system /system

else
   #Action if the user presses the volume down button
   package_extract_dir vendor /vendor

fi

If the user presses the volume up button, it will be interpreted as YES

If the user presses the volume down button, it will be interpreted as N0


  • multi_option "Variable" <Number of options> <loop>
loop = With a specified number of options, the word "loop" will do an infinite loop constantly resetting the number of options until one is selected (instead of ending in error if all options are discarded)

NOTE: If a number of options is not specified, an infinite loop is created until some N option number is selected (this number will be returned)
Bash:
ui_print " 1. First option"
ui_print " 2. Second option"
ui_print " 3. Third option"
ui_print " 4. Fourth option"

multi_option "my_menu" 4

#Or If you want to create an options loop:
#multi_option "my_menu" 4 loop

if undefined my_menu; then
   abort " No valid selection was obtained "
fi

if [[ $my_menu == 1 ]]; then
   #Actions for the option 1
   ui_print "Welcome to option 1"
elif [[ $my_menu == 2 ]]; then
      #Actions for the option 2
      ui_print "Welcome to option 2"
elif [[ $my_menu == 3 ]]; then
      #Actions for the option 3
      ui_print "Welcome to option 3"
elif [[ $my_menu == 4 ]]; then
      #Actions for the option 4
      ui_print "Welcome to option 4"
fi
Like $yes, the volume buttons are used (Down to discard an option / Up to select that option)
-----------------------------------
SOME EXTRA EDIFY REFERENCES:
To make the environment a bit easier for users who have used traditional installation scripts (Edify Scripts), these are some additional simulated Edify actions.
  • file_getprop "file with props" "file with props" "..." "prop to extract"
Extract one prop (a = b) from multiple external files (The value will only be returned once)
Bash:
file_getprop /system/build.prop "ro.build.display.id"

file_getprop /system/build.prop /vendor/build.prop /system_ext/build.prop "ro.build.display.id"

myid=$(file_getprop /system/build.prop "ro.build.display.id")

  • ifelse "Test this action" "Else run this action"
Supports: _addon and _zip extension

Execute an action and if it fails, execute action two (It is necessary to use a single quotes when you want to include double quotes in the action)


Bash:
#Notice that single quotes are used
ifelse "is_mounted /system" 'ui_print "/system inst mounted"'

#Btw the best practice is using this syntax
is_mounted /system || ui_print "/system inst mounted"

#Or for multiple actions
if is_mounted /system; then
   ui_print "/system already mounted"
   ui_print "Done"
else
   ui_print "/system inst mounted"
   ui_print "ERROR"
fi

  • greater_than_int / less_than_int "Number" "Number"
Allows you to check if a number is greater or less than another (Supports decimals)
Bash:
if greater_than_int "2.2" "1.5"; then
   ui_print "Is greater"
else
   ui_print "Is less or equal"
fi

if less_than_int "1.5" "2"; then
   ui_print "Is less"
else
   ui_print "Is greater or equal"
fi

  • concat "string" "string" "..."
Allows concatenation of multiple strings
Bash:
var="just test"
result=$(concat "h u h" "$var" "    a  ")

  • stdout [Any action]
Allows to execute an action and send all its results (Including errors - Stderr) to Stdout

NOTE: This does not ensure a screen print, for it use stdprint

Bash:
# echo2 prints text as ERROR (Stderr)
# But stdout converts it to main print text
stdout echo2 uwu

  • stderr [Any action]
The inverse of the stdout function, executes an action and prints everything as Error (Stdout to Stderr)
Bash:
#The impression will only be visible in the general log
stderr echo uwu

  • stdprint [Any action]
Execute the action and print its main results on the screen (Print Stdout in Recovery)
Bash:
#The print will be visible on the installation screen
stdprint echo uwu

#This allows to visualize the process of an action even in the Recovery
stdprint apktool --help

  • read_file "file" "file" "..."
Get the contents of one or more files
Bash:
read_file "$TMP/file.txt"

#Or with the native form
cat "$TMP/file.txt"

  • run_program "program" arg1 agr2 "..."
You can execute any supported file as a sh or binary, the file automatically receives the execution permissions and also you can send the arguments you want to that file
Bash:
run_program "$TMP/busybox" --help

  • symlink "FILE" "symlink" "symlink" "..."
You can create multiple symbolic links from a single file
Bash:
#Creating symlinks to busybox
symlink "$TMP/busybox" "$TMP/chmod" "$TMP/sed" "$TMP/tar"

  • convert_edify "Edify Script" "Result"
Allows you to try to convert Edify scripts to the script format supported by the Dynamic Installer (Experimental, it is recommended to manually review the result and not use it as something definitive)
Bash:
#Normal use
convert_edify "/sdcard/edify-script" "/sdcard/result"

#If no destination is specified, the script will be overwritten.
convert_edify "/sdcard/edify-script"
-----------------------------------
GET VALUES:
  • import_config "file with props"
Supports: _addon and _zip extension

Convert prop lines (a = b) to variables ($a)

NOTE: There are exceptions, if the name of the prop has some strange special character it will not become a variable (The name of a variable does not support those characters)

example.prop

Code:
name=Some name
current_version=v1.1.0
i_d_k=S o m e t h i n g

import_config
Bash:
import_config "$TMP/example.prop"
ui_print "$name"
ui_print "$current_version"
ui_print "$i_d_k"

  • get_file_prop "file" "file" "..." "prop to extract"
Extract one prop (a = b) from multiple external files (The value will only be returned once)
Bash:
get_file_prop /system/build.prop "ro.build.display.id" 

get_file_prop /system/build.prop /vendor/build.prop /system_ext/build.prop "ro.build.display.id"

myid=$(get_file_prop /system/build.prop "ro.build.display.id")

  • getdefault "file" "default to extract"
Extract "setdefault" values from external files (Multi-line content not supported)

something.txt

Code:
setdefault ole "a b c"
setdefault okay "d e f"
setdefault test "s o m e t h i n g"

getdefault
Bash:
getdefault "$TMP/something.txt" okay
getdefault "$TMP/something.txt" test

my_var=$(getdefault "$TMP/something.txt" okay)

  • get_array "String Pattern" "Fully ARRAY"
To get fully value in a array using some pattern
Bash:
#First defined array
test=("First array" "Other array" "A B")

#Get fully value in the array
#It will returns "Other array"
get_array "Other" "${test[@]}"

content=$(get_array "Other" "${test[@]}")

  • get_size_ext4 "Partition or .img"
To get the current size in Bytes of any partition or compatible file (RAW .img)
Bash:
#Get size of system block
get_size_ext4 "$(find_block system)"

#Get size of some .img in /sdcard
get_size_ext4 "/sdcard/vendor.img"

size=$(get_size_ext4 "$(find_block system)")

  • fullpath "File/Folder/Symlink"
To get the fully path of any file/folder or symlink, btw it returns the literal symlinks paths instead of its sources
Bash:
fullpath "folder/file"

complete_path=$(fullpath "folder/file")

  • find_content "Pattern" "Pattern" "..." "ZIP FILE"
Returns the paths of all the contents of the ZIP that match the established patterns

-dirs (-d) = Find only folders in the ZIP (By default only Files)
-regex (-r) = Enable Regular Expression support for patterns

-maxdepth (-max) = A number that limits the range of the resulting paths, considering the root of the ZIP as the first level (1) (That is, if "-maxdepth 2", then only contents that are in a maximum range from the root (1) to a single folder (2) of the ZIP will be returned, if the path extends to two subfolders (-maxdepth 3) or more they will not be returned for example)


Bash:
#By default, any File path that has the pattern internally is found
find_content ".mp4" ".mp3" /sdcard/ole.zip

#Find only Folders
find_content -d "huh" /sdcard/ole.zip

#Using Regular Expressions
find_content -regex "(.mp4|.mp3)$" /sdcard/ole.zip

#You can even include multiple Regex
find_content -regex "(.mp4|.mp3)$" "^ole.*(.jpg|.png)$" /sdcard/ole.zip

#Limiting the results to only files that are in the root of the ZIP
find_content -max 1 ".mp4" ".mp3" /sdcard/ole.zip

#Limiting results to only folders that are at most 2 levels
find_content -max 2 -d "huh" "ole" /sdcard/ole.zip

#To get the paths of all the folders in the ZIP that are at most 3 levels
#Regex has infinite possibilities
find_content -d -max 3 -regex ".*" /sdcard/ole.zip
-----------------------------------
SET PERMISSIONS:
  • set_perm "UID" "GID" "MODE" "FILE/FOLDER" "FILE/FOLDER" "..."
Allows you to define the UID (User ID), the GID (Group ID) and the MODE (Permissions) for multiple single files/folders (it is NOT recursive)
Bash:
set_perm 0 0 0755 /system/build.prop

#Multiple files/folder
set_perm 0 0 0755 /system/build.prop /system/test.txt /data/folder

  • set_perm_recursive "UID" "GID" "FOLDERs MODE" "FILEs MODE" "FOLDER" "FOLDER" "..."
Allows you to define the UID (User ID), the GID (Group ID) and the MODE (Permissions) for ALL files and folders within a multiple directories (Recursive), the MODE is one specific for files and another for folders
Bash:
set_perm_recursive 0 0 0644 0755 /system

#Multiple DIRECTORIES
set_perm_recursive 0 0 0644 0755 /system /vendor /product

  • saveperm "FILE/FOLDER" "FILE/FOLDER" "..."
To save the UID (User ID), the GID (Group ID) and the MODE (Permissions) of all files/folders in a path (Recursively) or on single files

NOTE: When any folder is specified it will automatically expand to all its contents

Bash:
#Single file
saveperm /system/build.prop

#Recursively (All contents of this folders)
saveperm /system/app /system/bin /vendor

  • copy_perm_list "Destination File"
You can export the list of permissions generated by "saveperm" (this list is a substitute for "saveperm", in other words you can reuse this list in new projects without the need to use "saveperm" again)

Bash:
#Export the current permission list
copy_perm_list /sdcard/permissions.txt

  • restoreperm "FILE/FOLDER" "FILE/FOLDER" "..."
To restore the UID (User ID), the GID (Group ID) and the MODE (Permissions) previously saved with "saveperm" of all files/folders in a path (Recursively) or on single files

-file (-f) = You can load a previously saved list (with this you can avoid using "saveperm")

NOTE: When any folder is specified it will automatically expand to all its contents, additionally if the save was recursive you can restore the permission of a single file within that directory

Bash:
#Single file
restoreperm /system/build.prop

#Recursively (All contents of this folders)
restoreperm /system/app /system/bin /vendor

#Use a previous list
restoreperm -file "$TMP/permissions.txt" /system/app /system/bin /vendor

  • eval_perm / eval_user / eval_group / eval_all_perm "FILE/FOLDER"
They are functions that allow evaluating the most common UID (User ID), the GID (Group ID) and the MODE (Permissions) within a directory or a single file.

Bash:
#Get only the Mode (Permissions)
eval_perm /system/build.prop
eval_perm /vendor

#Get only the User ID
eval_user /system/build.prop
eval_user /vendor

#Get only the Group ID
eval_group /system/build.prop
eval_group /vendor

#Get only the Group ID
eval_group /system/build.prop
eval_group /vendor

#Get the User ID / Group ID / Mode
eval_all_perm /system/build.prop
eval_all_perm /vendor

  • get_all_perm "FILE/FOLDER"
Unlike eval_all_perm, it returns the literal User ID / Group ID / Mode of a folder, instead of evaluating common results within it.

Bash:
#Get the User ID / Group ID / Mode
get_all_perm /system/build.prop
get_all_perm /vendor
-----------------------------------
GET/SET CONTEXTS:
Contexts in Android (Linux) are properties of all files or folders that determine the type of file or folder and allow the system to know how to treat or catalog that file/folder

NOTE: As Magisk modules work as a layer on top of the system, when you include files within your module they will be installed without any defined context and without a context you could have unwanted results.
  • eval_context "FOLDER or File"
It will find and print the most used context for files and folders (It eval the common results) in a directory or it can just return the context of a single FILE.
Bash:
#It will return u:object_r:system_file:s0
eval_context /system

#It will return u:object_r:vendor_overlay_file:s0
eval_context /vendor/overlay

#It will return u:object_r:sec_efs_file:s0
eval_context /efs

#Get context of a single file
#It will return u:object_r:system_file:s0
eval_context /system/build.prop

  • get_context "FOLDER or File"
Unlike eval_context, it returns the literal context of a folder, instead of evaluating common results within it.
Bash:
#It will return u:object_r:system_file:s0
get_context /system/app
get_context /system/build.prop

  • set_context "PATH or FILE" "PATH or FILE"
To use the contexts of one path in another, the best contexts are logically evaluated for ALL folders and files, although you can also assign the context of a single file to another (Perfect for Magisk modules)
Bash:
#It will apply all the contexts of /system in "$MODPATH/system"
set_context "/system" "$MODPATH/system"

#It will apply all the contexts of /vendor in "$MODPATH/system/vendor"
set_context "/vendor" "$MODPATH/system/vendor"

#It will apply all the contexts of /vendor/etc in "$MODPATH/system/vendor/etc"
set_context "/vendor/etc" "$MODPATH/system/vendor/etc"

#It will apply the context of /system/build.prop in /data/test/test.prop
set_context "/system/build.prop" "/data/test/test.prop"


  • savecontext "FILE/FOLDER" "FILE/FOLDER" "..."
To save the contexts of all files/folders in a path (Recursively) or on single files

NOTE: When any folder is specified it will automatically expand to all its contents

Bash:
#Single file
savecontext /system/build.prop

#Recursively (All contents of this folders)
savecontext /system/app /system/bin /vendor

  • copy_context_list "Destination File"
You can export the list of contexts generated by "savecontext" (this list is a substitute for "savecontext", in other words you can reuse this list in new projects without the need to use "savecontext" again)

Bash:
#Export the current contexts list
copy_context_list /sdcard/contexts.txt

  • restorecontext "FILE/FOLDER" "FILE/FOLDER" "..."
To restore the contexts previously saved with "savecontext" of all files/folders in a path (Recursively) or on single files

-file (-f) = You can load a previously saved list (with this you can avoid using "savecontext")

NOTE: When any folder is specified it will automatically expand to all its contents, additionally if the save was recursive you can restore the context of a single file within that directory

Bash:
#Single file
restorecontext /system/build.prop

#Recursively (All contents of this folders)
restorecontext /system/app /system/bin /vendor

#Use a previous list
restorecontext -file "$TMP/contexts.txt" /system/app /system/bin /vendor

  • ch_con_recursive "Files Context" "Folders Context" "FOLDER" "FOLDER" "..."
To manually set the context to ALL files/folders of multiple directories

The context format can be complete or partial

Complete = u:'object_r:system_file:s0
Partial = system_file

-file (-f) = Only apply contexts in Files
-dir (-d) = Only apply contexs in Folders

Bash:
#With Complete contexts
#Files/Folders
ch_con_recursive "u:object_r:system_file:s0" "u:object_r:system_file:s0" /data/test

#With Partial contexts
#Files/Folders
ch_con_recursive "system_file" "system_file" /data/test

#Apply context to only Files in /data/test
ch_con_recursive -f "system_file" /data/test

#Apply context to only Folders in /data/test
ch_con_recursive -d "system_file" /data/test

#Apply Contexts in Mutiple directories
ch_con_recursive "system_file" "vendor_file" /data/test /data/test2 /data/test3

#Only Files (Mutiple directories)
ch_con_recursive -f "vendor_file" /data/test "$MODPATH/system/vendor"

  • ch_con "Context" "FILE/FOLDER" "FILE/FOLDER" "..."
To manually set the context to mutiple single files/folders (Support Complete or Partial context format like ch_con_recursive)

Bash:
#Complete context
ch_con "u:object_r:system_file:s0" /data/test/huh.txt
ch_con "u:object_r:vendor_file:s0" /data/test/huh.txt

#Partial Context
ch_con system_file /data/test
ch_con vendor_file /data/test/huh.txt

#Mutiple single files/folders
ch_con system_file /data/test /data/a.prop /data/test/huh.txt
-----------------------------------
EDITING FILES:
  • savestate "variable" "file"
Makes a record of the current state of the file and is saved in the variable, any minor editing will change the value
Bash:
#Current state of build.prop will be saved in "$test" variable
savestate test /system/build.prop

#After some modifications
update_file_string "ro.product.system.model=Just Test" /system/build.prop

#The state of the build.prop will be change
savestate test2 /system/build.prop

"$test" ISNT EQUAL TO "$test2"

#You can compare it
if [[ "$test" == "$test2" ]]; then
   ui_print " build.prop was not edited"
else
   ui_print " build.prop changed"
fi

  • patch_fstab "Pattern to find Line to Patch" "Pattern to find property" "New property" "FILE"
Allows you to replace properties of fstab files (For example: /vendor/etc/fstab.qcom)
Bash:
#It will replace fileencryption=ice to encryptable in userdata line
patch_fstab userdata "fileencryption" "encryptable" "/vendor/etc/fstab.qcom"

  • update_file "FILE with New props" "DEST FILE"
Supports: _addon and _zip extension

Updates lines of .prop files without changing the original structure, btw this only works for updating already existing lines, if any line doesnt exist it wont do anything

Bash:
update_file "NewPropLines.txt" "/system/build.prop"

  • force_update_file "FILE with New props" "DEST FILE"
Supports: _addon and _zip extension

Similar to update_file but forces the existence of the new lines, if the lines already exists in the Dest File it remove them and then it will add the new prop lines

Bash:
force_update_file "NewPropLines.txt" "/system/build.prop"

  • update_file_string "line" "line" "..." "file"
Same as update_file but doesnt require extra files, you can include the new lines to update directly as strings
Bash:
update_file_string 'ro.product.system.model=NEW MODEL' /system/build.prop

update_file_string 'ro.product.system.model=NEW MODEL' 'ro.product.system.name=NEW NAME' 'ro.build.display.id=NEW ID' /system/build.prop

  • force_update_file_string "line" "line" "..." "file"
Same as force_update_file but doesnt require extra files, you can include the new lines to update directly as strings
Bash:
force_update_file_string 'ro.product.system.model=NEW MODEL' /system/build.prop

force_update_file_string 'ro.product.system.model=NEW MODEL' 'ro.product.system.name=NEW NAME' 'ro.build.display.id=NEW ID' /system/build.prop


  • xml_kit -open "Start XML section" "End XML Section" -open "Start XML Section" "..." -in "Some pattern" -change-value / -change-tag / -change-content / -add / -add-inside / -after-line / -before-line / -remove "XML FILE"
You can edit XML files by scrolling through sections (You can edit very specific sections)

The results will be analyzed automatically, if you receive any warning the original XML will not be altered, check your code, you are probably setting something wrong

NOTE: If an action is not specified, it will just return the result of all the opened sections (If there are multiple results it is necessary to include -in flag or it will give an error)

-open = Open a section of the XML, specifying the beginning pattern and the end pattern, in addition, you can open more sections within a previously opened section (Until you reach the desired section)

-in = To avoid editing unwanted sections use -in to find the section you want using a specified pattern inside that section (Its use is highly recommended to avoid errors)

-change-value = To change a XML attribute value ( a="value" )

-change-tag = To change a XML value that is inside two tags ( <a> value </a> )

-change-content = To replace any text with another in the opened XML section

-add = To add text after the opened XML section

-add-inside = To add text inside the opened XML section

-after-line = To add text after some line inside the opened XML section

-before-line = To add text before some line inside the opened XML section

-remove = Just remove opened XML section

-print = Print the result instead of editing the XML file

-only-result = Just keep the result of all opened XML sections instead of merging it with the original XML

-no-auto-spaces = Don't use autospacing based on current opened XML section


XML EXAMPLE: /sdcard/Test.xml
XML:
<manifest version="2.0" type="device" target-level="3">
    <hal format="hidl">
        <name>Example_1</name>
        <version>3.0</version>
        <interface>
            <name>Internal One</name>
            <instance>default</instance>
        </interface>
    </hal>
    <hal format="hidl">
        <name>Example_2</name>
        <version>6.0</version>
        <interface>
            <name>Internal Two</name>
            <instance>default</instance>
        </interface>
    </hal>
</manifest>

xml_kit ACTIONS
Bash:
#Open first XML section
xml_kit -open '<manifest' '</manifest>' /sdcard/Test.xml

#Open a section within an already opened section
xml_kit -open '<manifest' '</manifest>' -open '<hal format="hidl">' '</hal>' /sdcard/Test.xml

#The opening of sections is Unlimited
xml_kit -open '<manifest' '</manifest>' -open '<hal format="hidl">' '</hal>' -open '<interface>' '</interface>' /sdcard/Test.xml

#Only edit the section that has this pattern
xml_kit -open '<manifest' '</manifest>' -open '<hal format="hidl">' '</hal>' -in Example_2 /sdcard/Test.xml

#Change some XML attribute
#Change format="hidl" to format="Just test"
xml_kit -open '<manifest' '</manifest>' -open '<hal format="hidl">' '</hal>' -in Example_2 -change-value format "Just Test" /sdcard/Test.xml

#Change some value inside TAGs
#For example: <version>3.0</version>
#Change 3.0 to "Just Test"
xml_kit -open '<manifest' '</manifest>' -open '<hal format="hidl">' '</hal>' -in Example_1 -change-tag version "Just Test" /sdcard/Test.xml

#Add Text after the Opened XML section
xml_kit -open '<manifest' '</manifest>' -open '<hal format="hidl">' '</hal>' -open '<interface>' '</interface>' -in "Internal Two" -add "Just Test" /sdcard/Test.xml

#Add Text after some line
xml_kit -open '<manifest' '</manifest>' -open '<hal format="hidl">' '</hal>' -in Example_1 -after-line Internal "Just Test" /sdcard/Test.xml

#Add Text before some line
xml_kit -open '<manifest' '</manifest>' -open '<hal format="hidl">' '</hal>' -in Example_2 -before-line Internal "Just Test" /sdcard/Test.xml

#Just Remove opened section
xml_kit -open '<manifest' '</manifest>' -open '<hal format="hidl">' '</hal>' -in Example_1 -remove /sdcard/Test.xml

  • add_lines "file" "file" "file" "DEST FILE"
Supports: _addon and _zip extension

Add lines from multiple files to an existing or new file

Supports -after-line and -before-line like add_lines_string

Bash:
#Add the content of a single file to the Destination file
add_lines "Add.txt" /system/build.prop

#Add all contents of multiple files to the Destination file
add_lines "Add.txt" "Add2.txt" "Add3.txt" /system/build.prop

#Add contents BUT after some line
add_lines -after-line "Some line" "Add.txt" /system/build.prop

#Add contents BUT before some line
add_lines -before-line "Some line" "Add.txt" /system/build.prop

#Mix
add_lines -after-line "Some line" "Add.txt" -after-line "Some line 2" "Add2.txt" -before-line "Some Line 3" "Add3.txt" "Extra.txt" "Extra2.txt" /system/build.prop

  • add_lines_string "line" "line" "..." "DEST FILE"
Same as add_lines but doesnt require extra files, you can include the new lines to add directly as strings (Support empy lines)

-after-line (-al) = Add content after a specific line (Unlimited)

-before-line (-bl) = Add content before a specific line (Unlimited)

Bash:
#Normal usage
add_lines_string "New line" "New line 2" /system/build.prop

#Add empy lines
add_lines_string " " /system/build.prop
add_lines_string " " " " /system/build.prop

#Add lines after some line
add_lines_string -after-line "Some line" "add this after" -after-line "Some line 2" "add this after" /system/build.prop

#Add lines before some line
add_lines_string -before-line "Some line" "add this before" -before-line "Some line 2" "add this before" /system/build.prop

#Mix
add_lines_string "New line" " " "New line 2" " " /system/build.prop
add_lines_string " " "New line" -after-line "Some line" "add this after" -after-line "Some line 2" "add this after" " " "Finish line" /system/build.prop

  • replace "Old Text" "New Text" "File or Directory"
Allows you to replace only specific text or all lines that contains it (-all-line) within a file or directory (-recursive)

-recursive(-r) = Finds the specified text in the whole directory and replaces it

-all-line(-a) = Instead of just replacing the text, replace the entire line that contains it (You can replace the line with a paragraph but not vice versa)

Bash:
#In a file
replace "HUH" "OLE" /system/build.prop

#In a whole directory (Recursive)
replace -r "HUH" "OLE" /system

  • replace_name "Pattern Name" "New Pattern Name" "File or Directory"
It allows you to rename a file/folder or a whole directory (-recursive), so it is possible to change several pieces of names or full names of multiple files/folders easily.

-recursive (-r) = Find all files/folders matching the name pattern in the whole directory and rename them

-files (-f) = Only rename files

-dirs (-d) = Only rename folders

-regex = Enable the use of Regular Expressions for the name pattern

NOTE: By default if only files or only folders are not specified, the names of both files and folders will be replaced

Bash:
#Change part of a file name
#Change the extension ".jpg" to ".png"
replace_name ".jpg" ".png" /system/test.jpg

#Same for folders
replace_name "old" "new" /system/folder_old

#Remove the ".bak" extension
replace_name ".bak" "" /system/test.prop.bak

#Recursive
#Change the extension ".jpg" to ".png" in an entire directory
replace_name -r ".jpg" ".png" /system

#Remove the ".bak" extension in an entire directory
replace_name -r ".bak" "" /system

#Btw you can specify that it Only applies to Files
replace_name -f -r ".bak" "" /system

#Or Only Folders
replace_name -d -r "_ext" "_new" /system

#Using Regex the possibilities are endless
#Replace ".bak" only if it is at the end of the entire file names
replace_name -regex -r ".bak$" "" /system

  • remove "Text to remove" "File or Directory"
Allows you to remove only specific text or all lines that contains it (-all-line) within a file or directory (-recursive)

-recursive(-r) = Finds the specified text in the whole directory and removes it

-all-line(-a) = Instead of just removing the text, remove the entire line that contains it

Bash:
#In a file
remove "HUH" /system/build.prop

#In a whole directory (Recursive)
remove -r "HUH" /system

#Remove all empty lines
remove -a "" /system/build.prop
remove -r -a "" /system
-----------------------------------
EXECUTION:
  • run "variable" "file" arguments
Supports: _addon and _zip extension

Try to run a file (like a sh, binary ..) and save the result in the variable (The file automatically receive execution permissions)

Bash:
run log1 "$TMP/busybox" chmod --help

  • run_wait "time in seconds" action with any arguments
Limits the execution time of any process, including Dynamic Installer functions, doesnt affect the execution speed, it only activates if the action takes too long (Experimental)
Bash:
run_wait 5 run log1 "$TMP/busybox" echo HUH

  • run_jar "DEXED jar file" arguments
Supports: _addon and _zip extension

Allows to run .JAR files using the native Android dalvik machine (If dalvik isnt available, a warning will be given), the .JARs must be converted to .dex to work (Btw not all .jars works)
Bash:
run_jar "$TMP/apktool.jar" --help

  • run_jar_class "DEXED jar file" "class to load" arguments
Supports: _addon and _zip extension

It works like run_jar but you can specify which class of the jar should be executed

Bash:
run_jar_class "$TMP/apktool.jar" "brut.apktool.Main" --help
-----------------------------------
MANIPULATION OF STRINGS:
  • split_string "pattern separator" "line"
Separate text based on a delimiter
Bash:
split_string ':' "A B: C D E: FG"
#Result:
#A B
#C D E
#FG

split_string "word" "A Bword C D E word FG"
#Result:
#A B
#C D E
#FG

  • split_cut "separator pattern" "number" "line"
Separates the text like split_string but only returns the content up to the number of the indicated result
Bash:
split_cut ':' 2 "A B: C D E: FG"
#Result:
#A B
#C D E

split_cut "word" 1 "A Bword C D E word FG"
#Result:
#A B

  • split_extract "separator pattern" "number" "line"
Separates the text like split_string but only returns a single value that is in the number of the indicated result
Bash:
split_extract ':' 2 "A B: C D E: FG"
#Result:
#C D E

split_extract "word" 3 "A Bword C D E word FG"
#Result:
#FG

  • repeat "number" "String"
Repeat text by a specific number
Bash:
repeat 5 OLE
#Result: OLEOLEOLEOLEOLE

  • string <replace/replace_line/remove/inside/extract/complete_extract/-after-line/-before-line/escape/upper/lower/count> "string to process"
A multi-utility to easily manipulate strings

replace (UnLimited) = Replace substring-1 with substring-2

replace_line (UnLimited) = Replace the full lines that contain the substring (You can replace the line containing the text with a paragraph but not vice versa)

remove (UnLimited) = Remove some substring

inside = Extract the substring that is inside two delimiters (It only works if the string to be processed does NOT have more than one line)

extract = Extract all the content that is within two lines with the established pattern (Effectively only works if the string has multiple lines)

complete_extract = Same as extract, but includes the lines that delimit the content

force = Always return a result (by default nothing was returned if the original text was equal to the result)

-recursive (-r) = It allows to apply changes/process ALL results (not just the first one) with "remove/replace/extract/complete_extract"

-pattern (-p) = It allows to return only results with some internal string (Just with extract/complete_extract)

-after-line (UnLimited) = Add text after some line with the established pattern

-before-line (UnLimited) = Add text before some line with the established pattern

-get-after = Get all text after some pattern (Only single line)

-get-before = Get all text before some pattern (Only single line)

-file (-f) = It allows to directly load a file instead of using string

escape = Escape " ] [ \ / $ * . ^" characters that cause conflicts with some Linux utilities like sed (Being escaped they will be taken as literal characters)

upper = Convert all text to Uppercase

lower = Convert all text to Lowercase

count = It only returns the number of characters in the string


Examples:
Bash:
#Just replace the first result
string replace "A" "B" "Hi, A will be replaced with B"

#Recursive (Replace ALL)
string -r replace "A" "B" "Hi, AAAA will be replaced with B"

#Recursive (Remove ALL)
string -r remove "A" "This AAAAAA will be removed"

string inside "A" "B" "Hi A this content will be return B sayonara"

string upper "this content will be return as uppercase"

string lower "THIS CONTENT WILL BE RETURN AS LOWERCASE"

Unlimited Examples:
Bash:
#Just remove the first results
string remove "A" remove "B" remove "C" "ABDC"

#Recursive (Remove ALL)
string -r remove "A" remove "B" remove "C" "AAAAAABBBBBDDDDDCCCC"

#Recursive (Replace ALL)
string -r replace "A" "C" replace "B" "D" replace "C" "Hi" "C, AACCBBDDCC"

Extra Examples:
Bash:
example="
Hi,
Hello world
A
B
C
Okay, sayonara
Hello world 2
D
E
F
sayonara again
"

#It will returns the first result
string extract "world" "sayonara" "$example"

#Extract but verify if it have some substring
#The first result is only returned if it have "B" substring
string -p "B" extract "world" "sayonara" "$example"

#Recursive, Extract ALL pattern paragraphs inside "world" and "sayonara"
string -r extract "world" "sayonara" "$example"

#Using recursive mode it will analyze all results and using pattern will only return the content that contains "E"
string -r -p "E" extract "world" "sayonara" "$example"

#Add some string after some line
string -after-line "world" "ADD this after" "$example"

#Multi actions
string remove "A" remove "B" replace "C" "Ole" "$example"

string -after-line "world" "ADD this after" -after-line "B" "ADD this after" "$example"

#Just count characters in result
string count remove "A" remove "B" replace "C" "Ole" "$example"
-----------------------------------
CONVERSION:
  • convert "NUMBER with UNIT" "NEW UNIT"
Convert any type of units, mainly for storage units such as b, B, KB, MB, GB, TB, there is no combination limits (It returns completely decimal or integer numbers). Btw It is necessary to clarify that it supports integers and decimals in ANY conversion.

-decimals (-d) = Number of decimals allowed (if they exist)

-show (-s) = Show the sequence of conversion with its respective units (The conversion is dynamic, it uses a sequence of units until reaching the final unit)

NOTE: It is very important to respect the lowercase or uppercase of the units ("b" is not the same as "B"ytes)

Bash:
convert 100MB KB
convert 10TB MB
convert 1b TB
convert 1TB B
convert 1.56GB B
convert 1.3333333333B KB

#Save the result in a variable
result=$(convert 1005MB B)

To avoid placing the unit in each number to be converted, there are two variables convert_from and convert_to that can be defined before use.
Bash:
#Convert from this unit
convert_from=GB

#Convert to this unit
convert_to=KB

result=$(convert 15)

#It is also possible to mix the default variables with new units
convert_from=b
convert_to=MB

#Convert 10 GB to the default MB
result=$(convert 10GB)
-----------------------------------
CHECKING:
  • exist <file/folder/symlink/block/any> "file" "file" "file" "..."
It can check if one or more files/folders/symlinks/blocks or any type of file exists

Example:

Bash:
#By default if u dont include any flag it will check any type of folders/files/symlinks/blocks/..

if exist "Myfile.bin"; then
   ui_print " Okey passed"
else
   ui_print " FATAL ERROR"
fi

#For only Folders
if exist folder "FOLDER"; then
   ui_print " Okey passed"
else
   ui_print " FATAL ERROR"
fi

#For only Files
if exist file "myfile.txt"; then
   ui_print " Okey passed"
else
   ui_print " FATAL ERROR"
fi

#For only Symlinks
if exist symlink "/system/vendor"; then
   ui_print " It exists and its a symbolic link"
else
   ui_print " FATAL ERROR"
fi

#For only Blocks
if exist block "/dev/block/dm-0"; then
   ui_print " It exists and its a block (Partition)"
else
   ui_print " FATAL ERROR"
fi

#Multi-check
if exist "Myfile.bin" "OTHER.bin" "OTHER.zip" "FOLDER"; then
   ui_print " Okey passed"
else
   ui_print " FATAL ERROR"
fi

if exist symlink "/system/bin/sed" "/system/vendor"; then
   ui_print " They exist and are symlinks"
else
   ui_print " FATAL ERROR"
fi
  • is_valid "file" "file" "file" "..."
It can check if one or more files exist and are not empty
  • contains "Text" "Text" "..." "FILE"
It can check the existence of any text in a File
  • check_content "file" "file" "..." "ZIP File"
Check if one or more files exist within a ZIP file

Example:

Bash:
if check_content "file.txt" "Main.zip"; then
   ui_print " Passed "
else
   ui_print " ERROR "
fi

#Multi-check
if check_content "file.txt" "file2.txt" "folder/huh.bin" "MAIN.zip"; then
   ui_print " Passed "
else
   ui_print " ERROR "
fi
  • can_run "Binary file"
Check if a binary can run on the device
  • is_number "possible number"
Check if the string is a number (Supports decimal numbers)

  • is_hex "possible Hexadecimal string"
Check if the string is Hexadecimal

  • is_abc "possible alphabetical string"
Check if the string is alphabetical (A - Z), supports spaces and new empty lines but it will only be True if all visible characters are only alphabetic

  • is_text "possible string"
Check ANY visible character, if there are only empty spaces or new lines it will return False.

  • is_zip/is_tar/is_gzip/is_bzip/is_xz "File"
Check some file types using Hex Magic values, so the file extension doesnt matter

  • is_less/is_greater/is_equal/is_greater_equal/is_less_equal "String/Number" "String2/Number2"
Check if a number (Supports decimals) is greater/less/equal or equal less/equal greater than another, just is_equal function support text comparison
  • is64bit "FILE (binary)"
Check if a binary supports 64bits arch
  • contains_array "String" "Fully ARRAY"
To check if a array already have some value
Bash:
#First define array
test=("a" "o l e" "huh")

#Check if some value exist
#It ends with error
contains_array "test" "${test[@]}"

#It ends without error
contains_array "o l e" "${test[@]}"

  • magic_file -type "FILE TYPE" "FILE"
You can check file types using their Magic hex values, in this way it doesnt matter if the file doesnt have an extension, the check will still work (Similar to the Linux "file" tool but fully customizable)

By default, it has file types already preloaded in "META-INF/zbin/configs/file_types.config"

Already preloaded files types:


- zip, gzip, bzip, xz, tar, Z, rar, 7z, lz4
- png, jpg, webp, ico, bmp, gif, gks, rgb, pm
- mp3, ogg, wav
- mp4, avi
- msdos (Windows Executable files)
- unix (Unix Executable files)
- dex (Android Dalvik Executable .dex)
- cpio (Android Ramdisk format)
- ramdisk (Its equal to cpio)
- sparse (Android Sparse IMGs)
Bash:
magic_file -type jpg "/sdcard/Test.jpg"

magic_file -t mp4 "/sdcard/test.mp4"

magic_file -t zip "/sdcard/test.zip"

magic_file -t xz "/sdcard/test.xz"

magic_file -t dex "/sdcard/classes.dex"

-offset (-o) = Number to skip bytes (Optional)

-bytes (-b) = Bytes per line to get (Optional, by default: 100)

-line (-l) = After splitting hexadecimal code by -bytes, this number represents how many hex lines to take (Optional, by default: 1)

-type (-t) = To use any of the file types already preloaded (No additional configuration required)

-show (-s) = Prints all the Hex code that is being parsed (Only useful if more than 1 hex line is specified)

-show-line (-sl) = Prints only the Hex line that matches the Magic Hex Code (If it doesnt exist, it will only return "NULL")


Bash:
#Practical example

#With Preloaded Files Types

if magic_file -t jpg "$TMP/possible_jpg_image"; then
   ui_print "Detected JPG IMAGE!"
else
   abort "THIS IS NOT A JPG IMAGE!"
fi

if magic_file -t tar "$TMP/possible_tar_file"; then
   ui_print "Detected TAR COMPRESSED FILE!"
else
   abort "THIS IS NOT A TAR FILE!"
fi

#With Manual Mode (Using directly the Magic Hex Value)
if magic_file ffd8ffe0 "$TMP/possible_jpg_image"; then
   ui_print "Detected JPG IMAGE!"
else
   abort "THIS IS NOT A JPG IMAGE!"
fi

if magic_file -offset 257 7573746172 "$TMP/possible_tar_file"; then
   ui_print "Detected TAR COMPRESSED FILE!"
else
   abort "THIS IS NOT A TAR FILE!"
fi

  • testrw "Folder" "Folder" "..."
Test if one or more folders has write permissions
Bash:
if testrw "/system"; then
   ui_print "You can write in /system!"
else
   ui_print "Read-Only /system"
fi

if ! testrw "/system" "/vendor" "/odm"; then
   abort "One of the required partitions is Read-Only"
fi

  • testvarname "Text"
Verify if the text is valid to be used as a variable name
-----------------------------------
APK/JAR TOOLS:
  • apktool arguments
Its the standard version of the apktool so that you can configure special options of the apktool

  • sign arguments
Its the standard version of the zipsigner so that you can configure special options of the zipsigner

  • apk_package "APK file"
Get the package of any apk
Bash:
apk_package "/system/app/Example.apk"

#Save it in a variable
app_package=$(apk_package "/system/app/Example.apk")

  • apk_main "APK file"
Get the main launchable activity (if it exists) of any apk
Bash:
apk_main "/system/app/Example.apk"

#Save it in a variable
app_activity=$(apk_main "/system/app/Example.apk")

  • apk_icon "APK file"
Get the icon path inside "res" of any apk
Bash:
apk_icon "/system/app/Example.apk"

#Save it in a variable
app_icon=$(apk_icon "/system/app/Example.apk")

  • apk_launch "APK file or its Package" <Activity to launch>
Launch the main launchable activity (or a specific activity) of some PRE-installed APP on the device (when its already booted)

NOTE: The PRE-installed application refers that the APP must already be installed on the device prior to its launch.

Bash:
#Try to find the main lauchable activity and launchs it
apk_launch "/system/app/Example.apk"

#Launch "com.app.main" activity of "/system/app/Example.apk"
apk_launch "/system/app/Example.apk" "com.app.main"

#Launch "com.android.systemui.DessertCase" of SystemUI.apk (Using the package directly)
apk_launch "com.android.systemui" "com.android.systemui.DessertCase"

  • decode_xml "XML File"
To decode AndroidManifest.xml (Does not support all XML)
Bash:
decode_xml "$TMP/AndroidManifest.xml"

  • encode_xml "XML File"
To encode AndroidManifest.xml or other predecoded APK XMLs (Supports any other xml)
Bash:
encode_xml "$TMP/AndroidManifest.xml"

  • find_apk "APK package" "APK Package" "..." "PATH to find"
Allows to find multiple APKs using its package in a specific path (it will return the exact path of those apks)

By default splits and overlays are ignored

Bash:
find_apk "com.android.systemui" "com.android.settings" "com.sec.android.app.launcher" /system

#Or recursive find (It will result in all apks with a similar pattern in the package):

find_apk -r "com.google" /system
-include-overlays (-io) = Include overlays (.APK)
-include-splits (-is) = Include splits (.APK)


  • patch_apk "FOLDER to inject" ".APK file" zipalign/sign
Supports: _addon and _zip extension

Its a portable version of vrtheme, it allows you to inject the contents of a folder into an .APK, additionally you can specify if you want to sign (Just works if dalvikvm available) or zipalign the apk

Bash:
patch_apk "FOLDER" SystemUI.apk sign

patch_apk "FOLDER" SystemUI.apk zipalign

  • make_overlay "Priority" "Destination Package" "FOLDER to build as res" "Result"
Supports: _addon and _zip extension

You can compile overlays (Layers that can alter values of other .APKs) only for Android 9+, but you CANNOT include images due to the limitations with the experimental apktool build for Dynamic Installer (See bugs section)

Priority = Priority level, if there are several overlays that alter the same value, the one with the highest priority number will be used

Package = Package of the app to which the overlay is directed

FOLDER = Folder in which the "res" to be used is located

Result = Resulting overlay path (Output)

Bash:
make_overlay 1 com.android.systemui "FOLDER" "/system/vendor/overlay/test.apk"
-----------------------------------
APK/JAR ADVANCED TOOL KITS:
  • dynamic_apktool -decompile(-d) "FILE" -framework(-f) "FILE" -add(-a) "FILE/FOLDER" -command(-c) "EXTRA APKTOOL OPTIONS to decompile" -output(-o) "DEST"

  • dynamic_apktool -preserve-signature(-ps) -recompile(-r) "FILE" -framework(-f) "FILE" -add(-a) "FILE/FOLDER" -command(-c) "EXTRA APKTOOL OPTIONS to recompile" -output(-o) "DEST" -sign(-s) -zipalign(-z)
-decompile = APK or .JAR to decompile

-add = FOLDERs or FILEs to add in the result

-framework = framework-res.apk to use

-output = Full path to results

-recompile = FOLDER to recompile

-sign = Sign the result (recompile)

-zipalign = Zipalign the result (recompile)

-command = Allows to add extra apktool.jar options

-preserve-signature = Try to keep the original META-INF and AndroidManifest.xml (recompile)

-no-api = Disable automatic specification of the device API

-no-extras = Disable original resource checking/adding (decompile)

-use-baksmali = Set an external baksmali.jar (DEXED) instead of the native apktool one (decompile)

-use-smali = Set an external smali.jar (DEXED) instead of the native apktool one (recompile)



Bash:
dynamic_apktool -decompile "Test.apk" -o "/sdcard/Test" -add "/sdcard/folder"

dynamic_apktool -no-extras -use-baksmali "$TMP/custom.jar" -decompile "Test.apk" -o "/sdcard/Test" -add "/sdcard/folder"

dynamic_apktool -recompile "/sdcard/Test" -add "/sdcard/testfolder" -add "/sdcard/Test/original/META-INF" -a "/sdcard/test.txt" -zipalign -sign

  • smali_kit -dir(-d) "FOLDER" -file(-f) "FILE" -method(-m) "METHOD to find" -replace(-r) "Full NEW METHOD" -replace-in-method(-rim) "OLD STRING" "NEW STRING" -delete-in-method(-dim) "STRING to remove" -remake(-re) "NEW INTERNAL CONTENT" -after-line(-al) "LINE" "STRING to add after" -before-line(-bl) "LINE" "STRING to add before" -name(-n) "PATTERN NAME of .smali FILEs" -static-name(-sn) "EXACTLY name of .smali" -limit(-l) "LIMIT NUMBER OF RESULTS" -check(-c) -delete-method(-dm) -print-path(-pp)
-dir = PATH to find .smali methods

-file = File to find .smali methods

-method = Pattern .method name to find


-print-path = Just print the paths of all .smali files with that .method

-replace = Replace ALL found .method

-replace-in-method = Replace STRING of .method found with STRING2 (STRING to STRING2)

-delete-in-method = Delete STRING of .method found

-delete-method = Remove whole .method found

-remake = Replace only the internal content of the .method found

-after-line = Add a STRING after the specified line inside the found .method

-before-line = Add a STRING before the specified line inside the found .method

-name = Pattern that .smali files must have

-static-name = Exactly name that ONE .smali must have

-limit = The amount of results can be processed

-check = Report modified files or if there were no changes

Bash:
REPLACE="
.method public static isTima()Z
    .locals 1

    const/4 v0, 0x1

    return v0
.end method
"

TEST="
    .locals 1

    const/4 v0, 0x4

    return v0
"

smali_kit -check -method "isTima" -d "FOLDER" -replace "$REPLACE"

smali_kit -method "isTima" -dir "FOLDER" -replace-in-method "const/4 v0, 0x1" "const/4 v0, 0x0"

smali_kit -method "isTima" -d "FOLDER" -remake "$TEST"

smali_kit -method "isTima" -f "file.smali" -replace "$REPLACE"
-----------------------------------
EXTRA TOOLS:
  • adb arguments
Its the standard version of the ADB so that you can configure special options
-----------------------------------
LOGGING:
  • startlog "PATH/file"
Create a file that will be used to save the contents with "savelog"
  • savelog "Text" "Text" "..."
Send text to file created with "startlog"
  • endlog
To stop "savelog" that started with "startlog" (When logging is finished, any text attempted to be sent with "savelog\echolog\printlog" will be ignored)
  • echolog "Text" "Text" "..."
The text is printed both in the general log (Text as Error - Stderr), and in the file created by "startlog"
  • printlog "Text" "Text" "..."
The text is printed both on the screen (ui_print), and in the file created by "startlog"
-----------------------------------
DYNAMIC VARIABLES:
  • setdefault "variable" "string"
Its equivalent to defining a normal variable (myvar = b) but it allows dynamic variable names
Bash:
var_name="test"

#Since the content of var_name is "test", the name of the new variable is "test"
setdefault $var_name "just test"
ui_print "$test"

  • checkvar "variable" "variable" "..."
Check multiple variables and return the value of those that are defined
Bash:
var_contents=$(checkvar var1 var2 var3)

#Very useful to obtain the content of variables with dynamic names
number=4
setdefault var$number "o l e"
var_content=$(checkvar var$number)

  • filtervar "variable" "variable" "..." "pattern"
Check multiple variables and look for a matching pattern in the value of these variables (the complete value of those variables is returned)
Bash:
matched_content=$(filtervar var1 var2 var3 "find this")
  • defined "variable" "variable" "..."
Check if multiple variables are defined
Bash:
if defined var1; then
   ui_print "Success"
fi

#Multi check
if defined var1 var2 var3; then
   ui_print "Success"
fi

#Dynamic var names
number=4
setdefault var$number "o l e"
if defined var$number; then
   ui_print "Success"
fi
  • undefined "variable" "variable" "..."
Check if multiple variables are not defined
Bash:
if undefined var1; then
   ui_print "Empty var1"
fi

#Multi check
if undefined var1 var2 var3; then
   ui_print "Empty var1, var2 and var3"
fi

#Dynamic var names
number=4
setdefault var$number "o l e"
if undefined var$number; then
   ui_print "Empty var$number"
fi
-----------------------------------
CREATE FILES/FOLDERS:
  • create_dir "NEW folder" "NEW folder" "..."
You can create new folders (if needed) and also check the Read/Write permissions in them

  • create_file "NEW file" "NEW file" "..."
You can create new files (or overwrite already existing files) - The necessary folders are created automatically

  • make_zip -script "Text" -type <recovery/magisk> -output "Result ZIP"
You can create new ZIPs using your current version of the Dynamic Installer as a base

-script (-s) = The Script for the New ZIP (In text format - string)

-type (-t) = The type can be "recovery" or "magisk" and it helps to build the ZIP

-head (-h) = The setdefaults header (In text format - String) to use in the updater-script when using -type "magisk"

-include (-i) = Include files or folders in the root of the ZIP

-magisk-include (-mi) = Include files or folders in Magisk space

-preserve-addons (-pa) = Keep the META-INF/addons contents of the current ZIP


-preserve-magisk (-pm) = Keep the META-INF/com/google/android/magisk contents of the current ZIP

-output (-o) = Path for the resulting ZIP

Bash:
script='
#-----------Dynamic Installer Configs-----------#
#The #MAGISK tag is required, dont remove it
#MAGISK
setdefault magisk_support on
setdefault import_addons off
setdefault apex_mount off
setdefault extraction_speed default
setdefault permissions "0:0:0755:0644"
setdefault devices off
#-----------------------------------------------#
#Your script starts here:

mount_all
delete /system/just_test
umount_all
'

make_zip -script "$script" -type recovery -include "FOLDER" -include "FILE" -output "/sdcard/Test.zip"
-----------------------------------
INSTALL FILES:
  • update ".img/.img.xz/.img.gz/.bin/..." "partition" <exit number>
Supports: _addon and _zip extension

Try install img or bin files (system.img super.img boot.img optics.img prism.img param.bin ...)

-xz = To install a .xz compressed File

-gz = To install a .gz compressed File

-sparse = To install Sparse IMGs instead of RAW IMGs (Only for 64bit devices)

exit number = If "1" is used, it will be evaluated if the installation of the file was successful, otherwise everything will be aborted

Bash:
#Update system
update /sdcard/system.img $(find_block system)

#Using _zip extension
#Update using file inside ZIP
update_zip system.img $(find_block system)

#Update using .xz compressed file
update_zip -xz vendor.img.xz $(find_block vendor)

#Update using .gz compressed file
update_zip -gz boot.img.gz $(find_block boot)

#Update using an IMG Sparse
update_zip -sparse system.img $(find_block system)

#Update using an IMG Sparse additionally compressed as .xz
update_zip -sparse -xz system.img.xz $(find_block system)

#Update but ABORT the ZIP installation in case of error
update_zip -xz super.img.xz "$(find_block super)" 1

  • flash "variable" "zip file" <print>
Supports: _addon and _zip extension

Try to install a new ZIP file within the current installation and the result is saved in the variable, also you can include a third optional argument "print" to allow the new ZIP to print text on Recovery.

Bash:
#External ZIP
flash log1 "/sdcard/custom.zip"

#Internal ZIP
flash_zip log_name "folder/test.zip"

#Allow text printing in recovery
flash_zip log_name "folder/test.zip" print

#...

  • dynamic_install "path" "path"
Similar to package_extract_dir but only works with existing paths outside the ZIP
Bash:
dynamic_install "/vendor" "$MODPATH/system/vendor"

  • dynamic_install_apk "path outside zip" "path outside zip"
Find all existing APKs in the first folder in the second folder (Not by name, by package), in case the second folder already contains one of the APKs, it will be replaced keeping the original path and name. if it does not exist, the directory will be created according to the first folder

You can also redirect the destination path (Compare 2 directories with .APKs, perfect for Magisk modules)

NOTE: By default overlays are ignored but APK Splits are included with the main app

-no-replace(-nr) = Avoid replacing existing APKs
-no-add(-na) = Avoid adding new APKs
-include(-i) = Add extra folders/files references to add in the destination of the APKs - UnLimited
-remove-oat = Remove all oat folders of old apks (in the destination)

Bash:
#Simple usage
dynamic_install_apk "FOLDER" "/system"

#Include extra files/Folders
#The "oat" and "lib" folders will be included in the destination of all APKs
dynamic_install_apk -include "oat" -include "lib" "FOLDER" "/system"

#Redirect results
dynamic_install_apk "FOLDER" "/system" -output "/sdcard/results"

  • apk_install ".APK or .APKM" ".APK or .APKM" "..."
Install multiple .APK or .APKM (ApkMirror) files, .APKM files are a ZIP with the main .APK and Splits required for each device, these Splits will be filtered and included in the installation automatically based on device specifications, however , you are free to include additional Splits

To include Splits in the .APK installation:

Bash:
#Install single .APK with multiple external Splits
apk_install "$TMP/Main.apk:$TMP/Split.apk:$TMP/Split2.apk"

#Multi .APK installation with multiple external Splits
apk_install "/sdcard/Main.apk:$TMP/Split.apk:$TMP/Split2.apk" "/sdcard/Main2.apk:$TMP/Split3.apk:$TMP/Split4.apk"

To include additional Splits in the .APKM installation:

NOTE: For .APKM you can just include the name of the Split and it will try to extract from the .APKM instead of taking it from an external path

Bash:
#Install single .APKM with multiple additional external Splits
apk_install "$TMP/Main.apkm:$TMP/Split.apk:$TMP/Split2.apk"

#Multi .APKM installation with multiple additional external Splits
apk_install "/sdcard/Main.apkm:$TMP/Split.apk:$TMP/Split2.apk" "/sdcard/Main2.apkm:$TMP/Split3.apk:$TMP/Split4.apk"

#Include additional Splits that exist within the .APKM
apk_install "$TMP/Main.apkm:split_config.ru.apk:split_voip.apk"


  • apk_install_recursive "FOLDER" "FOLDER" "..."
Install all .APK/.APKM that are inside a folder, also allows creating subfolders to group specific .APK/.APKM with additional splits

/sdcard/myapps

Bash:
/sdcard/myapps/Normal.apk
/sdcard/myapps/Normal2.apkm
/sdcard/myapps/subfolder/Main.apk
/sdcard/myapps/subfolder/split.apk
/sdcard/myapps/subfolder/split2.apk

When performing the recursive installation in this example, only "Main.apk" will be installed together with the .APKs that accompany it (Splits), because it is the only one that is grouped in a subfolder
Bash:
apk_install_recursive "/sdcard/myapps"

  • unify_path "First PATH" "Second PATH"
To compare one folder with another, this includes a comparison of files that already exist in both folders, if they are not the same, they are replaced or added to the second folder
Bash:
#Compare folder TEST with TEST2
#Fix ALL differences in TEST2
unify_path "/sdcard/TEST" "/sdcard/TEST2"
-----------------------------------
HEXADECIMAL PATCH:
  • hex_patch "Hex code to find" "New Hex code" "file"
Allows to substitute Hex fragments within files (perfect for patching)
Bash:
hex_patch "74696d65" "00696d65" /system/bin/testfile

  • hex_search <include> "Hex code to find" "file"
Allows to search Hexadecimal lines within files (The resulting line is returned)

Additional digits can be included before or after the found hex:

Bash:
hex_search -include "after:10 before:5" "74696d65" /system/bin/testfile
##If the Hex code is found, it will return the result together with 10 previous digits and 5 extra digits at the end of the string

  • hex_check "Hex code to find" "file"
Checks for the existence of a Hexadecimal fragment within a file
Bash:
hex_check "74696d65" /system/bin/testfile
-----------------------------------
DYNAMIC PARTITIONS (SUPER):
  • checksuper "SUPER Partition or RAW .img"
To check if a image/partition is a SUPER image in record time
Bash:
#Check SUPER partition
checksuper $(find_block super)

#Check SUPER image
checksuper "/sdcard/super.img"
  • get_offset "Subpartition Name" "SUPER Partition or RAW .img"
To get the offset of any subpartition inside a SUPER partition/image in record time
Bash:
get_offset system $(find_block super)

#For A/B
get_offset system$slot $(find_block super)
  • get_group "Subpartition Name" "SUPER Partition or RAW .img"
To get the group of any subpartition inside a SUPER partition/image in record time
  • get_total_size "SUPER Partition or RAW .img"
To get the total size of all subpartitions inside a SUPER partition/image
Bash:
get_total_size $(find_block super)
  • get_all_subparts "SUPER Partition or RAW .img"
To get the name of all subpartitions of an img/partition (SUPER)
Bash:
get_all_subparts $(find_block super)
  • start_loop "Subpartition Name" "SUPER Partition or RAW .img"
To make new mount point of any subpartition inside a SUPER partition/image (Designed for new Virtual Dynamic Partitions)

The new mount point (Loop device) is assigned in $LOOP variable

Bash:
#Make new point with system inside SUPER .img
start_loop system /sdcard/super.img
system_point="$LOOP"

#Make new point with vendor inside SUPER partition
start_loop vendor $(find_block super)
vendor_point="$LOOP"

#Make new point for A/B devices
start_loop system_a $(find_block super)
system_point="$LOOP"
  • end_loop
To end previously made mount point with "start_loop" based on the order of creation (It works like "end_tmp")
Bash:
#First make multiple Mount Points
start_loop system_a /sdcard/super.img
system="$LOOP"

start_loop vendor_a /sdcard/super.img
vendor="$LOOP"

start_loop product_a /sdcard/super.img
product="$LOOP"

#Now to finish NEW POINTS
end_loop
end_loop
end_loop

  • unlock_all <Partition/IMG>
To try convert all internal subpartitions of SUPER to Read/Write on-fly

NOTE: It is not necessary to specify the partition/IMG (Super of the device is used by default), but you can do it if you need it

  • unlock "Subpartition Name" <Partition/IMG>
To convert specific subpartition of SUPER to Read/Write (Like unlock_all doesnt work in some cases)

NOTE: It is not necessary to specify the partition/IMG (Super of the device is used by default), but you can do it if you need it

Bash:
#For A/B u need to use $slot

#Try enable RW in system (Active slot)
unlock system$slot

#Specific slot
unlock system_a

#Try enable RW in vendor (Active slot)
unlock vendor$slot

#Try enable RW in vendor from external SUPER.img
unlock vendor_a /sdcard/super.img
-----------------------------------
PROTECT YOUR CODE:
  • obfuscate "Text"
Allows you to encode the shell script code (or Dynamic Installer scripts), keeping it working but making it difficult for common users to read (you can mix obfuscated code with readable code)

-base64 (-b64) = This option ensures the preservation of all the original code, encoding the code in base64 before being obfuscated, this implies a greater weight (Only use if the default obfuscation gives bad results)

NOTE: For its use, it is recommended to load the Dynamic Installer in Termux, through the "Test Mode" mentioned in the first thread

WARNING: Never obfuscate the default "setdefault"s in the DI updater-script (they need to be readable for the installation process)

EXTRA WARNING: The "off_readonly" lines cannot be obfuscated either, as they are read and interpreted during installation

Example:1 (Note the use of single quotes):

Bash:
#Obfuscate commands directly (Default mode)
obfuscate ' ui_print "All this will be obfuscated"
ui_print "Mounting partitions..."
mount_all ' > /sdcard/obfuscated.sh

#With Base64 Mode
obfuscate -b64 ' ui_print "All this will be obfuscated"
ui_print "Unmounting partitions..."
umount_all ' > /sdcard/obfuscated.sh

Example:2 (Obfuscate files):
Bash:
obfuscate "$(cat /sdcard/original.sh)" > /sdcard/obfuscated.sh

#You can also use this syntax:
cat /sdcard/original.sh | obfuscate > /sdcard/obfuscated.sh

#With Base64 Mode
cat /sdcard/original.sh | obfuscate -b64 > /sdcard/obfuscated.sh

Example:3 (Mix obfuscated code with readable code):
Bash:
obfuscate '   ole="Hi, this action will be obfuscated"  ' > /sdcard/obfuscated.sh
Obfuscated code:
Bash:
cjifh="=";gegb=" ";bjbij=",";iagg=\";bhbcb="a";ichh="b";dafa="c";chaa="d";hb="e";cjdeb="f";gfah="H";bjac="i";caddf="l";bgfgf="n";bhcj="o";daafj="s";cdefi="t";cdaib="u";caedc="w";bgacd="v";${hb}${bgacd}${bhbcb}${caddf}${gegb}"${gegb}${gegb}${gegb}${bhcj}${caddf}${hb}${cjifh}${iagg}${gfah}${bjac}${bjbij}${gegb}${cdefi}h${bjac}${daafj}${gegb}${bhbcb}${dafa}${cdefi}${bjac}${bhcj}${bgfgf}${gegb}${caedc}${bjac}${caddf}${caddf}${gegb}${ichh}${hb}${gegb}${bhcj}${ichh}${cjdeb}${cdaib}${daafj}${dafa}${bhbcb}${cdefi}${hb}${chaa}${iagg}${gegb}${gegb}"
This would print "Hi, this action will be obfuscated"
Bash:
cjifh="=";gegb=" ";bjbij=",";iagg=\";bhbcb="a";ichh="b";dafa="c";chaa="d";hb="e";cjdeb="f";gfah="H";bjac="i";caddf="l";bgfgf="n";bhcj="o";daafj="s";cdefi="t";cdaib="u";caedc="w";bgacd="v";${hb}${bgacd}${bhbcb}${caddf}${gegb}"${gegb}${gegb}${gegb}${bhcj}${caddf}${hb}${cjifh}${iagg}${gfah}${bjac}${bjbij}${gegb}${cdefi}h${bjac}${daafj}${gegb}${bhbcb}${dafa}${cdefi}${bjac}${bhcj}${bgfgf}${gegb}${caedc}${bjac}${caddf}${caddf}${gegb}${ichh}${hb}${gegb}${bhcj}${ichh}${cjdeb}${cdaib}${daafj}${dafa}${bhbcb}${cdefi}${hb}${chaa}${iagg}${gegb}${gegb}"

ui_print "$ole"
-----------------------------------
OTHER STUFF:
  • fprint "file"
Supports: _addon and _zip extension

Print the content of a file in the recovery or magisk


  • import_bin "File"
Supports: _addon and _zip extension

Allows you to import new files to the Dynamic Installer work environment (Perfect for adding extra binaries, they can be used directly in your scripts after an import)


  • getsize "file"
Return the size of any file (In Bytes)

  • getblocks
Convert all existing partitions to variables ($system, $vendor, $boot, $vbmeta)
  • getbins
Returns all available binaries (commands) and also generates a $bins variable that contains all
  • copy "original" "dest"
Copy any file or folder (Dest folders auto-created)

  • move "original" "dest"
Move any file or folder (Dest folders auto-created)

  • echo2 "Text"
Print text as Error - Stderr (For example, the text doesnt appear on the Magisk installation screen but yeah in the LOG)

  • calc <Operations>
To make basic operations like addition, subtraction, division, exponents (The result will not always be an integer or decimal, results with scientific notation are accepted)
Bash:
result=$(calc "5 + 5")

result=$(calc "20^45 * ( 30 / 5 )")

  • int <Number or Operations>
To convert any number to an integer or ensure an operational result as an integer
Bash:
#Will return "5" without rounding
result=$(int "5.5")

#Will return "62" without rounding
result=$(int "(5^3)/2")

  • float <Number or Operations>
To convert any number to an floating-point number, or ensure an operational result as an floating-point number
Bash:
#Will return "5.500000000" with 9 decimals by default
result=$(float "5.5")

#Will return "62.500000000" with 9 decimals by default
result=$(float "(5^3)/2")

#How to increase decimal parts?
setdefault float_length 10
#Will return "5.5000000000" with 10 decimals
result=$(float "5.5")

#How to decrease decimal parts?
setdefault float_length 2
#Will return "5.50" with 2 decimals
result=$(float "5.5")

  • round <Number or Operations>
To round any number to only integers or to ensure an operational result as an rounded integer
Bash:
#Will return "6" with rounding
result=$(round "5.5")

#Will return "63" with rounding
result=$(round "(5^3)/2")

  • change_bin "Binary name" "Binary name" "..."
By default the Dynamic Installer uses the native Busybox binaries (with the exception of a few like "xxd" and "xz"), however, these binaries are trimmed versions, where any external version generally provides more options. The change_bin function can find for and change any binary currently in use to any other available external version.

-while (-w) = Allows detailing that the binary must support a specific option (Although there are external versions available, if they do not support the established option, they will not be considered)

NOTE: The changes are random, that is, if three binaries with the same name are found, a random change will be made, and it can be any of these three, the only condition is that it is different from the one currently used (For each use of "change_bin" you will get a different result, with chances of going back to the original binary)

EXTRA NOTE: If the full path of an existing file is specified and it is different from the current binary, change_bin will make the change with that file ignoring any of the other options (it will take the file name as reference)

Bash:
#Try using some other version of "chmod"
change_bin "chmod"

#Change the "unzip" binary only to another version that supports the "-p" option
change_bin "unzip" -while "-p"

#Muti change
change_bin "chmod" "unzip" "find"

#Restore to Original Busybox binaries
#$l is the path where all the native DI binaries are
change_bin "$l/chmod"
 
Last edited:

BlassGO

Senior Member
Jan 19, 2021
161
383
SCRIPT EXAMPLES:

  • ROM Installation
NOTE: The use of RAW IMGs is recommended (more direct and faster installation) but it is also possible to use Sparse IMGs (Only for 64bit devices)

META-INF/com/google/android/updater-script

Bash:
#-----------Dynamic Installer Configs-----------#
#The #MAGISK tag is required, dont remove it
#MAGISK
setdefault magisk_support on
setdefault ensure_root on
setdefault import_addons off
setdefault apex_mount off
setdefault extraction_speed default
setdefault permissions "0:0:0755:0644"
setdefault devices off
#-----------------------------------------------#
#Your script starts here:

ui_print "--------------------------------"
ui_print "          ElementaryOS          "
ui_print "           OneUI 3.1            "
ui_print "--------------------------------"
ui_print "           by BlassGO           "
ui_print "--------------------------------"
ui_print " "

ui_print "-------------------"
ui_print " UNMOUNT           "
ui_print "-------------------"
ui_print " "
umount_all

ui_print "-------------------"
ui_print " INSTALLING PARAM  "
ui_print "-------------------"
ui_print " "
update_zip param.bin "$(find_block up_param)"

ui_print "-------------------"
ui_print " INSTALLING KERNEL  "
ui_print "-------------------"
ui_print " "
update_zip boot.img "$(find_block boot)"

ui_print "-------------------"
ui_print " INSTALLING OMC    "
ui_print "-------------------"
ui_print " "

update_zip optics.img "$(find_block optics)"

#Using a Sparse IMG
update_zip -sparse prism.img "$(find_block prism)"

#Installing RAW SUPER (system, vendor, product, odm)
ui_print "-------------------"
ui_print " INSTALLING SUPER  "
ui_print "-------------------"
ui_print " "
#Extra compressed as XZ
update_zip -xz super.img.xz "$(find_block super)"

ui_print "-------------------"
ui_print " DONE              "
ui_print "-------------------"
ui_print " "
  • Only Extraction
META-INF/com/google/android/updater-script
Bash:
#-----------Dynamic Installer Configs-----------#
#The #MAGISK tag is required, dont remove it
#MAGISK
setdefault magisk_support on
setdefault ensure_root on
setdefault import_addons off
setdefault apex_mount off
setdefault extraction_speed default
setdefault permissions "0:0:0755:0644"
setdefault devices off
#-----------------------------------------------#
#Your script starts here:

ui_print " "
ui_print " -- Mounting partitions..."
mount_all

ui_print " -- Extracting mods..."
package_extract_dir system /system
package_extract_dir vendor /vendor
package_extract_dir system_ext /system_ext

ui_print " -- Unmounting ALL"
umount_all

ui_print " "
ui_print " -- Done"
ui_print " "
  • Magisk Module
NOTE: You can add folders directly in META-INF/com/google/android/magisk and they will be added automatically in your module

META-INF/com/google/android/magisk/customize.sh

Bash:
#Magisk modules use $MODPATH as main path
#Your script starts here:

ui_print "-------------------------------------------------- "
ui_print " MODS for Android                  "
ui_print "-------------------------------------------------- "
ui_print " by @BlassGO      |   Version: 1.0                 "
ui_print "-------------------------------------------------- "
ui_print " "

ui_print " -- Installing MODS in /system"
package_extract_dir system "$MODPATH/system"

ui_print " -- Installing MODS in /vendor"
package_extract_dir vendor "$MODPATH/system/vendor"

ui_print " -- Installing MODS in /product"
package_extract_dir product "$MODPATH/system/product"

ui_print " -- Fixing Contexts"
set_context /system "$MODPATH/system"

ui_print " "
ui_print " -- Done"
ui_print " "
  • Magisk Module (APKTOOL)
NOTE: The dynamic_apktool only decodes ALL classes.dex, no content of "res" is directly editable (Check the BUGS of the Dynamic Installer)

META-INF/com/google/android/magisk/customize.sh

Bash:
#Magisk modules use $MODPATH as main path
#Your script starts here:

enable='
    .locals 1

    const/4 v0, 0x1

    return v0
'

ui_print " -- Finding SystemUI.apk"
APK=$(find_apk com.android.systemui /system)

ui_print " -- Checking results"
if undefined APK; then
   abort " CANT FIND: SystemUI.apk"
fi

ui_print " -- Decompiling SystemUI.apk"
dynamic_apktool -decompile "$APK" -output "$TMP/decompiled"

ui_print " -- Patching SystemUI.apk"
smali_kit -check -method "isUnlockingWithBiometricAllowed" -remake "$enable" -dir "$TMP/decompiled"

ui_print " -- Recompiling SystemUI.apk"
dynamic_apktool -preserve-signature -recompile "$TMP/decompiled" -output "$MODPATH$APK"

ui_print " -- Checking results"
if ! is_valid "$MODPATH$APK"; then
   abort "Some error in the APK recompilation"
fi

ui_print " -- Fixing Context "
set_context "$APK" "$MODPATH$APK"

ui_print " "
ui_print " -- Done "
ui_print " "
  • Magisk and KernelSU Module
NOTE: You can add folders directly in META-INF/com/google/android/magisk and they will be added automatically in your module (for KernelSU and Magisk)

META-INF/com/google/android/magisk/customize.sh

Bash:
#Magisk modules use $MODPATH as main path
#Your script starts here:

ui_print "-------------------------------------------------- "
ui_print " MODS for Android                  "
ui_print "-------------------------------------------------- "
ui_print " by @BlassGO      |   Version: 1.0                 "
ui_print "-------------------------------------------------- "
ui_print " "

if [ $CUSTOM_SETUP = 0 ]; then
   ui_print " - Installation by MAGISK "
else
   ui_print " - Installation by KernelSU (or something else)"
fi

ui_print " -- Installing MODS in /system"
package_extract_dir system "$MODPATH/system"

ui_print " -- Installing MODS in /vendor"
package_extract_dir vendor "$MODPATH/system/vendor"

ui_print " -- Installing MODS in /product"
package_extract_dir product "$MODPATH/system/product"

ui_print " -- Fixing Contexts"
set_context /system "$MODPATH/system"

ui_print " "
ui_print " -- Done"
ui_print " "
 
Last edited:

BlassGO

Senior Member
Jan 19, 2021
161
383
CHANGELOG:
[CHANGELOG 1.1]
-- dynamic_install_apk now support redirection of output, APK splits, APK lib folder and -no-replace -no-add flags

[CHANGELOG 1.2]
-- Improvements and new functions for smali_kit (Change in syntax of -replace-in-method)

[CHANGELOG 1.3]
-- Small improvements to Mounting partitions
-- smali_kit now ignores abstract methods
-- dynamic_apktool now supports extra commands for apktool
-- Now u can use apk_pkg as an equivalent of apk_package


[CHANGELOG 1.4]
-- The Dynamic Installer was restructured for greater optimization and organization
-- A new setdefault "fast_mode" has been added that allows a much faster execution (When activated you will not have the variables of the partitions $system/$vendor/$boot/... and the variables $bins/$all_partitions)
-- A new "replace" function was added, check the Actions section / Editing Files
-- filetype function was removed


[CHANGELOG 1.4-b]
-- Fixed a fatal bug inside auto_mount_partitions Ooof

[CHANGELOG 1.5]
-- Maintenance, fixed and optimized functions
-- update_file_string and add_lines_string now support any type of strings
-- If you use " " an empty space with add_lines_string a new empty line will be added to the file
-- add_lines_string now supports -after-line and -before-line infinitely, you can add text before or after a specific line
-- ui_print now supports more situations, you can print several lines (ui_print "line1" " " "line3") or a whole paragraph(ui_print "$paragraph") even from Recovery
-- New function:
force_update_file_string

[CHANGELOG 2.0]

New functions:

string >> Advanced and easy string manipulation
run_wait >> Limit the execution time of any process (Includes Dynamic Installer functions)
is_valid >> Check if files exists and non-empy
is_number >> Check if is a number
check_content >> Check if a file exists inside a .ZIP
getsize >> Return the size of any file
can_run >> Check if a binary can run on the device
exist >> Check if files or folders exists
repeat >> Repeat text by a specific number
copy >> Force copy files and folders
move >> Force move files and folders
echo2 >> Print text as error (For example, the text doesnt appear on the Magisk screen but yeah in the LOG)
is_zip/is_tar/is_gzip/is_bzip/is_xz >> Check type of some files

Improved:
hex_search/hex_check/hex_patch
>> Important fixes and new functions, full support for hexadecimal manipulation

dynamic_apktool >> Some fixes and now supports -preserve-signature for APKs and JARs

update_file/update_file_string/force_update_file/force_update_file_string >> Important fixes and now supports more XML cases and delimiters (-delim flag)
savestate >> Fixed some errors
replace >> Fixed some errors

Extra Fixes:
-- Fixed infinite loop when using try_mount with uncommon partitions

New variables:
$TMP2
>> Multiple Dynamic Temp Spaces (start_tmp/end_tmp)

New setdefaults:
setdefault apex_mount >> Now you can control if you want to mount APEX or not (If you use it in "off" the mounting will be much faster)


[CHANGELOG 2.1]
-- Slight errors fixed
-- Now most of the Dynamic Installer actions support false/positive results (You can use an "if" condition with these actions)
-- New function: make_overlay was added


[CHANGELOG 2.2]
-- A fatal error was fixed in try_mount
-- Improved functions for updating .props and .xml (update_file_string/update_file/...)
-- Removed setdefault results (Deprecated)


[CHANGELOG 2.3]
-- Fixed defined/undefined/checkvar
/filtervar functions with some variables
-- replace function now supports any pattern to find and replace with -recursive flag (Not just whole words)
-- add_lines now support -after-line and -before-line (Unlimited) and multiple files to add (Unlimited)
-- umount_all has been improved to avoid "Cannot mount /partition" errors on some devices after installation

[CHANGELOG 2.6]

- Maintenance (Some fixes and improvements)
- Removed setdefault fast_mode (Deprecated)
- New "Test Mode", now u can test some Dynamic Installer functions in Termux on Android
- Improved all update_file functions (update_file_string/force_update_file/..)


[CHANGELOG 2.7]
- /system_root as RW (Read/Write), you will be able to make changes inside, previously it was mounted in Read/Only and only specific sections like /system in RW

- smali_kit now supports a search mode for .smali files that have a .method (-print-path)
- smali_kit now can remove whole .methods (-delete-method)

- Fixed "Test Mode" (Execution problems
)

[CHANGELOG 2.7-b3]
- Small but important fixes
- Replaced "flash" function with "force_flash" (So now just exist "flash" to install extra ZIPs)
- The correct assignment of permissions was ensured with functions that gave them automatically (package_extract_dir, package_extract_file, dynamic_install_apk, .....)


[CHANGELOG 3.0]

News:

  • Finally support dalvikvm from Recovery Android 11+ (Beta - You can use apktool and other Smali tools) - setdefault apex_mount is needed
  • Many functions were improved to work in more situations
Fixes:
  • Fixed issues adding paragraphs or spaces directly with some flags like -after-line -before-line (add_lines_string/smali_kit/...)
  • Fixed package_extract_dir with file names with spaces
  • Fixed error loading .sh that have names with spaces when activating setdefault run_addons
Improved:
  • find_apk now supports infinite packages to find (find_apk "package1" "package2" "..." "PATH")
  • dynamic_install_apk now supports "-include" flag to include extra files/folders with the apks and "-remove-oat" to remove all oat folders in the destination
  • string function now supports -after-line and -before-line
  • getbins and getblocks functions reformed (were previously deprecated)
  • setdefault devices format improved
New functions:
  • is_greater/is_equal/is_less (Comparison)
  • make_zip (To make functional ZIPs using ur current Dynamic Installer as base)

New variables:
  • $chipname that will allow to identify snapdragon/exynos/mediatek/kirin chipsets

[CHANGELOG 3.1]
  • Improved chipset detection for $chipname variable
  • copy and move functions now can create the destination folders
  • defined and undefined functions now supports infinite variables to check
  • New function set_context to use the contexts of one path in another, the best contexts are logically evaluated for ALL folders and files, although you can also assign the context of a single file to another (Perfect for Magisk modules)
  • New function eval_context to get the most common context in a path (It eval the common results) or just get the context of a single file
  • Now by default find_apk ignores splits and overlays unless you enable it manually with "-include-splits" or "-include-overlays"
  • try_mount can now mount the partitions specifically in Read/Write or Read/Only (By default both are used) with "-read-write" and "-read-only" flags, it also includes "-remount" to unmount the partitions before mounting
  • update_file/update_file_string/force_update_file/.... now supports "-no-spaces" flag to prevent auto-detection of spaces in new lines

[CHANGELOG 3.2]
  • Some fixes
  • New function patch_fstab to patch fstab properties easily
  • New function contains to check the existence of infinite strings in a file
  • Now string function will only process the first result with the "remove/replace/extract/complete_extract" flags but it can also process all results (-recursive) even in text extraction, also "extract/complete_extract" support returning only paragraphs that have a pattern substring(-pattern), and supports -file flag to directly load a file
  • New Recovery Mode (Similar to Test Mode) to use the Dynamic Installer actions from the Recovery terminal
  • The Test Mode was improved
[CHANGELOG 3.3]

News:

  • Some fixes
  • Fixed common A/B partitions mount
  • Fixed exist function with dummy find
  • Fixed find_apk (It was broken)
  • Fixed string (lower and upper)
  • Experimental Support for Virtual Dynamic Partitions
  • Now you can mount .img (RAW) directly, this allows you to make edits without having to redo the .img
  • Support for direct partition mounting/editing when the device is already booted with auto_mount_partitions and try_mount (Experimental)
Improved:
  • find_block now supports a very fast find without the need for a long wait (-express), also supports the find to be stopped at a specific time (-time)
  • try_mount now supports specifying the block to find/mount (-name), also support specify a file to mount (-file) instead of a partition, also supports "-express" like find_block and extra improvements
  • Improved unmount
  • Improved umount_all
  • Improved is_greater/is_less (Now supports decimal numbers)
  • Improved is_mounted (Now it can check a folder in the current directory without needed of fully path)
  • update_file/update_file_string/force_update_file/force_update_file_string now support -pattern flag using -delim to apply changes only to a segment that has the specific pattern (It analyze all segments within the specified delim)
New setdefault:
  • New setdefault magisk_support to disable magisk space and just use updater-script (Device booted)
  • New setdefault extraction_speed to change the speed (MB/s) for update/update_zip/write_raw_image functions
New functions:
  • New function is64bit to check if a binary supports 64bits arch
  • New function echolog to print as error(echo2) and "savelog" in the same time
  • New function printlog to ui_print and "savelog" in the same time
  • New function endlog to stop "savelog" that started with "startlog"
  • New function contains_array to check if a array already have some value
  • New function get_array to get fully value in a array using some pattern
  • New function get_size_ext4 to get the current size of any partition or compatible file (ext4/.img)
  • New function calc to make basic operations like addition, subtraction, division, exponents (also supports parentheses and multiplication but you must use quotes to escape that symbols '()' '*' )
  • New function unify_path to compare one folder with another, this includes a comparison of files that already exist in both paths, if they are not the same, they are replaced or added to the second path
New functions for Dynamic Partitions:
  • New function checksuper to check if a image/partition is a SUPER image in record time
  • New function get_offset to get the offset of any subpartition inside a SUPER partition/image in record time
  • New function get_group to get the group of any subpartition inside a SUPER partition/image in record time
  • New function get_total_size to get the total size of all subpartitions inside a SUPER partition/image
  • New function start_loop to make new mount point of any subpartition inside a SUPER partition/image (Designed for new Virtual Dynamic Partitions)
  • New function end_loop to end previously made mount point with "start_loop" based on the order of creation (It works like "end_tmp")
  • New function super_rw to enable Read/Write on SUPER partitions/images (Designed for Virtual Dynamic Partitions), this method extracts and converts all internal subpartitions of SUPER (It takes a little time) for this reason you have to add "super_rw" in the updater-script manually
  • New function unlock_all to try convert all internal subpartitions of SUPER to Read/Write on-fly (It doesnt require a very long waiting time like super_rw but it may not work in some cases)
  • New function unlock to convert specific subpartition of SUPER to Read/Write (Like unlock_all doesnt work in some cases)

[CHANGELOG 3.4]
  • Some fixes
  • Improved umount_all
  • Improved dynamic_apktool (Now it will not decompile "res" from the .APK by default)
  • setdefault devices now support Model names (Example: SM-A515F)
  • New function wipe to wipe any section like system, vendor, product, odm, data, dalvik, cache
  • Read-Only was activated in all native functions of the Dynamic Installer to avoid substitution problems when importing a new shell script (.sh) that contains functions with the same names of the native functions (Now native functions cannot be altered during installation)
[CHANGELOG 3.5]
  • Now only abort can end the installation with error, previously if the last action used ended in error the whole installation did too
  • When "$TMP" is auto-wiped, files with .log extension will not be deleted to avoid significant loss of information (You will not lose any LOG after installation)
  • New feature off_readonly to notify the Dynamic Installer that you want to modify some functions of its code in your script, with this the specified functions can be replaced during the installation (By default all functions are in Read/Only)
  • Improved package_extract_dir and package_extract_file (Now if a destination path is not provided the files will be returned directly as Text, useful to process files without extracting them)
  • Now update/update_zip/.. supports two new formats .xz and .gz, you can install the files you want using this type of compression, the files will be installed directly (they are not extracted) so using them does not increase the time of installation, it only reduces the size of your ZIP
[CHANGELOG 3.6]
  • Some fixes
  • Updated Magisk Module installer
  • Fixed "ERROR: Failed to setup busybox" on some devices
  • Now important variables protected with Read/Only (Btw u can use off_readonly)
  • Improved /apex mount
  • Fixed possible slot detection bugs for A/B devices
  • Fixed savestate
  • Improved update/update_zip (By default it will try to set the dest block as Read/Write if possible, else end with error)
  • New experimental variable $encrypted to check if the the device has encrypted internal memory
  • Added more detailed warnings in case of error
  • New function ch_con to manually set the context in mutiple single files/folders
  • New function ch_con_recursive to manually set the context to ALL files/folders of some directory (Btw u can set the context for only files or folders if u want)

[CHANGELOG 3.7]
  • Some fixes
  • General improvements
  • Improved general Mounting
  • Added /system_ext mounting with auto_mount_partitions
  • Improved is_greater/is_less
  • Added support to Android 12 (This includes /apex mounting, so you can run dexed JAR files like Apktool from Recovery if you enable setdefault apex_mount)
[CHANGELOG 4.0]
  • Some improvements
  • Improved general setup
  • Added more verifiers to ensure installation
  • Improved string function
  • Improved try_mount function
  • New function apex_mount to mount any .apex file or folder in /apex space
  • New function decode_xml to decode AndroidManifest.xml (Experimental)
  • New function encode_xml to encode AndroidManifest.xml and extra predecoded APK xml (Experimental)
  • New xml_kit function to manipulate XML code quickly and easily, I designed the tool based on XML logic (breaking the XML structure is very unlikely), xml_kit allows u to moving through the XML structure by sections (Very specific pieces can be edited)
  • Now string supports -get-before and -get-after to extract all text after/before some pattern
[CHANGELOG 4.1]
  • Some fixes
  • Some setup improvements
  • Fixed can_run (Broken with some commands)
  • Ensured plugins extraction
  • Some restructuring and better organization for general installation
  • Improved Test Mode setup
  • Some plugins were separated in META-INF/addons/extra.zip that are not always needed (Now you can remove them)
[CHANGELOG 4.2]
  • Some fixes
  • A problem was fixed in the extraction of some actions
  • Fixed extraction problems in some ROMs
  • Improved mounting detection for no block sections like /system_ext
  • An error with the text processing base of the Dynamic Installer (string function) was fixed that caused an incorrect interpretation in the verification with -after-line -before-line and extract flags with rare strings
[CHANGELOG 4.3]
  • Some important fixes
  • To unify syntax with the common edify actions:
    • Now u can also use get_file_prop as file_getprop
    • Added ifelse action (ifelse "action" "else action")
    • Added read_file (read_file "file" "file" "..")
    • Added run_program (run_program "program" arg1 arg2 ...)
  • Now package_extract_dir action supports the extraction of empy folders (Now also u can specify another zip to extract instead of the current installing ZIP)
  • Now package_extract_file action supports the extraction from another zip instead of the current installing ZIP
  • Now dynamic_install action supports empy folders
  • Now set_perm action supports multiple files in a single command line (also now supports symlinks)
  • Now set_perm_recursive action supports multiple directories in a single command line (also now supports symlinks and its much faster)
  • New fullpath action (To get the fully path of any file/folder or symlink, btw it returns the literal symlink path instead of its source)
  • Improved symlink action (Now interprets paths much better, also supports creating infinite symlinks in a single command line)
  • Improved ch_con / ch_con_recursive (General operation)
  • Fixed flags of add_lines_zip/add_lines_addon actions (Previously special flags were not supported as with add_lines)
  • Detection of native variables such as $is64bit, $arch, $arch32, $dynamic_partitions, ... has been improved through a temporary mount attempt to obtain values directly from the current system and vendor (Since some custom Recoverys run on 64bits when the system is 32bits and cause incorrect real time information)

[CHANGELOG 4.3-b]
  • Improved is_tar action (Tar checking is much faster even on large files)
  • Now is_number support decimal numbers
  • New function is_hex to check Hexadecimal strings
  • New function is_abc to check alphabetic strings
  • New magic_file action to check file types using their Magic Hex values(You can check a file type even if it doesnt have an extension), additionally, u can include an -offset number to skip bytes and also the -bytes per line to get, and with this also the number of hex -line to use (to find the Magic value in a specific range number of hex lines from 1), btw, it includes several types of files already preloaded, using the -type indicator, these dont require additional configuration

[CHANGELOG 4.4]
  • Improved and fixed general mounting
  • Now you can use "mount_all" as "auto_mount_partitions" function
  • Added /odm mounting in mount_all / auto_mount_partitions function
  • Added extra reports of general mounts
  • super_rw function was discontinued (not effective)
  • Fixed a relevant bug in many functions that support multiple options (if a special flag was used without all the required arguments it would enter an infinite loop)
  • Fixed a relevant bug in the string function that did not allow adding 2 lines with -after-line -before-line (Only 1 lines or 3 lines+ huh)
  • Fixed fruitloop on some devices when using functions that work with superrepack from extra.zip (It was encapsulated for safe use)
  • Improved and fixed xml_kit / replace / ch_con / ch_con_recursive and other functions
  • A minimum free space check is now performed for root "/" only with mount_all / auto_mount_partitions (Some stock firmwares does not even have 1 Byte free and some actions / editions cannot be performed)
  • Now the string function supports replacing with multiple lines all the lines that contain a pattern (replace_line flag)
  • Now the get_file_prop / file_getprop functions supports multiple files to find a specific prop
  • Now the replace function supports replacing with multiple lines all the lines that contain a pattern (-all-line flag)
  • Now is_abc function accepts spaces and new lines (But it will only be True if all visible characters are only alphabetic)
  • Now string function can be forced to always return a result with the "force" flag (previously nothing was returned if the original text was equal to the result)
  • New functions saveperm / restoreperm to save and restore permissions (UID/GID/MODE) of all files/folders in a path (Recursively) or on single files
  • New functions savecontext / restorecontext to save and restore contexts of all files/folders in a path (Recursively) or on single files
  • New function eval_perm to get the most used Permission/Mode of a path or a single file
  • New function eval_user to get the most used User ID of a path or a single file
  • New function eval_group to get the most used Group ID of a path or a single file
  • New function eval_all_perm to get the most used User ID/Group ID/Mode of a path or a single file
  • New function get_all_perm to get the User ID/Group ID/Mode of a folder or a single file
  • New function get_context to get the context of a single folders/files
  • New function is_text to check ANY visible character, if there are only empty spaces or new lines it will return False.
  • Added cpio / ramdisk format in magic_file function ( with -type flag)
  • New setdefault permissions to change the default permissions for folders/files used by ALL Dynamic Installer functions
  • New function is_same_mount to check if two folders are linked to the same partition (For example /system and /system_ext use the same partition in most devices)
  • New Edify simulated functions greater_than_int/less_than_int/concat/stdout
  • New number comparison functions is_greater_equal / is_less_equal
  • New function convert to convert any type of units, mainly for storage units such as b, B, KB, MB, GB, TB, there is no combination limits (It returns completely decimal or integer numbers)

[CHANGELOG 4.4-b]
  • Fixed some warnings
  • Added Unisoc chipset detection for the native variable $chipname
  • smali_kit improved, fixed and slightly restructured
  • smali_kit now supports string function fixes / improvements with -after-line -before-line flags
  • Nothing more

[CHANGELOG 4.4-b3]
  • General improvements
  • Some mount / unmount improvements
  • Improved /apex configs for Android 12
  • Fixed make_overlay (Due to changes with the dynamic_apktool it did not work correctly)
  • Now the setdefault permissions supports User ID and Group ID (UID/GID)
  • Optimized device verification with setdefault devices
  • Replaced native busybox reboot action with /system/bin/reboot (best)
  • Find within folders symlinks is now supported by default in set_context / dynamic_install / dynamic_install_apk / find_apk / saveperm / savecontext / restoreperm / restorecontext functions (This allows deeper finds)
  • Now ui_print will better evaluate prints for unconventional installations (adb)
  • New variables $di_version and $main_version (Information of the current version of the Dynamic Installer)
  • New function convert_edify to try to convert Edify scripts to Dynamic Installer scripts (Experimental)

[CHANGELOG 4.5]
  • General improvements / maintenance
  • Added Installer Configs in the log
  • Thanks to a new dynamic temporary space ($TMP), additional ZIPs can now be flashed without risk of affecting the current installation
  • flash/flash_addon/flash_zip functions has been improved to take advantage of the new $TMP, also now supports a third optional argument "print" to allow the new ZIPs to print text on Recovery
  • add_lines / add_lines_string /add_lines_addon / add_lines_zip functions now supports creating new files (previously they only supported editing existing files)
  • magic_file now supports "sparse" type to detect Android Sparse IMGs

[CHANGELOG 4.5-b]
  • Device verification has been optimized (setdefault devices - Avoided repeating the verification for device information already checked)
  • package_extract_dir fixed, due to a logical error when there were two or more folders in the same ZIP path that started with a common pattern (system system1 system2), when extracting the base pattern (In this example "system"), all these folders were extracted instead of just one

[CHANGELOG 4.5-b2]
  • General maintenance
  • Fixed a serious issue that would freeze/reboot some devices when the DI was installed by Magisk (Thx to @quadraticfunction for the tests)
  • Fixed checksuper function (Due to a logic error, the device could be bricked after use)
  • Added more checks (Like Read/Write permissions) in most functions for more understandable logs
  • Replaced "setdefault run_addons" with "setdefault import_addons" (Now allows importing all $addons plugins with .sh extension before main script execution)
  • New functions create_dir / create_file (Ensure new files or folders easily)
  • New function testrw (To test if one or more folders has write permissions)
  • New function testvarname (Allows to verify if the text is valid to be used as a variable name)

[CHANGELOG 4.5-b3]
  • Fixed find_apk function (Skipping overlays and splits did not work when using -recursive find)
  • Fixed replace function (After text replacement, if the result had not even 1 visible character, the whole operation failed)
  • New remove function to remove text in a file or -recursive in a directory
  • New multi_option function to get a user selection from a list of many options
  • New apk_main function to get the activity that can be launched in an APK (if it exists)
  • New apk_icon function to get the internal path of the icon of an APK
  • New apk_launch function to launch the main launchable activity (or a specific activity) of some pre-installed APP on the device (when its booted)

[CHANGELOG 4.6]
  • General improvements and maintenance
  • New obfuscate function that allows you to encode the shell script code (or Dynamic Installer scripts), keeping it working but making it difficult for common users to read (you can mix obfuscated code with readable code)
  • New apk_install function to install .apk or .apkm files (ApkMirror), the inclusion of splits together with main .apk/.apkm is supported (It is necessary that the device is already booted)
  • New apk_install_recursive function, installs all .apk/.apkm that are inside a folder, also supports creating subfolders to group .apk/.apkm with additional splits
  • New function stderr (Run and print any action as error)
  • New function stdprint (Run and print any action on the screen - ui_print)
  • New set_metadata_recursive function (Simulated Edify function)

[CHANGELOG 4.6-b]
  • General improvements and fixes
  • Many functions were optimized at the code level
  • It is now possible to use "not" to negate an expression (Equivalent to using "!"), for example:
Bash:
if not exist "/system/ole"; then
   ui_print "ERROR"
fi
  • Improved reports (logs) of package_extract_file / package_extract_dir, now you can easily identify extraction problems
  • Importing addons with "setdefault import_addons" will now be alphabetical (to control load order)
  • Added simg2img to extra.zip for 64bit devices only
  • New functions int, float, round to obtain integer, decimal or rounded numbers (Math operations are supported directly)
  • New function get_all_subparts to get the name of all subpartitions of an img/partition (SUPER)
  • New end function to stop the script (similar to abort), but without ending the installation on error
  • The repeat function now supports paragraphs (Multi line)
  • The contains function now supports finding paragraphs (multi line)
  • The multi_option function now supports an optional third argument "loop" to keep an infinite loop of options on a constant restart (Until a valid option is selected)
  • The exist function now supports specific recognition for blocks and symlinks (exist symlink "TEST", exist block "/dev/block/dm-0")
  • The unlock_all/unlock functions now support specifying an IMG/Partition
  • You can now also use the -file option on try_mount to specify a block to mount (Previously focused only on specifying files)
  • update/update_zip/update_addon functions now support Sparse IMGs experimentally (need to import simg2img)

[CHANGELOG 4.6-b2]
  • Fixed a serious problem with the new "not" logical function (it didn't work at all due to an implementation problem)
  • The "installzip" native variable was unlocked (Previously in Read-Only by default), because it conflicted with the functionality of using external ZIPs with package_extract_file / package_extract_dir
  • New function find_content to get the paths of all the contents of the ZIP that match the established patterns

[CHANGELOG 4.7]
  • Updated apktool to v2.7.0 (with baksmali/smali 2.5.2)
  • Fixed de/compilation problems of the framework.jar (a12+)
  • Automatic import of all APEX binaries (This ensures access to actions completely isolated from /system)
  • Importing APEX binaries fixes dalvikvm issues on some devices (Required for running JARs)
  • patch_fstab fixed (Now only active lines will be patched)
  • dynamic_apktool function can now check and add missing original resources in the final APK/JAR
  • dynamic_apktool function now includes a specification of the device API (This prevents bugs in newer apktool versions)
  • New replace_name function to flexibly rename multiple files/folders (or just one)


[CHANGELOG 4.7-b]
  • Fixed a bug in the dynamic_apktool function (Checking/adding original resources even extended to "res", causing slower decompile and recompile errors)
  • dynamic_apktool now has the -no-extras option to disable original resource checking/adding (Although it is recommended to keep it)
  • dynamic_apktool now has the -no-api option to disable automatic specification of the device API (Although it is recommended to keep it)
  • dynamic_apktool now has the -use-baksmali option to set an external baksmali.jar (DEXED) instead of the native apktool one


[CHANGELOG 4.7-b2]
  • The structure and operation of the update-binary have been improved (This script is the initial launcher of the ZIP, its improvement ensures the execution of the ZIP in more hostile environments or with compatibility problems and a more accurate logging in case of critical problems)
  • Fixed a small warning in the make_zip function
  • Fixed long timeouts when unmounting partitions mounted on non-common paths
  • Mount functions in general now have better logging warnings
  • By default the "unzip" binary will try to change to some external version, this to try to avoid extraction problems when the size of the ZIP exceeds Busybox's "unzip" support (However, not all versions of unzip support extracting files larger than 4GB)
  • testrw function can now identify a Read/Only mounted folder (Without the need to create a file, empty file creation for write verification will now only be used for folders not previously mounted)
  • try_mount function now ensures mounts specified as Read/Write only, i.e. even if the mount is "successful", if it really is not writeable to it, it will be treated as failed
  • dynamic_apktool now supports -use-smali to specify an external smali.jar(DEXED) instead of the one already included in apktool
  • savelog, echolog and printlog functions now support multiple lines (each argument is one line to print/write)
  • New change_bin function to try to use another available binary, remembering that Busybox binaries are used by default, with this it is possible to try to change them for available external versions
  • New "setdefault ensure_root", if set to "off", mount_all will allow Read-Only systems (Even if you can't make edits internally, you can still mount read-only, previously if the device had any restrictions like EROFS, the complete installation was aborted warning of a read-only system)
  • "setdefault magisk_support" now supports the "force" option, to always use Magisk space (customize.sh), even from a Recovery install

[CHANGELOG 4.7-b3]
  • Fixed a fatal bug that kept all functions using superrepack in an infinite loop. Oops!
  • No more

[CHANGELOG 4.8]
  • Support for KernelSU (or any other future Manager as long as it does not stray from the general logic of Magisk modules). Strictly requires some additional files, as will be detailed in the main Thread
  • New native variable $CUSTOM_SETUP, which allows identifying custom setups such as KernelSU (or any other)
  • Fixed obtaining valid APEX packages, as well as general support for Android 14+ standards for the operation of dalvikvm (Currently works perfectly on AOSP A14, but not on OneUI 6, this will possibly be fixed in future versions or a specific plugin)
  • New optional "setdefault mount_all", it is not a standard added to the native setdefaults in the updater-script header, it is simply an option that can be changed at any time during installation before using the "mount_all" action. If specified in "ro" mount_all will always work in Read/Only mode for all mounts. By default, when not specified, Read/Write mounts are attempted and if one fails, the latter is set to Read/Only
  • is_number function now supports negative numbers

[CHANGELOG 4.8-b]
  • Fixed a bug reported by @saadelasfur27 in TWRP versions 3.7.1+. The assignment/generation of free loop devices for mounting APEX/CAPEX was freezing the Script when trying to do it on one that already existed in Recovery, consequently, the mount_all action never finished.
 
Last edited:

BlassGO

Senior Member
Jan 19, 2021
161
383
DOWNLOADS:

STABLE V4.8-b:
Standard version of the DI. Use the native "unzip" command to handle extractions, this can give better compatibility since it is an existing command in all custom Recoverys, but implies a dependency on the capacity of the size of ZIP files that it natively supports (4GB at best of the cases). If your final compressed project will not exceed 3.5GB, you can use this version without worries.
MEDIAFIRE




STABLE V4.8-bZ:
Experimental variant of DI (does not imply that it is unstable). Instead of using the native "unzip" command, it includes a 7zip binary embedded from quite early points in the installation to handle extractions, allowing processing of large ZIPs. Requires either the "base64" command or the "awk" command to exist. If your final compressed project exceeds 3.5GB, consider trying this version.

NOTE: To ensure compatibility, you can simply flash this blank template and if you don't receive any warning, it is supported!

 
Last edited:

BlassGO

Senior Member
Jan 19, 2021
161
383
can this method be used to patch systemui.apk to possibly replace resources.arsc or change specific colors under values\res\colors.xml
For compatibility reasons you can only directly make smali edits (classes.dex), check the BUGs section with the apktool, although you could do is an overlays (As its a simple apk it can be decompiled and compiled)

But if you just want to replace the resources.arsc without previously decompiling it you can use the patch_apk function
 

blaze2051

Senior Member
Jul 26, 2010
385
47
LG G7 ThinQ
LG V40
For compatibility reasons you can only directly make smali edits (classes.dex), check the BUGs section with the apktool, although you could do is an overlays (As its a simple apk it can be decompiled and compiled)

But if you just want to replace the resources.arsc without previously decompiling it you can use the patch_apk function
this looks so confusing, but can this be used to make a recovery partition to install twrp to a A/B dynamic partition device that only has boot partition?
 
  • Like
Reactions: BlassGO

BlassGO

Senior Member
Jan 19, 2021
161
383
this looks so confusing, but can this be used to make a recovery partition to install twrp to a A/B dynamic partition device that only has boot partition?
The Dynamic Installer focuses on general installations for mods, roms or patchs, but it has an open space for plugins, you can contact me from the support group that is at the beginning of the thread to develop/test a plugin that allows that installation

Btw the previous message was probably confusing cuz it also supports code patching in APKs, its a very multi-use installer.
 

Techguy777

Senior Member
May 24, 2018
1,515
427
Samsung Galaxy S10 Lite
Xiaomi Poco F3
There are tons of things on xda now that I have absolutely no clue as to what the use would be. This is one of them if you can install a recovery than you install the recovery with adb or Odin or whatever. If you need to install magisk module you install it in manager. Apk install normally. I don't understand what this gave us that wasn't able to do before?

Same with sim number setter xposed module it doesn't do anything. It changes some arbitrary number that has no bearing on anything It's completely pointless.
 

BlassGO

Senior Member
Jan 19, 2021
161
383
There are tons of things on xda now that I have absolutely no clue as to what the use would be. This is one of them if you can install a recovery than you install the recovery with adb or Odin or whatever. If you need to install magisk module you install it in manager. Apk install normally. I don't understand what this gave us that wasn't able to do before?

Same with sim number setter xposed module it doesn't do anything. It changes some arbitrary number that has no bearing on anything It's completely pointless.
That is a superficial view, the installation of ROMs / MODs and others only put it on a par with traditional installers (Edify Scripts), the objective of Dynamic Installer is to shorten / facilitate actions for complex projects and in fact, there are projects to patch the Secure Folder / Samsung Theme Store, create bootanimations using any video, all directly from Magisk using this installer, and more, in short, it is a very well equipped, free and easy to write work environment, which even expands to the Magisk Modules space ( Also I think there is a confusion, it is not intended to replace the Magisk Manager, it is a ZIP, it works like any magisk module for the user)
 

Techguy777

Senior Member
May 24, 2018
1,515
427
Samsung Galaxy S10 Lite
Xiaomi Poco F3
That is a superficial view, the installation of ROMs / MODs and others only put it on a par with traditional installers (Edify Scripts), the objective of Dynamic Installer is to shorten / facilitate actions for complex projects and in fact, there are projects to patch the Secure Folder / Samsung Theme Store, create bootanimations using any video, all directly from Magisk using this installer, and more, in short, it is a very well equipped, free and easy to write work environment, which even expands to the Magisk Modules space ( Also I think there is a confusion, it is not intended to replace the Magisk Manager, it is a ZIP, it works like any magisk module for the user)
Now when you there are projects to patch secure folder are any of the projects successful and is it for Android 12 aka one ui 4.1? That would be a good use. The boot animation with any video would be cool to but the secure folder is more practical or useful. Where can I find this project at?
 

Techguy777

Senior Member
May 24, 2018
1,515
427
Samsung Galaxy S10 Lite
Xiaomi Poco F3
That is a superficial view, the installation of ROMs / MODs and others only put it on a par with traditional installers (Edify Scripts), the objective of Dynamic Installer is to shorten / facilitate actions for complex projects and in fact, there are projects to patch the Secure Folder / Samsung Theme Store, create bootanimations using any video, all directly from Magisk using this installer, and more, in short, it is a very well equipped, free and easy to write work environment, which even expands to the Magisk Modules space ( Also I think there is a confusion, it is not intended to replace the Magisk Manager, it is a ZIP, it works like any magisk module for the user)
So there's really no secure folder patch available it's just talked about or working on it? That's what I mean if there is something of use that only this can do it makes it great but if there's nothing I fail to see the point.
 

BlassGO

Senior Member
Jan 19, 2021
161
383
Now when you there are projects to patch secure folder are any of the projects successful and is it for Android 12 aka one ui 4.1? That would be a good use. The boot animation with any video would be cool to but the secure folder is more practical or useful. Where can I find this project at?
@skyflyteam

In the support tg channel you will find some projects, one of them for the SecureFolder OneUI 4.1
 

BlassGO

Senior Member
Jan 19, 2021
161
383
it says failed to unpack zip

In that case it isnt a problem of the installer, check the compression, the most common error is to compress the unziped folder that contains everything, instead of each specific element like META-INF, META-INF must always be in the root of the ZIP, to check it you can open your current ZIP and verify that the first thing you see is the META-INF
 

Top Liked Posts

  • There are no posts matching your filters.
  • 19
    20210222_103348.jpg

    SUPPORT: TELEGRAM CHANNEL - TELEGRAM GROUP - SUPPORT ME

    ABOUT THIS:
    With this you can make Automatic Installers (.ZIP flash files) for All Android devices without limitations (Supports an installation from Recovery or can be used to create a Magisk module)

    By default the installer mounts the partitions as RW (Read/Write) and creates its own environment (Busybox + Bash) to work even if your installation environment is not the most suitable

    Although the name "Dynamic Installer" can be confusing, the installer is not exclusive for devices with Dynamic Partitions, it supports devices with old and new partitions.


    Compatibility:
    • ARM/ARM64​
    General Features:
    • Fully shell script based (Open source)​
    • It can mount main partitions as RW (/system_root, /system, /system_ext, /vendor, /product, /odm)​
    • Supports /apex mounting (dalvikvm support included)​
    • Supports old and new partitions​
    • Support for a Dual installation (Recovery or Magisk)​
    • It has many useful actions that make it easy to mount partitions, edit/patch files or install ROMs​
    • It has many other special features for patching smali JARs/APKs, XML editing, running JARs directly and more.​
    • It has 4 types of execution (ZIP for Recovery or Magisk, Just load from Recovery Terminal or Termux)​
    • It runs with BASH instead of ASH, DASH​
    • Support for addons and more​

    Default Variables:
    Bash:
    $TMP: The value of this variable contains the temp directory (A directory that only exists during execution, you can use it to store temporary contents)
    
    $BOOTMODE: This value will be "true" only if the device is already booted (or "false")
    
    $chipname: The value of this variable can be "snapdragon/exynos/mediatek/kirin/unisoc" depending on the chipset of the device
    
    $installzip: The value of this variable contains the path of your ZIP (that the user is installing)
    
    $is64bit: The value of this variable will be "true" only if the device is 64-bit (or "false")
    
    $API: The value of this variable contains the API number (of the Android version) of the device
    
    $slot: Contains the Active Slot (_a or _b) if the device has A/B partitions (It can be refreshed with "getarch" )
    
    $dynamic_partitions: The value of this variable will be "true" if the device has a Dynamic Partitions (or "false")
    
    $virtual_partitions: The value of this variable will be "true" if the device has a Virtual Dynamic Partitions (or "false")
    
    ${n}: Allows creating new lines within a string ( Example: paragraph=" First line ${n} Second line ${n} Third line " )
    
    $encrypted: It will be "true" only if the device has encrypted Internal Memory (or "false")
    
    $di_version: The complete current version of Dynamic Installer
    
    $main_version: The main version of the Dynamic Installer (Only include whole numbers or decimals, without the -b -b2 -b3 ... variant extensions)
    
    $CUSTOM_SETUP: If the installation is conventional (Recovery or Magisk) it is set by default to 0, if Test Mode is being used it is set to 1 and finally, if it is an externally managed installation such as KernelSU, it is set to 2.

    Updater-Script configs
    PATH: META-INF/com/google/android/updater-script

    Here you will find some lines that start with "setdefault" (These conditions affect even if you make a Magisk module)

    • setdefault devices (code name/Model of supported devices or off)
    If you want the installer to only run on specific devices you can replace "off" with the code name or Model of the supported devices (Use ":" to separate them)
    Bash:
    #By default
    setdefault devices off
    
    #For example to only supports Galaxy A51
    #Check using one code name
    setdefault devices "a51"
    
    #Check using two code names
    setdefault devices "a51:a51nsxx"
    
    #Check Galaxy A51 but with Models
    setdefault devices "SM-A515F:SM-A515FN"
    
    #For example to only supports Pixel 4 XL and Pixel 2
    setdefault devices "Pixel 2:Pixel 4 XL"
    
    #Or a Mix
    #For example to only supports Pixel 4 XL/Pixel 2 and Galaxy A51
    setdefault devices "a51:a51nsxx:Pixel 2:Pixel 4 XL"
    • setdefault apex_mount ( on or off)
    You can change the "off" to "on" to allow mounting of /apex, (this could cause a very slow mounting with mount_all action), activate it only if necessary (When you want to use actions like apktool / sign / run_jar that require dalvikvm from Recovery)
    Bash:
    #By default
    setdefault apex_mount off
    
    #To allow /apex mount using /system/apex and /system_ext/apex
    setdefault apex_mount on

    • setdefault import_addons (on or off)
    If you activate it all files with extension .sh within META-INF/addons will be imported before execution, this way you can load several plugins for your main script

    NOTE: The import will respect an alphabetical (a.sh, b.sh, c.sh, ...) or numerical (1.sh, 2.sh, 3.sh, ...) order
    Bash:
    #By default
    setdefault import_addons off
    
    #To import all META-INF/addons/*.sh
    setdefault import_addons on

    • setdefault magisk_support ( on / off / force)
    To enable, disable or force the Magisk space:
    1. on = Automatically switch between updater-script (Device not booted) or customize.sh (Device already booted). Dual installation, two possible execution scripts.
    2. off = Never use the Magisk space, so the updater-script will always be used in any case of installation (Device already booted or not booted)
    3. force = Always use the Magisk space, so the customize.sh will always be used for any installation case (Device already booted or not booted)

    NOTE: When magisk_support is set to "off", it is understood that any references to magisk modules, such as $MODPATH, will not be available even if the ZIP is installed from the Magisk App.
    Bash:
    #By default
    setdefault magisk_support on
    
    #To use updater-script instead of customize.sh
    #(Device already Booted)
    setdefault magisk_support off
    
    #To use customize.sh instead of updater-script 
    #(Device NOT Booted - Recovery)
    setdefault magisk_support force

    • setdefault extraction_speed (default or custom value)
    Allows you to change the extraction speed (MB/s) only when using these actions: update/update_zip/write_raw_image
    Bash:
    #By default
    setdefault extraction_speed default
    
    #To use 5MB / s in the supported actions
    #Use "M" for Megabytes
    setdefault extraction_speed 5M

    • setdefault ensure_root (on or off)
    If set to "off", mount_all will allow Read-Only systems (Even if you can't make edits internally, you can still mount read-only, otherwise, with "on", the installation would be aborted)
    Bash:
    #By default
    setdefault ensure_root on
    
    #To allow RO systems
    setdefault ensure_root off

    • setdefault permissions (0:0:0755:0644 or custom value)
    Allows you to change the default permissions for folders/files used by ALL Dynamic Installer functions (It means that any function that interacts with files or folders will use these permissions in the result)

    Format = User ID : Group ID : Folder permissions : File permissions

    Bash:
    #By default
    setdefault permissions "0:0:0755:0644"
    
    #To use 0755 in Folders and 0777 in Files
    setdefault permissions "0 : 0 : 0755 : 0777"

    Pre-introduction to Addons
    The contents inside META-INF/addons are extracted automatically in the installation, to refer to the path use $addons variable

    Plugins here
    Bash:
    ::If you have META-INF/addons/myfile.txt
    #To print this file
    #You don't need to extract it
    fprint "$addons/myfile.txt"

    Pre-introduction to Actions
    Some of these actions support specific extensions as follows:
    • _addon: If you add "_addon" to the end of each supported action it will take the files directly from "META-INF/addons" folder inside the zip
    Bash:
    #META-INF/addons/Example.txt
    update_file_addon "Example.txt" /system/build.prop
    • _zip: If you add "_zip" at the end of each supported action it will take the files directly from the ZIP, you can include paths with folders
    Bash:
    #To use "folder/Example.txt" file inside the ZIP
    update_file_zip "folder/Example.txt" /system/build.prop
    • If this extension isnt included in the action, it will work as an external command to the zip
    Bash:
    update_file "/sdcard/Example.txt" /system/build.prop
    How does it work?
    • update-binary It is the script that creates the proper environment and executes the entire ZIP
    • zbin contains all the necessary plugins
    • updater-script It is the script that is executed only if the ZIP is installed from Recovery (or when the device is not booted in general)
    • customize.sh It is the script that is executed only if the ZIP is installed from the Magisk App (or when the device is already booted in general)

    Test MODE
    The "Test Mode" allows you to test most actions of the Dynamic Installer using the Termux App for Android or some Custom Recovery Terminal (with this you can practice)
    20220104_152849.jpg


    To use it, extract this folder:

    • META-INF/zbin
    Also this file:
    • META-INF/addons/extra.zip
    To your internal memory: /sdcard

    Execution in Termux (ROOT):

    Bash:
    #First method
    su
    cd /sdcard/zbin
    . ./setup
    
    #Second method
    su
    . /sdcard/zbin/setup /sdcard/zbin

    Execution in Custom Recovery Terminal:
    Bash:
    #First method
    cd /sdcard/zbin
    . ./setup
    
    #Second method
    . /sdcard/zbin/setup /sdcard/zbin

    Now you can test some actions:
    Bash:
    update_file_string "ro.product.system.model= TEST" /sdcard/build.prop
    
    apktool --help

    Magisk SPACE
    NOTE: You can use all the additional functions of the Dynamic Installer during the installation by Magisk

    SPACE: META-INF/com/google/android/magisk

    In this space you can configure the script and the information of your Magisk module, but the format of the script is totally free, do not rely too much on the existing formats for magisk modules

    The magisk modules use a "$MODPATH" variable which is where you must direct all the files to be applied

    For example to just extract contents of your ZIP in "$MODPATH/system" (This will apply the changes to /system after reboot)
    Bash:
    package_extract_dir "FolderInsideZIP" "$MODPATH/system"

    KernelSU Support
    NOTE: You can use all the additional functions of the Dynamic Installer during the installation by KSU

    SPACE: META-INF/com/google/android/magisk

    The same Magisk space is used, in this space you can configure the Script or special additional Scripts like service.sh. The format of the main script (customize.sh) is totally free, do not rely too much on the existing formats for Magisk/KSU modules.

    Before continuing, it is important to understand the problems and what were the solutions implemented from v4.8+


    PROBLEMS:
    • Unlike Magisk Modules, the customize.sh and module.prop files must be strictly in the ROOT of the ZIP, since their reading is static and is not managed by the installer itself. This makes it impossible for these files to be obtained from the Magisk Space implemented in the Dynamic Installer.
    • Unlike Magisk Modules, the execution of the ZIP is not controlled by the "META-INF/com/google/android/update-binary" file, which is the main requirement to load the Dynamic Installer, KSU transfers this logic to the Manager itself. which directly executes "customize.sh" from the root of the ZIP.
    SOLUTIONS:
    • Add a module.prop in the root of the ZIP from which the module information such as Name, Author, Description, ... will be read only for an installation with the KSU manager.
    • Add a customize.sh in the root of the ZIP that calls the update-binary of the Dynamic Installer allowing its conventional execution only for an installation with the KSU manager.

    Okay, now it is easier to understand the role played by these two files that must be added to the ROOT of any module based on the Dynamic Installer v4.8+ that wants to support KernelSU or other external Managers different from Magisk.

    DOWNLOAD

    So, your final ZIP should look something like this:
    Code:
    META-INF
    customize.sh
    module.prop

    In this module.prop configure the information of the module you want for an installation by KernelSU, and in "META-INF/com/google/android/magisk/module.prop" the information you want for an installation by Magisk.


    EXTRA:
    The KSU modules use a "$MODPATH" variable which is where you must direct all the files to be applied

    For example to just extract contents of your ZIP in "$MODPATH/system" (This will apply the changes to /system after reboot)
    Bash:
    package_extract_dir "FolderInsideZIP" "$MODPATH/system"

    REPLACE NATIVE FUNCTIONS
    By default all the Native functions of the Dynamic Installer and some Native Variables are in Read/Only to prevent them from being altered by imported shell scripts, however there is a way to allow their substitution from your script: off_readonly

    NOTE: off_readonly is interpreted during the installation of the ZIP, so it doesn't work from Test Mode
    Bash:
    #off_readonly "function name" "function name" "..."
    off_readonly ui_print update_file
    
    #Now you can use your custom functions
    ui_print() {
       echo My custom ui_print function
    }
    
    update_file() {
       echo My custom update_file function
    }
    
    #For some Native Variables like $TMP
    off_readonly TMP TMPDIR
    
    #New values
    TMP="My custom value"
    TMPDIR="My custom value"

    TMP2
    This variable ($TMP2) is generated by using start_tmp function and ends with end_tmp, the value contains a new temporary path that disappears after installation

    Multiple spaces can be generated and finished the same number of times in different periods
    Bash:
    start_tmp
    Space1="$TMP2"
    
    start_tmp
    Space2="$TMP2"
    
    start_tmp
    Space3="$TMP2"
    
    #U need to finish ALL dynamic spaces
    #end_tmp will be remove the created temp directory based on the order of creation
    
    end_tmp
    end_tmp
    end_tmp

    BUGS:
    • The functions to decompile/compile APKs use an experimental apktool build that CANNOT process images, so dont try to process a full complex APKs! Only smali editions

    CREDITS TO:

    • Me @BlassGO ( Creator of Dynamic Installer)
    • @osm0sis ( Traditional installer functionalities in shell code)
    • @topjohnwu ( Some very cool functions in shell code)
    • @munjeni for superrepack and superunpack (Best tools to manipulate SUPER images)
    • @lebigmac cuz I used his project systemrw as a base to made my super_rw function for Dynamic Installer
    • 3arthur6 for its binary 7zip for the experimental Z variants of the DI


    MORE EXPLANATIONS
    AND DOWNLOADS
    IN THE NEXT POSTS
    8
    SCRIPT EXAMPLES:

    • ROM Installation
    NOTE: The use of RAW IMGs is recommended (more direct and faster installation) but it is also possible to use Sparse IMGs (Only for 64bit devices)

    META-INF/com/google/android/updater-script

    Bash:
    #-----------Dynamic Installer Configs-----------#
    #The #MAGISK tag is required, dont remove it
    #MAGISK
    setdefault magisk_support on
    setdefault ensure_root on
    setdefault import_addons off
    setdefault apex_mount off
    setdefault extraction_speed default
    setdefault permissions "0:0:0755:0644"
    setdefault devices off
    #-----------------------------------------------#
    #Your script starts here:
    
    ui_print "--------------------------------"
    ui_print "          ElementaryOS          "
    ui_print "           OneUI 3.1            "
    ui_print "--------------------------------"
    ui_print "           by BlassGO           "
    ui_print "--------------------------------"
    ui_print " "
    
    ui_print "-------------------"
    ui_print " UNMOUNT           "
    ui_print "-------------------"
    ui_print " "
    umount_all
    
    ui_print "-------------------"
    ui_print " INSTALLING PARAM  "
    ui_print "-------------------"
    ui_print " "
    update_zip param.bin "$(find_block up_param)"
    
    ui_print "-------------------"
    ui_print " INSTALLING KERNEL  "
    ui_print "-------------------"
    ui_print " "
    update_zip boot.img "$(find_block boot)"
    
    ui_print "-------------------"
    ui_print " INSTALLING OMC    "
    ui_print "-------------------"
    ui_print " "
    
    update_zip optics.img "$(find_block optics)"
    
    #Using a Sparse IMG
    update_zip -sparse prism.img "$(find_block prism)"
    
    #Installing RAW SUPER (system, vendor, product, odm)
    ui_print "-------------------"
    ui_print " INSTALLING SUPER  "
    ui_print "-------------------"
    ui_print " "
    #Extra compressed as XZ
    update_zip -xz super.img.xz "$(find_block super)"
    
    ui_print "-------------------"
    ui_print " DONE              "
    ui_print "-------------------"
    ui_print " "
    • Only Extraction
    META-INF/com/google/android/updater-script
    Bash:
    #-----------Dynamic Installer Configs-----------#
    #The #MAGISK tag is required, dont remove it
    #MAGISK
    setdefault magisk_support on
    setdefault ensure_root on
    setdefault import_addons off
    setdefault apex_mount off
    setdefault extraction_speed default
    setdefault permissions "0:0:0755:0644"
    setdefault devices off
    #-----------------------------------------------#
    #Your script starts here:
    
    ui_print " "
    ui_print " -- Mounting partitions..."
    mount_all
    
    ui_print " -- Extracting mods..."
    package_extract_dir system /system
    package_extract_dir vendor /vendor
    package_extract_dir system_ext /system_ext
    
    ui_print " -- Unmounting ALL"
    umount_all
    
    ui_print " "
    ui_print " -- Done"
    ui_print " "
    • Magisk Module
    NOTE: You can add folders directly in META-INF/com/google/android/magisk and they will be added automatically in your module

    META-INF/com/google/android/magisk/customize.sh

    Bash:
    #Magisk modules use $MODPATH as main path
    #Your script starts here:
    
    ui_print "-------------------------------------------------- "
    ui_print " MODS for Android                  "
    ui_print "-------------------------------------------------- "
    ui_print " by @BlassGO      |   Version: 1.0                 "
    ui_print "-------------------------------------------------- "
    ui_print " "
    
    ui_print " -- Installing MODS in /system"
    package_extract_dir system "$MODPATH/system"
    
    ui_print " -- Installing MODS in /vendor"
    package_extract_dir vendor "$MODPATH/system/vendor"
    
    ui_print " -- Installing MODS in /product"
    package_extract_dir product "$MODPATH/system/product"
    
    ui_print " -- Fixing Contexts"
    set_context /system "$MODPATH/system"
    
    ui_print " "
    ui_print " -- Done"
    ui_print " "
    • Magisk Module (APKTOOL)
    NOTE: The dynamic_apktool only decodes ALL classes.dex, no content of "res" is directly editable (Check the BUGS of the Dynamic Installer)

    META-INF/com/google/android/magisk/customize.sh

    Bash:
    #Magisk modules use $MODPATH as main path
    #Your script starts here:
    
    enable='
        .locals 1
    
        const/4 v0, 0x1
    
        return v0
    '
    
    ui_print " -- Finding SystemUI.apk"
    APK=$(find_apk com.android.systemui /system)
    
    ui_print " -- Checking results"
    if undefined APK; then
       abort " CANT FIND: SystemUI.apk"
    fi
    
    ui_print " -- Decompiling SystemUI.apk"
    dynamic_apktool -decompile "$APK" -output "$TMP/decompiled"
    
    ui_print " -- Patching SystemUI.apk"
    smali_kit -check -method "isUnlockingWithBiometricAllowed" -remake "$enable" -dir "$TMP/decompiled"
    
    ui_print " -- Recompiling SystemUI.apk"
    dynamic_apktool -preserve-signature -recompile "$TMP/decompiled" -output "$MODPATH$APK"
    
    ui_print " -- Checking results"
    if ! is_valid "$MODPATH$APK"; then
       abort "Some error in the APK recompilation"
    fi
    
    ui_print " -- Fixing Context "
    set_context "$APK" "$MODPATH$APK"
    
    ui_print " "
    ui_print " -- Done "
    ui_print " "
    • Magisk and KernelSU Module
    NOTE: You can add folders directly in META-INF/com/google/android/magisk and they will be added automatically in your module (for KernelSU and Magisk)

    META-INF/com/google/android/magisk/customize.sh

    Bash:
    #Magisk modules use $MODPATH as main path
    #Your script starts here:
    
    ui_print "-------------------------------------------------- "
    ui_print " MODS for Android                  "
    ui_print "-------------------------------------------------- "
    ui_print " by @BlassGO      |   Version: 1.0                 "
    ui_print "-------------------------------------------------- "
    ui_print " "
    
    if [ $CUSTOM_SETUP = 0 ]; then
       ui_print " - Installation by MAGISK "
    else
       ui_print " - Installation by KernelSU (or something else)"
    fi
    
    ui_print " -- Installing MODS in /system"
    package_extract_dir system "$MODPATH/system"
    
    ui_print " -- Installing MODS in /vendor"
    package_extract_dir vendor "$MODPATH/system/vendor"
    
    ui_print " -- Installing MODS in /product"
    package_extract_dir product "$MODPATH/system/product"
    
    ui_print " -- Fixing Contexts"
    set_context /system "$MODPATH/system"
    
    ui_print " "
    ui_print " -- Done"
    ui_print " "
    8
    CHANGELOG:
    [CHANGELOG 1.1]
    -- dynamic_install_apk now support redirection of output, APK splits, APK lib folder and -no-replace -no-add flags

    [CHANGELOG 1.2]
    -- Improvements and new functions for smali_kit (Change in syntax of -replace-in-method)

    [CHANGELOG 1.3]
    -- Small improvements to Mounting partitions
    -- smali_kit now ignores abstract methods
    -- dynamic_apktool now supports extra commands for apktool
    -- Now u can use apk_pkg as an equivalent of apk_package


    [CHANGELOG 1.4]
    -- The Dynamic Installer was restructured for greater optimization and organization
    -- A new setdefault "fast_mode" has been added that allows a much faster execution (When activated you will not have the variables of the partitions $system/$vendor/$boot/... and the variables $bins/$all_partitions)
    -- A new "replace" function was added, check the Actions section / Editing Files
    -- filetype function was removed


    [CHANGELOG 1.4-b]
    -- Fixed a fatal bug inside auto_mount_partitions Ooof

    [CHANGELOG 1.5]
    -- Maintenance, fixed and optimized functions
    -- update_file_string and add_lines_string now support any type of strings
    -- If you use " " an empty space with add_lines_string a new empty line will be added to the file
    -- add_lines_string now supports -after-line and -before-line infinitely, you can add text before or after a specific line
    -- ui_print now supports more situations, you can print several lines (ui_print "line1" " " "line3") or a whole paragraph(ui_print "$paragraph") even from Recovery
    -- New function:
    force_update_file_string

    [CHANGELOG 2.0]

    New functions:

    string >> Advanced and easy string manipulation
    run_wait >> Limit the execution time of any process (Includes Dynamic Installer functions)
    is_valid >> Check if files exists and non-empy
    is_number >> Check if is a number
    check_content >> Check if a file exists inside a .ZIP
    getsize >> Return the size of any file
    can_run >> Check if a binary can run on the device
    exist >> Check if files or folders exists
    repeat >> Repeat text by a specific number
    copy >> Force copy files and folders
    move >> Force move files and folders
    echo2 >> Print text as error (For example, the text doesnt appear on the Magisk screen but yeah in the LOG)
    is_zip/is_tar/is_gzip/is_bzip/is_xz >> Check type of some files

    Improved:
    hex_search/hex_check/hex_patch
    >> Important fixes and new functions, full support for hexadecimal manipulation

    dynamic_apktool >> Some fixes and now supports -preserve-signature for APKs and JARs

    update_file/update_file_string/force_update_file/force_update_file_string >> Important fixes and now supports more XML cases and delimiters (-delim flag)
    savestate >> Fixed some errors
    replace >> Fixed some errors

    Extra Fixes:
    -- Fixed infinite loop when using try_mount with uncommon partitions

    New variables:
    $TMP2
    >> Multiple Dynamic Temp Spaces (start_tmp/end_tmp)

    New setdefaults:
    setdefault apex_mount >> Now you can control if you want to mount APEX or not (If you use it in "off" the mounting will be much faster)


    [CHANGELOG 2.1]
    -- Slight errors fixed
    -- Now most of the Dynamic Installer actions support false/positive results (You can use an "if" condition with these actions)
    -- New function: make_overlay was added


    [CHANGELOG 2.2]
    -- A fatal error was fixed in try_mount
    -- Improved functions for updating .props and .xml (update_file_string/update_file/...)
    -- Removed setdefault results (Deprecated)


    [CHANGELOG 2.3]
    -- Fixed defined/undefined/checkvar
    /filtervar functions with some variables
    -- replace function now supports any pattern to find and replace with -recursive flag (Not just whole words)
    -- add_lines now support -after-line and -before-line (Unlimited) and multiple files to add (Unlimited)
    -- umount_all has been improved to avoid "Cannot mount /partition" errors on some devices after installation

    [CHANGELOG 2.6]

    - Maintenance (Some fixes and improvements)
    - Removed setdefault fast_mode (Deprecated)
    - New "Test Mode", now u can test some Dynamic Installer functions in Termux on Android
    - Improved all update_file functions (update_file_string/force_update_file/..)


    [CHANGELOG 2.7]
    - /system_root as RW (Read/Write), you will be able to make changes inside, previously it was mounted in Read/Only and only specific sections like /system in RW

    - smali_kit now supports a search mode for .smali files that have a .method (-print-path)
    - smali_kit now can remove whole .methods (-delete-method)

    - Fixed "Test Mode" (Execution problems
    )

    [CHANGELOG 2.7-b3]
    - Small but important fixes
    - Replaced "flash" function with "force_flash" (So now just exist "flash" to install extra ZIPs)
    - The correct assignment of permissions was ensured with functions that gave them automatically (package_extract_dir, package_extract_file, dynamic_install_apk, .....)


    [CHANGELOG 3.0]

    News:

    • Finally support dalvikvm from Recovery Android 11+ (Beta - You can use apktool and other Smali tools) - setdefault apex_mount is needed
    • Many functions were improved to work in more situations
    Fixes:
    • Fixed issues adding paragraphs or spaces directly with some flags like -after-line -before-line (add_lines_string/smali_kit/...)
    • Fixed package_extract_dir with file names with spaces
    • Fixed error loading .sh that have names with spaces when activating setdefault run_addons
    Improved:
    • find_apk now supports infinite packages to find (find_apk "package1" "package2" "..." "PATH")
    • dynamic_install_apk now supports "-include" flag to include extra files/folders with the apks and "-remove-oat" to remove all oat folders in the destination
    • string function now supports -after-line and -before-line
    • getbins and getblocks functions reformed (were previously deprecated)
    • setdefault devices format improved
    New functions:
    • is_greater/is_equal/is_less (Comparison)
    • make_zip (To make functional ZIPs using ur current Dynamic Installer as base)

    New variables:
    • $chipname that will allow to identify snapdragon/exynos/mediatek/kirin chipsets

    [CHANGELOG 3.1]
    • Improved chipset detection for $chipname variable
    • copy and move functions now can create the destination folders
    • defined and undefined functions now supports infinite variables to check
    • New function set_context to use the contexts of one path in another, the best contexts are logically evaluated for ALL folders and files, although you can also assign the context of a single file to another (Perfect for Magisk modules)
    • New function eval_context to get the most common context in a path (It eval the common results) or just get the context of a single file
    • Now by default find_apk ignores splits and overlays unless you enable it manually with "-include-splits" or "-include-overlays"
    • try_mount can now mount the partitions specifically in Read/Write or Read/Only (By default both are used) with "-read-write" and "-read-only" flags, it also includes "-remount" to unmount the partitions before mounting
    • update_file/update_file_string/force_update_file/.... now supports "-no-spaces" flag to prevent auto-detection of spaces in new lines

    [CHANGELOG 3.2]
    • Some fixes
    • New function patch_fstab to patch fstab properties easily
    • New function contains to check the existence of infinite strings in a file
    • Now string function will only process the first result with the "remove/replace/extract/complete_extract" flags but it can also process all results (-recursive) even in text extraction, also "extract/complete_extract" support returning only paragraphs that have a pattern substring(-pattern), and supports -file flag to directly load a file
    • New Recovery Mode (Similar to Test Mode) to use the Dynamic Installer actions from the Recovery terminal
    • The Test Mode was improved
    [CHANGELOG 3.3]

    News:

    • Some fixes
    • Fixed common A/B partitions mount
    • Fixed exist function with dummy find
    • Fixed find_apk (It was broken)
    • Fixed string (lower and upper)
    • Experimental Support for Virtual Dynamic Partitions
    • Now you can mount .img (RAW) directly, this allows you to make edits without having to redo the .img
    • Support for direct partition mounting/editing when the device is already booted with auto_mount_partitions and try_mount (Experimental)
    Improved:
    • find_block now supports a very fast find without the need for a long wait (-express), also supports the find to be stopped at a specific time (-time)
    • try_mount now supports specifying the block to find/mount (-name), also support specify a file to mount (-file) instead of a partition, also supports "-express" like find_block and extra improvements
    • Improved unmount
    • Improved umount_all
    • Improved is_greater/is_less (Now supports decimal numbers)
    • Improved is_mounted (Now it can check a folder in the current directory without needed of fully path)
    • update_file/update_file_string/force_update_file/force_update_file_string now support -pattern flag using -delim to apply changes only to a segment that has the specific pattern (It analyze all segments within the specified delim)
    New setdefault:
    • New setdefault magisk_support to disable magisk space and just use updater-script (Device booted)
    • New setdefault extraction_speed to change the speed (MB/s) for update/update_zip/write_raw_image functions
    New functions:
    • New function is64bit to check if a binary supports 64bits arch
    • New function echolog to print as error(echo2) and "savelog" in the same time
    • New function printlog to ui_print and "savelog" in the same time
    • New function endlog to stop "savelog" that started with "startlog"
    • New function contains_array to check if a array already have some value
    • New function get_array to get fully value in a array using some pattern
    • New function get_size_ext4 to get the current size of any partition or compatible file (ext4/.img)
    • New function calc to make basic operations like addition, subtraction, division, exponents (also supports parentheses and multiplication but you must use quotes to escape that symbols '()' '*' )
    • New function unify_path to compare one folder with another, this includes a comparison of files that already exist in both paths, if they are not the same, they are replaced or added to the second path
    New functions for Dynamic Partitions:
    • New function checksuper to check if a image/partition is a SUPER image in record time
    • New function get_offset to get the offset of any subpartition inside a SUPER partition/image in record time
    • New function get_group to get the group of any subpartition inside a SUPER partition/image in record time
    • New function get_total_size to get the total size of all subpartitions inside a SUPER partition/image
    • New function start_loop to make new mount point of any subpartition inside a SUPER partition/image (Designed for new Virtual Dynamic Partitions)
    • New function end_loop to end previously made mount point with "start_loop" based on the order of creation (It works like "end_tmp")
    • New function super_rw to enable Read/Write on SUPER partitions/images (Designed for Virtual Dynamic Partitions), this method extracts and converts all internal subpartitions of SUPER (It takes a little time) for this reason you have to add "super_rw" in the updater-script manually
    • New function unlock_all to try convert all internal subpartitions of SUPER to Read/Write on-fly (It doesnt require a very long waiting time like super_rw but it may not work in some cases)
    • New function unlock to convert specific subpartition of SUPER to Read/Write (Like unlock_all doesnt work in some cases)

    [CHANGELOG 3.4]
    • Some fixes
    • Improved umount_all
    • Improved dynamic_apktool (Now it will not decompile "res" from the .APK by default)
    • setdefault devices now support Model names (Example: SM-A515F)
    • New function wipe to wipe any section like system, vendor, product, odm, data, dalvik, cache
    • Read-Only was activated in all native functions of the Dynamic Installer to avoid substitution problems when importing a new shell script (.sh) that contains functions with the same names of the native functions (Now native functions cannot be altered during installation)
    [CHANGELOG 3.5]
    • Now only abort can end the installation with error, previously if the last action used ended in error the whole installation did too
    • When "$TMP" is auto-wiped, files with .log extension will not be deleted to avoid significant loss of information (You will not lose any LOG after installation)
    • New feature off_readonly to notify the Dynamic Installer that you want to modify some functions of its code in your script, with this the specified functions can be replaced during the installation (By default all functions are in Read/Only)
    • Improved package_extract_dir and package_extract_file (Now if a destination path is not provided the files will be returned directly as Text, useful to process files without extracting them)
    • Now update/update_zip/.. supports two new formats .xz and .gz, you can install the files you want using this type of compression, the files will be installed directly (they are not extracted) so using them does not increase the time of installation, it only reduces the size of your ZIP
    [CHANGELOG 3.6]
    • Some fixes
    • Updated Magisk Module installer
    • Fixed "ERROR: Failed to setup busybox" on some devices
    • Now important variables protected with Read/Only (Btw u can use off_readonly)
    • Improved /apex mount
    • Fixed possible slot detection bugs for A/B devices
    • Fixed savestate
    • Improved update/update_zip (By default it will try to set the dest block as Read/Write if possible, else end with error)
    • New experimental variable $encrypted to check if the the device has encrypted internal memory
    • Added more detailed warnings in case of error
    • New function ch_con to manually set the context in mutiple single files/folders
    • New function ch_con_recursive to manually set the context to ALL files/folders of some directory (Btw u can set the context for only files or folders if u want)

    [CHANGELOG 3.7]
    • Some fixes
    • General improvements
    • Improved general Mounting
    • Added /system_ext mounting with auto_mount_partitions
    • Improved is_greater/is_less
    • Added support to Android 12 (This includes /apex mounting, so you can run dexed JAR files like Apktool from Recovery if you enable setdefault apex_mount)
    [CHANGELOG 4.0]
    • Some improvements
    • Improved general setup
    • Added more verifiers to ensure installation
    • Improved string function
    • Improved try_mount function
    • New function apex_mount to mount any .apex file or folder in /apex space
    • New function decode_xml to decode AndroidManifest.xml (Experimental)
    • New function encode_xml to encode AndroidManifest.xml and extra predecoded APK xml (Experimental)
    • New xml_kit function to manipulate XML code quickly and easily, I designed the tool based on XML logic (breaking the XML structure is very unlikely), xml_kit allows u to moving through the XML structure by sections (Very specific pieces can be edited)
    • Now string supports -get-before and -get-after to extract all text after/before some pattern
    [CHANGELOG 4.1]
    • Some fixes
    • Some setup improvements
    • Fixed can_run (Broken with some commands)
    • Ensured plugins extraction
    • Some restructuring and better organization for general installation
    • Improved Test Mode setup
    • Some plugins were separated in META-INF/addons/extra.zip that are not always needed (Now you can remove them)
    [CHANGELOG 4.2]
    • Some fixes
    • A problem was fixed in the extraction of some actions
    • Fixed extraction problems in some ROMs
    • Improved mounting detection for no block sections like /system_ext
    • An error with the text processing base of the Dynamic Installer (string function) was fixed that caused an incorrect interpretation in the verification with -after-line -before-line and extract flags with rare strings
    [CHANGELOG 4.3]
    • Some important fixes
    • To unify syntax with the common edify actions:
      • Now u can also use get_file_prop as file_getprop
      • Added ifelse action (ifelse "action" "else action")
      • Added read_file (read_file "file" "file" "..")
      • Added run_program (run_program "program" arg1 arg2 ...)
    • Now package_extract_dir action supports the extraction of empy folders (Now also u can specify another zip to extract instead of the current installing ZIP)
    • Now package_extract_file action supports the extraction from another zip instead of the current installing ZIP
    • Now dynamic_install action supports empy folders
    • Now set_perm action supports multiple files in a single command line (also now supports symlinks)
    • Now set_perm_recursive action supports multiple directories in a single command line (also now supports symlinks and its much faster)
    • New fullpath action (To get the fully path of any file/folder or symlink, btw it returns the literal symlink path instead of its source)
    • Improved symlink action (Now interprets paths much better, also supports creating infinite symlinks in a single command line)
    • Improved ch_con / ch_con_recursive (General operation)
    • Fixed flags of add_lines_zip/add_lines_addon actions (Previously special flags were not supported as with add_lines)
    • Detection of native variables such as $is64bit, $arch, $arch32, $dynamic_partitions, ... has been improved through a temporary mount attempt to obtain values directly from the current system and vendor (Since some custom Recoverys run on 64bits when the system is 32bits and cause incorrect real time information)

    [CHANGELOG 4.3-b]
    • Improved is_tar action (Tar checking is much faster even on large files)
    • Now is_number support decimal numbers
    • New function is_hex to check Hexadecimal strings
    • New function is_abc to check alphabetic strings
    • New magic_file action to check file types using their Magic Hex values(You can check a file type even if it doesnt have an extension), additionally, u can include an -offset number to skip bytes and also the -bytes per line to get, and with this also the number of hex -line to use (to find the Magic value in a specific range number of hex lines from 1), btw, it includes several types of files already preloaded, using the -type indicator, these dont require additional configuration

    [CHANGELOG 4.4]
    • Improved and fixed general mounting
    • Now you can use "mount_all" as "auto_mount_partitions" function
    • Added /odm mounting in mount_all / auto_mount_partitions function
    • Added extra reports of general mounts
    • super_rw function was discontinued (not effective)
    • Fixed a relevant bug in many functions that support multiple options (if a special flag was used without all the required arguments it would enter an infinite loop)
    • Fixed a relevant bug in the string function that did not allow adding 2 lines with -after-line -before-line (Only 1 lines or 3 lines+ huh)
    • Fixed fruitloop on some devices when using functions that work with superrepack from extra.zip (It was encapsulated for safe use)
    • Improved and fixed xml_kit / replace / ch_con / ch_con_recursive and other functions
    • A minimum free space check is now performed for root "/" only with mount_all / auto_mount_partitions (Some stock firmwares does not even have 1 Byte free and some actions / editions cannot be performed)
    • Now the string function supports replacing with multiple lines all the lines that contain a pattern (replace_line flag)
    • Now the get_file_prop / file_getprop functions supports multiple files to find a specific prop
    • Now the replace function supports replacing with multiple lines all the lines that contain a pattern (-all-line flag)
    • Now is_abc function accepts spaces and new lines (But it will only be True if all visible characters are only alphabetic)
    • Now string function can be forced to always return a result with the "force" flag (previously nothing was returned if the original text was equal to the result)
    • New functions saveperm / restoreperm to save and restore permissions (UID/GID/MODE) of all files/folders in a path (Recursively) or on single files
    • New functions savecontext / restorecontext to save and restore contexts of all files/folders in a path (Recursively) or on single files
    • New function eval_perm to get the most used Permission/Mode of a path or a single file
    • New function eval_user to get the most used User ID of a path or a single file
    • New function eval_group to get the most used Group ID of a path or a single file
    • New function eval_all_perm to get the most used User ID/Group ID/Mode of a path or a single file
    • New function get_all_perm to get the User ID/Group ID/Mode of a folder or a single file
    • New function get_context to get the context of a single folders/files
    • New function is_text to check ANY visible character, if there are only empty spaces or new lines it will return False.
    • Added cpio / ramdisk format in magic_file function ( with -type flag)
    • New setdefault permissions to change the default permissions for folders/files used by ALL Dynamic Installer functions
    • New function is_same_mount to check if two folders are linked to the same partition (For example /system and /system_ext use the same partition in most devices)
    • New Edify simulated functions greater_than_int/less_than_int/concat/stdout
    • New number comparison functions is_greater_equal / is_less_equal
    • New function convert to convert any type of units, mainly for storage units such as b, B, KB, MB, GB, TB, there is no combination limits (It returns completely decimal or integer numbers)

    [CHANGELOG 4.4-b]
    • Fixed some warnings
    • Added Unisoc chipset detection for the native variable $chipname
    • smali_kit improved, fixed and slightly restructured
    • smali_kit now supports string function fixes / improvements with -after-line -before-line flags
    • Nothing more

    [CHANGELOG 4.4-b3]
    • General improvements
    • Some mount / unmount improvements
    • Improved /apex configs for Android 12
    • Fixed make_overlay (Due to changes with the dynamic_apktool it did not work correctly)
    • Now the setdefault permissions supports User ID and Group ID (UID/GID)
    • Optimized device verification with setdefault devices
    • Replaced native busybox reboot action with /system/bin/reboot (best)
    • Find within folders symlinks is now supported by default in set_context / dynamic_install / dynamic_install_apk / find_apk / saveperm / savecontext / restoreperm / restorecontext functions (This allows deeper finds)
    • Now ui_print will better evaluate prints for unconventional installations (adb)
    • New variables $di_version and $main_version (Information of the current version of the Dynamic Installer)
    • New function convert_edify to try to convert Edify scripts to Dynamic Installer scripts (Experimental)

    [CHANGELOG 4.5]
    • General improvements / maintenance
    • Added Installer Configs in the log
    • Thanks to a new dynamic temporary space ($TMP), additional ZIPs can now be flashed without risk of affecting the current installation
    • flash/flash_addon/flash_zip functions has been improved to take advantage of the new $TMP, also now supports a third optional argument "print" to allow the new ZIPs to print text on Recovery
    • add_lines / add_lines_string /add_lines_addon / add_lines_zip functions now supports creating new files (previously they only supported editing existing files)
    • magic_file now supports "sparse" type to detect Android Sparse IMGs

    [CHANGELOG 4.5-b]
    • Device verification has been optimized (setdefault devices - Avoided repeating the verification for device information already checked)
    • package_extract_dir fixed, due to a logical error when there were two or more folders in the same ZIP path that started with a common pattern (system system1 system2), when extracting the base pattern (In this example "system"), all these folders were extracted instead of just one

    [CHANGELOG 4.5-b2]
    • General maintenance
    • Fixed a serious issue that would freeze/reboot some devices when the DI was installed by Magisk (Thx to @quadraticfunction for the tests)
    • Fixed checksuper function (Due to a logic error, the device could be bricked after use)
    • Added more checks (Like Read/Write permissions) in most functions for more understandable logs
    • Replaced "setdefault run_addons" with "setdefault import_addons" (Now allows importing all $addons plugins with .sh extension before main script execution)
    • New functions create_dir / create_file (Ensure new files or folders easily)
    • New function testrw (To test if one or more folders has write permissions)
    • New function testvarname (Allows to verify if the text is valid to be used as a variable name)

    [CHANGELOG 4.5-b3]
    • Fixed find_apk function (Skipping overlays and splits did not work when using -recursive find)
    • Fixed replace function (After text replacement, if the result had not even 1 visible character, the whole operation failed)
    • New remove function to remove text in a file or -recursive in a directory
    • New multi_option function to get a user selection from a list of many options
    • New apk_main function to get the activity that can be launched in an APK (if it exists)
    • New apk_icon function to get the internal path of the icon of an APK
    • New apk_launch function to launch the main launchable activity (or a specific activity) of some pre-installed APP on the device (when its booted)

    [CHANGELOG 4.6]
    • General improvements and maintenance
    • New obfuscate function that allows you to encode the shell script code (or Dynamic Installer scripts), keeping it working but making it difficult for common users to read (you can mix obfuscated code with readable code)
    • New apk_install function to install .apk or .apkm files (ApkMirror), the inclusion of splits together with main .apk/.apkm is supported (It is necessary that the device is already booted)
    • New apk_install_recursive function, installs all .apk/.apkm that are inside a folder, also supports creating subfolders to group .apk/.apkm with additional splits
    • New function stderr (Run and print any action as error)
    • New function stdprint (Run and print any action on the screen - ui_print)
    • New set_metadata_recursive function (Simulated Edify function)

    [CHANGELOG 4.6-b]
    • General improvements and fixes
    • Many functions were optimized at the code level
    • It is now possible to use "not" to negate an expression (Equivalent to using "!"), for example:
    Bash:
    if not exist "/system/ole"; then
       ui_print "ERROR"
    fi
    • Improved reports (logs) of package_extract_file / package_extract_dir, now you can easily identify extraction problems
    • Importing addons with "setdefault import_addons" will now be alphabetical (to control load order)
    • Added simg2img to extra.zip for 64bit devices only
    • New functions int, float, round to obtain integer, decimal or rounded numbers (Math operations are supported directly)
    • New function get_all_subparts to get the name of all subpartitions of an img/partition (SUPER)
    • New end function to stop the script (similar to abort), but without ending the installation on error
    • The repeat function now supports paragraphs (Multi line)
    • The contains function now supports finding paragraphs (multi line)
    • The multi_option function now supports an optional third argument "loop" to keep an infinite loop of options on a constant restart (Until a valid option is selected)
    • The exist function now supports specific recognition for blocks and symlinks (exist symlink "TEST", exist block "/dev/block/dm-0")
    • The unlock_all/unlock functions now support specifying an IMG/Partition
    • You can now also use the -file option on try_mount to specify a block to mount (Previously focused only on specifying files)
    • update/update_zip/update_addon functions now support Sparse IMGs experimentally (need to import simg2img)

    [CHANGELOG 4.6-b2]
    • Fixed a serious problem with the new "not" logical function (it didn't work at all due to an implementation problem)
    • The "installzip" native variable was unlocked (Previously in Read-Only by default), because it conflicted with the functionality of using external ZIPs with package_extract_file / package_extract_dir
    • New function find_content to get the paths of all the contents of the ZIP that match the established patterns

    [CHANGELOG 4.7]
    • Updated apktool to v2.7.0 (with baksmali/smali 2.5.2)
    • Fixed de/compilation problems of the framework.jar (a12+)
    • Automatic import of all APEX binaries (This ensures access to actions completely isolated from /system)
    • Importing APEX binaries fixes dalvikvm issues on some devices (Required for running JARs)
    • patch_fstab fixed (Now only active lines will be patched)
    • dynamic_apktool function can now check and add missing original resources in the final APK/JAR
    • dynamic_apktool function now includes a specification of the device API (This prevents bugs in newer apktool versions)
    • New replace_name function to flexibly rename multiple files/folders (or just one)


    [CHANGELOG 4.7-b]
    • Fixed a bug in the dynamic_apktool function (Checking/adding original resources even extended to "res", causing slower decompile and recompile errors)
    • dynamic_apktool now has the -no-extras option to disable original resource checking/adding (Although it is recommended to keep it)
    • dynamic_apktool now has the -no-api option to disable automatic specification of the device API (Although it is recommended to keep it)
    • dynamic_apktool now has the -use-baksmali option to set an external baksmali.jar (DEXED) instead of the native apktool one


    [CHANGELOG 4.7-b2]
    • The structure and operation of the update-binary have been improved (This script is the initial launcher of the ZIP, its improvement ensures the execution of the ZIP in more hostile environments or with compatibility problems and a more accurate logging in case of critical problems)
    • Fixed a small warning in the make_zip function
    • Fixed long timeouts when unmounting partitions mounted on non-common paths
    • Mount functions in general now have better logging warnings
    • By default the "unzip" binary will try to change to some external version, this to try to avoid extraction problems when the size of the ZIP exceeds Busybox's "unzip" support (However, not all versions of unzip support extracting files larger than 4GB)
    • testrw function can now identify a Read/Only mounted folder (Without the need to create a file, empty file creation for write verification will now only be used for folders not previously mounted)
    • try_mount function now ensures mounts specified as Read/Write only, i.e. even if the mount is "successful", if it really is not writeable to it, it will be treated as failed
    • dynamic_apktool now supports -use-smali to specify an external smali.jar(DEXED) instead of the one already included in apktool
    • savelog, echolog and printlog functions now support multiple lines (each argument is one line to print/write)
    • New change_bin function to try to use another available binary, remembering that Busybox binaries are used by default, with this it is possible to try to change them for available external versions
    • New "setdefault ensure_root", if set to "off", mount_all will allow Read-Only systems (Even if you can't make edits internally, you can still mount read-only, previously if the device had any restrictions like EROFS, the complete installation was aborted warning of a read-only system)
    • "setdefault magisk_support" now supports the "force" option, to always use Magisk space (customize.sh), even from a Recovery install

    [CHANGELOG 4.7-b3]
    • Fixed a fatal bug that kept all functions using superrepack in an infinite loop. Oops!
    • No more

    [CHANGELOG 4.8]
    • Support for KernelSU (or any other future Manager as long as it does not stray from the general logic of Magisk modules). Strictly requires some additional files, as will be detailed in the main Thread
    • New native variable $CUSTOM_SETUP, which allows identifying custom setups such as KernelSU (or any other)
    • Fixed obtaining valid APEX packages, as well as general support for Android 14+ standards for the operation of dalvikvm (Currently works perfectly on AOSP A14, but not on OneUI 6, this will possibly be fixed in future versions or a specific plugin)
    • New optional "setdefault mount_all", it is not a standard added to the native setdefaults in the updater-script header, it is simply an option that can be changed at any time during installation before using the "mount_all" action. If specified in "ro" mount_all will always work in Read/Only mode for all mounts. By default, when not specified, Read/Write mounts are attempted and if one fails, the latter is set to Read/Only
    • is_number function now supports negative numbers

    [CHANGELOG 4.8-b]
    • Fixed a bug reported by @saadelasfur27 in TWRP versions 3.7.1+. The assignment/generation of free loop devices for mounting APEX/CAPEX was freezing the Script when trying to do it on one that already existed in Recovery, consequently, the mount_all action never finished.
    6

    ALL ACTIONS
    -----------------------------------
    ABORT / END:
    • abort "Text" "Text" "..."
    Print an optional message and then terminate the whole installation as failed
    Bash:
    abort "There was a problem, stopping installation!"

    • end "Text" "Text" "..."
    Print an optional message and then terminate the whole installation but without failure alert
    Bash:
    end "Nothing to do..."
    -----------------------------------
    VARIABLES / SUB-PROCESSES:
    How to play with variables and sub-processes
    • MyVar="Text"
    Assign a textual value to a variable (MyVar)

    NOTE: There is a distinction between uppercase and lowercase for the name of the variables ("a" and "A" can be used as two different variables)

    WARNING: The name of the variable must always start with alphabetic characters or the "_" character (A or __A is valid), it cannot start with numbers ( 90 or 90__MyVar it's not valid), fulfilling this start condition, the rest of the name can have both numeric characters, alphabetic characters or "_" character ( MyVar__90 is valid), the number of times you want
    Bash:
    a="Ole"
    A="Just test"
    A10="a b c d e"
    __A="1 2 3 4 5"
    __B__="W e l c o m e !"
    _ABC_1_2_3="-------------------------"

    • $MyVar / ${MyVar} / $(sub-process)
    The "$" symbol is used to invoke variables or create sub-processes

    By default, values for both Variables and Actions are taken as literal text
    Bash:
    MyVar="W e l c o m e !"
    
    #It will literally print "MyVar"
    ui_print "MyVar"

    But with the symbol "$" it is possible to make that text be interpreted, instead of being taken as something literal
    Bash:
    __B__="W e l c o m e !"
    
    MyVar="$__B__"
    
    #It will be print "W e l c o m e !"
    ui_print "$MyVar"

    For variables, sometimes it is necessary to limit the text that should be interpreted, for this use curly brackets ${MyVar}
    Bash:
    MyVar="W e l c o m e "
    
    ui_print "${MyVar}Blass!"

    Finally, some available Actions can return text, being possible to include this text as a value for a Variable or another Action. For this the symbol "$" is used, followed by a grouping with parentheses $(action)

    Bash:
    #The "string" action will return "welcome" in uppercase "WELCOME" and this will be the printed text
    #Result: WELCOME Blass!
    ui_print "$(string upper "welcome") Blass!"
    
    #Same for Variables
    Result="$(string upper "welcome") Blass!"
    ui_print "$Result"
    -----------------------------------
    LOGIC OF EXPRESSIONS:
    As in many programming languages, the use of logical connectors is supported
    • Action/Expression && Action/Expression && Action/Expression ...
    "&&" allows to join several expressions/actions, it is interpreted as "and", the whole line will end without error, if and only if, all expressions/actions end without any error

    NOTE: If the previous action/expression ends in error, the next expression/action will not even be executed
    Bash:
    exist "/system/build.prop" && exist "/system/ole" && exist "/system/a"

    • Action/Expression || Action/Expression || Action/Expression ...
    "||" allows to join several possible expressions/actions, it is interpreted as "or", the whole line will end without error, if any of the actions/expressions end without error (It is not necessary for all of them to do, but at least one must be satisfactory)

    NOTE: If the previous action/expression completes without error, the next expression/action will not even be executed
    Bash:
    exist "/system/build.prop" || exist "/system/ole" || exist "/system/a"

    • (Action/Expression && Action/Expression) || (Action/Expression && Action/Expression) ...
    "()" parentheses allow multiple Actions/Expressions to be grouped together, making them form a new Expression

    NOTE: The grouped actions/expressions will be executed in a separate space, that is, they will not be able to alter values in your main script
    Bash:
    (exist "/system/build.prop" && exist "/system/ole") || (exist "/system/huh" && exist "/system/a")

    • not Action/Expression
    "not" allows to negate any expression/action, making its operation inverse, that is, if the expression/action ends with an error, it will be interpreted inversely as successful, and if it ends without error, it will be interpreted inversely as failed.

    You can use either "not" or "!", they are the same

    NOTE: "not" only affects each individual action/expression, new actions/expressions joined with "&&" or "||" will not be affected by the negation

    WARNING: When negating a grouping "()" it is important to understand that also the connectors "&&" and "||" are inverted, that is, "&&" in negation becomes "||" and vice versa
    Bash:
    not exist "/system/build.prop" && not exist "/system/ole" && not exist "/system/a"
    
    #Using grouping it is possible to avoid repetitive use of "not"
    #Note the change of "&&" to "||"  to preserve the logic of the previous example
    not (exist "/system/build.prop" || exist "/system/ole" || exist "/system/a")
    -----------------------------------
    MOUNT:
    • mount_all
    It will mount the main partitions automatically (/system_root, /system, /system_ext, /vendor, /product, /odm , /apex only if setdefault apex_mount enabled)

    • try_mount "part" "part" "part" "..."
    Mount specific partitions (By default in Read/Write if possible or Read/Only)

    NOTE: For /system_root, /system_ext, /system, /vendor, /product, /odm or /apex use mount_all

    -read-write (-rw) = To only mount partitions in Read/Write

    -read-only (-ro) = To only mount partitions in Read/Only

    -remount (-re) = Unmount partitions before mounting

    -express (-e) = This does a superficial find of the partition, avoiding a long waiting time in case that partition does not exist

    -name (-n) = Specify a name to find the partition to mount instead of the automatic name (For A/B devices, if the slot is not specified, the active slot will be used by default)

    -file (-f) = Mount a file (only .IMG RAW supported) / Or specify a partition (block) to mount
    Bash:
    #Read/Write if possible or RO
    try_mount /cache /optics /prism /odm /vendor
    
    #Only Read/Write
    try_mount -rw /optics /prism
    
    #Only Read/Only
    try_mount -ro /optics /prism
    
    #Unmount before mount
    try_mount -remount /optics /prism
    
    #Specifying custom name to find the Partition Block to Mount
    try_mount -name "system" /test
    
    #For A/B? Its the same
    #Supports A/B by default with common names
    #Use Active Slot by default
    try_mount -name "vendor" /test
    #Or optionally specify a slot
    try_mount -name "vendor_b" /test
    
    #Don't look for the partition block for long time
    try_mount -express /system
    
    #Specifying a FILE to mount instead of partition
    try_mount -file "/sdcard/system.img" /test
    
    #Specifying a block to mount
    try_mount -file "/dev/block/dm-0" /system_root
    
    #Mix
    try_mount -remount -rw /optics /prism
    try_mount -express -name "vendor" /mnt/vendor
    try_mount -ro -file "/sdcard/vendor.img" /mnt/vendor
    
    #Mount subpartition of SUPER image (.img RAW)
    try_mount -file "/sdcard/super.img" -name "system" /mnt/system_inside_SUPER
    
    #Mount subpartition of SUPER image (.img RAW)
    #A/B super.img need the slot to mount
    try_mount -file "/sdcard/super.img" -name "system_a" /mnt/system_inside_SUPER

    • apex_mount ".apex/.capex File or Folder"
    To mount Android Pony Express (APEX) files or folders in /apex space

    NOTE: Supports .apex and New Android 12 .capex File formats

    Bash:
    #Mount APEX File
    #/system/apex/com.android.runtime.apex
    apex_mount "/system/apex/com.android.runtime.apex"
    
    #Mount APEX Folder
    #/system/apex/com.android.runtime
    apex_mount "/system/apex/com.android.runtime"

    • umount_all
    Unmount ALL mounted partitions with mount_all / auto_mount_partitions, ALL mounted partitions with try_mount and ALL mounted partitions with apex_mount

    • find_block "Block name"
    In case you need to get the exact block of a partition (Supports A/B by default)

    NOTE: By default if a partition block isnt found, it will stop after 5 seconds to avoid an infinite loop

    -express (-e) = This does a superficial find of the partition, avoiding a long waiting time in case that partition does not exist

    -time (-t) = Does a full find but only for a limited time


    Bash:
    #For example to get real system block
    #In this example it will return "/dev/block/dm-0"
    find_block "system"
    
    #For A/B? Its the same
    #Supports A/B by default with common names
    find_block "system"
    
    #Fast find
    find_block -e system
    
    #Find with limited time
    find_block -t 5 system

    • is_same_mount "FOLDER" "FOLDER"
    Check if two folders are linked to the same partition (For example /system and /system_ext use the same partition in most devices)

    NOTE: Both folders must be mounted

    Bash:
    if is_same_mount "/system" "/system_ext"; then
       ui_print "/system_ext is inside the system partition"
    else
       ui_print "/system_ext must have a separate partition"
    fi
    -----------------------------------
    EXTRACT:
    • package_extract_dir "Folder inside ZIP" "Destination Folder"
    You can extract contents of a whole folder within the ZIP to an external path

    NOTE: You can define a third argument with the path of an external ZIP, this ZIP will be used instead of the current installation ZIP
    Bash:
    package_extract_dir "Folder" /system
    
    #Extracting from an external ZIP
    package_extract_dir "Folder" /system "/sdcard/External.zip"
    • package_extract_file "Fully File path Inside ZIP" "Fully Dest path outside ZIP"
    You can extract a single file from the ZIP to an external path (You can rename the resulting file) or you can get it directly as Text if u want

    NOTE: You can define a third argument with the path of an external ZIP, this ZIP will be used instead of the current installation ZIP
    Bash:
    #Extract to an external path
    package_extract_file "Folder/file.txt" /system/test.txt
    
    #Just get the File content directly as Text
    #If you dont add a destination path
    content=$(package_extract_file "Folder/file.txt")
    
    #Extracting from an external ZIP
    package_extract_file "Folder/file.txt" /system/test.txt "/sdcard/External.zip"
    -----------------------------------
    WIPES:
    • wipe "Common Partition name"
    To wipe any section like system, vendor, product, odm, data, dalvik, cache

    data = Wipe /data but IGNORE /data/media (Internal storage)

    userdata = Fully /data wipe

    Bash:
    #To wipe /system
    wipe system
    
    #To wipe /data but WITHOUT Internal Storage
    wipe data
    
    #To wipe ALL /data
    wipe userdata
    
    #To wipe dalvik-cache
    wipe dalvik
    
    #To wipe cache
    wipe cache
    
    #Mix
    #To wipe /data /system /vendor /product /cache
    wipe data cache system vendor product
    -----------------------------------
    USER SELECTION:
    • Simple selection (Yes or No)
    Bash:
    if $yes; then
       #Action if the user presses the volume up button
       package_extract_dir system /system
    
    else
       #Action if the user presses the volume down button
       package_extract_dir vendor /vendor
    
    fi

    If the user presses the volume up button, it will be interpreted as YES

    If the user presses the volume down button, it will be interpreted as N0


    • multi_option "Variable" <Number of options> <loop>
    loop = With a specified number of options, the word "loop" will do an infinite loop constantly resetting the number of options until one is selected (instead of ending in error if all options are discarded)

    NOTE: If a number of options is not specified, an infinite loop is created until some N option number is selected (this number will be returned)
    Bash:
    ui_print " 1. First option"
    ui_print " 2. Second option"
    ui_print " 3. Third option"
    ui_print " 4. Fourth option"
    
    multi_option "my_menu" 4
    
    #Or If you want to create an options loop:
    #multi_option "my_menu" 4 loop
    
    if undefined my_menu; then
       abort " No valid selection was obtained "
    fi
    
    if [[ $my_menu == 1 ]]; then
       #Actions for the option 1
       ui_print "Welcome to option 1"
    elif [[ $my_menu == 2 ]]; then
          #Actions for the option 2
          ui_print "Welcome to option 2"
    elif [[ $my_menu == 3 ]]; then
          #Actions for the option 3
          ui_print "Welcome to option 3"
    elif [[ $my_menu == 4 ]]; then
          #Actions for the option 4
          ui_print "Welcome to option 4"
    fi
    Like $yes, the volume buttons are used (Down to discard an option / Up to select that option)
    -----------------------------------
    SOME EXTRA EDIFY REFERENCES:
    To make the environment a bit easier for users who have used traditional installation scripts (Edify Scripts), these are some additional simulated Edify actions.
    • file_getprop "file with props" "file with props" "..." "prop to extract"
    Extract one prop (a = b) from multiple external files (The value will only be returned once)
    Bash:
    file_getprop /system/build.prop "ro.build.display.id"
    
    file_getprop /system/build.prop /vendor/build.prop /system_ext/build.prop "ro.build.display.id"
    
    myid=$(file_getprop /system/build.prop "ro.build.display.id")

    • ifelse "Test this action" "Else run this action"
    Supports: _addon and _zip extension

    Execute an action and if it fails, execute action two (It is necessary to use a single quotes when you want to include double quotes in the action)


    Bash:
    #Notice that single quotes are used
    ifelse "is_mounted /system" 'ui_print "/system inst mounted"'
    
    #Btw the best practice is using this syntax
    is_mounted /system || ui_print "/system inst mounted"
    
    #Or for multiple actions
    if is_mounted /system; then
       ui_print "/system already mounted"
       ui_print "Done"
    else
       ui_print "/system inst mounted"
       ui_print "ERROR"
    fi

    • greater_than_int / less_than_int "Number" "Number"
    Allows you to check if a number is greater or less than another (Supports decimals)
    Bash:
    if greater_than_int "2.2" "1.5"; then
       ui_print "Is greater"
    else
       ui_print "Is less or equal"
    fi
    
    if less_than_int "1.5" "2"; then
       ui_print "Is less"
    else
       ui_print "Is greater or equal"
    fi

    • concat "string" "string" "..."
    Allows concatenation of multiple strings
    Bash:
    var="just test"
    result=$(concat "h u h" "$var" "    a  ")

    • stdout [Any action]
    Allows to execute an action and send all its results (Including errors - Stderr) to Stdout

    NOTE: This does not ensure a screen print, for it use stdprint

    Bash:
    # echo2 prints text as ERROR (Stderr)
    # But stdout converts it to main print text
    stdout echo2 uwu

    • stderr [Any action]
    The inverse of the stdout function, executes an action and prints everything as Error (Stdout to Stderr)
    Bash:
    #The impression will only be visible in the general log
    stderr echo uwu

    • stdprint [Any action]
    Execute the action and print its main results on the screen (Print Stdout in Recovery)
    Bash:
    #The print will be visible on the installation screen
    stdprint echo uwu
    
    #This allows to visualize the process of an action even in the Recovery
    stdprint apktool --help

    • read_file "file" "file" "..."
    Get the contents of one or more files
    Bash:
    read_file "$TMP/file.txt"
    
    #Or with the native form
    cat "$TMP/file.txt"

    • run_program "program" arg1 agr2 "..."
    You can execute any supported file as a sh or binary, the file automatically receives the execution permissions and also you can send the arguments you want to that file
    Bash:
    run_program "$TMP/busybox" --help

    • symlink "FILE" "symlink" "symlink" "..."
    You can create multiple symbolic links from a single file
    Bash:
    #Creating symlinks to busybox
    symlink "$TMP/busybox" "$TMP/chmod" "$TMP/sed" "$TMP/tar"

    • convert_edify "Edify Script" "Result"
    Allows you to try to convert Edify scripts to the script format supported by the Dynamic Installer (Experimental, it is recommended to manually review the result and not use it as something definitive)
    Bash:
    #Normal use
    convert_edify "/sdcard/edify-script" "/sdcard/result"
    
    #If no destination is specified, the script will be overwritten.
    convert_edify "/sdcard/edify-script"
    -----------------------------------
    GET VALUES:
    • import_config "file with props"
    Supports: _addon and _zip extension

    Convert prop lines (a = b) to variables ($a)

    NOTE: There are exceptions, if the name of the prop has some strange special character it will not become a variable (The name of a variable does not support those characters)

    example.prop

    Code:
    name=Some name
    current_version=v1.1.0
    i_d_k=S o m e t h i n g

    import_config
    Bash:
    import_config "$TMP/example.prop"
    ui_print "$name"
    ui_print "$current_version"
    ui_print "$i_d_k"

    • get_file_prop "file" "file" "..." "prop to extract"
    Extract one prop (a = b) from multiple external files (The value will only be returned once)
    Bash:
    get_file_prop /system/build.prop "ro.build.display.id" 
    
    get_file_prop /system/build.prop /vendor/build.prop /system_ext/build.prop "ro.build.display.id"
    
    myid=$(get_file_prop /system/build.prop "ro.build.display.id")

    • getdefault "file" "default to extract"
    Extract "setdefault" values from external files (Multi-line content not supported)

    something.txt

    Code:
    setdefault ole "a b c"
    setdefault okay "d e f"
    setdefault test "s o m e t h i n g"

    getdefault
    Bash:
    getdefault "$TMP/something.txt" okay
    getdefault "$TMP/something.txt" test
    
    my_var=$(getdefault "$TMP/something.txt" okay)

    • get_array "String Pattern" "Fully ARRAY"
    To get fully value in a array using some pattern
    Bash:
    #First defined array
    test=("First array" "Other array" "A B")
    
    #Get fully value in the array
    #It will returns "Other array"
    get_array "Other" "${test[@]}"
    
    content=$(get_array "Other" "${test[@]}")

    • get_size_ext4 "Partition or .img"
    To get the current size in Bytes of any partition or compatible file (RAW .img)
    Bash:
    #Get size of system block
    get_size_ext4 "$(find_block system)"
    
    #Get size of some .img in /sdcard
    get_size_ext4 "/sdcard/vendor.img"
    
    size=$(get_size_ext4 "$(find_block system)")

    • fullpath "File/Folder/Symlink"
    To get the fully path of any file/folder or symlink, btw it returns the literal symlinks paths instead of its sources
    Bash:
    fullpath "folder/file"
    
    complete_path=$(fullpath "folder/file")

    • find_content "Pattern" "Pattern" "..." "ZIP FILE"
    Returns the paths of all the contents of the ZIP that match the established patterns

    -dirs (-d) = Find only folders in the ZIP (By default only Files)
    -regex (-r) = Enable Regular Expression support for patterns

    -maxdepth (-max) = A number that limits the range of the resulting paths, considering the root of the ZIP as the first level (1) (That is, if "-maxdepth 2", then only contents that are in a maximum range from the root (1) to a single folder (2) of the ZIP will be returned, if the path extends to two subfolders (-maxdepth 3) or more they will not be returned for example)


    Bash:
    #By default, any File path that has the pattern internally is found
    find_content ".mp4" ".mp3" /sdcard/ole.zip
    
    #Find only Folders
    find_content -d "huh" /sdcard/ole.zip
    
    #Using Regular Expressions
    find_content -regex "(.mp4|.mp3)$" /sdcard/ole.zip
    
    #You can even include multiple Regex
    find_content -regex "(.mp4|.mp3)$" "^ole.*(.jpg|.png)$" /sdcard/ole.zip
    
    #Limiting the results to only files that are in the root of the ZIP
    find_content -max 1 ".mp4" ".mp3" /sdcard/ole.zip
    
    #Limiting results to only folders that are at most 2 levels
    find_content -max 2 -d "huh" "ole" /sdcard/ole.zip
    
    #To get the paths of all the folders in the ZIP that are at most 3 levels
    #Regex has infinite possibilities
    find_content -d -max 3 -regex ".*" /sdcard/ole.zip
    -----------------------------------
    SET PERMISSIONS:
    • set_perm "UID" "GID" "MODE" "FILE/FOLDER" "FILE/FOLDER" "..."
    Allows you to define the UID (User ID), the GID (Group ID) and the MODE (Permissions) for multiple single files/folders (it is NOT recursive)
    Bash:
    set_perm 0 0 0755 /system/build.prop
    
    #Multiple files/folder
    set_perm 0 0 0755 /system/build.prop /system/test.txt /data/folder

    • set_perm_recursive "UID" "GID" "FOLDERs MODE" "FILEs MODE" "FOLDER" "FOLDER" "..."
    Allows you to define the UID (User ID), the GID (Group ID) and the MODE (Permissions) for ALL files and folders within a multiple directories (Recursive), the MODE is one specific for files and another for folders
    Bash:
    set_perm_recursive 0 0 0644 0755 /system
    
    #Multiple DIRECTORIES
    set_perm_recursive 0 0 0644 0755 /system /vendor /product

    • saveperm "FILE/FOLDER" "FILE/FOLDER" "..."
    To save the UID (User ID), the GID (Group ID) and the MODE (Permissions) of all files/folders in a path (Recursively) or on single files

    NOTE: When any folder is specified it will automatically expand to all its contents

    Bash:
    #Single file
    saveperm /system/build.prop
    
    #Recursively (All contents of this folders)
    saveperm /system/app /system/bin /vendor

    • copy_perm_list "Destination File"
    You can export the list of permissions generated by "saveperm" (this list is a substitute for "saveperm", in other words you can reuse this list in new projects without the need to use "saveperm" again)

    Bash:
    #Export the current permission list
    copy_perm_list /sdcard/permissions.txt

    • restoreperm "FILE/FOLDER" "FILE/FOLDER" "..."
    To restore the UID (User ID), the GID (Group ID) and the MODE (Permissions) previously saved with "saveperm" of all files/folders in a path (Recursively) or on single files

    -file (-f) = You can load a previously saved list (with this you can avoid using "saveperm")

    NOTE: When any folder is specified it will automatically expand to all its contents, additionally if the save was recursive you can restore the permission of a single file within that directory

    Bash:
    #Single file
    restoreperm /system/build.prop
    
    #Recursively (All contents of this folders)
    restoreperm /system/app /system/bin /vendor
    
    #Use a previous list
    restoreperm -file "$TMP/permissions.txt" /system/app /system/bin /vendor

    • eval_perm / eval_user / eval_group / eval_all_perm "FILE/FOLDER"
    They are functions that allow evaluating the most common UID (User ID), the GID (Group ID) and the MODE (Permissions) within a directory or a single file.

    Bash:
    #Get only the Mode (Permissions)
    eval_perm /system/build.prop
    eval_perm /vendor
    
    #Get only the User ID
    eval_user /system/build.prop
    eval_user /vendor
    
    #Get only the Group ID
    eval_group /system/build.prop
    eval_group /vendor
    
    #Get only the Group ID
    eval_group /system/build.prop
    eval_group /vendor
    
    #Get the User ID / Group ID / Mode
    eval_all_perm /system/build.prop
    eval_all_perm /vendor

    • get_all_perm "FILE/FOLDER"
    Unlike eval_all_perm, it returns the literal User ID / Group ID / Mode of a folder, instead of evaluating common results within it.

    Bash:
    #Get the User ID / Group ID / Mode
    get_all_perm /system/build.prop
    get_all_perm /vendor
    -----------------------------------
    GET/SET CONTEXTS:
    Contexts in Android (Linux) are properties of all files or folders that determine the type of file or folder and allow the system to know how to treat or catalog that file/folder

    NOTE: As Magisk modules work as a layer on top of the system, when you include files within your module they will be installed without any defined context and without a context you could have unwanted results.
    • eval_context "FOLDER or File"
    It will find and print the most used context for files and folders (It eval the common results) in a directory or it can just return the context of a single FILE.
    Bash:
    #It will return u:object_r:system_file:s0
    eval_context /system
    
    #It will return u:object_r:vendor_overlay_file:s0
    eval_context /vendor/overlay
    
    #It will return u:object_r:sec_efs_file:s0
    eval_context /efs
    
    #Get context of a single file
    #It will return u:object_r:system_file:s0
    eval_context /system/build.prop

    • get_context "FOLDER or File"
    Unlike eval_context, it returns the literal context of a folder, instead of evaluating common results within it.
    Bash:
    #It will return u:object_r:system_file:s0
    get_context /system/app
    get_context /system/build.prop

    • set_context "PATH or FILE" "PATH or FILE"
    To use the contexts of one path in another, the best contexts are logically evaluated for ALL folders and files, although you can also assign the context of a single file to another (Perfect for Magisk modules)
    Bash:
    #It will apply all the contexts of /system in "$MODPATH/system"
    set_context "/system" "$MODPATH/system"
    
    #It will apply all the contexts of /vendor in "$MODPATH/system/vendor"
    set_context "/vendor" "$MODPATH/system/vendor"
    
    #It will apply all the contexts of /vendor/etc in "$MODPATH/system/vendor/etc"
    set_context "/vendor/etc" "$MODPATH/system/vendor/etc"
    
    #It will apply the context of /system/build.prop in /data/test/test.prop
    set_context "/system/build.prop" "/data/test/test.prop"


    • savecontext "FILE/FOLDER" "FILE/FOLDER" "..."
    To save the contexts of all files/folders in a path (Recursively) or on single files

    NOTE: When any folder is specified it will automatically expand to all its contents

    Bash:
    #Single file
    savecontext /system/build.prop
    
    #Recursively (All contents of this folders)
    savecontext /system/app /system/bin /vendor

    • copy_context_list "Destination File"
    You can export the list of contexts generated by "savecontext" (this list is a substitute for "savecontext", in other words you can reuse this list in new projects without the need to use "savecontext" again)

    Bash:
    #Export the current contexts list
    copy_context_list /sdcard/contexts.txt

    • restorecontext "FILE/FOLDER" "FILE/FOLDER" "..."
    To restore the contexts previously saved with "savecontext" of all files/folders in a path (Recursively) or on single files

    -file (-f) = You can load a previously saved list (with this you can avoid using "savecontext")

    NOTE: When any folder is specified it will automatically expand to all its contents, additionally if the save was recursive you can restore the context of a single file within that directory

    Bash:
    #Single file
    restorecontext /system/build.prop
    
    #Recursively (All contents of this folders)
    restorecontext /system/app /system/bin /vendor
    
    #Use a previous list
    restorecontext -file "$TMP/contexts.txt" /system/app /system/bin /vendor

    • ch_con_recursive "Files Context" "Folders Context" "FOLDER" "FOLDER" "..."
    To manually set the context to ALL files/folders of multiple directories

    The context format can be complete or partial

    Complete = u:'object_r:system_file:s0
    Partial = system_file

    -file (-f) = Only apply contexts in Files
    -dir (-d) = Only apply contexs in Folders

    Bash:
    #With Complete contexts
    #Files/Folders
    ch_con_recursive "u:object_r:system_file:s0" "u:object_r:system_file:s0" /data/test
    
    #With Partial contexts
    #Files/Folders
    ch_con_recursive "system_file" "system_file" /data/test
    
    #Apply context to only Files in /data/test
    ch_con_recursive -f "system_file" /data/test
    
    #Apply context to only Folders in /data/test
    ch_con_recursive -d "system_file" /data/test
    
    #Apply Contexts in Mutiple directories
    ch_con_recursive "system_file" "vendor_file" /data/test /data/test2 /data/test3
    
    #Only Files (Mutiple directories)
    ch_con_recursive -f "vendor_file" /data/test "$MODPATH/system/vendor"

    • ch_con "Context" "FILE/FOLDER" "FILE/FOLDER" "..."
    To manually set the context to mutiple single files/folders (Support Complete or Partial context format like ch_con_recursive)

    Bash:
    #Complete context
    ch_con "u:object_r:system_file:s0" /data/test/huh.txt
    ch_con "u:object_r:vendor_file:s0" /data/test/huh.txt
    
    #Partial Context
    ch_con system_file /data/test
    ch_con vendor_file /data/test/huh.txt
    
    #Mutiple single files/folders
    ch_con system_file /data/test /data/a.prop /data/test/huh.txt
    -----------------------------------
    EDITING FILES:
    • savestate "variable" "file"
    Makes a record of the current state of the file and is saved in the variable, any minor editing will change the value
    Bash:
    #Current state of build.prop will be saved in "$test" variable
    savestate test /system/build.prop
    
    #After some modifications
    update_file_string "ro.product.system.model=Just Test" /system/build.prop
    
    #The state of the build.prop will be change
    savestate test2 /system/build.prop
    
    "$test" ISNT EQUAL TO "$test2"
    
    #You can compare it
    if [[ "$test" == "$test2" ]]; then
       ui_print " build.prop was not edited"
    else
       ui_print " build.prop changed"
    fi

    • patch_fstab "Pattern to find Line to Patch" "Pattern to find property" "New property" "FILE"
    Allows you to replace properties of fstab files (For example: /vendor/etc/fstab.qcom)
    Bash:
    #It will replace fileencryption=ice to encryptable in userdata line
    patch_fstab userdata "fileencryption" "encryptable" "/vendor/etc/fstab.qcom"

    • update_file "FILE with New props" "DEST FILE"
    Supports: _addon and _zip extension

    Updates lines of .prop files without changing the original structure, btw this only works for updating already existing lines, if any line doesnt exist it wont do anything

    Bash:
    update_file "NewPropLines.txt" "/system/build.prop"

    • force_update_file "FILE with New props" "DEST FILE"
    Supports: _addon and _zip extension

    Similar to update_file but forces the existence of the new lines, if the lines already exists in the Dest File it remove them and then it will add the new prop lines

    Bash:
    force_update_file "NewPropLines.txt" "/system/build.prop"

    • update_file_string "line" "line" "..." "file"
    Same as update_file but doesnt require extra files, you can include the new lines to update directly as strings
    Bash:
    update_file_string 'ro.product.system.model=NEW MODEL' /system/build.prop
    
    update_file_string 'ro.product.system.model=NEW MODEL' 'ro.product.system.name=NEW NAME' 'ro.build.display.id=NEW ID' /system/build.prop

    • force_update_file_string "line" "line" "..." "file"
    Same as force_update_file but doesnt require extra files, you can include the new lines to update directly as strings
    Bash:
    force_update_file_string 'ro.product.system.model=NEW MODEL' /system/build.prop
    
    force_update_file_string 'ro.product.system.model=NEW MODEL' 'ro.product.system.name=NEW NAME' 'ro.build.display.id=NEW ID' /system/build.prop


    • xml_kit -open "Start XML section" "End XML Section" -open "Start XML Section" "..." -in "Some pattern" -change-value / -change-tag / -change-content / -add / -add-inside / -after-line / -before-line / -remove "XML FILE"
    You can edit XML files by scrolling through sections (You can edit very specific sections)

    The results will be analyzed automatically, if you receive any warning the original XML will not be altered, check your code, you are probably setting something wrong

    NOTE: If an action is not specified, it will just return the result of all the opened sections (If there are multiple results it is necessary to include -in flag or it will give an error)

    -open = Open a section of the XML, specifying the beginning pattern and the end pattern, in addition, you can open more sections within a previously opened section (Until you reach the desired section)

    -in = To avoid editing unwanted sections use -in to find the section you want using a specified pattern inside that section (Its use is highly recommended to avoid errors)

    -change-value = To change a XML attribute value ( a="value" )

    -change-tag = To change a XML value that is inside two tags ( <a> value </a> )

    -change-content = To replace any text with another in the opened XML section

    -add = To add text after the opened XML section

    -add-inside = To add text inside the opened XML section

    -after-line = To add text after some line inside the opened XML section

    -before-line = To add text before some line inside the opened XML section

    -remove = Just remove opened XML section

    -print = Print the result instead of editing the XML file

    -only-result = Just keep the result of all opened XML sections instead of merging it with the original XML

    -no-auto-spaces = Don't use autospacing based on current opened XML section


    XML EXAMPLE: /sdcard/Test.xml
    XML:
    <manifest version="2.0" type="device" target-level="3">
        <hal format="hidl">
            <name>Example_1</name>
            <version>3.0</version>
            <interface>
                <name>Internal One</name>
                <instance>default</instance>
            </interface>
        </hal>
        <hal format="hidl">
            <name>Example_2</name>
            <version>6.0</version>
            <interface>
                <name>Internal Two</name>
                <instance>default</instance>
            </interface>
        </hal>
    </manifest>

    xml_kit ACTIONS
    Bash:
    #Open first XML section
    xml_kit -open '<manifest' '</manifest>' /sdcard/Test.xml
    
    #Open a section within an already opened section
    xml_kit -open '<manifest' '</manifest>' -open '<hal format="hidl">' '</hal>' /sdcard/Test.xml
    
    #The opening of sections is Unlimited
    xml_kit -open '<manifest' '</manifest>' -open '<hal format="hidl">' '</hal>' -open '<interface>' '</interface>' /sdcard/Test.xml
    
    #Only edit the section that has this pattern
    xml_kit -open '<manifest' '</manifest>' -open '<hal format="hidl">' '</hal>' -in Example_2 /sdcard/Test.xml
    
    #Change some XML attribute
    #Change format="hidl" to format="Just test"
    xml_kit -open '<manifest' '</manifest>' -open '<hal format="hidl">' '</hal>' -in Example_2 -change-value format "Just Test" /sdcard/Test.xml
    
    #Change some value inside TAGs
    #For example: <version>3.0</version>
    #Change 3.0 to "Just Test"
    xml_kit -open '<manifest' '</manifest>' -open '<hal format="hidl">' '</hal>' -in Example_1 -change-tag version "Just Test" /sdcard/Test.xml
    
    #Add Text after the Opened XML section
    xml_kit -open '<manifest' '</manifest>' -open '<hal format="hidl">' '</hal>' -open '<interface>' '</interface>' -in "Internal Two" -add "Just Test" /sdcard/Test.xml
    
    #Add Text after some line
    xml_kit -open '<manifest' '</manifest>' -open '<hal format="hidl">' '</hal>' -in Example_1 -after-line Internal "Just Test" /sdcard/Test.xml
    
    #Add Text before some line
    xml_kit -open '<manifest' '</manifest>' -open '<hal format="hidl">' '</hal>' -in Example_2 -before-line Internal "Just Test" /sdcard/Test.xml
    
    #Just Remove opened section
    xml_kit -open '<manifest' '</manifest>' -open '<hal format="hidl">' '</hal>' -in Example_1 -remove /sdcard/Test.xml

    • add_lines "file" "file" "file" "DEST FILE"
    Supports: _addon and _zip extension

    Add lines from multiple files to an existing or new file

    Supports -after-line and -before-line like add_lines_string

    Bash:
    #Add the content of a single file to the Destination file
    add_lines "Add.txt" /system/build.prop
    
    #Add all contents of multiple files to the Destination file
    add_lines "Add.txt" "Add2.txt" "Add3.txt" /system/build.prop
    
    #Add contents BUT after some line
    add_lines -after-line "Some line" "Add.txt" /system/build.prop
    
    #Add contents BUT before some line
    add_lines -before-line "Some line" "Add.txt" /system/build.prop
    
    #Mix
    add_lines -after-line "Some line" "Add.txt" -after-line "Some line 2" "Add2.txt" -before-line "Some Line 3" "Add3.txt" "Extra.txt" "Extra2.txt" /system/build.prop

    • add_lines_string "line" "line" "..." "DEST FILE"
    Same as add_lines but doesnt require extra files, you can include the new lines to add directly as strings (Support empy lines)

    -after-line (-al) = Add content after a specific line (Unlimited)

    -before-line (-bl) = Add content before a specific line (Unlimited)

    Bash:
    #Normal usage
    add_lines_string "New line" "New line 2" /system/build.prop
    
    #Add empy lines
    add_lines_string " " /system/build.prop
    add_lines_string " " " " /system/build.prop
    
    #Add lines after some line
    add_lines_string -after-line "Some line" "add this after" -after-line "Some line 2" "add this after" /system/build.prop
    
    #Add lines before some line
    add_lines_string -before-line "Some line" "add this before" -before-line "Some line 2" "add this before" /system/build.prop
    
    #Mix
    add_lines_string "New line" " " "New line 2" " " /system/build.prop
    add_lines_string " " "New line" -after-line "Some line" "add this after" -after-line "Some line 2" "add this after" " " "Finish line" /system/build.prop

    • replace "Old Text" "New Text" "File or Directory"
    Allows you to replace only specific text or all lines that contains it (-all-line) within a file or directory (-recursive)

    -recursive(-r) = Finds the specified text in the whole directory and replaces it

    -all-line(-a) = Instead of just replacing the text, replace the entire line that contains it (You can replace the line with a paragraph but not vice versa)

    Bash:
    #In a file
    replace "HUH" "OLE" /system/build.prop
    
    #In a whole directory (Recursive)
    replace -r "HUH" "OLE" /system

    • replace_name "Pattern Name" "New Pattern Name" "File or Directory"
    It allows you to rename a file/folder or a whole directory (-recursive), so it is possible to change several pieces of names or full names of multiple files/folders easily.

    -recursive (-r) = Find all files/folders matching the name pattern in the whole directory and rename them

    -files (-f) = Only rename files

    -dirs (-d) = Only rename folders

    -regex = Enable the use of Regular Expressions for the name pattern

    NOTE: By default if only files or only folders are not specified, the names of both files and folders will be replaced

    Bash:
    #Change part of a file name
    #Change the extension ".jpg" to ".png"
    replace_name ".jpg" ".png" /system/test.jpg
    
    #Same for folders
    replace_name "old" "new" /system/folder_old
    
    #Remove the ".bak" extension
    replace_name ".bak" "" /system/test.prop.bak
    
    #Recursive
    #Change the extension ".jpg" to ".png" in an entire directory
    replace_name -r ".jpg" ".png" /system
    
    #Remove the ".bak" extension in an entire directory
    replace_name -r ".bak" "" /system
    
    #Btw you can specify that it Only applies to Files
    replace_name -f -r ".bak" "" /system
    
    #Or Only Folders
    replace_name -d -r "_ext" "_new" /system
    
    #Using Regex the possibilities are endless
    #Replace ".bak" only if it is at the end of the entire file names
    replace_name -regex -r ".bak$" "" /system

    • remove "Text to remove" "File or Directory"
    Allows you to remove only specific text or all lines that contains it (-all-line) within a file or directory (-recursive)

    -recursive(-r) = Finds the specified text in the whole directory and removes it

    -all-line(-a) = Instead of just removing the text, remove the entire line that contains it

    Bash:
    #In a file
    remove "HUH" /system/build.prop
    
    #In a whole directory (Recursive)
    remove -r "HUH" /system
    
    #Remove all empty lines
    remove -a "" /system/build.prop
    remove -r -a "" /system
    -----------------------------------
    EXECUTION:
    • run "variable" "file" arguments
    Supports: _addon and _zip extension

    Try to run a file (like a sh, binary ..) and save the result in the variable (The file automatically receive execution permissions)

    Bash:
    run log1 "$TMP/busybox" chmod --help

    • run_wait "time in seconds" action with any arguments
    Limits the execution time of any process, including Dynamic Installer functions, doesnt affect the execution speed, it only activates if the action takes too long (Experimental)
    Bash:
    run_wait 5 run log1 "$TMP/busybox" echo HUH

    • run_jar "DEXED jar file" arguments
    Supports: _addon and _zip extension

    Allows to run .JAR files using the native Android dalvik machine (If dalvik isnt available, a warning will be given), the .JARs must be converted to .dex to work (Btw not all .jars works)
    Bash:
    run_jar "$TMP/apktool.jar" --help

    • run_jar_class "DEXED jar file" "class to load" arguments
    Supports: _addon and _zip extension

    It works like run_jar but you can specify which class of the jar should be executed

    Bash:
    run_jar_class "$TMP/apktool.jar" "brut.apktool.Main" --help
    -----------------------------------
    MANIPULATION OF STRINGS:
    • split_string "pattern separator" "line"
    Separate text based on a delimiter
    Bash:
    split_string ':' "A B: C D E: FG"
    #Result:
    #A B
    #C D E
    #FG
    
    split_string "word" "A Bword C D E word FG"
    #Result:
    #A B
    #C D E
    #FG

    • split_cut "separator pattern" "number" "line"
    Separates the text like split_string but only returns the content up to the number of the indicated result
    Bash:
    split_cut ':' 2 "A B: C D E: FG"
    #Result:
    #A B
    #C D E
    
    split_cut "word" 1 "A Bword C D E word FG"
    #Result:
    #A B

    • split_extract "separator pattern" "number" "line"
    Separates the text like split_string but only returns a single value that is in the number of the indicated result
    Bash:
    split_extract ':' 2 "A B: C D E: FG"
    #Result:
    #C D E
    
    split_extract "word" 3 "A Bword C D E word FG"
    #Result:
    #FG

    • repeat "number" "String"
    Repeat text by a specific number
    Bash:
    repeat 5 OLE
    #Result: OLEOLEOLEOLEOLE

    • string <replace/replace_line/remove/inside/extract/complete_extract/-after-line/-before-line/escape/upper/lower/count> "string to process"
    A multi-utility to easily manipulate strings

    replace (UnLimited) = Replace substring-1 with substring-2

    replace_line (UnLimited) = Replace the full lines that contain the substring (You can replace the line containing the text with a paragraph but not vice versa)

    remove (UnLimited) = Remove some substring

    inside = Extract the substring that is inside two delimiters (It only works if the string to be processed does NOT have more than one line)

    extract = Extract all the content that is within two lines with the established pattern (Effectively only works if the string has multiple lines)

    complete_extract = Same as extract, but includes the lines that delimit the content

    force = Always return a result (by default nothing was returned if the original text was equal to the result)

    -recursive (-r) = It allows to apply changes/process ALL results (not just the first one) with "remove/replace/extract/complete_extract"

    -pattern (-p) = It allows to return only results with some internal string (Just with extract/complete_extract)

    -after-line (UnLimited) = Add text after some line with the established pattern

    -before-line (UnLimited) = Add text before some line with the established pattern

    -get-after = Get all text after some pattern (Only single line)

    -get-before = Get all text before some pattern (Only single line)

    -file (-f) = It allows to directly load a file instead of using string

    escape = Escape " ] [ \ / $ * . ^" characters that cause conflicts with some Linux utilities like sed (Being escaped they will be taken as literal characters)

    upper = Convert all text to Uppercase

    lower = Convert all text to Lowercase

    count = It only returns the number of characters in the string


    Examples:
    Bash:
    #Just replace the first result
    string replace "A" "B" "Hi, A will be replaced with B"
    
    #Recursive (Replace ALL)
    string -r replace "A" "B" "Hi, AAAA will be replaced with B"
    
    #Recursive (Remove ALL)
    string -r remove "A" "This AAAAAA will be removed"
    
    string inside "A" "B" "Hi A this content will be return B sayonara"
    
    string upper "this content will be return as uppercase"
    
    string lower "THIS CONTENT WILL BE RETURN AS LOWERCASE"

    Unlimited Examples:
    Bash:
    #Just remove the first results
    string remove "A" remove "B" remove "C" "ABDC"
    
    #Recursive (Remove ALL)
    string -r remove "A" remove "B" remove "C" "AAAAAABBBBBDDDDDCCCC"
    
    #Recursive (Replace ALL)
    string -r replace "A" "C" replace "B" "D" replace "C" "Hi" "C, AACCBBDDCC"

    Extra Examples:
    Bash:
    example="
    Hi,
    Hello world
    A
    B
    C
    Okay, sayonara
    Hello world 2
    D
    E
    F
    sayonara again
    "
    
    #It will returns the first result
    string extract "world" "sayonara" "$example"
    
    #Extract but verify if it have some substring
    #The first result is only returned if it have "B" substring
    string -p "B" extract "world" "sayonara" "$example"
    
    #Recursive, Extract ALL pattern paragraphs inside "world" and "sayonara"
    string -r extract "world" "sayonara" "$example"
    
    #Using recursive mode it will analyze all results and using pattern will only return the content that contains "E"
    string -r -p "E" extract "world" "sayonara" "$example"
    
    #Add some string after some line
    string -after-line "world" "ADD this after" "$example"
    
    #Multi actions
    string remove "A" remove "B" replace "C" "Ole" "$example"
    
    string -after-line "world" "ADD this after" -after-line "B" "ADD this after" "$example"
    
    #Just count characters in result
    string count remove "A" remove "B" replace "C" "Ole" "$example"
    -----------------------------------
    CONVERSION:
    • convert "NUMBER with UNIT" "NEW UNIT"
    Convert any type of units, mainly for storage units such as b, B, KB, MB, GB, TB, there is no combination limits (It returns completely decimal or integer numbers). Btw It is necessary to clarify that it supports integers and decimals in ANY conversion.

    -decimals (-d) = Number of decimals allowed (if they exist)

    -show (-s) = Show the sequence of conversion with its respective units (The conversion is dynamic, it uses a sequence of units until reaching the final unit)

    NOTE: It is very important to respect the lowercase or uppercase of the units ("b" is not the same as "B"ytes)

    Bash:
    convert 100MB KB
    convert 10TB MB
    convert 1b TB
    convert 1TB B
    convert 1.56GB B
    convert 1.3333333333B KB
    
    #Save the result in a variable
    result=$(convert 1005MB B)

    To avoid placing the unit in each number to be converted, there are two variables convert_from and convert_to that can be defined before use.
    Bash:
    #Convert from this unit
    convert_from=GB
    
    #Convert to this unit
    convert_to=KB
    
    result=$(convert 15)
    
    #It is also possible to mix the default variables with new units
    convert_from=b
    convert_to=MB
    
    #Convert 10 GB to the default MB
    result=$(convert 10GB)
    -----------------------------------
    CHECKING:
    • exist <file/folder/symlink/block/any> "file" "file" "file" "..."
    It can check if one or more files/folders/symlinks/blocks or any type of file exists

    Example:

    Bash:
    #By default if u dont include any flag it will check any type of folders/files/symlinks/blocks/..
    
    if exist "Myfile.bin"; then
       ui_print " Okey passed"
    else
       ui_print " FATAL ERROR"
    fi
    
    #For only Folders
    if exist folder "FOLDER"; then
       ui_print " Okey passed"
    else
       ui_print " FATAL ERROR"
    fi
    
    #For only Files
    if exist file "myfile.txt"; then
       ui_print " Okey passed"
    else
       ui_print " FATAL ERROR"
    fi
    
    #For only Symlinks
    if exist symlink "/system/vendor"; then
       ui_print " It exists and its a symbolic link"
    else
       ui_print " FATAL ERROR"
    fi
    
    #For only Blocks
    if exist block "/dev/block/dm-0"; then
       ui_print " It exists and its a block (Partition)"
    else
       ui_print " FATAL ERROR"
    fi
    
    #Multi-check
    if exist "Myfile.bin" "OTHER.bin" "OTHER.zip" "FOLDER"; then
       ui_print " Okey passed"
    else
       ui_print " FATAL ERROR"
    fi
    
    if exist symlink "/system/bin/sed" "/system/vendor"; then
       ui_print " They exist and are symlinks"
    else
       ui_print " FATAL ERROR"
    fi
    • is_valid "file" "file" "file" "..."
    It can check if one or more files exist and are not empty
    • contains "Text" "Text" "..." "FILE"
    It can check the existence of any text in a File
    • check_content "file" "file" "..." "ZIP File"
    Check if one or more files exist within a ZIP file

    Example:

    Bash:
    if check_content "file.txt" "Main.zip"; then
       ui_print " Passed "
    else
       ui_print " ERROR "
    fi
    
    #Multi-check
    if check_content "file.txt" "file2.txt" "folder/huh.bin" "MAIN.zip"; then
       ui_print " Passed "
    else
       ui_print " ERROR "
    fi
    • can_run "Binary file"
    Check if a binary can run on the device
    • is_number "possible number"
    Check if the string is a number (Supports decimal numbers)

    • is_hex "possible Hexadecimal string"
    Check if the string is Hexadecimal

    • is_abc "possible alphabetical string"
    Check if the string is alphabetical (A - Z), supports spaces and new empty lines but it will only be True if all visible characters are only alphabetic

    • is_text "possible string"
    Check ANY visible character, if there are only empty spaces or new lines it will return False.

    • is_zip/is_tar/is_gzip/is_bzip/is_xz "File"
    Check some file types using Hex Magic values, so the file extension doesnt matter

    • is_less/is_greater/is_equal/is_greater_equal/is_less_equal "String/Number" "String2/Number2"
    Check if a number (Supports decimals) is greater/less/equal or equal less/equal greater than another, just is_equal function support text comparison
    • is64bit "FILE (binary)"
    Check if a binary supports 64bits arch
    • contains_array "String" "Fully ARRAY"
    To check if a array already have some value
    Bash:
    #First define array
    test=("a" "o l e" "huh")
    
    #Check if some value exist
    #It ends with error
    contains_array "test" "${test[@]}"
    
    #It ends without error
    contains_array "o l e" "${test[@]}"

    • magic_file -type "FILE TYPE" "FILE"
    You can check file types using their Magic hex values, in this way it doesnt matter if the file doesnt have an extension, the check will still work (Similar to the Linux "file" tool but fully customizable)

    By default, it has file types already preloaded in "META-INF/zbin/configs/file_types.config"

    Already preloaded files types:


    - zip, gzip, bzip, xz, tar, Z, rar, 7z, lz4
    - png, jpg, webp, ico, bmp, gif, gks, rgb, pm
    - mp3, ogg, wav
    - mp4, avi
    - msdos (Windows Executable files)
    - unix (Unix Executable files)
    - dex (Android Dalvik Executable .dex)
    - cpio (Android Ramdisk format)
    - ramdisk (Its equal to cpio)
    - sparse (Android Sparse IMGs)
    Bash:
    magic_file -type jpg "/sdcard/Test.jpg"
    
    magic_file -t mp4 "/sdcard/test.mp4"
    
    magic_file -t zip "/sdcard/test.zip"
    
    magic_file -t xz "/sdcard/test.xz"
    
    magic_file -t dex "/sdcard/classes.dex"

    -offset (-o) = Number to skip bytes (Optional)

    -bytes (-b) = Bytes per line to get (Optional, by default: 100)

    -line (-l) = After splitting hexadecimal code by -bytes, this number represents how many hex lines to take (Optional, by default: 1)

    -type (-t) = To use any of the file types already preloaded (No additional configuration required)

    -show (-s) = Prints all the Hex code that is being parsed (Only useful if more than 1 hex line is specified)

    -show-line (-sl) = Prints only the Hex line that matches the Magic Hex Code (If it doesnt exist, it will only return "NULL")


    Bash:
    #Practical example
    
    #With Preloaded Files Types
    
    if magic_file -t jpg "$TMP/possible_jpg_image"; then
       ui_print "Detected JPG IMAGE!"
    else
       abort "THIS IS NOT A JPG IMAGE!"
    fi
    
    if magic_file -t tar "$TMP/possible_tar_file"; then
       ui_print "Detected TAR COMPRESSED FILE!"
    else
       abort "THIS IS NOT A TAR FILE!"
    fi
    
    #With Manual Mode (Using directly the Magic Hex Value)
    if magic_file ffd8ffe0 "$TMP/possible_jpg_image"; then
       ui_print "Detected JPG IMAGE!"
    else
       abort "THIS IS NOT A JPG IMAGE!"
    fi
    
    if magic_file -offset 257 7573746172 "$TMP/possible_tar_file"; then
       ui_print "Detected TAR COMPRESSED FILE!"
    else
       abort "THIS IS NOT A TAR FILE!"
    fi

    • testrw "Folder" "Folder" "..."
    Test if one or more folders has write permissions
    Bash:
    if testrw "/system"; then
       ui_print "You can write in /system!"
    else
       ui_print "Read-Only /system"
    fi
    
    if ! testrw "/system" "/vendor" "/odm"; then
       abort "One of the required partitions is Read-Only"
    fi

    • testvarname "Text"
    Verify if the text is valid to be used as a variable name
    -----------------------------------
    APK/JAR TOOLS:
    • apktool arguments
    Its the standard version of the apktool so that you can configure special options of the apktool

    • sign arguments
    Its the standard version of the zipsigner so that you can configure special options of the zipsigner

    • apk_package "APK file"
    Get the package of any apk
    Bash:
    apk_package "/system/app/Example.apk"
    
    #Save it in a variable
    app_package=$(apk_package "/system/app/Example.apk")

    • apk_main "APK file"
    Get the main launchable activity (if it exists) of any apk
    Bash:
    apk_main "/system/app/Example.apk"
    
    #Save it in a variable
    app_activity=$(apk_main "/system/app/Example.apk")

    • apk_icon "APK file"
    Get the icon path inside "res" of any apk
    Bash:
    apk_icon "/system/app/Example.apk"
    
    #Save it in a variable
    app_icon=$(apk_icon "/system/app/Example.apk")

    • apk_launch "APK file or its Package" <Activity to launch>
    Launch the main launchable activity (or a specific activity) of some PRE-installed APP on the device (when its already booted)

    NOTE: The PRE-installed application refers that the APP must already be installed on the device prior to its launch.

    Bash:
    #Try to find the main lauchable activity and launchs it
    apk_launch "/system/app/Example.apk"
    
    #Launch "com.app.main" activity of "/system/app/Example.apk"
    apk_launch "/system/app/Example.apk" "com.app.main"
    
    #Launch "com.android.systemui.DessertCase" of SystemUI.apk (Using the package directly)
    apk_launch "com.android.systemui" "com.android.systemui.DessertCase"

    • decode_xml "XML File"
    To decode AndroidManifest.xml (Does not support all XML)
    Bash:
    decode_xml "$TMP/AndroidManifest.xml"

    • encode_xml "XML File"
    To encode AndroidManifest.xml or other predecoded APK XMLs (Supports any other xml)
    Bash:
    encode_xml "$TMP/AndroidManifest.xml"

    • find_apk "APK package" "APK Package" "..." "PATH to find"
    Allows to find multiple APKs using its package in a specific path (it will return the exact path of those apks)

    By default splits and overlays are ignored

    Bash:
    find_apk "com.android.systemui" "com.android.settings" "com.sec.android.app.launcher" /system
    
    #Or recursive find (It will result in all apks with a similar pattern in the package):
    
    find_apk -r "com.google" /system
    -include-overlays (-io) = Include overlays (.APK)
    -include-splits (-is) = Include splits (.APK)


    • patch_apk "FOLDER to inject" ".APK file" zipalign/sign
    Supports: _addon and _zip extension

    Its a portable version of vrtheme, it allows you to inject the contents of a folder into an .APK, additionally you can specify if you want to sign (Just works if dalvikvm available) or zipalign the apk

    Bash:
    patch_apk "FOLDER" SystemUI.apk sign
    
    patch_apk "FOLDER" SystemUI.apk zipalign

    • make_overlay "Priority" "Destination Package" "FOLDER to build as res" "Result"
    Supports: _addon and _zip extension

    You can compile overlays (Layers that can alter values of other .APKs) only for Android 9+, but you CANNOT include images due to the limitations with the experimental apktool build for Dynamic Installer (See bugs section)

    Priority = Priority level, if there are several overlays that alter the same value, the one with the highest priority number will be used

    Package = Package of the app to which the overlay is directed

    FOLDER = Folder in which the "res" to be used is located

    Result = Resulting overlay path (Output)

    Bash:
    make_overlay 1 com.android.systemui "FOLDER" "/system/vendor/overlay/test.apk"
    -----------------------------------
    APK/JAR ADVANCED TOOL KITS:
    • dynamic_apktool -decompile(-d) "FILE" -framework(-f) "FILE" -add(-a) "FILE/FOLDER" -command(-c) "EXTRA APKTOOL OPTIONS to decompile" -output(-o) "DEST"

    • dynamic_apktool -preserve-signature(-ps) -recompile(-r) "FILE" -framework(-f) "FILE" -add(-a) "FILE/FOLDER" -command(-c) "EXTRA APKTOOL OPTIONS to recompile" -output(-o) "DEST" -sign(-s) -zipalign(-z)
    -decompile = APK or .JAR to decompile

    -add = FOLDERs or FILEs to add in the result

    -framework = framework-res.apk to use

    -output = Full path to results

    -recompile = FOLDER to recompile

    -sign = Sign the result (recompile)

    -zipalign = Zipalign the result (recompile)

    -command = Allows to add extra apktool.jar options

    -preserve-signature = Try to keep the original META-INF and AndroidManifest.xml (recompile)

    -no-api = Disable automatic specification of the device API

    -no-extras = Disable original resource checking/adding (decompile)

    -use-baksmali = Set an external baksmali.jar (DEXED) instead of the native apktool one (decompile)

    -use-smali = Set an external smali.jar (DEXED) instead of the native apktool one (recompile)



    Bash:
    dynamic_apktool -decompile "Test.apk" -o "/sdcard/Test" -add "/sdcard/folder"
    
    dynamic_apktool -no-extras -use-baksmali "$TMP/custom.jar" -decompile "Test.apk" -o "/sdcard/Test" -add "/sdcard/folder"
    
    dynamic_apktool -recompile "/sdcard/Test" -add "/sdcard/testfolder" -add "/sdcard/Test/original/META-INF" -a "/sdcard/test.txt" -zipalign -sign

    • smali_kit -dir(-d) "FOLDER" -file(-f) "FILE" -method(-m) "METHOD to find" -replace(-r) "Full NEW METHOD" -replace-in-method(-rim) "OLD STRING" "NEW STRING" -delete-in-method(-dim) "STRING to remove" -remake(-re) "NEW INTERNAL CONTENT" -after-line(-al) "LINE" "STRING to add after" -before-line(-bl) "LINE" "STRING to add before" -name(-n) "PATTERN NAME of .smali FILEs" -static-name(-sn) "EXACTLY name of .smali" -limit(-l) "LIMIT NUMBER OF RESULTS" -check(-c) -delete-method(-dm) -print-path(-pp)
    -dir = PATH to find .smali methods

    -file = File to find .smali methods

    -method = Pattern .method name to find


    -print-path = Just print the paths of all .smali files with that .method

    -replace = Replace ALL found .method

    -replace-in-method = Replace STRING of .method found with STRING2 (STRING to STRING2)

    -delete-in-method = Delete STRING of .method found

    -delete-method = Remove whole .method found

    -remake = Replace only the internal content of the .method found

    -after-line = Add a STRING after the specified line inside the found .method

    -before-line = Add a STRING before the specified line inside the found .method

    -name = Pattern that .smali files must have

    -static-name = Exactly name that ONE .smali must have

    -limit = The amount of results can be processed

    -check = Report modified files or if there were no changes

    Bash:
    REPLACE="
    .method public static isTima()Z
        .locals 1
    
        const/4 v0, 0x1
    
        return v0
    .end method
    "
    
    TEST="
        .locals 1
    
        const/4 v0, 0x4
    
        return v0
    "
    
    smali_kit -check -method "isTima" -d "FOLDER" -replace "$REPLACE"
    
    smali_kit -method "isTima" -dir "FOLDER" -replace-in-method "const/4 v0, 0x1" "const/4 v0, 0x0"
    
    smali_kit -method "isTima" -d "FOLDER" -remake "$TEST"
    
    smali_kit -method "isTima" -f "file.smali" -replace "$REPLACE"
    -----------------------------------
    EXTRA TOOLS:
    • adb arguments
    Its the standard version of the ADB so that you can configure special options
    -----------------------------------
    LOGGING:
    • startlog "PATH/file"
    Create a file that will be used to save the contents with "savelog"
    • savelog "Text" "Text" "..."
    Send text to file created with "startlog"
    • endlog
    To stop "savelog" that started with "startlog" (When logging is finished, any text attempted to be sent with "savelog\echolog\printlog" will be ignored)
    • echolog "Text" "Text" "..."
    The text is printed both in the general log (Text as Error - Stderr), and in the file created by "startlog"
    • printlog "Text" "Text" "..."
    The text is printed both on the screen (ui_print), and in the file created by "startlog"
    -----------------------------------
    DYNAMIC VARIABLES:
    • setdefault "variable" "string"
    Its equivalent to defining a normal variable (myvar = b) but it allows dynamic variable names
    Bash:
    var_name="test"
    
    #Since the content of var_name is "test", the name of the new variable is "test"
    setdefault $var_name "just test"
    ui_print "$test"

    • checkvar "variable" "variable" "..."
    Check multiple variables and return the value of those that are defined
    Bash:
    var_contents=$(checkvar var1 var2 var3)
    
    #Very useful to obtain the content of variables with dynamic names
    number=4
    setdefault var$number "o l e"
    var_content=$(checkvar var$number)

    • filtervar "variable" "variable" "..." "pattern"
    Check multiple variables and look for a matching pattern in the value of these variables (the complete value of those variables is returned)
    Bash:
    matched_content=$(filtervar var1 var2 var3 "find this")
    • defined "variable" "variable" "..."
    Check if multiple variables are defined
    Bash:
    if defined var1; then
       ui_print "Success"
    fi
    
    #Multi check
    if defined var1 var2 var3; then
       ui_print "Success"
    fi
    
    #Dynamic var names
    number=4
    setdefault var$number "o l e"
    if defined var$number; then
       ui_print "Success"
    fi
    • undefined "variable" "variable" "..."
    Check if multiple variables are not defined
    Bash:
    if undefined var1; then
       ui_print "Empty var1"
    fi
    
    #Multi check
    if undefined var1 var2 var3; then
       ui_print "Empty var1, var2 and var3"
    fi
    
    #Dynamic var names
    number=4
    setdefault var$number "o l e"
    if undefined var$number; then
       ui_print "Empty var$number"
    fi
    -----------------------------------
    CREATE FILES/FOLDERS:
    • create_dir "NEW folder" "NEW folder" "..."
    You can create new folders (if needed) and also check the Read/Write permissions in them

    • create_file "NEW file" "NEW file" "..."
    You can create new files (or overwrite already existing files) - The necessary folders are created automatically

    • make_zip -script "Text" -type <recovery/magisk> -output "Result ZIP"
    You can create new ZIPs using your current version of the Dynamic Installer as a base

    -script (-s) = The Script for the New ZIP (In text format - string)

    -type (-t) = The type can be "recovery" or "magisk" and it helps to build the ZIP

    -head (-h) = The setdefaults header (In text format - String) to use in the updater-script when using -type "magisk"

    -include (-i) = Include files or folders in the root of the ZIP

    -magisk-include (-mi) = Include files or folders in Magisk space

    -preserve-addons (-pa) = Keep the META-INF/addons contents of the current ZIP


    -preserve-magisk (-pm) = Keep the META-INF/com/google/android/magisk contents of the current ZIP

    -output (-o) = Path for the resulting ZIP

    Bash:
    script='
    #-----------Dynamic Installer Configs-----------#
    #The #MAGISK tag is required, dont remove it
    #MAGISK
    setdefault magisk_support on
    setdefault import_addons off
    setdefault apex_mount off
    setdefault extraction_speed default
    setdefault permissions "0:0:0755:0644"
    setdefault devices off
    #-----------------------------------------------#
    #Your script starts here:
    
    mount_all
    delete /system/just_test
    umount_all
    '
    
    make_zip -script "$script" -type recovery -include "FOLDER" -include "FILE" -output "/sdcard/Test.zip"
    -----------------------------------
    INSTALL FILES:
    • update ".img/.img.xz/.img.gz/.bin/..." "partition" <exit number>
    Supports: _addon and _zip extension

    Try install img or bin files (system.img super.img boot.img optics.img prism.img param.bin ...)

    -xz = To install a .xz compressed File

    -gz = To install a .gz compressed File

    -sparse = To install Sparse IMGs instead of RAW IMGs (Only for 64bit devices)

    exit number = If "1" is used, it will be evaluated if the installation of the file was successful, otherwise everything will be aborted

    Bash:
    #Update system
    update /sdcard/system.img $(find_block system)
    
    #Using _zip extension
    #Update using file inside ZIP
    update_zip system.img $(find_block system)
    
    #Update using .xz compressed file
    update_zip -xz vendor.img.xz $(find_block vendor)
    
    #Update using .gz compressed file
    update_zip -gz boot.img.gz $(find_block boot)
    
    #Update using an IMG Sparse
    update_zip -sparse system.img $(find_block system)
    
    #Update using an IMG Sparse additionally compressed as .xz
    update_zip -sparse -xz system.img.xz $(find_block system)
    
    #Update but ABORT the ZIP installation in case of error
    update_zip -xz super.img.xz "$(find_block super)" 1

    • flash "variable" "zip file" <print>
    Supports: _addon and _zip extension

    Try to install a new ZIP file within the current installation and the result is saved in the variable, also you can include a third optional argument "print" to allow the new ZIP to print text on Recovery.

    Bash:
    #External ZIP
    flash log1 "/sdcard/custom.zip"
    
    #Internal ZIP
    flash_zip log_name "folder/test.zip"
    
    #Allow text printing in recovery
    flash_zip log_name "folder/test.zip" print
    
    #...

    • dynamic_install "path" "path"
    Similar to package_extract_dir but only works with existing paths outside the ZIP
    Bash:
    dynamic_install "/vendor" "$MODPATH/system/vendor"

    • dynamic_install_apk "path outside zip" "path outside zip"
    Find all existing APKs in the first folder in the second folder (Not by name, by package), in case the second folder already contains one of the APKs, it will be replaced keeping the original path and name. if it does not exist, the directory will be created according to the first folder

    You can also redirect the destination path (Compare 2 directories with .APKs, perfect for Magisk modules)

    NOTE: By default overlays are ignored but APK Splits are included with the main app

    -no-replace(-nr) = Avoid replacing existing APKs
    -no-add(-na) = Avoid adding new APKs
    -include(-i) = Add extra folders/files references to add in the destination of the APKs - UnLimited
    -remove-oat = Remove all oat folders of old apks (in the destination)

    Bash:
    #Simple usage
    dynamic_install_apk "FOLDER" "/system"
    
    #Include extra files/Folders
    #The "oat" and "lib" folders will be included in the destination of all APKs
    dynamic_install_apk -include "oat" -include "lib" "FOLDER" "/system"
    
    #Redirect results
    dynamic_install_apk "FOLDER" "/system" -output "/sdcard/results"

    • apk_install ".APK or .APKM" ".APK or .APKM" "..."
    Install multiple .APK or .APKM (ApkMirror) files, .APKM files are a ZIP with the main .APK and Splits required for each device, these Splits will be filtered and included in the installation automatically based on device specifications, however , you are free to include additional Splits

    To include Splits in the .APK installation:

    Bash:
    #Install single .APK with multiple external Splits
    apk_install "$TMP/Main.apk:$TMP/Split.apk:$TMP/Split2.apk"
    
    #Multi .APK installation with multiple external Splits
    apk_install "/sdcard/Main.apk:$TMP/Split.apk:$TMP/Split2.apk" "/sdcard/Main2.apk:$TMP/Split3.apk:$TMP/Split4.apk"

    To include additional Splits in the .APKM installation:

    NOTE: For .APKM you can just include the name of the Split and it will try to extract from the .APKM instead of taking it from an external path

    Bash:
    #Install single .APKM with multiple additional external Splits
    apk_install "$TMP/Main.apkm:$TMP/Split.apk:$TMP/Split2.apk"
    
    #Multi .APKM installation with multiple additional external Splits
    apk_install "/sdcard/Main.apkm:$TMP/Split.apk:$TMP/Split2.apk" "/sdcard/Main2.apkm:$TMP/Split3.apk:$TMP/Split4.apk"
    
    #Include additional Splits that exist within the .APKM
    apk_install "$TMP/Main.apkm:split_config.ru.apk:split_voip.apk"


    • apk_install_recursive "FOLDER" "FOLDER" "..."
    Install all .APK/.APKM that are inside a folder, also allows creating subfolders to group specific .APK/.APKM with additional splits

    /sdcard/myapps

    Bash:
    /sdcard/myapps/Normal.apk
    /sdcard/myapps/Normal2.apkm
    /sdcard/myapps/subfolder/Main.apk
    /sdcard/myapps/subfolder/split.apk
    /sdcard/myapps/subfolder/split2.apk

    When performing the recursive installation in this example, only "Main.apk" will be installed together with the .APKs that accompany it (Splits), because it is the only one that is grouped in a subfolder
    Bash:
    apk_install_recursive "/sdcard/myapps"

    • unify_path "First PATH" "Second PATH"
    To compare one folder with another, this includes a comparison of files that already exist in both folders, if they are not the same, they are replaced or added to the second folder
    Bash:
    #Compare folder TEST with TEST2
    #Fix ALL differences in TEST2
    unify_path "/sdcard/TEST" "/sdcard/TEST2"
    -----------------------------------
    HEXADECIMAL PATCH:
    • hex_patch "Hex code to find" "New Hex code" "file"
    Allows to substitute Hex fragments within files (perfect for patching)
    Bash:
    hex_patch "74696d65" "00696d65" /system/bin/testfile

    • hex_search <include> "Hex code to find" "file"
    Allows to search Hexadecimal lines within files (The resulting line is returned)

    Additional digits can be included before or after the found hex:

    Bash:
    hex_search -include "after:10 before:5" "74696d65" /system/bin/testfile
    ##If the Hex code is found, it will return the result together with 10 previous digits and 5 extra digits at the end of the string

    • hex_check "Hex code to find" "file"
    Checks for the existence of a Hexadecimal fragment within a file
    Bash:
    hex_check "74696d65" /system/bin/testfile
    -----------------------------------
    DYNAMIC PARTITIONS (SUPER):
    • checksuper "SUPER Partition or RAW .img"
    To check if a image/partition is a SUPER image in record time
    Bash:
    #Check SUPER partition
    checksuper $(find_block super)
    
    #Check SUPER image
    checksuper "/sdcard/super.img"
    • get_offset "Subpartition Name" "SUPER Partition or RAW .img"
    To get the offset of any subpartition inside a SUPER partition/image in record time
    Bash:
    get_offset system $(find_block super)
    
    #For A/B
    get_offset system$slot $(find_block super)
    • get_group "Subpartition Name" "SUPER Partition or RAW .img"
    To get the group of any subpartition inside a SUPER partition/image in record time
    • get_total_size "SUPER Partition or RAW .img"
    To get the total size of all subpartitions inside a SUPER partition/image
    Bash:
    get_total_size $(find_block super)
    • get_all_subparts "SUPER Partition or RAW .img"
    To get the name of all subpartitions of an img/partition (SUPER)
    Bash:
    get_all_subparts $(find_block super)
    • start_loop "Subpartition Name" "SUPER Partition or RAW .img"
    To make new mount point of any subpartition inside a SUPER partition/image (Designed for new Virtual Dynamic Partitions)

    The new mount point (Loop device) is assigned in $LOOP variable

    Bash:
    #Make new point with system inside SUPER .img
    start_loop system /sdcard/super.img
    system_point="$LOOP"
    
    #Make new point with vendor inside SUPER partition
    start_loop vendor $(find_block super)
    vendor_point="$LOOP"
    
    #Make new point for A/B devices
    start_loop system_a $(find_block super)
    system_point="$LOOP"
    • end_loop
    To end previously made mount point with "start_loop" based on the order of creation (It works like "end_tmp")
    Bash:
    #First make multiple Mount Points
    start_loop system_a /sdcard/super.img
    system="$LOOP"
    
    start_loop vendor_a /sdcard/super.img
    vendor="$LOOP"
    
    start_loop product_a /sdcard/super.img
    product="$LOOP"
    
    #Now to finish NEW POINTS
    end_loop
    end_loop
    end_loop

    • unlock_all <Partition/IMG>
    To try convert all internal subpartitions of SUPER to Read/Write on-fly

    NOTE: It is not necessary to specify the partition/IMG (Super of the device is used by default), but you can do it if you need it

    • unlock "Subpartition Name" <Partition/IMG>
    To convert specific subpartition of SUPER to Read/Write (Like unlock_all doesnt work in some cases)

    NOTE: It is not necessary to specify the partition/IMG (Super of the device is used by default), but you can do it if you need it

    Bash:
    #For A/B u need to use $slot
    
    #Try enable RW in system (Active slot)
    unlock system$slot
    
    #Specific slot
    unlock system_a
    
    #Try enable RW in vendor (Active slot)
    unlock vendor$slot
    
    #Try enable RW in vendor from external SUPER.img
    unlock vendor_a /sdcard/super.img
    -----------------------------------
    PROTECT YOUR CODE:
    • obfuscate "Text"
    Allows you to encode the shell script code (or Dynamic Installer scripts), keeping it working but making it difficult for common users to read (you can mix obfuscated code with readable code)

    -base64 (-b64) = This option ensures the preservation of all the original code, encoding the code in base64 before being obfuscated, this implies a greater weight (Only use if the default obfuscation gives bad results)

    NOTE: For its use, it is recommended to load the Dynamic Installer in Termux, through the "Test Mode" mentioned in the first thread

    WARNING: Never obfuscate the default "setdefault"s in the DI updater-script (they need to be readable for the installation process)

    EXTRA WARNING: The "off_readonly" lines cannot be obfuscated either, as they are read and interpreted during installation

    Example:1 (Note the use of single quotes):

    Bash:
    #Obfuscate commands directly (Default mode)
    obfuscate ' ui_print "All this will be obfuscated"
    ui_print "Mounting partitions..."
    mount_all ' > /sdcard/obfuscated.sh
    
    #With Base64 Mode
    obfuscate -b64 ' ui_print "All this will be obfuscated"
    ui_print "Unmounting partitions..."
    umount_all ' > /sdcard/obfuscated.sh

    Example:2 (Obfuscate files):
    Bash:
    obfuscate "$(cat /sdcard/original.sh)" > /sdcard/obfuscated.sh
    
    #You can also use this syntax:
    cat /sdcard/original.sh | obfuscate > /sdcard/obfuscated.sh
    
    #With Base64 Mode
    cat /sdcard/original.sh | obfuscate -b64 > /sdcard/obfuscated.sh

    Example:3 (Mix obfuscated code with readable code):
    Bash:
    obfuscate '   ole="Hi, this action will be obfuscated"  ' > /sdcard/obfuscated.sh
    Obfuscated code:
    Bash:
    cjifh="=";gegb=" ";bjbij=",";iagg=\";bhbcb="a";ichh="b";dafa="c";chaa="d";hb="e";cjdeb="f";gfah="H";bjac="i";caddf="l";bgfgf="n";bhcj="o";daafj="s";cdefi="t";cdaib="u";caedc="w";bgacd="v";${hb}${bgacd}${bhbcb}${caddf}${gegb}"${gegb}${gegb}${gegb}${bhcj}${caddf}${hb}${cjifh}${iagg}${gfah}${bjac}${bjbij}${gegb}${cdefi}h${bjac}${daafj}${gegb}${bhbcb}${dafa}${cdefi}${bjac}${bhcj}${bgfgf}${gegb}${caedc}${bjac}${caddf}${caddf}${gegb}${ichh}${hb}${gegb}${bhcj}${ichh}${cjdeb}${cdaib}${daafj}${dafa}${bhbcb}${cdefi}${hb}${chaa}${iagg}${gegb}${gegb}"
    This would print "Hi, this action will be obfuscated"
    Bash:
    cjifh="=";gegb=" ";bjbij=",";iagg=\";bhbcb="a";ichh="b";dafa="c";chaa="d";hb="e";cjdeb="f";gfah="H";bjac="i";caddf="l";bgfgf="n";bhcj="o";daafj="s";cdefi="t";cdaib="u";caedc="w";bgacd="v";${hb}${bgacd}${bhbcb}${caddf}${gegb}"${gegb}${gegb}${gegb}${bhcj}${caddf}${hb}${cjifh}${iagg}${gfah}${bjac}${bjbij}${gegb}${cdefi}h${bjac}${daafj}${gegb}${bhbcb}${dafa}${cdefi}${bjac}${bhcj}${bgfgf}${gegb}${caedc}${bjac}${caddf}${caddf}${gegb}${ichh}${hb}${gegb}${bhcj}${ichh}${cjdeb}${cdaib}${daafj}${dafa}${bhbcb}${cdefi}${hb}${chaa}${iagg}${gegb}${gegb}"
    
    ui_print "$ole"
    -----------------------------------
    OTHER STUFF:
    • fprint "file"
    Supports: _addon and _zip extension

    Print the content of a file in the recovery or magisk


    • import_bin "File"
    Supports: _addon and _zip extension

    Allows you to import new files to the Dynamic Installer work environment (Perfect for adding extra binaries, they can be used directly in your scripts after an import)


    • getsize "file"
    Return the size of any file (In Bytes)

    • getblocks
    Convert all existing partitions to variables ($system, $vendor, $boot, $vbmeta)
    • getbins
    Returns all available binaries (commands) and also generates a $bins variable that contains all
    • copy "original" "dest"
    Copy any file or folder (Dest folders auto-created)

    • move "original" "dest"
    Move any file or folder (Dest folders auto-created)

    • echo2 "Text"
    Print text as Error - Stderr (For example, the text doesnt appear on the Magisk installation screen but yeah in the LOG)

    • calc <Operations>
    To make basic operations like addition, subtraction, division, exponents (The result will not always be an integer or decimal, results with scientific notation are accepted)
    Bash:
    result=$(calc "5 + 5")
    
    result=$(calc "20^45 * ( 30 / 5 )")

    • int <Number or Operations>
    To convert any number to an integer or ensure an operational result as an integer
    Bash:
    #Will return "5" without rounding
    result=$(int "5.5")
    
    #Will return "62" without rounding
    result=$(int "(5^3)/2")

    • float <Number or Operations>
    To convert any number to an floating-point number, or ensure an operational result as an floating-point number
    Bash:
    #Will return "5.500000000" with 9 decimals by default
    result=$(float "5.5")
    
    #Will return "62.500000000" with 9 decimals by default
    result=$(float "(5^3)/2")
    
    #How to increase decimal parts?
    setdefault float_length 10
    #Will return "5.5000000000" with 10 decimals
    result=$(float "5.5")
    
    #How to decrease decimal parts?
    setdefault float_length 2
    #Will return "5.50" with 2 decimals
    result=$(float "5.5")

    • round <Number or Operations>
    To round any number to only integers or to ensure an operational result as an rounded integer
    Bash:
    #Will return "6" with rounding
    result=$(round "5.5")
    
    #Will return "63" with rounding
    result=$(round "(5^3)/2")

    • change_bin "Binary name" "Binary name" "..."
    By default the Dynamic Installer uses the native Busybox binaries (with the exception of a few like "xxd" and "xz"), however, these binaries are trimmed versions, where any external version generally provides more options. The change_bin function can find for and change any binary currently in use to any other available external version.

    -while (-w) = Allows detailing that the binary must support a specific option (Although there are external versions available, if they do not support the established option, they will not be considered)

    NOTE: The changes are random, that is, if three binaries with the same name are found, a random change will be made, and it can be any of these three, the only condition is that it is different from the one currently used (For each use of "change_bin" you will get a different result, with chances of going back to the original binary)

    EXTRA NOTE: If the full path of an existing file is specified and it is different from the current binary, change_bin will make the change with that file ignoring any of the other options (it will take the file name as reference)

    Bash:
    #Try using some other version of "chmod"
    change_bin "chmod"
    
    #Change the "unzip" binary only to another version that supports the "-p" option
    change_bin "unzip" -while "-p"
    
    #Muti change
    change_bin "chmod" "unzip" "find"
    
    #Restore to Original Busybox binaries
    #$l is the path where all the native DI binaries are
    change_bin "$l/chmod"
    5
    DOWNLOADS:

    STABLE V4.8-b:
    Standard version of the DI. Use the native "unzip" command to handle extractions, this can give better compatibility since it is an existing command in all custom Recoverys, but implies a dependency on the capacity of the size of ZIP files that it natively supports (4GB at best of the cases). If your final compressed project will not exceed 3.5GB, you can use this version without worries.
    MEDIAFIRE




    STABLE V4.8-bZ:
    Experimental variant of DI (does not imply that it is unstable). Instead of using the native "unzip" command, it includes a 7zip binary embedded from quite early points in the installation to handle extractions, allowing processing of large ZIPs. Requires either the "base64" command or the "awk" command to exist. If your final compressed project exceeds 3.5GB, consider trying this version.

    NOTE: To ensure compatibility, you can simply flash this blank template and if you don't receive any warning, it is supported!