/* monogisk.c - Monolithic binary hosting Magisk binaries * * This code has to be compiled statically to work properly. * * To unify Magisk support for both legacy "normal" devices and new skip_initramfs devices, * this tool is born. Magisk binary compilation is split into two parts - first part contains * "magisk" and "magiskinit". The python build script will load these 2 binaries and compress * them with lzma2, dumping the results into "dump.h". Monogisk is simply just a static lzma * extractor embedded with binary blobs, with a few additional operations to construct an * environment for "magiskinit" to handle the rest of the work. */ #include #include #include #include #include #include #include "dump.h" #include "magiskrc.h" #define str(a) #a #define xstr(a) str(a) #define BUFSIZE 0x100000 lzma_stream strm = LZMA_STREAM_INIT; static void usage() { const char usage[] = "Monogisk v" xstr(MAGISK_VERSION) "(" xstr(MAGISK_VER_CODE) ") (by topjohnwu)\n" "A monolithic binary used as /init to add Magisk support\n" "\n" "Usage:\n" " monogisk -x \n" " extract \"magisk\", \"magiskinit\", or \"magiskrc\"\n" " /init\n" " Startup the system with Magisk support\n" "\n"; write(STDERR_FILENO, usage, sizeof(usage)); exit(1); } static int unxz(lzma_stream *strm, const void *buf, size_t size, int fd) { lzma_ret ret = 0; uint8_t out[BUFSIZE]; strm->next_in = buf; strm->avail_in = size; do { strm->next_out = out; strm->avail_out = sizeof(out); ret = lzma_code(strm, LZMA_RUN); write(fd, out, sizeof(out) - strm->avail_out); } while (strm->avail_out == 0 && ret == LZMA_OK); if (ret != LZMA_OK && ret != LZMA_STREAM_END) write(STDERR_FILENO, "LZMA error!\n", 13); return ret; } static int dump_magisk(const char *path, mode_t mode) { if (lzma_auto_decoder(&strm, UINT64_MAX, 0) != LZMA_OK) return 1; unlink(path); int fd = creat(path, mode); int ret = unxz(&strm, magisk_dump, sizeof(magisk_dump), fd); close(fd); return ret; } static int dump_magiskinit(const char *path, mode_t mode) { if (lzma_auto_decoder(&strm, UINT64_MAX, 0) != LZMA_OK) return 1; unlink(path); int fd = creat(path, mode); int ret = unxz(&strm, magiskinit_dump, sizeof(magiskinit_dump), fd); close(fd); return ret; } static int dump_magiskrc(const char *path, mode_t mode) { unlink(path); int fd = creat(path, mode); write(fd, magiskrc, sizeof(magiskrc)); close(fd); return 0; } static int init_main(int argc, char *argv[]) { dump_magiskinit("/init", 0750); mkdir("/overlay", 0); dump_magiskrc("/overlay/init.magisk.rc", 0750); mkdir("/overlay/sbin", 0755); dump_magisk("/overlay/sbin/magisk", 0755); mkdir("/overlay/root", 0755); link("/init", "/overlay/root/magiskpolicy"); link("/init", "/overlay/root/supolicy"); execv("/init", argv); return 1; /* Should not happen */ } int main(int argc, char *argv[]) { umask(0); if (argc == 1) return init_main(argc, argv); if (argc < 4) usage(); if (strcmp(argv[2], "magisk") == 0) dump_magisk(argv[3], 0755); else if (strcmp(argv[2], "magiskinit") == 0) dump_magiskinit(argv[3], 0755); else usage(); lzma_end(&strm); return 0; }