How Magisk Patches Boot Images for Root Access: The magiskboot Unpack/Patch/Repack Pipeline
Magisk patches boot images for root access by using the magiskboot binary to unpack the boot image into components, remove dm-verity and forced-encryption flags from the ramdisk, optionally patch the kernel, and repack everything into a modified boot image that maintains the original signature structure.
The magiskboot utility in the topjohnwu/Magisk repository is the core native tool that enables systemless root by manipulating Android boot images without external dependencies. This native C++/Rust binary orchestrates a three-stage pipeline—unpack, patch, and repack—that modifies boot images to inject the Magisk daemon while bypassing Android Verified Boot (AVB) checks.
Unpacking the Boot Image with magiskboot unpack
The magiskboot unpack <boot.img> command initiates the extraction process by calling the unpack() function defined in native/src/boot/bootimg.cpp (lines 633-680). This stage deconstructs the boot image into individual components stored as separate files.
Parsing Headers and Detecting Formats
The unpacking process begins with boot_img::parse_hdr(), which creates a dyn_img_hdr subclass capable of handling multiple boot image variants including AOSP, vendor-specific, and ChromeOS formats (lines 34-70). The parser examines the header to determine the layout offsets for each section.
Memory Mapping and Extraction
The implementation uses mmap_data img to memory-map the entire boot image, then extracts sections (kernel, ramdisk, second, extra, dtb) based on the parsed header offsets. Each component is written to disk using the filenames declared in native/src/boot/magiskboot.hpp (lines 5-15), such as kernel, ramdisk.cpio, and dtb.
Conditional Decompression
If a section is compressed and skip_decomp is false, check_fmt_lg() detects the compression format (distinguishing between LZ4 legacy and LG variants) and invokes the appropriate decompressor from compress.rs. Raw bytes are dumped directly when decompression is skipped or unnecessary.
Header Preservation
When the hdr flag is set, the original header is written to a file named header for potential modification before repacking.
Patching Components for Root Access
After unpacking, Magisk modifies specific components to disable security mechanisms and prepare the environment for root access.
Removing Verity and Encryption Flags from Ramdisk
The ramdisk CPIO archive undergoes modification via cpio::patch(), invoked through magiskboot cpio <ramdisk.cpio> patch. The core logic resides in native/src/boot/patch.rs (lines 64-88), which implements two critical functions:
pub fn patch_verity(buf: &mut [u8]) -> usize { … } // Strips "verify", "avb_keys"
pub fn patch_encryption(buf: &mut [u8]) -> usize { … } // Strips "forceencrypt"
Both functions utilize remove_pattern() with the match_patterns! macro to scan buffers for known boot-parameter strings and remove them in-place, returning the new buffer size. This eliminates dm-verity and forced-encryption flags that would otherwise prevent the device from booting with a modified system.
DTB Patching for fstab Modifications
For devices using Device Tree Blobs, magiskboot dtb <file> patch invokes dtb::dtb_patch() from native/src/boot/dtb.rs (lines 8-27). This function parses the DTB file, locates the fstab node, and applies patch_verity() to the fstab contents, clearing verity and avb flags from the device tree configuration.
Kernel Hex-Patching
Direct kernel modification uses magiskboot hexpatch <kernel> <oldhex> <newhex>, which maps the kernel file and converts hex strings to byte patterns via hex2byte. The MappedFile::patch() method (lines 90-118 in patch.rs) replaces every occurrence of the pattern, enabling low-level binary modifications without recompiling the kernel.
Repacking the Modified Boot Image
The magiskboot repack <orig_boot.img> [out_boot.img] command calls repack() in native/src/boot/bootimg.cpp (lines 15-52) to reconstruct the boot image with modifications.
Header Reconstruction and Component Compression
The repack process creates a clone of the original header (hdr = boot.hdr->clone()) and zeros the size fields. If a custom header file exists on disk, it overrides the original header values. For each component file present (kernel, ramdisk, etc.), the tool compresses data back into the original format using compress_bytes unless skip_comp is set, updating the corresponding header size fields (e.g., hdr->kernel_size()).
MTK and Special Wrapper Handling
The implementation handles vendor-specific quirks including MTK (MediaTek) and ZIMAGE wrappers by prepending extra headers when necessary.
AVB Footer and Signature Management
After writing all components, the tool computes SHA-1 or SHA-256 hashes over the new sections and writes them into the boot-image ID field hdr->id(). If the original image contained an AVB footer, it is copied and optionally patched with PATCHVBMETAFLAG to set the "disable verification" flag (lines 73-84). For already AVB-signed images, sign_payload regenerates the cryptographic signature to maintain the boot image's verified status.
Cleanup Operations
Upon completion, cleanup() (lines 53-64) removes temporary component files from the working directory.
The C++ to Rust FFI Bridge
The magiskboot binary unifies C++ and Rust code through a Foreign Function Interface defined in native/src/boot/lib.rs (lines 49-60). The CXX bridge exports C++ functions (unpack, repack, cleanup, check_fmt) declared in native/src/boot/magiskboot.hpp to the Rust CLI layer in cli.rs. This architecture allows the Rust command-line interface to invoke native boot-image manipulation routines directly, providing a seamless tool for shell scripts and the Android installer.
Practical Usage Example
The following sequence demonstrates the complete unpack/patch/repack workflow:
# 1. Unpack the original boot image
$ ./magiskboot unpack boot.img
# Directory now contains: header, kernel, ramdisk.cpio, dtb, etc.
# 2. Remove dm-verity and forced encryption from ramdisk
$ ./magiskboot cpio ramdisk.cpio patch
# 3. Optionally patch the kernel binary (example pattern)
$ ./magiskboot hexpatch kernel 821B8012 E2FF8F12
# 4. Repack into a modified boot image
$ ./magiskboot repack boot.img patched.img
The Magisk Android application automates this exact sequence in app/core/src/main/java/com/topjohnwu/magisk/core/tasks/MagiskInstaller.kt (lines 308-311), executing these commands during the installation process.
Summary
magiskboot unpackextracts boot image components usingunpack()inbootimg.cpp, handling multiple header formats and conditional decompression.- Patching operations modify the ramdisk (removing verity/encryption via
patch.rs), DTB (clearing fstab flags viadtb.rs), and kernel (hex-patching viaMappedFile::patch()). magiskboot repackreconstructs the image inbootimg.cpp, updating header sizes, handling MTK wrappers, and preserving or regenerating AVB signatures.- The C++ to Rust FFI in
lib.rsexposes these native functions to the CLI, enabling cross-language orchestration. - All operations preserve the original boot image structure enough to maintain signature validity or allow re-signing, ensuring the modified image remains bootable on locked bootloaders that permit user-signed images.
Frequently Asked Questions
What is the purpose of patching verity and encryption flags?
Removing verify and forceencrypt flags from the ramdisk and DTB disables Android's dm-verity checks and forced encryption requirements. This allows the device to boot with a modified system partition and prevents encryption from being enforced automatically, which is necessary for maintaining root access across reboots without triggering boot loops.
How does magiskboot handle different boot image formats?
The dyn_img_hdr class in bootimg.cpp abstracts header parsing to support AOSP standard headers, vendor-specific variants (including MTK and ChromeOS), and blob-style images. During both unpacking and repacking, the tool preserves format-specific metadata and handles special wrappers like DHTB or ZIMAGE headers automatically.
Can magiskboot repack images while maintaining the original signature?
Yes. The repack() function computes new SHA hashes for modified sections and updates the header's ID field accordingly. If the original image contained an AVB footer, magiskboot copies the footer and can patch the PATCHVBMETAFLAG to disable verification, or call sign_payload to regenerate signatures for user-locked bootloaders that require signed images.
Where does the Magisk app execute these commands during installation?
The Magisk installer runs the unpack/patch/repack sequence in MagiskInstaller.kt within the app core module. The Kotlin code orchestrates calling the native magiskboot binary with appropriate arguments based on the detected device configuration, automating the process described in this pipeline without requiring manual CLI interaction.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →