Here is step-by-step manual that will help you get started out:
Prerequisites
Basic Knowledge: Familiarity with Android's file system, shell scripting, and simple Linux commands.
Tools: A text editor (like VS Code or Notepad++), a rooted Android device, and a computer.
All Steps
1. Create Module Structure
Create a directory for your module. Inside this directory, you'll need to set up a specific structure:
MyModule
│
├── META-INF
│ └── com
│ └── google
│ └── android
│ ├── update-binary
│ └── updater-script
├── common
│ └── post-fs-data.sh
├── module.prop
└── system
└── <your files and directories>
2. The module.prop File
This file contains metadata about your module. Create a module.prop file in the root of your module directory and add the following content:
id=your.module.id
name=Your Module Name
version=1.0
versionCode=1
author=Your Name
description=A brief description of your module.
3. The update-binary Script
This script is used during the installation process. You can use the default update-binary provided by Magisk. It doesn’t need to be edited for most modules. You can download it from the Magisk GitHub repository and place it in the META-INF/com/google/android directory.
4. The updater-script
This script is also used during the installation process to define what happens when your module is installed. A basic updater-script might look like this:
post-fs-data.sh: This script runs after the filesystem is mounted but before data is restored.
service.sh: This script runs on each boot. Create this script if you need to perform actions on every boot.
Example post-fs-data.sh:
#!/system/bin/sh
# Your script here
Make sure to set the correct permissions for these scripts:
chmod 755 post-fs-data.sh
6. System Files
Place any files or directories you want to be modified or added to the system inside the system directory. For example, if you want to add a new binary to /system/bin, you would place it in system/bin/.
7. Packaging the Module
Once your module is ready, package it into a ZIP file. The ZIP structure should look like this:
MyModule.zip
│
├── META-INF
│ └── com
│ └── google
│ └── android
│ ├── update-binary
│ └── updater-script
├── common
│ └── post-fs-data.sh
├── module.prop
└── system
└── <your files and directories>
8. Testing the Module
Transfer the ZIP file to your rooted Android device.
Open the Magisk Manager app.
Go to the "Modules" section and tap on select from storage bar.
Select your module's ZIP file and install it.
Reboot your device.
9. Debugging
If the module doesn’t work as expected, check the Magisk logs for errors. You can find the logs in the Magisk Manager app under "Logs".
Example Module
Here's an example of a very simple module that adds a custom script to /system/bin:
1. Directory Structure:
CustomScriptModule
├── META-INF
│ └── com
│ └── google
│ └── android
│ ├── update-binary
│ └── updater-script
├── module.prop
└── system
└── bin
└── custom_script.sh
2. module.prop:
id=custom.script.module
name=Custom Script Module
version=1.0
versionCode=1
author=Your Name
description=Adds a custom script to /system/bin.
After following these steps, you should have a working Magisk module. Adjust the files and scripts according to your specific needs.
If you have followed all the steps above perfectly, congratulations! You have created a Magisk module. Share this tutorial about how to create magisk
module with your friends to help them learn how to create Magisk modules too.
If you're interested in creating a Magisk module for gaming, this course includes open-source codes and guides: Make Magisk Module Course. It's great for beginners looking to explore more open-source examples.
KernelSU Module Guide
Introduction
KernelSU provides a systemless module mechanism, allowing you to modify the system directory while maintaining the integrity of the system partition. If you are familiar with Magisk module development, you will find KernelSU modules very similar.
WebUI
KernelSU modules support displaying interfaces and interacting with users. For more information, refer to the WebUI documentation.
Busybox
KernelSU includes a feature-complete BusyBox binary with full SELinux support. This BusyBox is located at /data/adb/ksu/bin/busybox. KernelSU's BusyBox supports a runtime toggle-able "ASH Standalone Shell Mode", ensuring a predictable environment for scripts.
Standalone Mode
Every shell script executed in KernelSU will run in BusyBox's ash shell with standalone mode enabled.
To enable this mode outside of KernelSU:
Set the environment variable ASH_STANDALONE=1.
ASH_STANDALONE=1 /data/adb/ksu/bin/busybox sh <script>
Use the command-line option:
/data/adb/ksu/bin/busybox sh -o standalone <script>
Differences with Magisk
KernelSU's BusyBox is compiled directly from the Magisk project, ensuring compatibility with BusyBox scripts used in Magisk.
KernelSU Modules
A KernelSU module is a folder placed in /data/adb/modules with a specific structure:
/data/adb/modules
├── .
├── .
├── $MODID <-- Folder named with the ID of the module
│ ├── module.prop <-- Metadata of the module
│ ├── system <-- Mounted if skip_mount does not exist
│ │ ├── ...
│ │ └── ...
│ ├── skip_mount <-- Prevents mounting of the system folder
│ ├── disable <-- Disables the module
│ ├── remove <-- Removes the module on next reboot
│ ├── post-fs-data.sh <-- Executed in post-fs-data
│ ├── post-mount.sh <-- Executed in post-mount
│ ├── service.sh <-- Executed in late_start service
│ ├── boot-completed.sh <-- Executed on boot completed
│ ├── uninstall.sh <-- Executed when KernelSU removes the module
│ ├── system.prop <-- Loaded as system properties by resetprop
│ ├── sepolicy.rule <-- Additional custom sepolicy rules
│ ├── vendor <-- Symlink to $MODID/system/vendor
│ ├── product <-- Symlink to $MODID/system/product
│ ├── system_ext <-- Symlink to $MODID/system/system_ext
│ └── ...
Key Differences with Magisk
KernelSU does not support Zygisk natively. Use ZygiskNext to support Zygisk modules.
module.prop
The module.prop file is essential for KernelSU to recognize the module. It contains metadata:
KernelSU provides several script types for different boot stages:
post-fs-data.sh: Executed in post-fs-data mode (blocking).
post-mount.sh: Executed after overlayfs is mounted.
service.sh: Executed in late_start service mode (non-blocking).
boot-completed.sh: Executed on boot completed.
Note
Use MODDIR=${0%/*} to get your module's base directory path in scripts.
System Directory
The system directory in the module overlays the system's /system partition using overlayfs.
Overwriting Files: Files in the module's system directory will overwrite those in the system directory.
Merging Folders: Folders will be merged.
To delete a file/folder in the system directory, use:
mknod filename c 0 0
To replace a directory:
setfattr -n trusted.overlay.opaque -v y <TARGET>
system.prop
This file follows the same format as build.prop and contains system properties.
sepolicy.rule
This file includes additional custom sepolicy patches needed by the module.
Module Installer
A KernelSU module installer is a module packaged as a ZIP file to be flashed in the KernelSU manager app.
Warning
KernelSU modules cannot be installed via a Custom Recovery.
Customization
Optionally, you can create a customize.sh script to customize the installation process. This script will be sourced by the installer after file extraction and applying default permissions.
To fully control the installation, set SKIPUNZIP=1 in customize.sh.
Boot Scripts
KernelSU categorizes boot scripts into two modes:
post-fs-data mode: Blocking; scripts run before Zygote is started.
late_start service mode: Non-blocking; scripts run in parallel with the boot process.
Scripts are also divided based on their storage location:
General scripts: Placed in /data/adb/post-fs-data.d, /data/adb/service.d, /data/adb/post-mount.d, or /data/adb/boot-completed.d.
Module scripts: Placed in the module's own folder.
Boot Process Explanation
Here’s a simplified Android boot process with KernelSU operations:
1. Bootloader: Loads patched boot.img and kernel.
2. Kernel Execution: Executes init, mounts directories, reads properties and init.rc.
3. post-fs-data:
- KernelSU checks safe mode, executes general and module scripts in post-fs-data and post-mount modes.
4. Zygote Start: Starts Zygote, loads properties.
5. Boot: Executes general and module scripts in service and boot-completed modes.
6. User Operable: User can interact with the device.
For detailed Android Init Language, refer to its documentation.
Some Other Module making guide
Shizuku Module Build Guide
Learn how to create a Shizuku module for Android without root using Magisk. Shizuku permits apps to access system APIs with improved privileges, capability and security,instructions on building, installing, and configuring your Shizuku Script.
Discover how to develop a Brevent module for Android using Magisk without needing root access. Brevent prevents apps from running in background, optimizing battery life developing, customizing, and deploying your Brevent script to Improve any Android device performance.
Explore the process of building an ADB module for Android using Magisk without root privileges. ADB offers most powerful command-line access to your device, enabling advanced tweaks and modifications ,creating, testing, and installing your ADB Script to customise Android device.