boot.img解压 1 2 3 python /Volumes/android/aosp/system/tools/mkbootimg/unpack_bootimg.py \ --boot_img=/Users/juneleo/Downloads/magisk_patched-26300 _WZdn1.img \ --out /Users/juneleo/Downloads/magisk_boot
1 2 3 python /Volumes/android/aosp/system/tools/mkbootimg/unpack_bootimg.py \ --boot_img=/Users/juneleo/Downloads/boot.img \ --out /Users/juneleo/Downloads/boot
解压产物 可以看出magisk生成的patch boot 大了1M。
ramdisk对比 其中的ramdisk是一个gzip格式文件,需要改后缀名为.zg,然后直接解压
这里我们大概明白了Magisk大概做了什么
解压boot.img
解压ramdisk
修改init可执行文件
backup数据
复制数据到overlay.d
打包ramdisk和boot-patch.img
dtb对比 1 dtc -I dtb -O dts -o dtb.dts dtb
1 diff boot/dtb.dts magisk_boot/dtb.dts
Magisk boot patch Magisk/scripts/boot_patch.sh ** 这个文件最终会被复制到assets目录下 具体的大概逻辑是 通过 boot_patch.sh脚本将magiskinit可执行文件对ramdisk中的init文件进行了替换,**当执行完成magiskinit后,调用execv(‘system/bin/init’,arg)继续执行原init 原init是一个链接文件 具体细节在这个文档magiskinit替换init加载逻辑
boot_patch.sh Magisk/native/src/boot/main.cpp
日志 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 - Device platform: arm64-v8a - Installing: 26.3 (26300 ) - Copying image to cache Parsing boot image: [/data/user_de/0 /com.topjohnwu.magisk/install/boot.img] HEADER_VER [2 ] KERNEL_SZ [20997486 ] RAMDISK_SZ [10735279 ] SECOND_SZ [0 ] RECOV_DTBO_SZ [0 ] DTB_SZ [1002970 ] OS_VERSION [10.0 .0 ] OS_PATCH_LEVEL [2020 -07 ] PAGESIZE [4096 ] NAME [] CMDLINE [console=ttyMSM0,115200 n8 androidboot.console=ttyMSM0 printk.devkmsg=on msm_rtb.filter=0x237 ehci-hcd.park=3 service_locator.enable=1 androidboot.memcg=1 cgroup.memory=nokmem usbcore.autosuspend=7 androidboot.usbcontroller=a600000.dwc3 swiotlb=2048 androidboot.boot_devices=soc/1 d84000.ufshc buildvariant=user] CHECKSUM [f1828bcca9442e53297ac10d0f6fd4dacbc50378000000000000000000000000] - Unpacking boot image KERNEL_FMT [lz4] RAMDISK_FMT [gzip] unexpected ASN.1 DER tag: expected SEQUENCE, got APPLICATION [1 ] (primitive) VBMETA - Checking ramdisk status Loading cpio: [ramdisk.cpio] - Stock boot image detected - Patching ramdisk - Pre-init storage partition: metadata Loading cpio: [ramdisk.cpio] Add file [init] (100750 ) Create directory [overlay.d] (0750 ) Create directory [overlay.d/sbin] (0750 ) Add file [overlay.d/sbin/magisk32.xz] (100644 ) Add file [overlay.d/sbin/magisk64.xz] (100644 ) Add file [overlay.d/sbin/stub.xz] (100644 ) Patch with flag KEEPVERITY=[true ] KEEPFORCEENCRYPT=[true ] Loading cpio: [ramdisk.cpio.orig] Backup [init] -> [.backup/init] Record new entry: [overlay.d] -> [.backup/.rmlist] Record new entry: [overlay.d/sbin] -> [.backup/.rmlist] Record new entry: [overlay.d/sbin/magisk32.xz] -> [.backup/.rmlist] Record new entry: [overlay.d/sbin/magisk64.xz] -> [.backup/.rmlist] Record new entry: [overlay.d/sbin/stub.xz] -> [.backup/.rmlist] Create directory [.backup] (0000 ) Add file [.backup/.magisk] (100000 ) Dumping cpio: [ramdisk.cpio] Loading dtbs from [dtb] - Repacking boot image Parsing boot image: [/data/user_de/0 /com.topjohnwu.magisk/install/boot.img] HEADER_VER [2 ] KERNEL_SZ [20997486 ] RAMDISK_SZ [10735279 ] SECOND_SZ [0 ] RECOV_DTBO_SZ [0 ] DTB_SZ [1002970 ] OS_VERSION [10.0 .0 ] OS_PATCH_LEVEL [2020 -07 ] PAGESIZE [4096 ] NAME [] CMDLINE [console=ttyMSM0,115200 n8 androidboot.console=ttyMSM0 printk.devkmsg=on msm_rtb.filter=0x237 ehci-hcd.park=3 service_locator.enable=1 androidboot.memcg=1 cgroup.memory=nokmem usbcore.autosuspend=7 androidboot.usbcontroller=a600000.dwc3 swiotlb=2048 androidboot.boot_devices=soc/1 d84000.ufshc buildvariant=user] CHECKSUM [f1828bcca9442e53297ac10d0f6fd4dacbc50378000000000000000000000000] KERNEL_FMT [lz4] RAMDISK_FMT [gzip] unexpected ASN.1 DER tag: expected SEQUENCE, got APPLICATION [1 ] (primitive) VBMETA Repack to boot image: [new -boot.img] HEADER_VER [2 ] KERNEL_SZ [20997486 ] RAMDISK_SZ [11244718 ] SECOND_SZ [0 ] RECOV_DTBO_SZ [0 ] DTB_SZ [1002970 ] OS_VERSION [10.0 .0 ] OS_PATCH_LEVEL [2020 -07 ] PAGESIZE [4096 ] NAME [] CMDLINE [console=ttyMSM0,115200 n8 androidboot.console=ttyMSM0 printk.devkmsg=on msm_rtb.filter=0x237 ehci-hcd.park=3 service_locator.enable=1 androidboot.memcg=1 cgroup.memory=nokmem usbcore.autosuspend=7 androidboot.usbcontroller=a600000.dwc3 swiotlb=2048 androidboot.boot_devices=soc/1 d84000.ufshc buildvariant=user] CHECKSUM [110782426b 7905555aafca11e8c24144a070b180000000000000000000000000] **************************** Output file is written to /storage/emulated/0 /Download/magisk_patched-26300 _zEkUl.img **************************** - All done!
handleFile 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 private fun handleFile (uri: Uri) : Boolean { val outStream: OutputStream val outFile: MediaStoreUtils.UriFile try { uri.inputStream ().buffered ().use { src -> ... srcBoot = if (tarMagic.contentEquals ("ustar" .toByteArray ())) { ... } else { outFile = MediaStoreUtils.getFile ("$filename.img" , true ) outStream = outFile.uri.outputStream () try { if (magic.contentEquals ("CrAU" .toByteArray ())) { processPayload (src) } else if (magic.contentEquals ("PK\u0003\u0004" .toByteArray ())) { processZip (ZipInputStream (src)) } else { console.add ("- Copying image to cache" ) installDir.getChildFile ("boot.img" ).also { src.copyAndCloseOut (it.newOutputStream ()) } } } catch (e: IOException) { outStream.close () outFile.delete () throw e } } } } catch (e: IOException) { if (e is NoBootException) console.add ("! No boot image found" ) console.add ("! Process error" ) Timber.e (e) return false } if (!patchBoot ()) { outFile.delete () return false } try { val newBoot = installDir.getChildFile ("new-boot.img" ) if (outStream is TarOutputStream) { val name = with (srcBoot.path) { when { contains ("recovery" ) -> "recovery.img" contains ("init_boot" ) -> "init_boot.img" else -> "boot.img" } } outStream.putNextEntry (newTarEntry (name, newBoot.length ())) } newBoot.newInputStream ().copyAndClose (outStream) newBoot.delete () console.add ("" ) console.add ("****************************" ) console.add (" Output file is written to " ) console.add (" $outFile " ) console.add ("****************************" ) } catch (e: IOException) { console.add ("! Failed to output to $outFile" ) outFile.delete () Timber.e (e) return false } srcBoot.delete () "cp_readlink $installDir" .sh () return true }
patchBoot 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 private fun patchBoot () : Boolean { val newBoot = installDir.getChildFile ("new-boot.img" ) if (!useRootDir) { newBoot.createNewFile () File (installDir, "stock_boot.img" ).createNewFile () } val cmds = arrayOf ( "cd $installDir" , "KEEPFORCEENCRYPT=${Config.keepEnc} " + "KEEPVERITY=${Config.keepVerity} " + "PATCHVBMETAFLAG=${Info.patchBootVbmeta} " + "RECOVERYMODE=${Config.recovery} " + "LEGACYSAR=${Info.legacySAR} " + "sh boot_patch.sh $srcBoot" ) val isSuccess = cmds.sh ().isSuccess shell.newJob ().add ("./magiskboot cleanup" , "cd /" ).exec () return isSuccess }
patch Magisk/native/src/boot/cpio.rs
1 2 3 4 5 6 7 8 9 10 11 12 ./magiskboot cpio ramdisk.cpio \ "add 0750 $INIT magiskinit" \"mkdir 0750 overlay.d" \"mkdir 0750 overlay.d/sbin" \"$SKIP32 add 0644 overlay.d/sbin/magisk32.xz magisk32.xz" \"$SKIP64 add 0644 overlay.d/sbin/magisk64.xz magisk64.xz" \"add 0644 overlay.d/sbin/stub.xz stub.xz" \"patch" \"$SKIP_BACKUP backup ramdisk.cpio.orig" \"mkdir 000 .backup" \"add 000 .backup/.magisk config" \|| abort "! Unable to patch ramdisk"
Repack magiskinit 入口:Magisk/native/src/init/init.cpp main()