[ZIP - Dual Installer] Dynamic Installer Stable 4.8-b2 [ Android 10+ or earlier ] (2024)


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 VariablesResult="$(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 examplenot (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 ROtry_mount /cache /optics /prism /odm /vendor#Only Read/Writetry_mount -rw /optics /prism#Only Read/Onlytry_mount -ro /optics /prism#Unmount before mounttry_mount -remount /optics /prism#Specifying custom name to find the Partition Block to Mounttry_mount -name "system" /test#For A/B? Its the same#Supports A/B by default with common names#Use Active Slot by defaulttry_mount -name "vendor" /test#Or optionally specify a slottry_mount -name "vendor_b" /test#Don't look for the partition block for long timetry_mount -express /system#Specifying a FILE to mount instead of partitiontry_mount -file "/sdcard/system.img" /test#Specifying a block to mounttry_mount -file "/dev/block/dm-0" /system_root#Mixtry_mount -remount -rw /optics /prismtry_mount -express -name "vendor" /mnt/vendortry_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 mounttry_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.apexapex_mount "/system/apex/com.android.runtime.apex"#Mount APEX Folder#/system/apex/com.android.runtimeapex_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 namesfind_block "system"#Fast findfind_block -e system#Find with limited timefind_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 ZIPpackage_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 pathpackage_extract_file "Folder/file.txt" /system/test.txt#Just get the File content directly as Text#If you dont add a destination pathcontent=$(package_extract_file "Folder/file.txt")#Extracting from an external ZIPpackage_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 /systemwipe system#To wipe /data but WITHOUT Internal Storagewipe data#To wipe ALL /datawipe userdata#To wipe dalvik-cachewipe dalvik#To wipe cachewipe cache#Mix#To wipe /data /system /vendor /product /cachewipe 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 /systemelse #Action if the user presses the volume down button package_extract_dir vendor /vendorfi

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> "selected=new text" "skipped=new text"

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)

selected = Special definition to change the text printed by default when the user selects an option finally (Vol+). To refer to the current option number you can use "%i" within the new text

skipped = Special definition to change the text printed by default when the user skips an option (Vol-). To refer to the current option number you can use "%i" within the new text

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#Or if you want to change the default printed texts#multi_option "my_menu" 4 "selected=YOU SELECTED: %i" "skipped=YOU SKIPPED: %i"if undefined my_menu; then abort " No valid selection was obtained "fiif [[ $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 usedifelse "is_mounted /system" 'ui_print "/system inst mounted"'#Btw the best practice is using this syntaxis_mounted /system || ui_print "/system inst mounted"#Or for multiple actionsif 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"fiif 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 textstdout 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 logstderr 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 screenstdprint echo uwu#This allows to visualize the process of an action even in the Recoverystdprint apktool --help

  • read_file "file" "file" "..."

Get the contents of one or more files

Bash:

read_file "$TMP/file.txt"#Or with the native formcat "$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 busyboxsymlink "$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 useconvert_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 namecurrent_version=v1.1.0i_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


getdefault

Bash:

