Refactor magiskboot
This commit is contained in:
parent
e8dd1b292f
commit
a3c49de6a5
6
build.py
6
build.py
@ -266,7 +266,7 @@ def zip_main(args):
|
||||
with open(source, 'r') as script:
|
||||
# Add version info util_functions.sh
|
||||
util_func = script.read().replace(
|
||||
'MAGISK_VERSION_STUB', 'MAGISK_VER="{}"\nMAGISK_VER_CODE={}'.format(args.versionString, args.versionCode))
|
||||
'#MAGISK_VERSION_STUB', 'MAGISK_VER="{}"\nMAGISK_VER_CODE={}'.format(args.versionString, args.versionCode))
|
||||
target = os.path.join('common', 'util_functions.sh')
|
||||
print('zip: ' + source + ' -> ' + target)
|
||||
zipf.writestr(target, util_func)
|
||||
@ -316,11 +316,9 @@ def zip_uninstaller(args):
|
||||
source = os.path.join('scripts', 'util_functions.sh')
|
||||
with open(source, 'r') as script:
|
||||
# Remove the stub
|
||||
util_func = script.read().replace(
|
||||
'MAGISK_VERSION_STUB', '')
|
||||
target = os.path.join('util_functions.sh')
|
||||
print('zip: ' + source + ' -> ' + target)
|
||||
zipf.writestr(target, util_func)
|
||||
zipf.writestr(target, script.read())
|
||||
|
||||
# Prebuilts
|
||||
for chromeos in ['futility', 'kernel_data_key.vbprivk', 'kernel.keyblock']:
|
||||
|
@ -182,22 +182,24 @@ static void patch_ramdisk(int root) {
|
||||
close(fd);
|
||||
free(addr);
|
||||
|
||||
char *key, *value;
|
||||
full_read("/.backup/.magisk", &addr, &size);
|
||||
for (char *tok = strtok(addr, "\n"); tok; tok = strtok(NULL, "\n")) {
|
||||
key = tok;
|
||||
value = strchr(tok, '=') + 1;
|
||||
value[-1] = '\0';
|
||||
if (strcmp(key, "KEEPVERITY") == 0)
|
||||
keepverity = strcmp(value, "true") == 0;
|
||||
else if (strcmp(key, "KEEPFORCEENCRYPT") == 0)
|
||||
keepencrypt = strcmp(value, "true") == 0;
|
||||
}
|
||||
/* Disabled for now */
|
||||
|
||||
excl_list = (char *[]) { "system_root", "system", "vendor", NULL };
|
||||
in_order_walk(root, fstab_patch_cb);
|
||||
if (!keepverity)
|
||||
unlink("/verity_key");
|
||||
// char *key, *value;
|
||||
// full_read("/.backup/.magisk", &addr, &size);
|
||||
// for (char *tok = strtok(addr, "\n"); tok; tok = strtok(NULL, "\n")) {
|
||||
// key = tok;
|
||||
// value = strchr(tok, '=') + 1;
|
||||
// value[-1] = '\0';
|
||||
// if (strcmp(key, "KEEPVERITY") == 0)
|
||||
// keepverity = strcmp(value, "true") == 0;
|
||||
// else if (strcmp(key, "KEEPFORCEENCRYPT") == 0)
|
||||
// keepencrypt = strcmp(value, "true") == 0;
|
||||
// }
|
||||
|
||||
// excl_list = (char *[]) { "system_root", "system", "vendor", NULL };
|
||||
// in_order_walk(root, fstab_patch_cb);
|
||||
// if (!keepverity)
|
||||
// unlink("/verity_key");
|
||||
}
|
||||
|
||||
static int strend(const char *s1, const char *s2) {
|
||||
@ -472,17 +474,11 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
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
|
||||
if (access("/ramdisk.cpio.xz", R_OK) == 0) {
|
||||
// High compression mode
|
||||
void *addr;
|
||||
size_t size;
|
||||
mmap_ro(ramdisk_xz, &addr, &size);
|
||||
mmap_ro("/ramdisk.cpio.xz", &addr, &size);
|
||||
int fd = creat("/ramdisk.cpio", 0);
|
||||
unxz(addr, size, fd);
|
||||
munmap(addr, size);
|
||||
|
@ -42,6 +42,8 @@ typedef struct cpio_newc_header {
|
||||
} cpio_newc_header;
|
||||
|
||||
// Basic cpio functions
|
||||
void cpio_free(cpio_entry *e);
|
||||
int cpio_find(struct vector *v, const char *entry);
|
||||
int cpio_cmp(const void *a, const void *b);
|
||||
void parse_cpio(struct vector *v, const char *filename);
|
||||
void dump_cpio(struct vector *v, const char *filename);
|
||||
|
@ -7,8 +7,8 @@
|
||||
#include <sys/types.h>
|
||||
|
||||
struct vector {
|
||||
size_t size;
|
||||
size_t cap;
|
||||
unsigned size;
|
||||
unsigned cap;
|
||||
void **data;
|
||||
};
|
||||
|
||||
@ -26,11 +26,11 @@ struct vector *vec_dup(struct vector *v);
|
||||
/* Usage: vec_for_each(vector *v, void *e) */
|
||||
#define vec_for_each(v, e) \
|
||||
e = v ? (v)->data[0] : NULL; \
|
||||
for (size_t _ = 0; v && _ < (v)->size; ++_, e = (v)->data[_])
|
||||
for (int _ = 0; v && _ < (v)->size; ++_, e = (v)->data[_])
|
||||
|
||||
#define vec_for_each_r(v, e) \
|
||||
e = v ? (v)->data[(v)->size - 1] : NULL; \
|
||||
for (size_t _ = (v)->size; v && _ > 0; --_, e = (v)->data[_ - 1])
|
||||
for (int _ = ((int) (v)->size) - 1; v && _ >= 0; --_, e = (v)->data[_])
|
||||
|
||||
#define vec_cur(v) vec_entry(v)[_]
|
||||
|
||||
|
@ -55,7 +55,6 @@ static void print_hdr(const boot_img_hdr *hdr) {
|
||||
}
|
||||
fprintf(stderr, "NAME [%s]\n", hdr->name);
|
||||
fprintf(stderr, "CMDLINE [%s]\n", hdr->cmdline);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
int parse_img(const char *image, boot_img *boot) {
|
||||
@ -63,7 +62,7 @@ int parse_img(const char *image, boot_img *boot) {
|
||||
int is_blk = mmap_ro(image, &boot->map_addr, &boot->map_size);
|
||||
|
||||
// Parse image
|
||||
fprintf(stderr, "Parsing boot image: [%s]\n\n", image);
|
||||
fprintf(stderr, "Parsing boot image: [%s]\n", image);
|
||||
for (size_t pos = 0; pos < boot->map_size; pos += 256) {
|
||||
switch (check_type(boot->map_addr + pos)) {
|
||||
case CHROMEOS:
|
||||
@ -143,7 +142,6 @@ int parse_img(const char *image, boot_img *boot) {
|
||||
fprintf(stderr, "KERNEL_FMT [%s]\n", fmt);
|
||||
get_type_name(boot->ramdisk_type, fmt);
|
||||
fprintf(stderr, "RAMDISK_FMT [%s]\n", fmt);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
return boot->flags & CHROMEOS_FLAG ? CHROMEOS_RET :
|
||||
((is_blk && boot->tail_size < 500 * 1024) ? INSUF_BLOCK_RET : 0);
|
||||
@ -206,7 +204,7 @@ void repack(const char* orig_image, const char* out_image) {
|
||||
// Parse original image
|
||||
parse_img(orig_image, &boot);
|
||||
|
||||
fprintf(stderr, "Repack to boot image: [%s]\n\n", out_image);
|
||||
fprintf(stderr, "Repack to boot image: [%s]\n", out_image);
|
||||
|
||||
// Create new image
|
||||
int fd = creat(out_image, 0644);
|
||||
|
@ -437,7 +437,7 @@ void decomp_file(char *from, const char *to) {
|
||||
fd = STDOUT_FILENO;
|
||||
} else {
|
||||
fd = creat(to, 0644);
|
||||
fprintf(stderr, "Decompressing to [%s]\n\n", to);
|
||||
fprintf(stderr, "Decompressing to [%s]\n", to);
|
||||
}
|
||||
|
||||
decomp(type, fd, file, size);
|
||||
@ -498,7 +498,7 @@ void comp_file(const char *method, const char *from, const char *to) {
|
||||
fd = STDOUT_FILENO;
|
||||
} else {
|
||||
fd = creat(dest, 0644);
|
||||
fprintf(stderr, "Compressing to [%s]\n\n", dest);
|
||||
fprintf(stderr, "Compressing to [%s]\n", dest);
|
||||
}
|
||||
comp(type, fd, file, size);
|
||||
close(fd);
|
||||
|
@ -26,7 +26,7 @@ void hexpatch(const char *image, const char *from, const char *to) {
|
||||
hex2byte(to, patch);
|
||||
for (size_t i = 0; filesize > 0 && i < filesize - patternsize; ++i) {
|
||||
if (memcmp(file + i, pattern, patternsize) == 0) {
|
||||
fprintf(stderr, "Pattern %s found!\nPatching to %s\n", from, to);
|
||||
fprintf(stderr, "Patch @ %08X [%s]->[%s]\n", (unsigned) i, from, to);
|
||||
memset(file + i, 0, patternsize);
|
||||
memcpy(file + i, patch, patchsize);
|
||||
i += patternsize - 1;
|
||||
|
@ -18,7 +18,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(const char *image, boot_img *boot);
|
||||
int cpio_commands(const char *cmd, int argc, char *argv[]);
|
||||
int cpio_commands(int argc, char *argv[]);
|
||||
void comp_file(const char *method, const char *from, const char *to);
|
||||
void decomp_file(char *from, const char *to);
|
||||
int dtb_commands(const char *cmd, int argc, char *argv[]);
|
||||
|
@ -36,34 +36,39 @@ static void usage(char *arg0) {
|
||||
" --hexpatch <file> <hexpattern1> <hexpattern2>\n"
|
||||
" Search <hexpattern1> in <file>, and replace with <hexpattern2>\n"
|
||||
"\n"
|
||||
" --cpio-<cmd> <incpio> [flags...] [args...]\n"
|
||||
" Do cpio related cmds to <incpio> (modifications are done directly)\n"
|
||||
" --cpio <incpio> [commands...]\n"
|
||||
" Do cpio commands to <incpio> (modifications are done directly)\n"
|
||||
" Each command is a single argument, use quotes if necessary\n"
|
||||
" Supported commands:\n"
|
||||
" -rm [-r] <entry>\n"
|
||||
" Remove entry from <incpio>, flag [-r] to remove recursively\n"
|
||||
" -mkdir <mode> <entry>\n"
|
||||
" Create directory as an <entry>\n"
|
||||
" -ln <target> <entry>\n"
|
||||
" Create symlink <entry> to point to <target>\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"
|
||||
" rm [-r] ENTRY\n"
|
||||
" Remove ENTRY, specify [-r] to remove recursively\n"
|
||||
" mkdir MODE ENTRY\n"
|
||||
" Create directory ENTRY in permissions MODE\n"
|
||||
" ln TARGET ENTRY\n"
|
||||
" Create a symlink to TARGET with the name ENTRY\n"
|
||||
" mv SOURCE DEST\n"
|
||||
" Move SOURCE to DEST\n"
|
||||
" add MODE ENTRY INFILE\n"
|
||||
" Add INFILE as ENTRY in permissions MODE; replaces ENTRY if exists\n"
|
||||
" extract [ENTRY OUT]\n"
|
||||
" Extract ENTRY to OUT, or extract all entries to current directory\n"
|
||||
" test\n"
|
||||
" Test the current cpio's patch status\n"
|
||||
" Return value: 0/stock 1/Magisk 2/other (phh, SuperSU, Xposed)\n"
|
||||
" -patch <KEEPVERITY> <KEEPFORCEENCRYPT>\n"
|
||||
" patch KEEPVERITY KEEPFORCEENCRYPT\n"
|
||||
" Ramdisk patches. KEEP**** are boolean values\n"
|
||||
" This command is no longer used in Magisk installations\n"
|
||||
" -backup <origcpio> <HIGHCOMP> <KEEPVERITY> <KEEPFORCEENCRYPT> [SHA1]\n"
|
||||
" Create ramdisk backups into <incpio> from <origcpio>\n"
|
||||
" backup ORIG [SHA1]\n"
|
||||
" Create ramdisk backups from ORIG\n"
|
||||
" SHA1 of stock boot image is optional\n"
|
||||
" restore\n"
|
||||
" Restore ramdisk from ramdisk backup stored within incpio\n"
|
||||
" magisk ORIG HIGHCOMP KEEPVERITY KEEPFORCEENCRYPT [SHA1]\n"
|
||||
" Do Magisk patches and backups all in one step\n"
|
||||
" Create ramdisk backups from ORIG\n"
|
||||
" HIGHCOMP, KEEP**** are boolean values\n"
|
||||
" SHA1 of stock boot image is optional\n"
|
||||
" -restore\n"
|
||||
" Restore ramdisk from ramdisk backup within <incpio>\n"
|
||||
" -stocksha1\n"
|
||||
" Get stock boot SHA1 recorded within <incpio>\n"
|
||||
" sha1\n"
|
||||
" Print stock boot SHA1 if previously stored\n"
|
||||
"\n"
|
||||
" --dtb-<cmd> <dtb>\n"
|
||||
" Do dtb related cmds to <dtb> (modifications are done directly)\n"
|
||||
@ -104,11 +109,11 @@ static void usage(char *arg0) {
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
fprintf(stderr, "MagiskBoot v" xstr(MAGISK_VERSION) "(" xstr(MAGISK_VER_CODE) ") (by topjohnwu) - Boot Image Modification Tool\n\n");
|
||||
fprintf(stderr, "MagiskBoot v" xstr(MAGISK_VERSION) "(" xstr(MAGISK_VER_CODE) ") (by topjohnwu) - Boot Image Modification Tool\n");
|
||||
|
||||
umask(0);
|
||||
if (argc > 1 && strcmp(argv[1], "--cleanup") == 0) {
|
||||
fprintf(stderr, "Cleaning up...\n\n");
|
||||
fprintf(stderr, "Cleaning up...\n");
|
||||
char name[PATH_MAX];
|
||||
unlink(KERNEL_FILE);
|
||||
unlink(RAMDISK_FILE);
|
||||
@ -146,11 +151,8 @@ int main(int argc, char *argv[]) {
|
||||
comp_file(method, argv[2], argc > 3 ? argv[3] : NULL);
|
||||
} else if (argc > 4 && strcmp(argv[1], "--hexpatch") == 0) {
|
||||
hexpatch(argv[2], argv[3], argv[4]);
|
||||
} else if (argc > 2 && strncmp(argv[1], "--cpio", 6) == 0) {
|
||||
char *cmd = argv[1] + 6;
|
||||
if (*cmd == '\0') usage(argv[0]);
|
||||
else ++cmd;
|
||||
if (cpio_commands(cmd, argc - 2, argv + 2)) usage(argv[0]);
|
||||
} else if (argc > 2 && strcmp(argv[1], "--cpio") == 0) {
|
||||
if (cpio_commands(argc - 2, argv + 2)) usage(argv[0]);
|
||||
} else if (argc > 2 && strncmp(argv[1], "--dtb", 5) == 0) {
|
||||
char *cmd = argv[1] + 5;
|
||||
if (*cmd == '\0') usage(argv[0]);
|
||||
|
@ -9,19 +9,21 @@
|
||||
#include "cpio.h"
|
||||
|
||||
static void cpio_patch(struct vector *v, int keepverity, int keepforceencrypt) {
|
||||
cpio_entry *f;
|
||||
vec_for_each(v, f) {
|
||||
cpio_entry *e;
|
||||
vec_for_each(v, e) {
|
||||
if (!e) continue;
|
||||
if (!keepverity) {
|
||||
if (strstr(f->filename, "fstab") != NULL && S_ISREG(f->mode)) {
|
||||
patch_verity(&f->data, &f->filesize, 1);
|
||||
} else if (strcmp(f->filename, "verity_key") == 0) {
|
||||
if (strncmp(e->filename, ".backup", 7) && strstr(e->filename, "fstab") && S_ISREG(e->mode)) {
|
||||
patch_verity(&e->data, &e->filesize, 1);
|
||||
} else if (strcmp(e->filename, "verity_key") == 0) {
|
||||
fprintf(stderr, "Remove [verity_key]\n");
|
||||
f->remove = 1;
|
||||
cpio_free(e);
|
||||
vec_cur(v) = NULL;
|
||||
}
|
||||
}
|
||||
if (!keepforceencrypt) {
|
||||
if (strstr(f->filename, "fstab") != NULL && S_ISREG(f->mode)) {
|
||||
patch_encryption(&f->data, &f->filesize);
|
||||
if (strstr(e->filename, "fstab") != NULL && S_ISREG(e->mode)) {
|
||||
patch_encryption(&e->data, &e->filesize);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -32,33 +34,28 @@ static void cpio_patch(struct vector *v, int keepverity, int keepforceencrypt) {
|
||||
#define OTHER_PATCH 0x2
|
||||
|
||||
static int cpio_test(struct vector *v) {
|
||||
int ret = STOCK_BOOT;
|
||||
cpio_entry *f;
|
||||
const char *OTHER_LIST[] = { "sbin/launch_daemonsu.sh", "sbin/su", "init.xposed.rc", "boot/sbin/launch_daemonsu.sh", NULL };
|
||||
const char *MAGISK_LIST[] = { ".backup/.magisk", "init.magisk.rc", "overlay/init.magisk.rc", NULL };
|
||||
vec_for_each(v, f) {
|
||||
for (int i = 0; OTHER_LIST[i]; ++i) {
|
||||
if (strcmp(f->filename, OTHER_LIST[i]) == 0) {
|
||||
// Already find other files, abort
|
||||
|
||||
for (int i = 0; OTHER_LIST[i]; ++i)
|
||||
if (cpio_find(v, OTHER_LIST[i]) > 0)
|
||||
return OTHER_PATCH;
|
||||
}
|
||||
}
|
||||
for (int i = 0; MAGISK_LIST[i]; ++i) {
|
||||
if (strcmp(f->filename, MAGISK_LIST[i]) == 0)
|
||||
ret = MAGISK_PATCH;
|
||||
}
|
||||
}
|
||||
cpio_vec_destroy(v);
|
||||
return ret;
|
||||
|
||||
for (int i = 0; MAGISK_LIST[i]; ++i)
|
||||
if (cpio_find(v, MAGISK_LIST[i]) > 0)
|
||||
return MAGISK_PATCH;
|
||||
|
||||
return STOCK_BOOT;
|
||||
}
|
||||
|
||||
static char *cpio_stocksha1(struct vector *v) {
|
||||
cpio_entry *f;
|
||||
static char *cpio_sha1(struct vector *v) {
|
||||
cpio_entry *e;
|
||||
char sha1[41];
|
||||
vec_for_each(v, f) {
|
||||
if (strcmp(f->filename, "init.magisk.rc") == 0
|
||||
|| strcmp(f->filename, "overlay/init.magisk.rc") == 0) {
|
||||
for (void *pos = f->data; pos < f->data + f->filesize; pos = strchr(pos + 1, '\n') + 1) {
|
||||
vec_for_each(v, e) {
|
||||
if (!e) continue;
|
||||
if (strcmp(e->filename, "init.magisk.rc") == 0
|
||||
|| strcmp(e->filename, "overlay/init.magisk.rc") == 0) {
|
||||
for (void *pos = e->data; pos < e->data + e->filesize; pos = strchr(pos + 1, '\n') + 1) {
|
||||
if (memcmp(pos, "# STOCKSHA1=", 12) == 0) {
|
||||
pos += 12;
|
||||
memcpy(sha1, pos, 40);
|
||||
@ -66,61 +63,47 @@ static char *cpio_stocksha1(struct vector *v) {
|
||||
return strdup(sha1);
|
||||
}
|
||||
}
|
||||
} else if (strcmp(f->filename, ".backup/.sha1") == 0) {
|
||||
return f->data;
|
||||
} else if (strcmp(e->filename, ".backup/.sha1") == 0) {
|
||||
return e->data;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct vector *cpio_backup(struct vector *v, const char *orig, const char *keepverity,
|
||||
const char *keepforceencrypt, const char *sha1) {
|
||||
struct vector o_body, *o = &o_body, *ret;
|
||||
static void cpio_backup(struct vector *v, struct vector *bak, const char *orig, const char *sha1) {
|
||||
struct vector o_body, *o = &o_body;
|
||||
cpio_entry *m, *n, *rem, *cksm;
|
||||
char buf[PATH_MAX];
|
||||
int res, backup;
|
||||
|
||||
ret = xcalloc(sizeof(*ret), 1);
|
||||
|
||||
vec_init(o);
|
||||
vec_init(ret);
|
||||
|
||||
m = xcalloc(sizeof(*m), 1);
|
||||
m->filename = strdup(".backup");
|
||||
m->mode = S_IFDIR;
|
||||
vec_push_back(ret, m);
|
||||
|
||||
m = xcalloc(sizeof(*m), 1);
|
||||
m->filename = strdup(".backup/.magisk");
|
||||
m->mode = S_IFREG;
|
||||
m->data = xmalloc(50);
|
||||
snprintf(m->data, 50, "KEEPVERITY=%s\nKEEPFORCEENCRYPT=%s\n", keepverity, keepforceencrypt);
|
||||
m->filesize = strlen(m->data) + 1;
|
||||
vec_push_back(ret, m);
|
||||
vec_push_back(bak, m);
|
||||
|
||||
rem = xcalloc(sizeof(*rem), 1);
|
||||
rem->filename = strdup(".backup/.rmlist");
|
||||
rem->mode = S_IFREG;
|
||||
vec_push_back(ret, rem);
|
||||
|
||||
if (sha1) {
|
||||
fprintf(stderr, "Save SHA1: [%s] -> [.backup/.sha1]\n", sha1);
|
||||
cksm = xcalloc(sizeof(*cksm), 1);
|
||||
vec_push_back(ret, cksm);
|
||||
vec_push_back(bak, cksm);
|
||||
cksm->filename = strdup(".backup/.sha1");
|
||||
cksm->mode = S_IFREG;
|
||||
cksm->data = strdup(sha1);
|
||||
cksm->filesize = strlen(sha1) + 1;
|
||||
}
|
||||
|
||||
vec_init(o);
|
||||
parse_cpio(o, orig);
|
||||
// Remove possible backups in original ramdisk
|
||||
cpio_rm(o, 1, ".backup");
|
||||
cpio_rm(v, 1, ".backup");
|
||||
|
||||
// Sort both vectors before comparing
|
||||
vec_sort(v, cpio_cmp);
|
||||
vec_sort(o, cpio_cmp);
|
||||
vec_sort(v, cpio_cmp);
|
||||
|
||||
// Start comparing
|
||||
size_t i = 0, j = 0;
|
||||
@ -153,7 +136,6 @@ static struct vector *cpio_backup(struct vector *v, const char *orig, const char
|
||||
} else {
|
||||
// Someting new in ramdisk, record in rem
|
||||
++j;
|
||||
if (n->remove) continue;
|
||||
rem->data = xrealloc(rem->data, rem->filesize + strlen(n->filename) + 1);
|
||||
memcpy(rem->data + rem->filesize, n->filename, strlen(n->filename) + 1);
|
||||
rem->filesize += strlen(n->filename) + 1;
|
||||
@ -161,51 +143,49 @@ static struct vector *cpio_backup(struct vector *v, const char *orig, const char
|
||||
}
|
||||
if (backup) {
|
||||
sprintf(buf, ".backup/%s", m->filename);
|
||||
fprintf(stderr, "[%s] -> [%s]\n", m->filename, buf);
|
||||
free(m->filename);
|
||||
m->filename = strdup(buf);
|
||||
fprintf(stderr, "[%s] -> [%s]\n", buf, m->filename);
|
||||
vec_push_back(ret, m);
|
||||
vec_push_back(bak, m);
|
||||
// NULL the original entry, so it won't be freed
|
||||
vec_entry(o)[i - 1] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (rem->filesize == 0)
|
||||
rem->remove = 1;
|
||||
if (rem->filesize)
|
||||
vec_push_back(bak, rem);
|
||||
else
|
||||
cpio_free(rem);
|
||||
|
||||
// Cleanup
|
||||
cpio_vec_destroy(o);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void cpio_restore(struct vector *v) {
|
||||
cpio_entry *f, *n;
|
||||
vec_for_each(v, f) {
|
||||
if (strncmp(f->filename, ".backup", 7) == 0) {
|
||||
f->remove = 1;
|
||||
if (f->filename[7] == '\0') continue;
|
||||
if (f->filename[8] == '.') {
|
||||
if (strcmp(f->filename, ".backup/.rmlist") == 0) {
|
||||
for (int pos = 0; pos < f->filesize; pos += strlen(f->data + pos) + 1)
|
||||
cpio_rm(v, 0, f->data + pos);
|
||||
cpio_entry *e;
|
||||
vec_for_each(v, e) {
|
||||
if (!e) continue;
|
||||
if (strncmp(e->filename, ".backup", 7) == 0) {
|
||||
if (e->filename[7] == '\0') continue;
|
||||
if (e->filename[8] == '.') {
|
||||
if (strcmp(e->filename, ".backup/.rmlist") == 0) {
|
||||
for (int pos = 0; pos < e->filesize; pos += strlen(e->data + pos) + 1)
|
||||
cpio_rm(v, 0, e->data + pos);
|
||||
}
|
||||
continue;
|
||||
} else {
|
||||
n = xcalloc(sizeof(*n), 1);
|
||||
memcpy(n, f, sizeof(*f));
|
||||
n->filename = strdup(f->filename + 8);
|
||||
n->data = f->data;
|
||||
f->data = NULL;
|
||||
n->remove = 0;
|
||||
fprintf(stderr, "Restore [%s] -> [%s]\n", f->filename, n->filename);
|
||||
cpio_vec_insert(v, n);
|
||||
fprintf(stderr, "Restore [%s] -> [%s]\n", e->filename, e->filename + 8);
|
||||
vec_cur(v) = NULL;
|
||||
char *new_name = strdup(e->filename + 8);
|
||||
free(e->filename);
|
||||
e->filename = new_name;
|
||||
cpio_vec_insert(v, e);
|
||||
}
|
||||
}
|
||||
if (strncmp(f->filename, "overlay", 7) == 0)
|
||||
f->remove = 1;
|
||||
}
|
||||
// Some known stuff we can remove
|
||||
cpio_rm(v, 1, ".backup");
|
||||
cpio_rm(v, 1, "overlay");
|
||||
cpio_rm(v, 0, "sbin/magic_mask.sh");
|
||||
cpio_rm(v, 0, "init.magisk.rc");
|
||||
cpio_rm(v, 0, "magisk");
|
||||
@ -235,25 +215,16 @@ static void restore_high_compress(struct vector *v, const char *incpio) {
|
||||
}
|
||||
|
||||
static void enable_high_compress(struct vector *v, struct vector *b, const char *incpio) {
|
||||
cpio_entry *e, *magiskinit, *init;
|
||||
cpio_entry *init, *magiskinit;
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
int i = cpio_find(b, ".backup/init"), j = cpio_find(v, "init");
|
||||
init = vec_entry(b)[i];
|
||||
magiskinit = vec_entry(v)[j];
|
||||
free(init->filename);
|
||||
init->filename = strdup("init");
|
||||
vec_entry(v)[j] = init;
|
||||
vec_entry(b)[i] = NULL;
|
||||
|
||||
dump_cpio(v, incpio);
|
||||
cpio_vec_destroy(v);
|
||||
@ -269,64 +240,93 @@ static void enable_high_compress(struct vector *v, struct vector *b, const char
|
||||
cpio_add(v, 0, "ramdisk.cpio.xz", incpio);
|
||||
}
|
||||
|
||||
int cpio_commands(const char *command, int argc, char *argv[]) {
|
||||
int cpio_commands(int argc, char *argv[]) {
|
||||
char *incpio = argv[0];
|
||||
++argv;
|
||||
--argc;
|
||||
|
||||
struct vector v;
|
||||
vec_init(&v);
|
||||
parse_cpio(&v, incpio);
|
||||
|
||||
if (strcmp(command, "test") == 0) {
|
||||
int cmdc;
|
||||
char *cmdv[6];
|
||||
|
||||
while (argc) {
|
||||
cmdc = 0;
|
||||
for (char *tok = strtok(argv[0], " "); tok; tok = strtok(NULL, " "))
|
||||
cmdv[cmdc++] = tok;
|
||||
|
||||
if (strcmp(cmdv[0], "test") == 0) {
|
||||
exit(cpio_test(&v));
|
||||
} else if (strcmp(command, "restore") == 0) {
|
||||
} else if (strcmp(cmdv[0], "restore") == 0) {
|
||||
restore_high_compress(&v, incpio);
|
||||
cpio_restore(&v);
|
||||
} else if (strcmp(command, "stocksha1") == 0) {
|
||||
printf("%s\n", cpio_stocksha1(&v));
|
||||
} else if (strcmp(cmdv[0], "sha1") == 0) {
|
||||
char *sha1 = cpio_sha1(&v);
|
||||
if (sha1)
|
||||
printf("%s\n", sha1);
|
||||
return 0;
|
||||
} else if (argc >= 4 && strcmp(command, "backup") == 0) {
|
||||
struct vector *back;
|
||||
} else if (cmdc >= 2 && strcmp(cmdv[0], "backup") == 0) {
|
||||
struct vector back;
|
||||
vec_init(&back);
|
||||
cpio_backup(&v, &back, cmdv[1], cmdc > 2 ? cmdv[2] : NULL);
|
||||
cpio_entry *e;
|
||||
back = cpio_backup(&v, argv[0], argv[2], argv[3], argc > 4 ? argv[4] : NULL);
|
||||
vec_for_each(&back, e)
|
||||
if (e) vec_push_back(&v, e);
|
||||
vec_destroy(&back);
|
||||
} else if (cmdc >= 5 && strcmp(cmdv[0], "magisk") == 0) {
|
||||
cpio_patch(&v, strcmp(cmdv[3], "true") == 0, strcmp(cmdv[4], "true") == 0);
|
||||
|
||||
struct vector back;
|
||||
vec_init(&back);
|
||||
cpio_backup(&v, &back, cmdv[1], cmdc > 5 ? cmdv[5] : NULL);
|
||||
|
||||
cpio_entry *e;
|
||||
e = xcalloc(sizeof(*e), 1);
|
||||
e->filename = strdup(".backup/.magisk");
|
||||
e->mode = S_IFREG;
|
||||
e->data = xmalloc(50);
|
||||
snprintf(e->data, 50, "KEEPVERITY=%s\nKEEPFORCEENCRYPT=%s\n", cmdv[3], cmdv[4]);
|
||||
e->filesize = strlen(e->data) + 1;
|
||||
vec_push_back(&back, e);
|
||||
|
||||
// Enable high compression mode
|
||||
if (strcmp(argv[1], "true") == 0)
|
||||
enable_high_compress(&v, back, incpio);
|
||||
if (strcmp(cmdv[2], "true") == 0)
|
||||
enable_high_compress(&v, &back, incpio);
|
||||
|
||||
vec_for_each(back, e)
|
||||
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) {
|
||||
recursive = 1;
|
||||
++argv;
|
||||
}
|
||||
cpio_rm(&v, recursive, argv[0]);
|
||||
} else if (argc == 2 && strcmp(command, "mv") == 0) {
|
||||
if (cpio_mv(&v, argv[0], argv[1]))
|
||||
return 1;
|
||||
} else if (argc == 2 && strcmp(command, "patch") == 0) {
|
||||
cpio_patch(&v, strcmp(argv[0], "true") == 0, strcmp(argv[1], "true") == 0);
|
||||
} else if (strcmp(command, "extract") == 0) {
|
||||
if (argc == 2) {
|
||||
return cpio_extract(&v, argv[0], argv[1]);
|
||||
vec_destroy(&back);
|
||||
} else if (cmdc >= 2 && strcmp(cmdv[0], "rm") == 0) {
|
||||
int recur = cmdc > 2 && strcmp(cmdv[1], "-r") == 0;
|
||||
cpio_rm(&v, recur, cmdv[1 + recur]);
|
||||
} else if (cmdc == 3 && strcmp(cmdv[0], "mv") == 0) {
|
||||
cpio_mv(&v, cmdv[1], cmdv[2]);
|
||||
} else if (cmdc == 3 && strcmp(cmdv[0], "patch") == 0) {
|
||||
cpio_patch(&v, strcmp(cmdv[1], "true") == 0, strcmp(cmdv[2], "true") == 0);
|
||||
} else if (strcmp(cmdv[0], "extract") == 0) {
|
||||
if (cmdc == 3) {
|
||||
return cpio_extract(&v, cmdv[1], cmdv[2]);
|
||||
} else {
|
||||
cpio_extract_all(&v);
|
||||
return 0;
|
||||
}
|
||||
} else if (argc == 2 && strcmp(command, "mkdir") == 0) {
|
||||
cpio_mkdir(&v, strtoul(argv[0], NULL, 8), argv[1]);
|
||||
} else if (argc == 2 && strcmp(command, "ln") == 0) {
|
||||
cpio_ln(&v, argv[0], argv[1]);
|
||||
} else if (argc == 3 && strcmp(command, "add") == 0) {
|
||||
cpio_add(&v, strtoul(argv[0], NULL, 8), argv[1], argv[2]);
|
||||
} else if (cmdc == 3 && strcmp(cmdv[0], "mkdir") == 0) {
|
||||
cpio_mkdir(&v, strtoul(cmdv[1], NULL, 8), cmdv[2]);
|
||||
} else if (cmdc == 3 && strcmp(cmdv[0], "ln") == 0) {
|
||||
cpio_ln(&v, cmdv[1], cmdv[2]);
|
||||
} else if (cmdc == 4 && strcmp(cmdv[0], "add") == 0) {
|
||||
cpio_add(&v, strtoul(cmdv[1], NULL, 8), cmdv[2], cmdv[3]);
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
|
||||
--argc;
|
||||
++argv;
|
||||
}
|
||||
|
||||
dump_cpio(&v, incpio);
|
||||
cpio_vec_destroy(&v);
|
||||
exit(0);
|
||||
return 0;
|
||||
}
|
||||
|
@ -209,7 +209,7 @@ public:
|
||||
vector prop_list;
|
||||
|
||||
static int prop_cmp(const void *p1, const void *p2) {
|
||||
return strcmp((*((property **) p1))->name, (*((property **) p2))->name);
|
||||
return strcmp(((property *) p1)->name, ((property *) p2)->name);
|
||||
}
|
||||
|
||||
static void print_all_props_cb(const char *name, const char *value) {
|
||||
|
@ -22,34 +22,42 @@ static uint32_t x8u(char *hex) {
|
||||
return val;
|
||||
}
|
||||
|
||||
static void cpio_free(cpio_entry *f) {
|
||||
if (f) {
|
||||
free(f->filename);
|
||||
free(f->data);
|
||||
free(f);
|
||||
void cpio_free(cpio_entry *e) {
|
||||
if (e) {
|
||||
free(e->filename);
|
||||
free(e->data);
|
||||
free(e);
|
||||
}
|
||||
}
|
||||
|
||||
int cpio_find(struct vector *v, const char *entry) {
|
||||
cpio_entry *e;
|
||||
vec_for_each(v, e) {
|
||||
if (!e) continue;
|
||||
if (strcmp(e->filename, entry) == 0)
|
||||
return _;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int cpio_cmp(const void *a, const void *b) {
|
||||
return strcmp((*(cpio_entry **) a)->filename, (*(cpio_entry **) b)->filename);
|
||||
return strcmp(((cpio_entry *) a)->filename, ((cpio_entry *) b)->filename);
|
||||
}
|
||||
|
||||
void cpio_vec_insert(struct vector *v, cpio_entry *n) {
|
||||
cpio_entry *f;
|
||||
vec_for_each(v, f) {
|
||||
if (strcmp(f->filename, n->filename) == 0) {
|
||||
int i = cpio_find(v, n->filename);
|
||||
if (i > 0) {
|
||||
// Replace, then all is done
|
||||
cpio_free(f);
|
||||
vec_cur(v) = n;
|
||||
cpio_free(vec_entry(v)[i]);
|
||||
vec_entry(v)[i] = n;
|
||||
return;
|
||||
}
|
||||
}
|
||||
vec_push_back(v, n);
|
||||
}
|
||||
|
||||
// Parse cpio file to a vector of cpio_entry
|
||||
void parse_cpio(struct vector *v, const char *filename) {
|
||||
fprintf(stderr, "Loading cpio: [%s]\n\n", filename);
|
||||
fprintf(stderr, "Loading cpio: [%s]\n", filename);
|
||||
int fd = open(filename, O_RDONLY);
|
||||
if (fd < 0) return;
|
||||
cpio_newc_header header;
|
||||
@ -91,35 +99,34 @@ void parse_cpio(struct vector *v, const char *filename) {
|
||||
}
|
||||
|
||||
void dump_cpio(struct vector *v, const char *filename) {
|
||||
fprintf(stderr, "\nDump cpio: [%s]\n\n", filename);
|
||||
int fd = creat(filename, 0644);
|
||||
fprintf(stderr, "Dump cpio: [%s]\n", filename);
|
||||
unsigned inode = 300000;
|
||||
char header[111];
|
||||
// Sort by name
|
||||
vec_sort(v, cpio_cmp);
|
||||
cpio_entry *f;
|
||||
vec_for_each(v, f) {
|
||||
if (f->remove) continue;
|
||||
cpio_entry *e;
|
||||
int fd = creat(filename, 0644);
|
||||
vec_for_each(v, e) {
|
||||
sprintf(header, "070701%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x",
|
||||
inode++, // f->ino
|
||||
f->mode,
|
||||
f->uid,
|
||||
f->gid,
|
||||
1, // f->nlink
|
||||
0, // f->mtime
|
||||
f->filesize,
|
||||
0, // f->devmajor
|
||||
0, // f->devminor
|
||||
0, // f->rdevmajor
|
||||
0, // f->rdevminor
|
||||
(uint32_t) strlen(f->filename) + 1,
|
||||
0 // f->check
|
||||
inode++, // e->ino
|
||||
e->mode,
|
||||
e->uid,
|
||||
e->gid,
|
||||
1, // e->nlink
|
||||
0, // e->mtime
|
||||
e->filesize,
|
||||
0, // e->devmajor
|
||||
0, // e->devminor
|
||||
0, // e->rdevmajor
|
||||
0, // e->rdevminor
|
||||
(uint32_t) strlen(e->filename) + 1,
|
||||
0 // e->check
|
||||
);
|
||||
xwrite(fd, header, 110);
|
||||
xwrite(fd, f->filename, strlen(f->filename) + 1);
|
||||
xwrite(fd, e->filename, strlen(e->filename) + 1);
|
||||
file_align(fd, 4, 1);
|
||||
if (f->filesize) {
|
||||
xwrite(fd, f->data, f->filesize);
|
||||
if (e->filesize) {
|
||||
xwrite(fd, e->data, e->filesize);
|
||||
file_align(fd, 4, 1);
|
||||
}
|
||||
}
|
||||
@ -133,23 +140,22 @@ void dump_cpio(struct vector *v, const char *filename) {
|
||||
|
||||
void cpio_vec_destroy(struct vector *v) {
|
||||
// Free each cpio_entry
|
||||
cpio_entry *f;
|
||||
vec_for_each(v, f) {
|
||||
cpio_free(f);
|
||||
}
|
||||
cpio_entry *e;
|
||||
vec_for_each(v, e)
|
||||
cpio_free(e);
|
||||
vec_destroy(v);
|
||||
}
|
||||
|
||||
void cpio_rm(struct vector *v, int recursive, const char *entry) {
|
||||
cpio_entry *f;
|
||||
vec_for_each(v, f) {
|
||||
if (strncmp(f->filename, entry, strlen(entry)) == 0) {
|
||||
char next = f->filename[strlen(entry)];
|
||||
if ((recursive && next == '/') || next == '\0') {
|
||||
if (!f->remove) {
|
||||
fprintf(stderr, "Remove [%s]\n", f->filename);
|
||||
f->remove = 1;
|
||||
}
|
||||
cpio_entry *e;
|
||||
size_t len = strlen(entry);
|
||||
vec_for_each(v, e) {
|
||||
if (!e) continue;
|
||||
if (strncmp(e->filename, entry, len) == 0) {
|
||||
if ((recursive && e->filename[len] == '/') || e->filename[len] == '\0') {
|
||||
fprintf(stderr, "Remove [%s]\n", e->filename);
|
||||
cpio_free(e);
|
||||
vec_cur(v) = NULL;
|
||||
if (!recursive) return;
|
||||
}
|
||||
}
|
||||
@ -157,97 +163,94 @@ void cpio_rm(struct vector *v, int recursive, const char *entry) {
|
||||
}
|
||||
|
||||
void cpio_mkdir(struct vector *v, mode_t mode, const char *entry) {
|
||||
cpio_entry *f = xcalloc(sizeof(*f), 1);
|
||||
f->mode = S_IFDIR | mode;
|
||||
f->filename = strdup(entry);
|
||||
cpio_vec_insert(v, f);
|
||||
cpio_entry *e = xcalloc(sizeof(*e), 1);
|
||||
e->mode = S_IFDIR | mode;
|
||||
e->filename = strdup(entry);
|
||||
cpio_vec_insert(v, e);
|
||||
fprintf(stderr, "Create directory [%s] (%04o)\n",entry, mode);
|
||||
}
|
||||
|
||||
void cpio_ln(struct vector *v, const char *target, const char *entry) {
|
||||
cpio_entry *f = xcalloc(sizeof(*f), 1);
|
||||
f->mode = S_IFLNK;
|
||||
f->filename = strdup(entry);
|
||||
f->filesize = strlen(target);
|
||||
f->data = strdup(target);
|
||||
cpio_vec_insert(v, f);
|
||||
cpio_entry *e = xcalloc(sizeof(*e), 1);
|
||||
e->mode = S_IFLNK;
|
||||
e->filename = strdup(entry);
|
||||
e->filesize = strlen(target);
|
||||
e->data = strdup(target);
|
||||
cpio_vec_insert(v, e);
|
||||
fprintf(stderr, "Create symlink [%s] -> [%s]\n", entry, target);
|
||||
}
|
||||
|
||||
void cpio_add(struct vector *v, mode_t mode, const char *entry, const char *filename) {
|
||||
int fd = xopen(filename, O_RDONLY);
|
||||
cpio_entry *f = xcalloc(sizeof(*f), 1);
|
||||
f->mode = S_IFREG | mode;
|
||||
f->filename = strdup(entry);
|
||||
f->filesize = lseek(fd, 0, SEEK_END);
|
||||
cpio_entry *e = xcalloc(sizeof(*e), 1);
|
||||
e->mode = S_IFREG | mode;
|
||||
e->filename = strdup(entry);
|
||||
e->filesize = lseek(fd, 0, SEEK_END);
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
f->data = xmalloc(f->filesize);
|
||||
xxread(fd, f->data, f->filesize);
|
||||
e->data = xmalloc(e->filesize);
|
||||
xxread(fd, e->data, e->filesize);
|
||||
close(fd);
|
||||
cpio_vec_insert(v, f);
|
||||
cpio_vec_insert(v, e);
|
||||
fprintf(stderr, "Add entry [%s] (%04o)\n", entry, mode);
|
||||
}
|
||||
|
||||
int cpio_mv(struct vector *v, const char *from, const char *to) {
|
||||
struct cpio_entry *f, *t;
|
||||
vec_for_each(v, f) {
|
||||
if (strcmp(f->filename, from) == 0) {
|
||||
fprintf(stderr, "Move [%s] -> [%s]\n", from, to);
|
||||
vec_for_each(v, t) {
|
||||
if (strcmp(t->filename, to) == 0) {
|
||||
t->remove = 1;
|
||||
break;
|
||||
struct cpio_entry *e;
|
||||
int f = cpio_find(v, from), t = cpio_find(v, to);
|
||||
if (f > 0) {
|
||||
if (t > 0) {
|
||||
cpio_free(vec_entry(v)[t]);
|
||||
vec_entry(v)[t] = NULL;
|
||||
}
|
||||
}
|
||||
free(f->filename);
|
||||
f->filename = strdup(to);
|
||||
e = vec_entry(v)[f];
|
||||
free(e->filename);
|
||||
e->filename = strdup(to);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
fprintf(stderr, "Cannot find entry %s\n", from);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int cpio_extract(struct vector *v, const char *entry, const char *filename) {
|
||||
cpio_entry *f;
|
||||
vec_for_each(v, f) {
|
||||
if (strcmp(f->filename, entry) == 0) {
|
||||
fprintf(stderr, "Extracting [%s] to [%s]\n\n", entry, filename);
|
||||
if (S_ISREG(f->mode)) {
|
||||
int fd = creat(filename, f->mode & 0777);
|
||||
xwrite(fd, f->data, f->filesize);
|
||||
fchown(fd, f->uid, f->gid);
|
||||
int i = cpio_find(v, entry);
|
||||
if (i > 0) {
|
||||
cpio_entry *e = vec_entry(v)[i];
|
||||
fprintf(stderr, "Extracting [%s] to [%s]\n", entry, filename);
|
||||
if (S_ISREG(e->mode)) {
|
||||
int fd = creat(filename, e->mode & 0777);
|
||||
xwrite(fd, e->data, e->filesize);
|
||||
fchown(fd, e->uid, e->gid);
|
||||
close(fd);
|
||||
} else if (S_ISLNK(f->mode)) {
|
||||
char *target = xcalloc(f->filesize + 1, 1);
|
||||
memcpy(target, f->data, f->filesize);
|
||||
} else if (S_ISLNK(e->mode)) {
|
||||
char *target = xcalloc(e->filesize + 1, 1);
|
||||
memcpy(target, e->data, e->filesize);
|
||||
unlink(filename);
|
||||
symlink(target, filename);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
fprintf(stderr, "Cannot find the file entry [%s]\n", entry);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void cpio_extract_all(struct vector *v) {
|
||||
cpio_entry *f;
|
||||
vec_for_each(v, f) {
|
||||
fprintf(stderr, "Extracting [%s]\n", f->filename);
|
||||
unlink(f->filename);
|
||||
rmdir(f->filename);
|
||||
if (S_ISDIR(f->mode)) {
|
||||
mkdir(f->filename, f->mode & 0777);
|
||||
} else if (S_ISREG(f->mode)) {
|
||||
int fd = creat(f->filename, f->mode & 0777);
|
||||
xwrite(fd, f->data, f->filesize);
|
||||
fchown(fd, f->uid, f->gid);
|
||||
cpio_entry *e;
|
||||
vec_for_each(v, e) {
|
||||
if (!e) continue;
|
||||
fprintf(stderr, "Extracting [%s]\n", e->filename);
|
||||
unlink(e->filename);
|
||||
rmdir(e->filename);
|
||||
if (S_ISDIR(e->mode)) {
|
||||
mkdir(e->filename, e->mode & 0777);
|
||||
} else if (S_ISREG(e->mode)) {
|
||||
int fd = creat(e->filename, e->mode & 0777);
|
||||
xwrite(fd, e->data, e->filesize);
|
||||
fchown(fd, e->uid, e->gid);
|
||||
close(fd);
|
||||
} else if (S_ISLNK(f->mode)) {
|
||||
char *target = xcalloc(f->filesize + 1, 1);
|
||||
memcpy(target, f->data, f->filesize);
|
||||
symlink(target, f->filename);
|
||||
} else if (S_ISLNK(e->mode)) {
|
||||
char *target = xcalloc(e->filesize + 1, 1);
|
||||
memcpy(target, e->data, e->filesize);
|
||||
symlink(target, e->filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -29,9 +29,25 @@ void *vec_pop_back(struct vector *v) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int (*cmp)(const void *, const void *);
|
||||
|
||||
static int vec_comp(const void *a, const void *b) {
|
||||
void *aa = *((void **)a), *bb = *((void **)b);
|
||||
if (aa == NULL && bb == NULL) return 0;
|
||||
else if (aa == NULL) return 1;
|
||||
else if (bb == NULL) return -1;
|
||||
else return cmp ? cmp(aa, bb) : 0;
|
||||
}
|
||||
|
||||
void vec_sort(struct vector *v, int (*compar)(const void *, const void *)) {
|
||||
if (v == NULL) return;
|
||||
qsort(vec_entry(v), vec_size(v), sizeof(void*), compar);
|
||||
cmp = compar;
|
||||
qsort(vec_entry(v), vec_size(v), sizeof(void*), vec_comp);
|
||||
void *e;
|
||||
vec_for_each_r(v, e) {
|
||||
if (e) break;
|
||||
--vec_size(v);
|
||||
}
|
||||
}
|
||||
|
||||
/* Will cleanup only the vector itself
|
||||
|
@ -89,6 +89,7 @@ case $? in
|
||||
2 )
|
||||
ui_print "! Insufficient boot partition size detected"
|
||||
HIGHCOMP=true
|
||||
ui_print "- Enable high compression mode"
|
||||
;;
|
||||
3 )
|
||||
ui_print "- ChromeOS boot image detected"
|
||||
@ -103,20 +104,13 @@ case $? in
|
||||
abort "! Stock kernel cannot be patched, please use a custom kernel"
|
||||
esac
|
||||
|
||||
if [ -f /sdcard/ramdisk-recovery.img ]; then
|
||||
HIGHCOMP=true
|
||||
ui_print "- Detected ramdisk-recovery.img"
|
||||
fi
|
||||
|
||||
$HIGHCOMP && ui_print "- Enable high compression mode"
|
||||
|
||||
##########################################################################################
|
||||
# Ramdisk restores
|
||||
##########################################################################################
|
||||
|
||||
# Test patch status and do restore, after this section, ramdisk.cpio.orig is guaranteed to exist
|
||||
ui_print "- Checking ramdisk status"
|
||||
./magiskboot --cpio-test ramdisk.cpio
|
||||
./magiskboot --cpio ramdisk.cpio test
|
||||
case $? in
|
||||
0 ) # Stock boot
|
||||
ui_print "- Stock boot image detected!"
|
||||
@ -129,8 +123,8 @@ case $? in
|
||||
1 ) # Magisk patched
|
||||
ui_print "- Magisk patched image detected!"
|
||||
# Find SHA1 of stock boot image
|
||||
[ -z $SHA1 ] && SHA1=`./magiskboot --cpio-stocksha1 ramdisk.cpio 2>/dev/null`
|
||||
./magiskboot --cpio-restore ramdisk.cpio
|
||||
[ -z $SHA1 ] && SHA1=`./magiskboot --cpio ramdisk.cpio sha1 2>/dev/null`
|
||||
./magiskboot --cpio ramdisk.cpio restore
|
||||
cp -af ramdisk.cpio ramdisk.cpio.orig
|
||||
;;
|
||||
2 ) # Other patched
|
||||
@ -145,18 +139,12 @@ esac
|
||||
|
||||
ui_print "- Patching ramdisk"
|
||||
|
||||
./magiskboot --cpio-add ramdisk.cpio 750 init magiskinit
|
||||
./magiskboot --cpio-backup ramdisk.cpio ramdisk.cpio.orig $HIGHCOMP $KEEPVERITY $KEEPFORCEENCRYPT $SHA1
|
||||
./magiskboot --cpio ramdisk.cpio \
|
||||
'add 750 init magiskinit' \
|
||||
"magisk ramdisk.cpio.orig $HIGHCOMP $KEEPVERITY $KEEPFORCEENCRYPT $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
|
||||
##########################################################################################
|
||||
|
@ -71,7 +71,7 @@ esac
|
||||
|
||||
# Detect boot image state
|
||||
ui_print "- Checking ramdisk status"
|
||||
./magiskboot --cpio-test ramdisk.cpio
|
||||
./magiskboot --cpio ramdisk.cpio test
|
||||
case $? in
|
||||
0 ) # Stock boot
|
||||
ui_print "- Stock boot image detected!"
|
||||
@ -80,13 +80,13 @@ case $? in
|
||||
1 ) # Magisk patched
|
||||
ui_print "- Magisk patched image detected!"
|
||||
# Find SHA1 of stock boot image
|
||||
[ -z $SHA1 ] && SHA1=`./magiskboot --cpio-stocksha1 ramdisk.cpio 2>/dev/null`
|
||||
[ -z $SHA1 ] && SHA1=`./magiskboot --cpio ramdisk.cpio sha1 2>/dev/null`
|
||||
OK=false
|
||||
[ ! -z $SHA1 ] && restore_imgs $SHA1 && OK=true
|
||||
if ! $OK; then
|
||||
ui_print "! Boot image backup unavailable"
|
||||
ui_print "- Restoring ramdisk with internal backup"
|
||||
./magiskboot --cpio-restore ramdisk.cpio
|
||||
./magiskboot --cpio ramdisk.cpio restore
|
||||
./magiskboot --repack $BOOTIMAGE
|
||||
# Sign chromeos boot
|
||||
$CHROMEOS && sign_chromeos
|
||||
@ -104,6 +104,7 @@ cd /
|
||||
ui_print "- Removing Magisk files"
|
||||
rm -rf /cache/*magisk* /cache/unblock /data/*magisk* /data/cache/*magisk* /data/property/*magisk* \
|
||||
/data/Magisk.apk /data/busybox /data/custom_ramdisk_patch.sh /data/app/com.topjohnwu.magisk* \
|
||||
/data/user*/*/magisk.db /data/user*/*/com.topjohnwu.magisk /data/adb/*magisk* 2>/dev/null
|
||||
/data/user*/*/magisk.db /data/user*/*/com.topjohnwu.magisk /data/user*/*/.tmp.magisk.config \
|
||||
/data/adb/*magisk* 2>/dev/null
|
||||
|
||||
$BOOTMODE && reboot
|
||||
|
@ -7,11 +7,11 @@
|
||||
#
|
||||
##########################################################################################
|
||||
|
||||
MAGISK_VERSION_STUB
|
||||
#MAGISK_VERSION_STUB
|
||||
SCRIPT_VERSION=$MAGISK_VER_CODE
|
||||
|
||||
# Default location, will override if needed
|
||||
MAGISKBIN=/data/adb/magisk
|
||||
[ -d /data/adb/magisk ] && MAGISKBIN=/data/adb/magisk || MAGISKBIN=/data/magisk
|
||||
|
||||
BOOTSIGNER="/system/bin/dalvikvm -Xnodex2oat -Xnoimage-dex2oat -cp \$APK com.topjohnwu.magisk.utils.BootSigner"
|
||||
BOOTSIGNED=false
|
||||
|
Loading…
Reference in New Issue
Block a user