#include #include #include "magiskboot.hpp" #include "compress.hpp" using namespace std; static void print_formats() { for (int fmt = GZIP; fmt < LZOP; ++fmt) { fprintf(stderr, "%s ", fmt2name[(format_t) fmt]); } } static void usage(char *arg0) { fprintf(stderr, R"EOF(MagiskBoot - Boot Image Modification Tool Usage: %s [args...] Supported actions: unpack [-n] [-h] Unpack to, if available, kernel, kernel_dtb, ramdisk.cpio, second, dtb, extra, and recovery_dtbo into current directory. If '-n' is provided, it will not attempt to decompress kernel or ramdisk.cpio from their original formats. If '-h' is provided, it will dump header info to 'header', which will be parsed when repacking. Return values: 0:valid 1:error 2:chromeos repack [-n] [outbootimg] Repack boot image components from current directory to [outbootimg], or new-boot.img if not specified. If '-n' is provided, it will not attempt to recompress ramdisk.cpio, otherwise it will compress ramdisk.cpio and kernel with the same format as in if the file provided is not already compressed. All disable flags will be set in the vbmeta header, unless env variable KEEPVBMETAFLAG is set to true. hexpatch Search in , and replace with cpio [commands...] Do cpio commands to (modifications are done in-place) Each command is a single argument, add quotes for each command Supported commands: exists ENTRY Return 0 if ENTRY exists, else return 1 rm [-r] ENTRY Remove ENTRY, specify [-r] to remove recursively mkdir MODE ENTRY Create directory ENTRY in permissions MODE ln TARGET ENTRY Create a symlink to TARGET with the name ENTRY mv SOURCE DEST Move SOURCE to DEST add MODE ENTRY INFILE Add INFILE as ENTRY in permissions MODE; replaces ENTRY if exists extract [ENTRY OUT] Extract ENTRY to OUT, or extract all entries to current directory test Test the current cpio's status Return value is 0 or bitwise or-ed of following values: 0x1:Magisk 0x2:unsupported 0x4:Sony patch Apply ramdisk patches Configure with env variables: KEEPVERITY KEEPFORCEENCRYPT backup ORIG Create ramdisk backups from ORIG restore Restore ramdisk from ramdisk backup stored within incpio sha1 Print stock boot SHA1 if previously backed up in ramdisk dtb [args...] Do dtb related actions to Supported actions: print [-f] Print all contents of dtb for debugging Specify [-f] to only print fstab nodes patch Search for fstab and remove verity/avb Modifications are done directly to the file in-place Configure with env variables: KEEPVERITY split Split image.*-dtb into kernel + kernel_dtb sha1 Print the SHA1 checksum for cleanup Cleanup the current working directory compress[=format] [outfile] Compress with [format] (default: gzip), optionally to [outfile] /[outfile] can be '-' to be STDIN/STDOUT Supported formats: )EOF", arg0); print_formats(); fprintf(stderr, R"EOF( decompress [outfile] Detect format and decompress , optionally to [outfile] /[outfile] can be '-' to be STDIN/STDOUT Supported formats: )EOF"); print_formats(); fprintf(stderr, "\n\n"); exit(1); } int main(int argc, char *argv[]) { cmdline_logging(); umask(0); if (argc < 2) usage(argv[0]); // Skip '--' for backwards compatibility string_view action(argv[1]); if (str_starts(action, "--")) action = argv[1] + 2; if (action == "cleanup") { fprintf(stderr, "Cleaning up...\n"); unlink(HEADER_FILE); unlink(KERNEL_FILE); unlink(RAMDISK_FILE); unlink(SECOND_FILE); unlink(KER_DTB_FILE); unlink(EXTRA_FILE); unlink(RECV_DTBO_FILE); unlink(DTB_FILE); } else if (argc > 2 && action == "sha1") { uint8_t sha1[SHA_DIGEST_SIZE]; auto m = mmap_data(argv[2]); SHA_hash(m.buf, m.sz, sha1); for (uint8_t i : sha1) printf("%02x", i); printf("\n"); } else if (argc > 2 && action == "split") { return split_image_dtb(argv[2]); } else if (argc > 2 && action == "unpack") { int idx = 2; bool nodecomp = false; bool hdr = false; for (;;) { if (idx >= argc) usage(argv[0]); if (argv[idx][0] != '-') break; for (char *flag = &argv[idx][1]; *flag; ++flag) { if (*flag == 'n') nodecomp = true; else if (*flag == 'h') hdr = true; else usage(argv[0]); } ++idx; } return unpack(argv[idx], nodecomp, hdr); } else if (argc > 2 && action == "repack") { if (argv[2] == "-n"sv) { if (argc == 3) usage(argv[0]); repack(argv[3], argv[4] ? argv[4] : NEW_BOOT, true); } else { repack(argv[2], argv[3] ? argv[3] : NEW_BOOT); } } else if (argc > 2 && action == "decompress") { decompress(argv[2], argv[3]); } else if (argc > 2 && str_starts(action, "compress")) { compress(action[8] == '=' ? &action[9] : "gzip", argv[2], argv[3]); } else if (argc > 4 && action == "hexpatch") { return hexpatch(argv[2], argv[3], argv[4]); } else if (argc > 2 && action == "cpio"sv) { if (cpio_commands(argc - 2, argv + 2)) usage(argv[0]); } else if (argc > 3 && action == "dtb") { if (dtb_commands(argc - 2, argv + 2)) usage(argv[0]); } else { usage(argv[0]); } return 0; }