getdefault "$TMP/something.txt" okaygetdefault "$TMP/something.txt" testmy_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 arraytest=("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 blockget_size_ext4 "$(find_block system)"#Get size of some .img in /sdcardget_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 foundfind_content ".mp4" ".mp3" /sdcard/ole.zip#Find only Foldersfind_content -d "huh" /sdcard/ole.zip#Using Regular Expressionsfind_content -regex "(.mp4|.mp3)$" /sdcard/ole.zip#You can even include multiple Regexfind_content -regex "(.mp4|.mp3)$" "^ole.*(.jpg|.png)$" /sdcard/ole.zip#Limiting the results to only files that are in the root of the ZIPfind_content -max 1 ".mp4" ".mp3" /sdcard/ole.zip#Limiting results to only folders that are at most 2 levelsfind_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 possibilitiesfind_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/folderset_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 DIRECTORIESset_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 filesaveperm /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 listcopy_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 filerestoreperm /system/build.prop#Recursively (All contents of this folders)restoreperm /system/app /system/bin /vendor#Use a previous listrestoreperm -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.propeval_perm /vendor#Get only the User IDeval_user /system/build.propeval_user /vendor#Get only the Group IDeval_group /system/build.propeval_group /vendor#Get only the Group IDeval_group /system/build.propeval_group /vendor#Get the User ID / Group ID / Modeeval_all_perm /system/build.propeval_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 / Modeget_all_perm /system/build.propget_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:s0eval_context /system#It will return u:object_r:vendor_overlay_file:s0eval_context /vendor/overlay#It will return u:object_r:sec_efs_file:s0eval_context /efs#Get context of a single file#It will return u:object_r:system_file:s0eval_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:s0get_context /system/appget_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.propset_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 filesavecontext /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 listcopy_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 filerestorecontext /system/build.prop#Recursively (All contents of this folders)restorecontext /system/app /system/bin /vendor#Use a previous listrestorecontext -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/Foldersch_con_recursive "u:object_r:system_file:s0" "u:object_r:system_file:s0" /data/test#With Partial contexts#Files/Foldersch_con_recursive "system_file" "system_file" /data/test#Apply context to only Files in /data/testch_con_recursive -f "system_file" /data/test#Apply context to only Folders in /data/testch_con_recursive -d "system_file" /data/test#Apply Contexts in Mutiple directoriesch_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 contextch_con "u:object_r:system_file:s0" /data/test/huh.txtch_con "u:object_r:vendor_file:s0" /data/test/huh.txt#Partial Contextch_con system_file /data/testch_con vendor_file /data/test/huh.txt#Mutiple single files/foldersch_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" variablesavestate test /system/build.prop#After some modificationsupdate_file_string "ro.product.system.model=Just Test" /system/build.prop#The state of the build.prop will be changesavestate test2 /system/build.prop"$test" ISNT EQUAL TO "$test2"#You can compare itif [[ "$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 linepatch_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.propupdate_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.propforce_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 sectionxml_kit -open '<manifest' '</manifest>' /sdcard/Test.xml#Open a section within an already opened sectionxml_kit -open '<manifest' '</manifest>' -open '<hal format="hidl">' '</hal>' /sdcard/Test.xml#The opening of sections is Unlimitedxml_kit -open '<manifest' '</manifest>' -open '<hal format="hidl">' '</hal>' -open '<interface>' '</interface>' /sdcard/Test.xml#Only edit the section that has this patternxml_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 sectionxml_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 linexml_kit -open '<manifest' '</manifest>' -open '<hal format="hidl">' '</hal>' -in Example_1 -after-line Internal "Just Test" /sdcard/Test.xml#Add Text before some linexml_kit -open '<manifest' '</manifest>' -open '<hal format="hidl">' '</hal>' -in Example_2 -before-line Internal "Just Test" /sdcard/Test.xml#Just Remove opened sectionxml_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 fileadd_lines "Add.txt" /system/build.prop#Add all contents of multiple files to the Destination fileadd_lines "Add.txt" "Add2.txt" "Add3.txt" /system/build.prop#Add contents BUT after some lineadd_lines -after-line "Some line" "Add.txt" /system/build.prop#Add contents BUT before some lineadd_lines -before-line "Some line" "Add.txt" /system/build.prop#Mixadd_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 usageadd_lines_string "New line" "New line 2" /system/build.prop#Add empy linesadd_lines_string " " /system/build.propadd_lines_string " " " " /system/build.prop#Add lines after some lineadd_lines_string -after-line "Some line" "add this after" -after-line "Some line 2" "add this after" /system/build.prop#Add lines before some lineadd_lines_string -before-line "Some line" "add this before" -before-line "Some line 2" "add this before" /system/build.prop#Mixadd_lines_string "New line" " " "New line 2" " " /system/build.propadd_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 filereplace "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 foldersreplace_name "old" "new" /system/folder_old#Remove the ".bak" extensionreplace_name ".bak" "" /system/test.prop.bak#Recursive#Change the extension ".jpg" to ".png" in an entire directoryreplace_name -r ".jpg" ".png" /system#Remove the ".bak" extension in an entire directoryreplace_name -r ".bak" "" /system#Btw you can specify that it Only applies to Filesreplace_name -f -r ".bak" "" /system#Or Only Foldersreplace_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 namesreplace_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 fileremove "HUH" /system/build.prop#In a whole directory (Recursive)remove -r "HUH" /system#Remove all empty linesremove -a "" /system/build.propremove -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#FGsplit_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 Esplit_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 Esplit_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 resultstring 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 resultsstring 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 worldABco*kay, sayonaraHello world 2DEFsayonara again"#It will returns the first resultstring extract "world" "sayonara" "$example"#Extract but verify if it have some substring#The first result is only returned if it have "B" substringstring -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 linestring -after-line "world" "ADD this after" "$example"#Multi actionsstring 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 resultstring 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 KBconvert 10TB MBconvert 1b TBconvert 1TB Bconvert 1.56GB Bconvert 1.3333333333B KB#Save the result in a variableresult=$(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 unitconvert_from=GB#Convert to this unitconvert_to=KBresult=$(convert 15)#It is also possible to mix the default variables with new unitsconvert_from=bconvert_to=MB#Convert 10 GB to the default MBresult=$(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 Foldersif exist folder "FOLDER"; then ui_print " Okey passed"else ui_print " FATAL ERROR"fi#For only Filesif exist file "myfile.txt"; then ui_print " Okey passed"else ui_print " FATAL ERROR"fi#For only Symlinksif exist symlink "/system/vendor"; then ui_print " It exists and its a symbolic link"else ui_print " FATAL ERROR"fi#For only Blocksif exist block "/dev/block/dm-0"; then ui_print " It exists and its a block (Partition)"else ui_print " FATAL ERROR"fi#Multi-checkif exist "Myfile.bin" "OTHER.bin" "OTHER.zip" "FOLDER"; then ui_print " Okey passed"else ui_print " FATAL ERROR"fiif 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-checkif 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 arraytest=("a" "o l e" "huh")#Check if some value exist#It ends with errorcontains_array "test" "${test[@]}"#It ends without errorcontains_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 Typesif magic_file -t jpg "$TMP/possible_jpg_image"; then ui_print "Detected JPG IMAGE!"else abort "THIS IS NOT A JPG IMAGE!"fiif 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!"fiif 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"fiif ! 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 variableapp_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 variableapp_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 variableapp_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 itapk_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 signpatch_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 namesnumber=4setdefault 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 checkif defined var1 var2 var3; then ui_print "Success"fi#Dynamic var namesnumber=4setdefault 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 checkif undefined var1 var2 var3; then ui_print "Empty var1, var2 and var3"fi#Dynamic var namesnumber=4setdefault 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#MAGISKsetdefault magisk_support onsetdefault import_addons offsetdefault apex_mount offsetdefault extraction_speed defaultsetdefault permissions "0:0:0755:0644"setdefault devices off#-----------------------------------------------##Your script starts here:mount_alldelete /system/just_testumount_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 systemupdate /sdcard/system.img $(find_block system)#Using _zip extension#Update using file inside ZIPupdate_zip system.img $(find_block system)#Update using .xz compressed fileupdate_zip -xz vendor.img.xz $(find_block vendor)#Update using .gz compressed fileupdate_zip -gz boot.img.gz $(find_block boot)#Update using an IMG Sparseupdate_zip -sparse system.img $(find_block system)#Update using an IMG Sparse additionally compressed as .xzupdate_zip -sparse -xz system.img.xz $(find_block system)#Update but ABORT the ZIP installation in case of errorupdate_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 ZIPflash log1 "/sdcard/custom.zip"#Internal ZIPflash_zip log_name "folder/test.zip"#Allow text printing in recoveryflash_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 usagedynamic_install_apk "FOLDER" "/system"#Include extra files/Folders#The "oat" and "lib" folders will be included in the destination of all APKsdynamic_install_apk -include "oat" -include "lib" "FOLDER" "/system"#Redirect resultsdynamic_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 Splitsapk_install "$TMP/Main.apk:$TMP/Split.apk:$TMP/Split2.apk"#Multi .APK installation with multiple external Splitsapk_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 Splitsapk_install "$TMP/Main.apkm:$TMP/Split.apk:$TMP/Split2.apk"#Multi .APKM installation with multiple additional external Splitsapk_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 .APKMapk_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 TEST2unify_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 partitionchecksuper $(find_block super)#Check SUPER imagechecksuper "/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/Bget_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 .imgstart_loop system /sdcard/super.imgsystem_point="$LOOP"#Make new point with vendor inside SUPER partitionstart_loop vendor $(find_block super)vendor_point="$LOOP"#Make new point for A/B devicesstart_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 Pointsstart_loop system_a /sdcard/super.imgsystem="$LOOP"start_loop vendor_a /sdcard/super.imgvendor="$LOOP"start_loop product_a /sdcard/super.imgproduct="$LOOP"#Now to finish NEW POINTSend_loopend_loopend_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 slotunlock system_a#Try enable RW in vendor (Active slot)unlock vendor$slot#Try enable RW in vendor from external SUPER.imgunlock 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 Modeobfuscate -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 Modecat /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 roundingresult=$(int "5.5")#Will return "62" without roundingresult=$(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 defaultresult=$(float "5.5")#Will return "62.500000000" with 9 decimals by defaultresult=$(float "(5^3)/2")#How to increase decimal parts?setdefault float_length 10#Will return "5.5000000000" with 10 decimalsresult=$(float "5.5")#How to decrease decimal parts?setdefault float_length 2#Will return "5.50" with 2 decimalsresult=$(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 roundingresult=$(round "5.5")#Will return "63" with roundingresult=$(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" optionchange_bin "unzip" -while "-p"#Muti changechange_bin "chmod" "unzip" "find"#Restore to Original Busybox binaries#$l is the path where all the native DI binaries arechange_bin "$l/chmod"
[ZIP - Dual Installer] Dynamic Installer Stable 4.8-b2 [ Android 10+ or earlier ] (2024)
Top Articles
Latest Posts
Article information

Author: Greg Kuvalis

Last Updated:

Views: 5415

Rating: 4.4 / 5 (55 voted)

Reviews: 94% of readers found this page helpful

Author information

Name: Greg Kuvalis

Birthday: 1996-12-20

Address: 53157 Trantow Inlet, Townemouth, FL 92564-0267

Phone: +68218650356656

Job: IT Representative

Hobby: Knitting, Amateur radio, Skiing, Running, Mountain biking, Slacklining, Electronics

Introduction: My name is Greg Kuvalis, I am a witty, spotless, beautiful, charming, delightful, thankful, beautiful person who loves writing and wants to share my knowledge and understanding with you.