MagiskBoot refactor

This commit is contained in:
topjohnwu 2017-09-12 15:27:28 +08:00
parent 619b805894
commit b536046720
8 changed files with 157 additions and 107 deletions

View File

@ -4,7 +4,7 @@ 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 };
void mmap_ro(const char *filename, unsigned char **buf, size_t *size) {
void mmap_ro(const char *filename, void **buf, size_t *size) {
int fd = xopen(filename, O_RDONLY);
*size = lseek(fd, 0, SEEK_END);
lseek(fd, 0, SEEK_SET);
@ -12,7 +12,7 @@ void mmap_ro(const char *filename, unsigned char **buf, size_t *size) {
close(fd);
}
void mmap_rw(const char *filename, unsigned char **buf, size_t *size) {
void mmap_rw(const char *filename, void **buf, size_t *size) {
int fd = xopen(filename, O_RDWR);
*size = lseek(fd, 0, SEEK_END);
lseek(fd, 0, SEEK_SET);
@ -20,7 +20,7 @@ void mmap_rw(const char *filename, unsigned char **buf, size_t *size) {
close(fd);
}
file_t check_type(const unsigned char *buf) {
file_t check_type(const void *buf) {
if (memcmp(buf, CHROMEOS_MAGIC, 8) == 0) {
return CHROMEOS;
} else if (memcmp(buf, BOOT_MAGIC, BOOT_MAGIC_SIZE) == 0) {
@ -29,28 +29,72 @@ file_t check_type(const unsigned char *buf) {
return ELF32;
} else if (memcmp(buf, ELF64_MAGIC, 5) == 0) {
return ELF64;
} else if (memcmp(buf, "\x1f\x8b\x08\x00", 4) == 0) {
} else if (memcmp(buf, GZIP_MAGIC, 4) == 0) {
return GZIP;
} else if (memcmp(buf, "\x89\x4c\x5a\x4f\x00\x0d\x0a\x1a\x0a", 9) == 0) {
} else if (memcmp(buf, LZOP_MAGIC, 9) == 0) {
return LZOP;
} else if (memcmp(buf, "\xfd""7zXZ\x00", 6) == 0) {
} else if (memcmp(buf, XZ_MAGIC, 6) == 0) {
return XZ;
} else if (memcmp(buf, "\x5d\x00\x00", 3) == 0
&& (buf[12] == (unsigned char) '\xff' || buf[12] == (unsigned char) '\x00')) {
} else if (memcmp(buf, "\x5d\x00\x00", 3) == 0
&& (((char *)buf)[12] == '\xff' || ((char *)buf)[12] == '\x00')) {
return LZMA;
} else if (memcmp(buf, "BZh", 3) == 0) {
} else if (memcmp(buf, BZIP_MAGIC, 3) == 0) {
return BZIP2;
} else if (memcmp(buf, "\x04\x22\x4d\x18", 4) == 0) {
} else if (memcmp(buf, LZ4_MAGIC, 4) == 0) {
return LZ4;
} else if (memcmp(buf, "\x02\x21\x4c\x18", 4) == 0) {
} else if (memcmp(buf, LZ4_LEG_MAGIC, 4) == 0) {
return LZ4_LEGACY;
} else if (memcmp(buf, "\x88\x16\x88\x58", 4) == 0) {
} else if (memcmp(buf, MTK_MAGIC, 4) == 0) {
return MTK;
} else if (memcmp(buf, DTB_MAGIC, 4) == 0) {
return DTB;
} else {
return UNKNOWN;
}
}
void get_type_name(file_t type, char *name) {
char *s;
switch (type) {
case CHROMEOS:
s = "chromeos";
break;
case AOSP:
s = "aosp";
break;
case GZIP:
s = "gzip";
break;
case LZOP:
s = "lzop";
break;
case XZ:
s = "xz";
break;
case LZMA:
s = "lzma";
break;
case BZIP2:
s = "bzip2";
break;
case LZ4:
s = "lz4";
break;
case LZ4_LEGACY:
s = "lz4_legacy";
break;
case MTK:
s = "mtk";
break;
case DTB:
s = "dtb";
break;
default:
s = "raw";
}
strcpy(name, s);
}
void write_zero(int fd, size_t size) {
size_t pos = lseek(fd, 0, SEEK_CUR);
ftruncate(fd, pos + size);

View File

@ -1,12 +1,12 @@
#include "bootimg.h"
#include "magiskboot.h"
static unsigned char *kernel, *ramdisk, *second, *dtb, *extra;
static void *kernel, *ramdisk, *second, *dtb, *extra;
static boot_img_hdr hdr;
static int mtk_kernel = 0, mtk_ramdisk = 0;
static file_t ramdisk_type;
static void dump(unsigned char *buf, size_t size, const char *filename) {
static void dump(void *buf, size_t size, const char *filename) {
int fd = open_new(filename);
xwrite(fd, buf, size);
close(fd);
@ -36,12 +36,12 @@ static void print_info() {
int os_version, os_patch_level;
os_version = hdr.os_version >> 11;
os_patch_level = hdr.os_version & 0x7ff;
a = (os_version >> 14) & 0x7f;
b = (os_version >> 7) & 0x7f;
c = os_version & 0x7f;
fprintf(stderr, "OS_VERSION [%d.%d.%d]\n", a, b, c);
y = (os_patch_level >> 4) + 2000;
m = os_patch_level & 0xf;
fprintf(stderr, "PATCH_LEVEL [%d-%02d]\n", y, m);
@ -49,33 +49,15 @@ static void print_info() {
fprintf(stderr, "NAME [%s]\n", hdr.name);
fprintf(stderr, "CMDLINE [%s]\n", hdr.cmdline);
switch (ramdisk_type) {
case GZIP:
fprintf(stderr, "COMPRESSION [%s]\n", "gzip");
break;
case XZ:
fprintf(stderr, "COMPRESSION [%s]\n", "xz");
break;
case LZMA:
fprintf(stderr, "COMPRESSION [%s]\n", "lzma");
break;
case BZIP2:
fprintf(stderr, "COMPRESSION [%s]\n", "bzip2");
break;
case LZ4:
fprintf(stderr, "COMPRESSION [%s]\n", "lz4");
break;
case LZ4_LEGACY:
fprintf(stderr, "COMPRESSION [%s]\n", "lz4_legacy");
break;
default:
fprintf(stderr, "Unknown ramdisk format!\n");
}
char cmp[16];
get_type_name(ramdisk_type, cmp);
fprintf(stderr, "RAMDISK_COMP [%s]\n", cmp);
fprintf(stderr, "\n");
}
int parse_img(unsigned char *orig, size_t size) {
unsigned char *base, *end;
int parse_img(void *orig, size_t size) {
void *base, *end;
size_t pos = 0;
int ret = 0;
for(base = orig, end = orig + size; base < end; base += 256, size -= 256) {
@ -147,7 +129,7 @@ int parse_img(unsigned char *orig, size_t size) {
void unpack(const char* image) {
size_t size;
unsigned char *orig;
void *orig;
mmap_ro(image, &orig, &size);
// Parse image
@ -168,8 +150,8 @@ void unpack(const char* image) {
}
if (decomp(ramdisk_type, RAMDISK_FILE, ramdisk, hdr.ramdisk_size)) {
// Dump the compressed ramdisk
dump(ramdisk, hdr.ramdisk_size, RAMDISK_FILE ".unsupport");
LOGE(1, "Unsupported ramdisk format! Dumped to %s\n", RAMDISK_FILE ".unsupport");
dump(ramdisk, hdr.ramdisk_size, RAMDISK_FILE ".raw");
LOGE(1, "Unknown ramdisk format! Dumped to %s\n", RAMDISK_FILE ".raw");
}
if (hdr.second_size) {
@ -188,7 +170,7 @@ void unpack(const char* image) {
void repack(const char* orig_image, const char* out_image) {
size_t size;
unsigned char *orig;
void *orig;
char name[PATH_MAX];
// There are possible two MTK headers
@ -241,7 +223,7 @@ void repack(const char* orig_image, const char* out_image) {
}
size_t cpio_size;
unsigned char *cpio;
void *cpio;
mmap_ro(RAMDISK_FILE, &cpio, &cpio_size);
if (comp(ramdisk_type, RAMDISK_FILE, cpio, cpio_size))
@ -278,8 +260,8 @@ void repack(const char* orig_image, const char* out_image) {
// Check extra info, currently only for LG Bump and Samsung SEANDROIDENFORCE
if (extra) {
if (memcmp(extra, "SEANDROIDENFORCE", 16) == 0 ||
memcmp(extra, "\x41\xa9\xe4\x67\x74\x4d\x1d\x1b\xa4\x29\xf2\xec\xea\x65\x52\x79", 16) == 0 ) {
if (memcmp(extra, "SEANDROIDENFORCE", 16) == 0 ||
memcmp(extra, LG_BUMP_MAGIC, 16) == 0 ) {
restore_buf(fd, extra, 16);
}
}

View File

@ -31,7 +31,7 @@ static void report(const int mode, const char* filename) {
}
// Mode: 0 = decode; 1 = encode
void gzip(int mode, const char* filename, const unsigned char* buf, size_t size) {
void gzip(int mode, const char* filename, const void *buf, size_t size) {
size_t ret = 0, flush, have, pos = 0;
z_stream strm;
unsigned char out[CHUNK];
@ -102,7 +102,7 @@ void gzip(int mode, const char* filename, const unsigned char* buf, size_t size)
// Mode: 0 = decode xz/lzma; 1 = encode xz; 2 = encode lzma
void lzma(int mode, const char* filename, const unsigned char* buf, size_t size) {
void lzma(int mode, const char* filename, const void *buf, size_t size) {
size_t have, pos = 0;
lzma_ret ret = 0;
lzma_stream strm = LZMA_STREAM_INIT;
@ -167,14 +167,14 @@ void lzma(int mode, const char* filename, const unsigned char* buf, size_t size)
}
// Mode: 0 = decode; 1 = encode
void lz4(int mode, const char* filename, const unsigned char* buf, size_t size) {
void lz4(int mode, const char* filename, const void *buf, size_t size) {
LZ4F_decompressionContext_t dctx;
LZ4F_compressionContext_t cctx;
LZ4F_frameInfo_t info;
size_t outCapacity, avail_in, ret = 0, pos = 0;
size_t have, read;
unsigned char *out = NULL;
void *out = NULL;
report(mode, filename);
int fd = open_new(filename);
@ -190,7 +190,7 @@ void lz4(int mode, const char* filename, const unsigned char* buf, size_t size)
default:
LOGE(1, "Unsupported lz4 mode!\n");
}
if (LZ4F_isError(ret))
LOGE(1, "Context creation error: %s\n", LZ4F_getErrorName(ret));
@ -277,7 +277,7 @@ void lz4(int mode, const char* filename, const unsigned char* buf, size_t size)
}
// Mode: 0 = decode; 1 = encode
void bzip2(int mode, const char* filename, const unsigned char* buf, size_t size) {
void bzip2(int mode, const char* filename, const void* buf, size_t size) {
size_t ret = 0, action, have, pos = 0;
bz_stream strm;
char out[CHUNK];
@ -345,7 +345,7 @@ void bzip2(int mode, const char* filename, const unsigned char* buf, size_t size
}
// Mode: 0 = decode; 1 = encode
void lz4_legacy(int mode, const char* filename, const unsigned char* buf, size_t size) {
void lz4_legacy(int mode, const char* filename, const void* buf, size_t size) {
size_t pos = 0;
int have;
char *out;
@ -372,12 +372,13 @@ void lz4_legacy(int mode, const char* filename, const unsigned char* buf, size_t
}
do {
const char *buff = buf;
switch(mode) {
case 0:
block_size = buf[pos];
block_size += (buf[pos + 1]<<8);
block_size += (buf[pos + 2]<<16);
block_size += ((unsigned)buf[pos + 3])<<24;
block_size = buff[pos];
block_size += (buff[pos + 1]<<8);
block_size += (buff[pos + 2]<<16);
block_size += ((unsigned)buff[pos + 3])<<24;
pos += 4;
if (block_size > LZ4_COMPRESSBOUND(LZ4_LEGACY_BLOCKSIZE))
LOGE(1, "lz4_legacy block size too large!\n");
@ -395,10 +396,10 @@ void lz4_legacy(int mode, const char* filename, const unsigned char* buf, size_t
if (have == 0)
LOGE(1, "lz4_legacy compression error\n");
pos += insize;
block_size_le[0] = (unsigned char)have;
block_size_le[1] = (unsigned char)(have >> 8);
block_size_le[2] = (unsigned char)(have >> 16);
block_size_le[3] = (unsigned char)(have >> 24);
block_size_le[0] = have & 0xff;
block_size_le[1] = (have >> 8) & 0xff;
block_size_le[2] = (have >> 16) & 0xff;
block_size_le[3] = (have >> 24) & 0xff;
write_file(fd, block_size_le, 4, filename);
break;
}
@ -410,7 +411,7 @@ void lz4_legacy(int mode, const char* filename, const unsigned char* buf, size_t
close(fd);
}
int decomp(file_t type, const char *to, const unsigned char *from, size_t size) {
int decomp(file_t type, const char *to, const void *from, size_t size) {
switch (type) {
case GZIP:
gzip(0, to, from, size);
@ -438,7 +439,7 @@ int decomp(file_t type, const char *to, const unsigned char *from, size_t size)
}
// Output will be to.ext
int comp(file_t type, const char *to, const unsigned char *from, size_t size) {
int comp(file_t type, const char *to, const void *from, size_t size) {
char name[PATH_MAX];
const char *ext = strrchr(to, '.');
if (ext == NULL) ext = to;
@ -483,7 +484,7 @@ int comp(file_t type, const char *to, const unsigned char *from, size_t size) {
void decomp_file(char *from, const char *to) {
int ok = 1;
unsigned char *file;
void *file;
size_t size;
mmap_ro(from, &file, &size);
file_t type = check_type(file);
@ -556,7 +557,7 @@ void comp_file(const char *method, const char *from, const char *to) {
fprintf(stderr, "\n");
exit(1);
}
unsigned char *file;
void *file;
size_t size;
mmap_ro(from, &file, &size);
if (!to)

View File

@ -177,21 +177,28 @@ static void cpio_add(mode_t mode, const char *entry, const char *filename, struc
}
static void cpio_test(struct vector *v) {
#define MAGISK_PATCH 0x1
#define OTHER_PATCH 0x2
int ret = 0;
#define STOCK_BOOT 0x0
#define MAGISK_PATCH 0x1
#define OTHER_PATCH 0x2
int ret = STOCK_BOOT;
cpio_file *f;
const char *OTHER_LIST[] = { "sbin/launch_daemonsu.sh", "sbin/su", "init.xposed.rc", "init.supersu.rc", NULL };
const char *OTHER_LIST[] = { "sbin/launch_daemonsu.sh", "sbin/su", "init.xposed.rc", "boot/sbin/launch_daemonsu.sh", NULL };
const char *MAGISK_LIST[] = { "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)
if (strcmp(f->filename, OTHER_LIST[i]) == 0) {
ret |= OTHER_PATCH;
// Already find other files, abort
exit(OTHER_PATCH);
}
}
for (int i = 0; MAGISK_LIST[i]; ++i) {
if (strcmp(f->filename, MAGISK_LIST[i]) == 0)
ret = MAGISK_PATCH;
}
if (strcmp(f->filename, "init.magisk.rc") == 0)
ret |= MAGISK_PATCH;
}
cpio_vec_destroy(v);
exit((ret & OTHER_PATCH) ? OTHER_PATCH : (ret & MAGISK_PATCH));
exit(ret);
}
static int check_verity_pattern(const char *s) {

View File

@ -12,7 +12,7 @@ static void hex2byte(const char *hex, unsigned char *str) {
void hexpatch(const char *image, const char *from, const char *to) {
int patternsize = strlen(from) / 2, patchsize = strlen(to) / 2;
size_t filesize;
unsigned char *file, *pattern, *patch;
void *file, *pattern, *patch;
mmap_rw(image, &file, &filesize);
pattern = xmalloc(patternsize);
patch = xmalloc(patchsize);

34
jni/magiskboot/magic.h Normal file
View File

@ -0,0 +1,34 @@
#ifndef _MAGIC_H_
#define _MAGIC_H_
typedef enum {
UNKNOWN,
CHROMEOS,
AOSP,
ELF32,
ELF64,
GZIP,
LZOP,
XZ,
LZMA,
BZIP2,
LZ4,
LZ4_LEGACY,
MTK,
DTB
} file_t;
#define CHROMEOS_MAGIC "CHROMEOS"
#define ELF32_MAGIC "\x7f""ELF\x01"
#define ELF64_MAGIC "\x7f""ELF\x02"
#define GZIP_MAGIC "\x1f\x8b\x08\x00"
#define LZOP_MAGIC "\x89\x4c\x5a\x4f\x00\x0d\x0a\x1a\x0a"
#define XZ_MAGIC "\xfd""7zXZ\x00"
#define BZIP_MAGIC "BZh"
#define LZ4_MAGIC "\x04\x22\x4d\x18"
#define LZ4_LEG_MAGIC "\x02\x21\x4c\x18"
#define MTK_MAGIC "\x88\x16\x88\x58"
#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"
#endif

View File

@ -16,10 +16,7 @@
#include "sha1.h"
#include "magisk.h"
#include "utils.h"
#define CHROMEOS_MAGIC "CHROMEOS"
#define ELF32_MAGIC "\x7f""ELF\x01"
#define ELF64_MAGIC "\x7f""ELF\x02"
#include "magic.h"
#define KERNEL_FILE "kernel"
#define RAMDISK_FILE "ramdisk.cpio"
@ -30,22 +27,6 @@
#define str(a) #a
#define xstr(a) str(a)
typedef enum {
UNKNOWN,
CHROMEOS,
AOSP,
ELF32,
ELF64,
GZIP,
LZOP,
XZ,
LZMA,
BZIP2,
LZ4,
LZ4_LEGACY,
MTK
} file_t;
extern char *SUP_LIST[];
extern char *SUP_EXT_LIST[];
extern file_t SUP_TYPE_LIST[];
@ -54,25 +35,26 @@ extern file_t SUP_TYPE_LIST[];
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(unsigned char *orig, size_t size);
int parse_img(void *orig, size_t size);
int cpio_commands(const char *command, int argc, char *argv[]);
void cleanup();
// Compressions
void gzip(int mode, const char* filename, const unsigned char* buf, size_t size);
void lzma(int mode, const char* filename, const unsigned char* buf, size_t size);
void lz4(int mode, const char* filename, const unsigned char* buf, size_t size);
void bzip2(int mode, const char* filename, const unsigned char* buf, size_t size);
void lz4_legacy(int mode, const char* filename, const unsigned char* buf, size_t size);
int comp(file_t type, const char *to, const unsigned char *from, size_t size);
void gzip(int mode, const char* filename, const void *buf, size_t size);
void lzma(int mode, const char* filename, const void *buf, size_t size);
void lz4(int mode, const char* filename, const void *buf, size_t size);
void bzip2(int mode, const char* filename, const void *buf, size_t size);
void lz4_legacy(int mode, const char* filename, const void *buf, size_t size);
int comp(file_t type, const char *to, const void *from, size_t size);
void comp_file(const char *method, const char *from, const char *to);
int decomp(file_t type, const char *to, const unsigned char *from, size_t size);
int decomp(file_t type, const char *to, const void *from, size_t size);
void decomp_file(char *from, const char *to);
// Utils
void mmap_ro(const char *filename, unsigned char **buf, size_t *size);
void mmap_rw(const char *filename, unsigned char **buf, size_t *size);
file_t check_type(const unsigned char *buf);
void mmap_ro(const char *filename, void **buf, size_t *size);
void mmap_rw(const char *filename, void **buf, size_t *size);
file_t check_type(const void *buf);
void get_type_name(file_t type, char *name);
void write_zero(int fd, size_t size);
void mem_align(size_t *pos, size_t align);
void file_align(int fd, size_t align, int out);

View File

@ -67,7 +67,7 @@ int main(int argc, char *argv[]) {
} else if (argc > 2 && strcmp(argv[1], "--sha1") == 0) {
char sha1[21], *buf;
size_t size;
mmap_ro(argv[2], (unsigned char **) &buf, &size);
mmap_ro(argv[2], (void **) &buf, &size);
SHA1(sha1, buf, size);
for (int i = 0; i < 20; ++i)
printf("%02x", sha1[i]);