Add high compression ramdisk support
This commit is contained in:
parent
742dc137ed
commit
9f6a27c20d
@ -76,6 +76,7 @@ LOCAL_SRC_FILES := \
|
||||
utils/vector.c \
|
||||
utils/file.c \
|
||||
utils/xwrap.c \
|
||||
utils/cpio.c \
|
||||
magiskpolicy/api.c \
|
||||
magiskpolicy/magiskpolicy.c \
|
||||
magiskpolicy/rules.c \
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include "utils.h"
|
||||
#include "magiskpolicy.h"
|
||||
#include "daemon.h"
|
||||
#include "cpio.h"
|
||||
#include "magisk.h"
|
||||
|
||||
// #define VLOG(fmt, ...) printf(fmt, __VA_ARGS__) /* Enable to debug */
|
||||
@ -458,11 +459,36 @@ int main(int argc, char *argv[]) {
|
||||
mount(dev.path, "/vendor", "ext4", MS_RDONLY, NULL);
|
||||
|
||||
close(system_root);
|
||||
} else {
|
||||
char *ramdisk_xz = NULL;
|
||||
if (access("/ramdisk-recovery.xz", R_OK) == 0)
|
||||
ramdisk_xz = "/ramdisk-recovery.xz";
|
||||
else if (access("/ramdisk.cpio.xz", R_OK) == 0)
|
||||
ramdisk_xz = "/ramdisk.cpio.xz";
|
||||
|
||||
if (ramdisk_xz) {
|
||||
// High compress mode
|
||||
void *addr;
|
||||
size_t size;
|
||||
mmap_ro(ramdisk_xz, &addr, &size);
|
||||
int fd = creat("/ramdisk.cpio", 0);
|
||||
unxz(addr, size, fd);
|
||||
munmap(addr, size);
|
||||
close(fd);
|
||||
struct vector v;
|
||||
vec_init(&v);
|
||||
parse_cpio(&v, "/ramdisk.cpio");
|
||||
excl_list = (char *[]) { "overlay", ".backup", NULL };
|
||||
frm_rf(root);
|
||||
chdir("/");
|
||||
cpio_extract_all(&v);
|
||||
cpio_vec_destroy(&v);
|
||||
} else {
|
||||
// Revert original init binary
|
||||
unlink("/init");
|
||||
link("/.backup/init", "/init");
|
||||
}
|
||||
}
|
||||
|
||||
// Only patch initramfs if not intended to run in recovery (legacy devices)
|
||||
if (access("/etc/recovery.fstab", F_OK) != 0) {
|
||||
|
@ -55,8 +55,8 @@ void cpio_extract_all(struct vector *v);
|
||||
|
||||
// Magisk specific
|
||||
int cpio_test(struct vector *v);
|
||||
void cpio_backup(struct vector *v, const char *orig, const char *sha1);
|
||||
int cpio_restore(struct vector *v);
|
||||
struct vector *cpio_backup(struct vector *v, const char *orig, const char *sha1);
|
||||
void cpio_restore(struct vector *v);
|
||||
char *cpio_stocksha1(struct vector *v);
|
||||
|
||||
#endif
|
||||
|
@ -117,8 +117,8 @@ int fsetattr(int fd, struct file_attr *a);
|
||||
void fclone_attr(const int sourcefd, const int targetfd);
|
||||
void clone_attr(const char *source, const char *target);
|
||||
void restorecon(int dirfd, int force);
|
||||
void mmap_ro(const char *filename, void **buf, size_t *size);
|
||||
void mmap_rw(const char *filename, void **buf, size_t *size);
|
||||
int mmap_ro(const char *filename, void **buf, size_t *size);
|
||||
int mmap_rw(const char *filename, void **buf, size_t *size);
|
||||
void full_read(int fd, void **buf, size_t *size);
|
||||
void write_zero(int fd, size_t size);
|
||||
void mem_align(size_t *pos, size_t align);
|
||||
|
@ -8,6 +8,11 @@
|
||||
#include "utils.h"
|
||||
#include "logging.h"
|
||||
|
||||
#define INSUF_BLOCK_RET 2
|
||||
#define CHROMEOS_RET 3
|
||||
#define ELF32_RET 4
|
||||
#define ELF64_RET 5
|
||||
|
||||
static void dump(void *buf, size_t size, const char *filename) {
|
||||
int fd = creat(filename, 0644);
|
||||
xwrite(fd, buf, size);
|
||||
@ -53,60 +58,61 @@ static void print_hdr(const boot_img_hdr *hdr) {
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
int parse_img(void *orig, size_t size, boot_img *boot) {
|
||||
void *base, *end;
|
||||
size_t pos = 0;
|
||||
int ret = 0;
|
||||
int parse_img(const char *image, boot_img *boot) {
|
||||
memset(boot, 0, sizeof(*boot));
|
||||
for(base = orig, end = orig + size; base < end; base += 256, size -= 256) {
|
||||
switch (check_type(base)) {
|
||||
int is_blk = mmap_ro(image, &boot->map_addr, &boot->map_size);
|
||||
|
||||
// Parse image
|
||||
fprintf(stderr, "Parsing boot image: [%s]\n\n", image);
|
||||
for (size_t pos = 0; pos < boot->map_size; pos += 256) {
|
||||
switch (check_type(boot->map_addr + pos)) {
|
||||
case CHROMEOS:
|
||||
// The caller should know it's chromeos, as it needs additional signing
|
||||
ret = 2;
|
||||
boot->flags |= CHROMEOS_FLAG;
|
||||
continue;
|
||||
case ELF32:
|
||||
exit(3);
|
||||
exit(ELF32_RET);
|
||||
case ELF64:
|
||||
exit(4);
|
||||
exit(ELF64_RET);
|
||||
case AOSP:
|
||||
// Read the header
|
||||
memcpy(&boot->hdr, base, sizeof(boot->hdr));
|
||||
memcpy(&boot->hdr, boot->map_addr + pos, sizeof(boot->hdr));
|
||||
pos += boot->hdr.page_size;
|
||||
|
||||
print_hdr(&boot->hdr);
|
||||
|
||||
boot->kernel = base + pos;
|
||||
boot->kernel = boot->map_addr + pos;
|
||||
pos += boot->hdr.kernel_size;
|
||||
mem_align(&pos, boot->hdr.page_size);
|
||||
|
||||
boot->ramdisk = base + pos;
|
||||
boot->ramdisk = boot->map_addr + pos;
|
||||
pos += boot->hdr.ramdisk_size;
|
||||
mem_align(&pos, boot->hdr.page_size);
|
||||
|
||||
if (boot->hdr.second_size) {
|
||||
boot->second = base + pos;
|
||||
boot->second = boot->map_addr + pos;
|
||||
pos += boot->hdr.second_size;
|
||||
mem_align(&pos, boot->hdr.page_size);
|
||||
}
|
||||
|
||||
if (boot->hdr.extra_size) {
|
||||
boot->extra = base + pos;
|
||||
boot->extra = boot->map_addr + pos;
|
||||
pos += boot->hdr.extra_size;
|
||||
mem_align(&pos, boot->hdr.page_size);
|
||||
}
|
||||
|
||||
if (pos < size) {
|
||||
boot->tail = base + pos;
|
||||
boot->tail_size = end - base - pos;
|
||||
if (pos < boot->map_size) {
|
||||
boot->tail = boot->map_addr + pos;
|
||||
boot->tail_size = boot->map_size - pos;
|
||||
}
|
||||
|
||||
// Search for dtb in kernel
|
||||
for (int i = 0; i < boot->hdr.kernel_size; ++i) {
|
||||
for (uint32_t i = 0; i < boot->hdr.kernel_size; ++i) {
|
||||
if (memcmp(boot->kernel + i, DTB_MAGIC, 4) == 0) {
|
||||
boot->dtb = boot->kernel + i;
|
||||
boot->dt_size = boot->hdr.kernel_size - i;
|
||||
boot->hdr.kernel_size = i;
|
||||
fprintf(stderr, "DTB [%d]\n", boot->dt_size);
|
||||
fprintf(stderr, "DTB [%u]\n", boot->dt_size);
|
||||
}
|
||||
}
|
||||
|
||||
@ -139,25 +145,19 @@ int parse_img(void *orig, size_t size, boot_img *boot) {
|
||||
fprintf(stderr, "RAMDISK_FMT [%s]\n", fmt);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
return ret;
|
||||
return boot->flags & CHROMEOS_FLAG ? CHROMEOS_RET :
|
||||
((is_blk && boot->tail_size < 500 * 1024) ? INSUF_BLOCK_RET : 0);
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
}
|
||||
LOGE("No boot image magic found!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
void unpack(const char* image) {
|
||||
size_t size;
|
||||
void *orig;
|
||||
mmap_ro(image, &orig, &size);
|
||||
int fd;
|
||||
boot_img boot;
|
||||
|
||||
// Parse image
|
||||
fprintf(stderr, "Parsing boot image: [%s]\n\n", image);
|
||||
int ret = parse_img(orig, size, &boot);
|
||||
int ret = parse_img(image, &boot);
|
||||
int fd;
|
||||
|
||||
// Dump kernel
|
||||
if (COMPRESSED(boot.kernel_type)) {
|
||||
@ -193,24 +193,18 @@ void unpack(const char* image) {
|
||||
dump(boot.extra, boot.hdr.extra_size, EXTRA_FILE);
|
||||
}
|
||||
|
||||
munmap(orig, size);
|
||||
munmap(boot.map_addr, boot.map_size);
|
||||
exit(ret);
|
||||
}
|
||||
|
||||
void repack(const char* orig_image, const char* out_image) {
|
||||
size_t size;
|
||||
void *orig;
|
||||
boot_img boot;
|
||||
|
||||
// There are possible two MTK headers
|
||||
size_t mtk_kernel_off, mtk_ramdisk_off;
|
||||
|
||||
// Load original image
|
||||
mmap_ro(orig_image, &orig, &size);
|
||||
|
||||
// Parse original image
|
||||
fprintf(stderr, "Parsing boot image: [%s]\n\n", orig_image);
|
||||
parse_img(orig, size, &boot);
|
||||
parse_img(orig_image, &boot);
|
||||
|
||||
fprintf(stderr, "Repack to boot image: [%s]\n\n", out_image);
|
||||
|
||||
@ -309,7 +303,6 @@ void repack(const char* orig_image, const char* out_image) {
|
||||
// Print new image info
|
||||
print_hdr(&boot.hdr);
|
||||
|
||||
munmap(orig, size);
|
||||
munmap(boot.map_addr, boot.map_size);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
|
@ -103,20 +103,25 @@ typedef struct mtk_hdr {
|
||||
// Flags
|
||||
#define MTK_KERNEL 0x1
|
||||
#define MTK_RAMDISK 0x2
|
||||
#define CHROMEOS_FLAG 0x4
|
||||
|
||||
typedef struct boot_img {
|
||||
size_t map_size;
|
||||
uint32_t dt_size;
|
||||
size_t tail_size;
|
||||
uint8_t flags;
|
||||
file_t kernel_type, ramdisk_type;
|
||||
|
||||
boot_img_hdr hdr;
|
||||
mtk_hdr mtk_kernel_hdr, mtk_ramdisk_hdr;
|
||||
|
||||
void *map_addr;
|
||||
void *kernel;
|
||||
void *dtb;
|
||||
uint32_t dt_size;
|
||||
void *ramdisk;
|
||||
void *second;
|
||||
void *extra;
|
||||
void *tail;
|
||||
uint32_t tail_size;
|
||||
uint32_t flags;
|
||||
file_t kernel_type, ramdisk_type;
|
||||
mtk_hdr mtk_kernel_hdr, mtk_ramdisk_hdr;
|
||||
} boot_img;
|
||||
|
||||
#endif
|
||||
|
@ -17,7 +17,7 @@
|
||||
void unpack(const char *image);
|
||||
void repack(const char* orig_image, const char* out_image);
|
||||
void hexpatch(const char *image, const char *from, const char *to);
|
||||
int parse_img(void *orig, size_t size, boot_img *boot);
|
||||
int parse_img(const char *image, boot_img *boot);
|
||||
int cpio_commands(const char *cmd, int argc, char *argv[]);
|
||||
void comp_file(const char *method, const char *from, const char *to);
|
||||
void decomp_file(char *from, const char *to);
|
||||
|
@ -17,16 +17,21 @@ static void usage(char *arg0) {
|
||||
"Usage: %s <action> [args...]\n"
|
||||
"\n"
|
||||
"Supported actions:\n"
|
||||
" --parse <bootimg>\n"
|
||||
" Parse <bootimg> only, do not unpack. Return value: \n"
|
||||
" 0:OK 1:error 2:insufficient boot partition size\n"
|
||||
" 3:chromeos 4:ELF32 5:ELF64\n"
|
||||
"\n"
|
||||
" --unpack <bootimg>\n"
|
||||
" Unpack <bootimg> to kernel, ramdisk.cpio, (second), (dtb), (extra) into\n"
|
||||
" the current directory\n"
|
||||
" the current directory. Return value is the same as parse command\n"
|
||||
"\n"
|
||||
" --repack <origbootimg> [outbootimg]\n"
|
||||
" Repack kernel, ramdisk.cpio[.ext], second, dtb... from current directory\n"
|
||||
" to [outbootimg], or new-boot.img if not specified.\n"
|
||||
" It will compress ramdisk.cpio with the same method used in <origbootimg>\n"
|
||||
" if exists, or attempt to find ramdisk.cpio.[ext], and repack\n"
|
||||
" directly with the compressed ramdisk file\n"
|
||||
" It will compress ramdisk.cpio with the same method used in <origbootimg>,\n"
|
||||
" or attempt to find ramdisk.cpio.[ext], and repack directly with the\n"
|
||||
" compressed ramdisk file\n"
|
||||
"\n"
|
||||
" --hexpatch <file> <hexpattern1> <hexpattern2>\n"
|
||||
" Search <hexpattern1> in <file>, and replace with <hexpattern2>\n"
|
||||
@ -40,18 +45,19 @@ static void usage(char *arg0) {
|
||||
" Create directory as an <entry>\n"
|
||||
" -ln <target> <entry>\n"
|
||||
" Create symlink <entry> to point to <target>\n"
|
||||
" -add <mode> <entry> <infile>\n"
|
||||
" Add <infile> as an <entry>; replaces <entry> if already exists\n"
|
||||
" -mv <from-entry> <to-entry>\n"
|
||||
" Move <from-entry> to <to-entry>\n"
|
||||
" -add <mode> <entry> <infile>\n"
|
||||
" Add <infile> as an <entry>; replaces <entry> if already exists\n"
|
||||
" -extract [<entry> <outfile>]\n"
|
||||
" Extract <entry> to <outfile>, or extract all to current directory\n"
|
||||
" -test\n"
|
||||
" Return value: 0/stock 1/Magisk 2/other (phh, SuperSU, Xposed)\n"
|
||||
" -patch <KEEPVERITY> <KEEPFORCEENCRYPT>\n"
|
||||
" Patch cpio for Magisk. KEEP**** are true/false values\n"
|
||||
" -backup <origcpio> [SHA1]\n"
|
||||
" Patch cpio for Magisk. KEEP**** are boolean values\n"
|
||||
" -backup <origcpio> <HIGH_COMP> [SHA1]\n"
|
||||
" Create ramdisk backups into <incpio> from <origcpio>\n"
|
||||
" HIGH_COMP is a boolean value, toggles high compression mode\n"
|
||||
" SHA1 of stock boot image is optional\n"
|
||||
" -restore\n"
|
||||
" Restore ramdisk from ramdisk backup within <incpio>\n"
|
||||
@ -63,6 +69,9 @@ static void usage(char *arg0) {
|
||||
" Supported commands:\n"
|
||||
" -dump\n"
|
||||
" Dump all contents from dtb for debugging\n"
|
||||
" -test\n"
|
||||
" Check if fstab has verity/avb flags\n"
|
||||
" Return value: 0/no flags 1/flag exists"
|
||||
" -patch\n"
|
||||
" Search for fstab and remove verity/avb\n"
|
||||
"\n"
|
||||
@ -74,8 +83,7 @@ static void usage(char *arg0) {
|
||||
for (int i = 0; SUP_LIST[i]; ++i)
|
||||
fprintf(stderr, "%s ", SUP_LIST[i]);
|
||||
fprintf(stderr,
|
||||
"\n"
|
||||
"\n"
|
||||
"\n\n"
|
||||
" --decompress <infile> [outfile]\n"
|
||||
" Detect method and decompress <infile>, optionally to [outfile]\n"
|
||||
" <infile>/[outfile] can be '-' to be STDIN/STDOUT\n"
|
||||
@ -83,8 +91,7 @@ static void usage(char *arg0) {
|
||||
for (int i = 0; SUP_LIST[i]; ++i)
|
||||
fprintf(stderr, "%s ", SUP_LIST[i]);
|
||||
fprintf(stderr,
|
||||
"\n"
|
||||
"\n"
|
||||
"\n\n"
|
||||
" --sha1 <file>\n"
|
||||
" Print the SHA1 checksum for <file>\n"
|
||||
"\n"
|
||||
@ -121,6 +128,9 @@ int main(int argc, char *argv[]) {
|
||||
printf("%02x", sha1[i]);
|
||||
printf("\n");
|
||||
munmap(buf, size);
|
||||
} else if (argc > 2 && strcmp(argv[1], "--parse") == 0) {
|
||||
boot_img boot;
|
||||
exit(parse_img(argv[2], &boot));
|
||||
} else if (argc > 2 && strcmp(argv[1], "--unpack") == 0) {
|
||||
unpack(argv[2]);
|
||||
} else if (argc > 2 && strcmp(argv[1], "--repack") == 0) {
|
||||
|
@ -1,6 +1,9 @@
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <utils.h>
|
||||
#include <sys/mman.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "magiskboot.h"
|
||||
#include "cpio.h"
|
||||
@ -70,8 +73,68 @@ void cpio_patch(struct vector *v, int keepverity, int keepforceencrypt) {
|
||||
}
|
||||
}
|
||||
|
||||
static void restore_high_compress(struct vector *v, const char *incpio) {
|
||||
// Check if the ramdisk is in high compression mode
|
||||
if (cpio_extract(v, "ramdisk.cpio.xz", incpio) == 0) {
|
||||
void *addr, *xz;
|
||||
size_t size;
|
||||
mmap_ro(incpio, &addr, &size);
|
||||
xz = xmalloc(size);
|
||||
memcpy(xz, addr, size);
|
||||
munmap(addr, size);
|
||||
int fd = creat(incpio, 0644);
|
||||
lzma(0, fd, xz, size);
|
||||
close(fd);
|
||||
cpio_rm(v, 0, "ramdisk.cpio.xz");
|
||||
cpio_rm(v, 0, "init");
|
||||
struct vector vv;
|
||||
vec_init(&vv);
|
||||
parse_cpio(&vv, incpio);
|
||||
cpio_entry *e;
|
||||
vec_for_each(&vv, e)
|
||||
vec_push_back(v, e);
|
||||
vec_destroy(&vv);
|
||||
}
|
||||
}
|
||||
|
||||
static void enable_high_compress(struct vector *v, struct vector *b, const char *incpio) {
|
||||
cpio_entry *e, *magiskinit, *init;
|
||||
|
||||
// Swap magiskinit with original init
|
||||
vec_for_each(b, e) {
|
||||
if (strcmp(e->filename, ".backup/init") == 0) {
|
||||
free(e->filename);
|
||||
e->filename = strdup("init");
|
||||
init = e;
|
||||
vec_for_each(v, e) {
|
||||
if (strcmp(e->filename, "init") == 0) {
|
||||
magiskinit = e;
|
||||
vec_cur(v) = init;
|
||||
break;
|
||||
}
|
||||
}
|
||||
vec_cur(b) = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
dump_cpio(v, incpio);
|
||||
cpio_vec_destroy(v);
|
||||
void *addr, *cpio;
|
||||
size_t size;
|
||||
mmap_ro(incpio, &addr, &size);
|
||||
cpio = xmalloc(size);
|
||||
memcpy(cpio, addr, size);
|
||||
munmap(addr, size);
|
||||
int fd = creat(incpio, 0644);
|
||||
lzma(1, fd, cpio, size);
|
||||
close(fd);
|
||||
vec_init(v);
|
||||
vec_push_back(v, magiskinit);
|
||||
cpio_add(v, 0, "ramdisk.cpio.xz", incpio);
|
||||
}
|
||||
|
||||
int cpio_commands(const char *command, int argc, char *argv[]) {
|
||||
int ret = 0;
|
||||
char *incpio = argv[0];
|
||||
++argv;
|
||||
--argc;
|
||||
@ -82,12 +145,23 @@ int cpio_commands(const char *command, int argc, char *argv[]) {
|
||||
if (strcmp(command, "test") == 0) {
|
||||
exit(cpio_test(&v));
|
||||
} else if (strcmp(command, "restore") == 0) {
|
||||
ret = cpio_restore(&v);
|
||||
restore_high_compress(&v, incpio);
|
||||
cpio_restore(&v);
|
||||
} else if (strcmp(command, "stocksha1") == 0) {
|
||||
printf("%s\n", cpio_stocksha1(&v));
|
||||
return 0;
|
||||
} else if (argc >= 1 && strcmp(command, "backup") == 0) {
|
||||
cpio_backup(&v, argv[0], argc > 1 ? argv[1] : NULL);
|
||||
} else if (argc >= 2 && strcmp(command, "backup") == 0) {
|
||||
struct vector *back;
|
||||
cpio_entry *e;
|
||||
back = cpio_backup(&v, argv[0], argc > 2 ? argv[2] : NULL);
|
||||
|
||||
// Enable high compression mode
|
||||
if (strcmp(argv[1], "true") == 0)
|
||||
enable_high_compress(&v, back, incpio);
|
||||
|
||||
vec_for_each(back, e)
|
||||
if (e) vec_push_back(&v, e);
|
||||
|
||||
} else if (argc > 0 && strcmp(command, "rm") == 0) {
|
||||
int recursive = 0;
|
||||
if (argc == 2 && strcmp(argv[0], "-r") == 0) {
|
||||
@ -119,5 +193,5 @@ int cpio_commands(const char *command, int argc, char *argv[]) {
|
||||
|
||||
dump_cpio(&v, incpio);
|
||||
cpio_vec_destroy(&v);
|
||||
exit(ret);
|
||||
exit(0);
|
||||
}
|
||||
|
@ -3,10 +3,6 @@
|
||||
#include "bootimg.h"
|
||||
#include "types.h"
|
||||
|
||||
char *SUP_LIST[] = { "gzip", "xz", "lzma", "bzip2", "lz4", "lz4_legacy", NULL };
|
||||
char *SUP_EXT_LIST[] = { "gz", "xz", "lzma", "bz2", "lz4", "lz4", NULL };
|
||||
file_t SUP_TYPE_LIST[] = { GZIP, XZ, LZMA, BZIP2, LZ4, LZ4_LEGACY, 0 };
|
||||
|
||||
file_t check_type(const void *buf) {
|
||||
if (memcmp(buf, CHROMEOS_MAGIC, 8) == 0) {
|
||||
return CHROMEOS;
|
||||
|
@ -33,9 +33,8 @@ typedef enum {
|
||||
#define DTB_MAGIC "\xd0\x0d\xfe\xed"
|
||||
#define LG_BUMP_MAGIC "\x41\xa9\xe4\x67\x74\x4d\x1d\x1b\xa4\x29\xf2\xec\xea\x65\x52\x79"
|
||||
|
||||
extern char *SUP_LIST[];
|
||||
extern char *SUP_EXT_LIST[];
|
||||
extern file_t SUP_TYPE_LIST[];
|
||||
#define SUP_LIST ((char *[]) { "gzip", "xz", "lzma", "bzip2", "lz4", "lz4_legacy", NULL })
|
||||
#define SUP_EXT_LIST ((char *[]) { "gz", "xz", "lzma", "bz2", "lz4", "lz4", NULL })
|
||||
|
||||
file_t check_type(const void *buf);
|
||||
void get_type_name(file_t type, char *name);
|
||||
|
@ -213,7 +213,6 @@ int cpio_extract(struct vector *v, const char *entry, const char *filename) {
|
||||
vec_for_each(v, f) {
|
||||
if (strcmp(f->filename, entry) == 0) {
|
||||
fprintf(stderr, "Extracting [%s] to [%s]\n\n", entry, filename);
|
||||
unlink(filename);
|
||||
if (S_ISREG(f->mode)) {
|
||||
int fd = creat(filename, f->mode & 0777);
|
||||
xwrite(fd, f->data, f->filesize);
|
||||
@ -222,6 +221,7 @@ int cpio_extract(struct vector *v, const char *entry, const char *filename) {
|
||||
} else if (S_ISLNK(f->mode)) {
|
||||
char *target = xcalloc(f->filesize + 1, 1);
|
||||
memcpy(target, f->data, f->filesize);
|
||||
unlink(filename);
|
||||
symlink(target, filename);
|
||||
}
|
||||
return 0;
|
||||
@ -263,9 +263,8 @@ int cpio_test(struct vector *v) {
|
||||
vec_for_each(v, f) {
|
||||
for (int i = 0; OTHER_LIST[i]; ++i) {
|
||||
if (strcmp(f->filename, OTHER_LIST[i]) == 0) {
|
||||
ret |= OTHER_PATCH;
|
||||
// Already find other files, abort
|
||||
exit(OTHER_PATCH);
|
||||
return OTHER_PATCH;
|
||||
}
|
||||
}
|
||||
for (int i = 0; MAGISK_LIST[i]; ++i) {
|
||||
@ -277,34 +276,36 @@ int cpio_test(struct vector *v) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
void cpio_backup(struct vector *v, const char *orig, const char *sha1) {
|
||||
struct vector o_body, *o = &o_body, bak;
|
||||
struct vector * cpio_backup(struct vector *v, const char *orig, const char *sha1) {
|
||||
struct vector o_body, *o = &o_body, *ret;
|
||||
cpio_entry *m, *n, *rem, *cksm;
|
||||
char buf[PATH_MAX];
|
||||
int res, doBak;
|
||||
int res, backup;
|
||||
|
||||
ret = xcalloc(sizeof(*ret), 1);
|
||||
|
||||
vec_init(o);
|
||||
vec_init(&bak);
|
||||
vec_init(ret);
|
||||
|
||||
m = xcalloc(sizeof(*m), 1);
|
||||
m->filename = strdup(".backup");
|
||||
m->mode = S_IFDIR;
|
||||
vec_push_back(&bak, m);
|
||||
vec_push_back(ret, m);
|
||||
|
||||
m = xcalloc(sizeof(*m), 1);
|
||||
m->filename = strdup(".backup/.magisk");
|
||||
m->mode = S_IFREG;
|
||||
vec_push_back(&bak, m);
|
||||
vec_push_back(ret, m);
|
||||
|
||||
rem = xcalloc(sizeof(*rem), 1);
|
||||
rem->filename = strdup(".backup/.rmlist");
|
||||
rem->mode = S_IFREG;
|
||||
vec_push_back(&bak, rem);
|
||||
vec_push_back(ret, rem);
|
||||
|
||||
if (sha1) {
|
||||
fprintf(stderr, "Save SHA1: [%s] -> [.backup/.sha1]\n", sha1);
|
||||
cksm = xcalloc(sizeof(*cksm), 1);
|
||||
vec_push_back(&bak, cksm);
|
||||
vec_push_back(ret, cksm);
|
||||
cksm->filename = strdup(".backup/.sha1");
|
||||
cksm->mode = S_IFREG;
|
||||
cksm->data = strdup(sha1);
|
||||
@ -323,7 +324,7 @@ void cpio_backup(struct vector *v, const char *orig, const char *sha1) {
|
||||
// Start comparing
|
||||
size_t i = 0, j = 0;
|
||||
while(i != vec_size(o) || j != vec_size(v)) {
|
||||
doBak = 0;
|
||||
backup = 0;
|
||||
if (i != vec_size(o) && j != vec_size(v)) {
|
||||
m = vec_entry(o)[i];
|
||||
n = vec_entry(v)[j];
|
||||
@ -339,14 +340,14 @@ void cpio_backup(struct vector *v, const char *orig, const char *sha1) {
|
||||
if (res < 0) {
|
||||
// Something is missing in new ramdisk, backup!
|
||||
++i;
|
||||
doBak = 1;
|
||||
backup = 1;
|
||||
fprintf(stderr, "Backup missing entry: ");
|
||||
} else if (res == 0) {
|
||||
++i; ++j;
|
||||
if (m->filesize == n->filesize && memcmp(m->data, n->data, m->filesize) == 0)
|
||||
continue;
|
||||
// Not the same!
|
||||
doBak = 1;
|
||||
backup = 1;
|
||||
fprintf(stderr, "Backup mismatch entry: ");
|
||||
} else {
|
||||
// Someting new in ramdisk, record in rem
|
||||
@ -357,35 +358,30 @@ void cpio_backup(struct vector *v, const char *orig, const char *sha1) {
|
||||
rem->filesize += strlen(n->filename) + 1;
|
||||
fprintf(stderr, "Record new entry: [%s] -> [.backup/.rmlist]\n", n->filename);
|
||||
}
|
||||
if (doBak) {
|
||||
if (backup) {
|
||||
sprintf(buf, ".backup/%s", m->filename);
|
||||
free(m->filename);
|
||||
m->filename = strdup(buf);
|
||||
fprintf(stderr, "[%s] -> [%s]\n", buf, m->filename);
|
||||
vec_push_back(&bak, m);
|
||||
vec_push_back(ret, m);
|
||||
// NULL the original entry, so it won't be freed
|
||||
vec_entry(o)[i - 1] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Add the backup files to the original ramdisk
|
||||
vec_for_each(&bak, m) {
|
||||
vec_push_back(v, m);
|
||||
}
|
||||
|
||||
if (rem->filesize == 0)
|
||||
rem->remove = 1;
|
||||
|
||||
// Cleanup
|
||||
cpio_vec_destroy(o);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int cpio_restore(struct vector *v) {
|
||||
void cpio_restore(struct vector *v) {
|
||||
cpio_entry *f, *n;
|
||||
int ret = 1;
|
||||
vec_for_each(v, f) {
|
||||
if (strstr(f->filename, ".backup") != NULL) {
|
||||
ret = 0;
|
||||
if (strncmp(f->filename, ".backup", 7) == 0) {
|
||||
f->remove = 1;
|
||||
if (f->filename[7] == '\0') continue;
|
||||
if (f->filename[8] == '.') {
|
||||
@ -405,12 +401,14 @@ int cpio_restore(struct vector *v) {
|
||||
cpio_vec_insert(v, n);
|
||||
}
|
||||
}
|
||||
if (strncmp(f->filename, "overlay", 7) == 0)
|
||||
f->remove = 1;
|
||||
}
|
||||
// Some known stuff we can remove
|
||||
cpio_rm(v, 0, "sbin/magic_mask.sh");
|
||||
cpio_rm(v, 0, "init.magisk.rc");
|
||||
cpio_rm(v, 0, "magisk");
|
||||
return ret;
|
||||
cpio_rm(v, 0, "ramdisk-recovery.xz");
|
||||
}
|
||||
|
||||
char *cpio_stocksha1(struct vector *v) {
|
||||
|
@ -357,24 +357,25 @@ void restorecon(int dirfd, int force) {
|
||||
|
||||
#endif // SELINUX
|
||||
|
||||
static void _mmap(int rw, const char *filename, void **buf, size_t *size) {
|
||||
static int _mmap(int rw, const char *filename, void **buf, size_t *size) {
|
||||
struct stat st;
|
||||
stat(filename, &st);
|
||||
int fd = xopen(filename, rw ? O_RDWR : O_RDONLY);
|
||||
fstat(fd, &st);
|
||||
if (S_ISBLK(st.st_mode))
|
||||
ioctl(fd, BLKGETSIZE64, size);
|
||||
else
|
||||
*size = st.st_size;
|
||||
*buf = *size > 0 ? xmmap(NULL, *size, PROT_READ | (rw ? PROT_WRITE : 0), MAP_SHARED, fd, 0) : NULL;
|
||||
close(fd);
|
||||
return S_ISBLK(st.st_mode);
|
||||
}
|
||||
|
||||
void mmap_ro(const char *filename, void **buf, size_t *size) {
|
||||
_mmap(0, filename, buf, size);
|
||||
int mmap_ro(const char *filename, void **buf, size_t *size) {
|
||||
return _mmap(0, filename, buf, size);
|
||||
}
|
||||
|
||||
void mmap_rw(const char *filename, void **buf, size_t *size) {
|
||||
_mmap(1, filename, buf, size);
|
||||
int mmap_rw(const char *filename, void **buf, size_t *size) {
|
||||
return _mmap(1, filename, buf, size);
|
||||
}
|
||||
|
||||
void full_read(int fd, void **buf, size_t *size) {
|
||||
|
@ -64,6 +64,7 @@ BOOTIMAGE="$1"
|
||||
# Presets
|
||||
[ -z $KEEPVERITY ] && KEEPVERITY=false
|
||||
[ -z $KEEPFORCEENCRYPT ] && KEEPFORCEENCRYPT=false
|
||||
[ -z $HIGH_COMP ] && HIGH_COMP=false
|
||||
|
||||
chmod -R 755 .
|
||||
|
||||
@ -86,14 +87,19 @@ case $? in
|
||||
abort "! Unable to unpack boot image"
|
||||
;;
|
||||
2 )
|
||||
ui_print "! Insufficient boot partition size detected"
|
||||
ui_print "- Enable high compression mode"
|
||||
HIGH_COMP=true
|
||||
;;
|
||||
3 )
|
||||
ui_print "- ChromeOS boot image detected"
|
||||
CHROMEOS=true
|
||||
;;
|
||||
3 )
|
||||
4 )
|
||||
ui_print "! Sony ELF32 format detected"
|
||||
abort "! Please use BootBridge from @AdrianDC to flash Magisk"
|
||||
;;
|
||||
4 )
|
||||
5 )
|
||||
ui_print "! Sony ELF64 format detected"
|
||||
abort "! Stock kernel cannot be patched, please use a custom kernel"
|
||||
esac
|
||||
@ -118,30 +124,7 @@ case $? in
|
||||
ui_print "- Magisk patched image detected!"
|
||||
# Find SHA1 of stock boot image
|
||||
[ -z $SHA1 ] && SHA1=`./magiskboot --cpio-stocksha1 ramdisk.cpio 2>/dev/null`
|
||||
OK=false
|
||||
./magiskboot --cpio-restore ramdisk.cpio
|
||||
if [ $? -eq 0 ]; then
|
||||
ui_print "- Ramdisk restored from internal backup"
|
||||
OK=true
|
||||
else
|
||||
# Restore failed
|
||||
ui_print "! Cannot restore from internal backup"
|
||||
# If we are root and SHA1 known, we try to find the stock backup
|
||||
if [ ! -z $SHA1 ]; then
|
||||
STOCKDUMP=/data/stock_boot_${SHA1}.img.gz
|
||||
if [ -f $STOCKDUMP ]; then
|
||||
ui_print "- Stock boot image backup found"
|
||||
./magiskboot --decompress $STOCKDUMP stock_boot.img
|
||||
./magiskboot --unpack stock_boot.img
|
||||
rm -f stock_boot.img
|
||||
OK=true
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
if ! $OK; then
|
||||
ui_print "! Ramdisk restoration incomplete"
|
||||
ui_print "! Will still try to continue installation"
|
||||
fi
|
||||
cp -af ramdisk.cpio ramdisk.cpio.orig
|
||||
;;
|
||||
2 ) # Other patched
|
||||
@ -156,14 +139,21 @@ esac
|
||||
|
||||
ui_print "- Patching ramdisk"
|
||||
|
||||
./magiskboot --cpio-add ramdisk.cpio 750 init magiskinit
|
||||
./magiskboot --cpio-patch ramdisk.cpio $KEEPVERITY $KEEPFORCEENCRYPT
|
||||
[ -f /sdcard/ramdisk-recovery.img ] && HIGH_COMP=true
|
||||
|
||||
# Create ramdisk backups
|
||||
./magiskboot --cpio-backup ramdisk.cpio ramdisk.cpio.orig $SHA1
|
||||
./magiskboot --cpio-patch ramdisk.cpio $KEEPVERITY $KEEPFORCEENCRYPT
|
||||
./magiskboot --cpio-add ramdisk.cpio 750 init magiskinit
|
||||
./magiskboot --cpio-backup ramdisk.cpio ramdisk.cpio.orig $HIGH_COMP $SHA1
|
||||
|
||||
rm -f ramdisk.cpio.orig
|
||||
|
||||
if [ -f /sdcard/ramdisk-recovery.img ]; then
|
||||
ui_print "- Adding ramdisk-recovery.img"
|
||||
./magiskboot --decompress - < /sdcard/ramdisk-recovery.img | ./magiskboot --compress=xz - ramdisk-recovery.xz
|
||||
./magiskboot --cpio-add ramdisk.cpio 0 ramdisk-recovery.xz ramdisk-recovery.xz
|
||||
rm ramdisk-recovery.xz
|
||||
fi
|
||||
|
||||
##########################################################################################
|
||||
# Binary patches
|
||||
##########################################################################################
|
||||
|
@ -84,7 +84,7 @@ getvar() {
|
||||
local VARNAME=$1
|
||||
local VALUE=$(eval echo \$$VARNAME)
|
||||
[ ! -z $VALUE ] && return
|
||||
for DIR in /dev /data /cache /system; do
|
||||
for DIR in /.backup /data /cache /system; do
|
||||
VALUE=`grep_prop $VARNAME $DIR/.magisk`
|
||||
[ ! -z $VALUE ] && break;
|
||||
done
|
||||
|
Loading…
Reference in New Issue
Block a user