Cleanup magiskboot
This commit is contained in:
parent
76f81ece62
commit
727abbea8f
@ -4,12 +4,23 @@ include $(CLEAR_VARS)
|
|||||||
LOCAL_MODULE := magiskboot
|
LOCAL_MODULE := magiskboot
|
||||||
LOCAL_STATIC_LIBRARIES := libz liblzma liblz4 libbz2
|
LOCAL_STATIC_LIBRARIES := libz liblzma liblz4 libbz2
|
||||||
LOCAL_C_INCLUDES := \
|
LOCAL_C_INCLUDES := \
|
||||||
|
jni/utils \
|
||||||
jni/ndk-compression/zlib/ \
|
jni/ndk-compression/zlib/ \
|
||||||
jni/ndk-compression/xz/src/liblzma/api/ \
|
jni/ndk-compression/xz/src/liblzma/api/ \
|
||||||
jni/ndk-compression/lz4/lib/ \
|
jni/ndk-compression/lz4/lib/ \
|
||||||
jni/ndk-compression/bzip2/
|
jni/ndk-compression/bzip2/
|
||||||
|
|
||||||
LOCAL_SRC_FILES := main.c unpack.c repack.c hexpatch.c parseimg.c compress.c utils.c cpio.c sha1.c
|
LOCAL_SRC_FILES := \
|
||||||
|
main.c \
|
||||||
|
unpack.c \
|
||||||
|
repack.c \
|
||||||
|
hexpatch.c \
|
||||||
|
parseimg.c \
|
||||||
|
compress.c \
|
||||||
|
utils.c \
|
||||||
|
cpio.c \
|
||||||
|
sha1.c \
|
||||||
|
../utils/vector.c
|
||||||
LOCAL_CFLAGS += -DZLIB_CONST
|
LOCAL_CFLAGS += -DZLIB_CONST
|
||||||
include $(BUILD_EXECUTABLE)
|
include $(BUILD_EXECUTABLE)
|
||||||
|
|
||||||
|
@ -556,7 +556,7 @@ void comp_file(const char *method, const char *from, const char *to) {
|
|||||||
} else if (strcmp(method, "bzip2") == 0) {
|
} else if (strcmp(method, "bzip2") == 0) {
|
||||||
type = BZIP2;
|
type = BZIP2;
|
||||||
} else {
|
} else {
|
||||||
error(1, "Only support following methods: " SUP_LIST);
|
error(1, "Only support following methods: ");
|
||||||
}
|
}
|
||||||
unsigned char *file;
|
unsigned char *file;
|
||||||
size_t size;
|
size_t size;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "magiskboot.h"
|
#include "magiskboot.h"
|
||||||
#include "cpio.h"
|
#include "cpio.h"
|
||||||
|
#include "vector.h"
|
||||||
|
|
||||||
static uint32_t x8u(char *hex) {
|
static uint32_t x8u(char *hex) {
|
||||||
uint32_t val, inpos = 8, outpos;
|
uint32_t val, inpos = 8, outpos;
|
||||||
@ -25,13 +26,13 @@ static void cpio_free(cpio_file *f) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cpio_vec_insert(vector *v, cpio_file *n) {
|
static void cpio_vec_insert(struct vector *v, cpio_file *n) {
|
||||||
cpio_file *f, *t;
|
cpio_file *f, *t;
|
||||||
int shift = 0;
|
int shift = 0;
|
||||||
// Insert in alphabet order
|
// Insert in alphabet order
|
||||||
vec_for_each(v, f) {
|
vec_for_each(v, f) {
|
||||||
if (shift) {
|
if (shift) {
|
||||||
vec_entry(v)[_i] = t;
|
vec_entry(v)[_] = t;
|
||||||
t = f;
|
t = f;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -39,11 +40,11 @@ static void cpio_vec_insert(vector *v, cpio_file *n) {
|
|||||||
if (strcmp(f->filename, n->filename) == 0) {
|
if (strcmp(f->filename, n->filename) == 0) {
|
||||||
// Replace, then all is done
|
// Replace, then all is done
|
||||||
cpio_free(f);
|
cpio_free(f);
|
||||||
vec_entry(v)[_i] = n;
|
vec_entry(v)[_] = n;
|
||||||
return;
|
return;
|
||||||
} else if (strcmp(f->filename, n->filename) > 0) {
|
} else if (strcmp(f->filename, n->filename) > 0) {
|
||||||
// Insert, then start shifting
|
// Insert, then start shifting
|
||||||
vec_entry(v)[_i] = n;
|
vec_entry(v)[_] = n;
|
||||||
t = f;
|
t = f;
|
||||||
shift = 1;
|
shift = 1;
|
||||||
}
|
}
|
||||||
@ -59,7 +60,7 @@ static int cpio_compare(const void *a, const void *b) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Parse cpio file to a vector of cpio_file
|
// Parse cpio file to a vector of cpio_file
|
||||||
static void parse_cpio(const char *filename, vector *v) {
|
static void parse_cpio(const char *filename, struct vector *v) {
|
||||||
printf("Loading cpio: [%s]\n\n", filename);
|
printf("Loading cpio: [%s]\n\n", filename);
|
||||||
int fd = open(filename, O_RDONLY);
|
int fd = open(filename, O_RDONLY);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
@ -104,7 +105,7 @@ static void parse_cpio(const char *filename, vector *v) {
|
|||||||
vec_sort(v, cpio_compare);
|
vec_sort(v, cpio_compare);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dump_cpio(const char *filename, vector *v) {
|
static void dump_cpio(const char *filename, struct vector *v) {
|
||||||
printf("\nDump cpio: [%s]\n\n", filename);
|
printf("\nDump cpio: [%s]\n\n", filename);
|
||||||
int fd = open_new(filename);
|
int fd = open_new(filename);
|
||||||
unsigned inode = 300000;
|
unsigned inode = 300000;
|
||||||
@ -143,7 +144,7 @@ static void dump_cpio(const char *filename, vector *v) {
|
|||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cpio_vec_destroy(vector *v) {
|
static void cpio_vec_destroy(struct vector *v) {
|
||||||
// Free each cpio_file
|
// Free each cpio_file
|
||||||
cpio_file *f;
|
cpio_file *f;
|
||||||
vec_for_each(v, f) {
|
vec_for_each(v, f) {
|
||||||
@ -152,7 +153,7 @@ static void cpio_vec_destroy(vector *v) {
|
|||||||
vec_destroy(v);
|
vec_destroy(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cpio_rm(int recursive, const char *entry, vector *v) {
|
static void cpio_rm(int recursive, const char *entry, struct vector *v) {
|
||||||
cpio_file *f;
|
cpio_file *f;
|
||||||
vec_for_each(v, f) {
|
vec_for_each(v, f) {
|
||||||
if ((recursive && strncmp(f->filename, entry, strlen(entry)) == 0)
|
if ((recursive && strncmp(f->filename, entry, strlen(entry)) == 0)
|
||||||
@ -166,7 +167,7 @@ static void cpio_rm(int recursive, const char *entry, vector *v) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cpio_mkdir(mode_t mode, const char *entry, vector *v) {
|
static void cpio_mkdir(mode_t mode, const char *entry, struct vector *v) {
|
||||||
cpio_file *f = calloc(sizeof(*f), 1);
|
cpio_file *f = calloc(sizeof(*f), 1);
|
||||||
f->mode = S_IFDIR | mode;
|
f->mode = S_IFDIR | mode;
|
||||||
f->namesize = strlen(entry) + 1;
|
f->namesize = strlen(entry) + 1;
|
||||||
@ -176,7 +177,7 @@ static void cpio_mkdir(mode_t mode, const char *entry, vector *v) {
|
|||||||
printf("Create directory [%s] (%04o)\n",entry, mode);
|
printf("Create directory [%s] (%04o)\n",entry, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cpio_add(mode_t mode, const char *entry, const char *filename, vector *v) {
|
static void cpio_add(mode_t mode, const char *entry, const char *filename, struct vector *v) {
|
||||||
int fd = open(filename, O_RDONLY);
|
int fd = open(filename, O_RDONLY);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
error(1, "Cannot open %s", filename);
|
error(1, "Cannot open %s", filename);
|
||||||
@ -194,7 +195,7 @@ static void cpio_add(mode_t mode, const char *entry, const char *filename, vecto
|
|||||||
printf("Add entry [%s] (%04o)\n", entry, mode);
|
printf("Add entry [%s] (%04o)\n", entry, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cpio_test(vector *v) {
|
static void cpio_test(struct vector *v) {
|
||||||
#define MAGISK_PATCH 0x1
|
#define MAGISK_PATCH 0x1
|
||||||
#define SUPERSU_PATCH 0x2
|
#define SUPERSU_PATCH 0x2
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
@ -221,7 +222,7 @@ static int check_verity_pattern(const char *s) {
|
|||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cpio_dmverity(vector *v) {
|
static void cpio_dmverity(struct vector *v) {
|
||||||
cpio_file *f;
|
cpio_file *f;
|
||||||
size_t read, write;
|
size_t read, write;
|
||||||
int skip;
|
int skip;
|
||||||
@ -243,7 +244,7 @@ static void cpio_dmverity(vector *v) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cpio_forceencrypt(vector *v) {
|
static void cpio_forceencrypt(struct vector *v) {
|
||||||
cpio_file *f;
|
cpio_file *f;
|
||||||
size_t read, write;
|
size_t read, write;
|
||||||
#define ENCRYPT_LIST_SIZE 2
|
#define ENCRYPT_LIST_SIZE 2
|
||||||
@ -267,7 +268,7 @@ static void cpio_forceencrypt(vector *v) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cpio_extract(const char *entry, const char *filename, vector *v) {
|
static void cpio_extract(const char *entry, const char *filename, struct vector *v) {
|
||||||
cpio_file *f;
|
cpio_file *f;
|
||||||
vec_for_each(v, f) {
|
vec_for_each(v, f) {
|
||||||
if (strcmp(f->filename, entry) == 0 && S_ISREG(f->mode)) {
|
if (strcmp(f->filename, entry) == 0 && S_ISREG(f->mode)) {
|
||||||
@ -283,8 +284,8 @@ static void cpio_extract(const char *entry, const char *filename, vector *v) {
|
|||||||
error(1, "Cannot find the file entry [%s]", entry);
|
error(1, "Cannot find the file entry [%s]", entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cpio_backup(const char *orig, vector *v) {
|
static void cpio_backup(const char *orig, struct vector *v) {
|
||||||
vector o_body, *o = &o_body, bak;
|
struct vector o_body, *o = &o_body, bak;
|
||||||
cpio_file *m, *n, *dir, *rem;
|
cpio_file *m, *n, *dir, *rem;
|
||||||
char chk1[21], chk2[21], buf[PATH_MAX];
|
char chk1[21], chk2[21], buf[PATH_MAX];
|
||||||
int res, doBak;
|
int res, doBak;
|
||||||
@ -329,14 +330,14 @@ static void cpio_backup(const char *orig, vector *v) {
|
|||||||
// Something is missing in new ramdisk, backup!
|
// Something is missing in new ramdisk, backup!
|
||||||
++i;
|
++i;
|
||||||
doBak = 1;
|
doBak = 1;
|
||||||
printf("Entry [%s] is missing\n", m->filename);
|
printf("Backup missing entry: ");
|
||||||
} else if (res == 0) {
|
} else if (res == 0) {
|
||||||
++i; ++j;
|
++i; ++j;
|
||||||
if (m->filesize == n->filesize && memcmp(m->data, n->data, m->filesize) == 0)
|
if (m->filesize == n->filesize && memcmp(m->data, n->data, m->filesize) == 0)
|
||||||
continue;
|
continue;
|
||||||
// Not the same!
|
// Not the same!
|
||||||
doBak = 1;
|
doBak = 1;
|
||||||
printf("Entry [%s] missmatch\n", m->filename);
|
printf("Backup mismatch entry: ");
|
||||||
} else {
|
} else {
|
||||||
// Someting new in ramdisk, record in rem
|
// Someting new in ramdisk, record in rem
|
||||||
++j;
|
++j;
|
||||||
@ -344,13 +345,14 @@ static void cpio_backup(const char *orig, vector *v) {
|
|||||||
rem->data = realloc(rem->data, rem->filesize + n->namesize);
|
rem->data = realloc(rem->data, rem->filesize + n->namesize);
|
||||||
memcpy(rem->data + rem->filesize, n->filename, n->namesize);
|
memcpy(rem->data + rem->filesize, n->filename, n->namesize);
|
||||||
rem->filesize += n->namesize;
|
rem->filesize += n->namesize;
|
||||||
printf("Entry [%s] is new\n", n->filename);
|
printf("Record new entry: [%s] -> [.backup/.rmlist]\n", n->filename);
|
||||||
}
|
}
|
||||||
if (doBak) {
|
if (doBak) {
|
||||||
m->namesize += 8;
|
m->namesize += 8;
|
||||||
m->filename = realloc(m->filename, m->namesize);
|
m->filename = realloc(m->filename, m->namesize);
|
||||||
strcpy(buf, m->filename);
|
strcpy(buf, m->filename);
|
||||||
sprintf(m->filename, ".backup/%s", buf);
|
sprintf(m->filename, ".backup/%s", buf);
|
||||||
|
printf("[%s] -> [%s]\n", buf, m->filename);
|
||||||
vec_push_back(&bak, m);
|
vec_push_back(&bak, m);
|
||||||
// NULL the original entry, so it won't be freed
|
// NULL the original entry, so it won't be freed
|
||||||
vec_entry(o)[i - 1] = NULL;
|
vec_entry(o)[i - 1] = NULL;
|
||||||
@ -376,7 +378,7 @@ static void cpio_backup(const char *orig, vector *v) {
|
|||||||
cpio_vec_destroy(o);
|
cpio_vec_destroy(o);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cpio_restore(vector *v) {
|
static int cpio_restore(struct vector *v) {
|
||||||
cpio_file *f, *n;
|
cpio_file *f, *n;
|
||||||
int ret = 1;
|
int ret = 1;
|
||||||
vec_for_each(v, f) {
|
vec_for_each(v, f) {
|
||||||
@ -441,7 +443,7 @@ int cpio_commands(const char *command, int argc, char *argv[]) {
|
|||||||
cmd = NONE;
|
cmd = NONE;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
vector v;
|
struct vector v;
|
||||||
vec_init(&v);
|
vec_init(&v);
|
||||||
parse_cpio(incpio, &v);
|
parse_cpio(incpio, &v);
|
||||||
switch(cmd) {
|
switch(cmd) {
|
||||||
|
@ -1,151 +0,0 @@
|
|||||||
|
|
||||||
#ifndef _ELF_H_
|
|
||||||
#define _ELF_H_
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
** ELF structure
|
|
||||||
**
|
|
||||||
** +-----------------+
|
|
||||||
** | ELF magic | | 4 bytes
|
|
||||||
** +------------ +
|
|
||||||
** | ELF class | | 1 byte
|
|
||||||
** +------------ +
|
|
||||||
** | ELF header |
|
|
||||||
** +-----------------+
|
|
||||||
** ~
|
|
||||||
** +-----------------+
|
|
||||||
** | program header | kernel info
|
|
||||||
** +-----------------+
|
|
||||||
** | program header | ramdisk info
|
|
||||||
** +-----------------+
|
|
||||||
** | program header | dtb info
|
|
||||||
** +-----------------+
|
|
||||||
** | program header | (possible) cmdline info
|
|
||||||
** +-----------------+
|
|
||||||
** ~
|
|
||||||
** +-----------------+
|
|
||||||
** | section header | cmdline info
|
|
||||||
** +-----------------+
|
|
||||||
** ~
|
|
||||||
** +-----------------+
|
|
||||||
** | |
|
|
||||||
** | Data |
|
|
||||||
** | |
|
|
||||||
** +-----------------+
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef uint32_t elf32_addr;
|
|
||||||
typedef uint16_t elf32_half;
|
|
||||||
typedef uint32_t elf32_off;
|
|
||||||
typedef uint32_t elf32_word;
|
|
||||||
|
|
||||||
typedef uint64_t elf64_addr;
|
|
||||||
typedef uint16_t elf64_half;
|
|
||||||
typedef uint64_t elf64_off;
|
|
||||||
typedef uint32_t elf64_word;
|
|
||||||
typedef uint64_t elf64_xword;
|
|
||||||
|
|
||||||
#define ELF_MAGIC "\x7f""ELF"
|
|
||||||
#define ELF_MAGIC_SIZE 4
|
|
||||||
|
|
||||||
#define EI_CLASS 4
|
|
||||||
#define EI_DATA 5
|
|
||||||
#define EI_VERSION 6
|
|
||||||
#define EI_OSABI 7
|
|
||||||
#define EI_PAD 8
|
|
||||||
|
|
||||||
#define ELFCLASSNONE 0
|
|
||||||
#define ELFCLASS32 1
|
|
||||||
#define ELFCLASS64 2
|
|
||||||
#define ELFCLASSNUM 3
|
|
||||||
|
|
||||||
#define ET_EXEC 2
|
|
||||||
#define EM_ARM 40
|
|
||||||
#define EI_NIDENT 16
|
|
||||||
|
|
||||||
typedef struct elf32_ehdr {
|
|
||||||
unsigned char e_ident[EI_NIDENT];
|
|
||||||
elf32_half e_type;
|
|
||||||
elf32_half e_machine;
|
|
||||||
elf32_word e_version;
|
|
||||||
elf32_addr e_entry; /* Entry point */
|
|
||||||
elf32_off e_phoff;
|
|
||||||
elf32_off e_shoff;
|
|
||||||
elf32_word e_flags;
|
|
||||||
elf32_half e_ehsize;
|
|
||||||
elf32_half e_phentsize;
|
|
||||||
elf32_half e_phnum;
|
|
||||||
elf32_half e_shentsize;
|
|
||||||
elf32_half e_shnum;
|
|
||||||
elf32_half e_shstrndx;
|
|
||||||
} elf32_ehdr;
|
|
||||||
|
|
||||||
typedef struct elf64_ehdr {
|
|
||||||
unsigned char e_ident[EI_NIDENT]; /* ELF "magic number" */
|
|
||||||
elf64_half e_type;
|
|
||||||
elf64_half e_machine;
|
|
||||||
elf64_word e_version;
|
|
||||||
elf64_addr e_entry; /* Entry point virtual address */
|
|
||||||
elf64_off e_phoff; /* Program header table file offset */
|
|
||||||
elf64_off e_shoff; /* Section header table file offset */
|
|
||||||
elf64_word e_flags;
|
|
||||||
elf64_half e_ehsize;
|
|
||||||
elf64_half e_phentsize;
|
|
||||||
elf64_half e_phnum;
|
|
||||||
elf64_half e_shentsize;
|
|
||||||
elf64_half e_shnum;
|
|
||||||
elf64_half e_shstrndx;
|
|
||||||
} elf64_ehdr;
|
|
||||||
|
|
||||||
typedef struct elf32_phdr {
|
|
||||||
elf32_word p_type;
|
|
||||||
elf32_off p_offset;
|
|
||||||
elf32_addr p_vaddr;
|
|
||||||
elf32_addr p_paddr;
|
|
||||||
elf32_word p_filesz;
|
|
||||||
elf32_word p_memsz;
|
|
||||||
elf32_word p_flags;
|
|
||||||
elf32_word p_align;
|
|
||||||
} elf32_phdr;
|
|
||||||
|
|
||||||
typedef struct elf64_phdr {
|
|
||||||
elf64_word p_type;
|
|
||||||
elf64_word p_flags;
|
|
||||||
elf64_off p_offset; /* Segment file offset */
|
|
||||||
elf64_addr p_vaddr; /* Segment virtual address */
|
|
||||||
elf64_addr p_paddr; /* Segment physical address */
|
|
||||||
elf64_xword p_filesz; /* Segment size in file */
|
|
||||||
elf64_xword p_memsz; /* Segment size in memory */
|
|
||||||
elf64_xword p_align; /* Segment alignment, file & memory */
|
|
||||||
} elf64_phdr;
|
|
||||||
|
|
||||||
typedef struct elf32_shdr {
|
|
||||||
elf32_word s_name;
|
|
||||||
elf32_word s_type;
|
|
||||||
elf32_word s_flags;
|
|
||||||
elf32_addr s_addr;
|
|
||||||
elf32_off s_offset;
|
|
||||||
elf32_word s_size;
|
|
||||||
elf32_word s_link;
|
|
||||||
elf32_word s_info;
|
|
||||||
elf32_word s_addralign;
|
|
||||||
elf32_word s_entsize;
|
|
||||||
} elf32_shdr;
|
|
||||||
|
|
||||||
typedef struct elf64_shdr {
|
|
||||||
elf64_word s_name; /* Section name, index in string tbl */
|
|
||||||
elf64_word s_type; /* Type of section */
|
|
||||||
elf64_xword s_flags; /* Miscellaneous section attributes */
|
|
||||||
elf64_addr s_addr; /* Section virtual addr at execution */
|
|
||||||
elf64_off s_offset; /* Section file offset */
|
|
||||||
elf64_xword s_size; /* Size of section in bytes */
|
|
||||||
elf64_word s_link; /* Index of another section */
|
|
||||||
elf64_word s_info; /* Additional section information */
|
|
||||||
elf64_xword s_addralign; /* Section alignment */
|
|
||||||
elf64_xword s_entsize; /* Entry size if section holds table */
|
|
||||||
} elf64_shdr;
|
|
||||||
|
|
||||||
#endif
|
|
@ -17,7 +17,8 @@
|
|||||||
#include "sha1.h"
|
#include "sha1.h"
|
||||||
|
|
||||||
#define CHROMEOS_MAGIC "CHROMEOS"
|
#define CHROMEOS_MAGIC "CHROMEOS"
|
||||||
#define CHROMEOS_MAGIC_SIZE 8
|
#define ELF32_MAGIC "\x7f""ELF\x01"
|
||||||
|
#define ELF64_MAGIC "\x7f""ELF\x02"
|
||||||
|
|
||||||
#define KERNEL_FILE "kernel"
|
#define KERNEL_FILE "kernel"
|
||||||
#define RAMDISK_FILE "ramdisk.cpio"
|
#define RAMDISK_FILE "ramdisk.cpio"
|
||||||
@ -25,11 +26,15 @@
|
|||||||
#define DTB_FILE "dtb"
|
#define DTB_FILE "dtb"
|
||||||
#define NEW_BOOT "new-boot.img"
|
#define NEW_BOOT "new-boot.img"
|
||||||
|
|
||||||
|
#define str(a) #a
|
||||||
|
#define xstr(a) str(a)
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
UNKNOWN,
|
UNKNOWN,
|
||||||
CHROMEOS,
|
CHROMEOS,
|
||||||
AOSP,
|
AOSP,
|
||||||
ELF,
|
ELF32,
|
||||||
|
ELF64,
|
||||||
GZIP,
|
GZIP,
|
||||||
LZOP,
|
LZOP,
|
||||||
XZ,
|
XZ,
|
||||||
@ -37,8 +42,7 @@ typedef enum {
|
|||||||
BZIP2,
|
BZIP2,
|
||||||
LZ4,
|
LZ4,
|
||||||
LZ4_LEGACY,
|
LZ4_LEGACY,
|
||||||
MTK,
|
MTK
|
||||||
QCDT,
|
|
||||||
} file_t;
|
} file_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@ -54,38 +58,14 @@ typedef enum {
|
|||||||
RESTORE
|
RESTORE
|
||||||
} command_t;
|
} command_t;
|
||||||
|
|
||||||
#define SUP_LIST "gzip, xz, lzma, bzip2, lz4, lz4_legacy"
|
extern char *SUP_LIST[];
|
||||||
#define SUP_NUM 6
|
extern char *SUP_EXT_LIST[];
|
||||||
|
extern file_t SUP_TYPE_LIST[];
|
||||||
// Cannot declare in header, but place a copy here for convenience
|
|
||||||
// char *SUP_EXT_LIST[SUP_NUM] = { "gz", "xz", "lzma", "bz2", "lz4", "lz4" };
|
|
||||||
// file_t SUP_TYPE_LIST[SUP_NUM] = { GZIP, XZ, LZMA, BZIP2, LZ4, LZ4_LEGACY };
|
|
||||||
extern char *SUP_EXT_LIST[SUP_NUM];
|
|
||||||
extern file_t SUP_TYPE_LIST[SUP_NUM];
|
|
||||||
|
|
||||||
// Vector
|
|
||||||
typedef struct vector {
|
|
||||||
size_t size;
|
|
||||||
size_t cap;
|
|
||||||
void **data;
|
|
||||||
} vector;
|
|
||||||
void vec_init(vector *v);
|
|
||||||
void vec_push_back(vector *v, void *p);
|
|
||||||
void vec_sort(vector *v, int (*compar)(const void *, const void *));
|
|
||||||
void vec_destroy(vector *v);
|
|
||||||
|
|
||||||
#define vec_size(v) (v)->size
|
|
||||||
#define vec_cap(v) (v)->cap
|
|
||||||
#define vec_entry(v) (v)->data
|
|
||||||
// vec_for_each(vector *v, void *e)
|
|
||||||
#define vec_for_each(v, e) \
|
|
||||||
e = (v)->data[0]; \
|
|
||||||
for (size_t _i = 0; _i < (v)->size; ++_i, e = (v)->data[_i])
|
|
||||||
|
|
||||||
// Global variables
|
// Global variables
|
||||||
extern unsigned char *kernel, *ramdisk, *second, *dtb, *extra;
|
extern unsigned char *kernel, *ramdisk, *second, *dtb, *extra;
|
||||||
extern boot_img_hdr hdr;
|
extern boot_img_hdr hdr;
|
||||||
extern file_t boot_type, ramdisk_type, dtb_type;
|
extern file_t ramdisk_type;
|
||||||
extern int mtk_kernel, mtk_ramdisk;
|
extern int mtk_kernel, mtk_ramdisk;
|
||||||
|
|
||||||
// Main entries
|
// Main entries
|
||||||
|
@ -5,50 +5,55 @@
|
|||||||
*********************/
|
*********************/
|
||||||
|
|
||||||
static void usage(char *arg0) {
|
static void usage(char *arg0) {
|
||||||
fprintf(stderr, "%s --unpack <bootimg>\n", arg0);
|
fprintf(stderr,
|
||||||
fprintf(stderr, " Unpack <bootimg> to kernel, ramdisk.cpio, (second), (dtb) into the\n current directory\n");
|
"%s --unpack <bootimg>\n"
|
||||||
fprintf(stderr, "\n");
|
" Unpack <bootimg> to kernel, ramdisk.cpio, (second), (dtb) into the\n current directory\n"
|
||||||
|
"\n"
|
||||||
fprintf(stderr, "%s --repack <origbootimg> [outbootimg]\n", arg0);
|
"%s --repack <origbootimg> [outbootimg]\n"
|
||||||
fprintf(stderr, " Repack kernel, ramdisk.cpio[.ext], second, dtb... from current directory\n");
|
" Repack kernel, ramdisk.cpio[.ext], second, dtb... from current directory\n"
|
||||||
fprintf(stderr, " to [outbootimg], or new-boot.img if not specified.\n");
|
" to [outbootimg], or new-boot.img if not specified.\n"
|
||||||
fprintf(stderr, " It will compress ramdisk.cpio with the same method used in <origbootimg>\n");
|
" It will compress ramdisk.cpio with the same method used in <origbootimg>\n"
|
||||||
fprintf(stderr, " if exists, or attempt to find ramdisk.cpio.[ext], and repack\n");
|
" if exists, or attempt to find ramdisk.cpio.[ext], and repack\n"
|
||||||
fprintf(stderr, " directly with the compressed ramdisk file\n");
|
" directly with the compressed ramdisk file\n"
|
||||||
fprintf(stderr, "\n");
|
"\n"
|
||||||
|
"%s --hexpatch <file> <hexpattern1> <hexpattern2>\n"
|
||||||
fprintf(stderr, "%s --hexpatch <file> <hexpattern1> <hexpattern2>\n", arg0);
|
" Search <hexpattern1> in <file>, and replace with <hexpattern2>\n"
|
||||||
fprintf(stderr, " Search <hexpattern1> in <file>, and replace with <hexpattern2>\n");
|
"\n"
|
||||||
fprintf(stderr, "\n");
|
"%s --cpio-<cmd> <incpio> [flags...] [params...]\n"
|
||||||
|
" Do cpio related cmds to <incpio> (modifications are done directly)\n Supported commands:\n"
|
||||||
fprintf(stderr, "%s --cpio-<cmd> <incpio> [flags...] [params...]\n", arg0);
|
" --cpio-rm <incpio> [-r] <entry>\n Remove entry from cpio, flag -r to remove recursively\n"
|
||||||
fprintf(stderr, " Do cpio related cmds to <incpio> (modifications are done directly)\n Supported commands:\n");
|
" --cpio-mkdir <incpio> <mode> <entry>\n Create directory as an <entry>\n"
|
||||||
fprintf(stderr, " --cpio-rm <incpio> [-r] <entry>\n Remove entry from cpio, flag -r to remove recursively\n");
|
" --cpio-add <incpio> <mode> <entry> <infile>\n Add <infile> as an <entry>; replaces <entry> if already exists\n"
|
||||||
fprintf(stderr, " --cpio-mkdir <incpio> <mode> <entry>\n Create directory as an <entry>\n");
|
" --cpio-extract <incpio> <entry> <outfile>\n Extract <entry> to <outfile>\n"
|
||||||
fprintf(stderr, " --cpio-add <incpio> <mode> <entry> <infile>\n Add <infile> as an <entry>; replaces <entry> if already exists\n");
|
" --cpio-test <incpio>\n Return value: 0/not patched 1/Magisk 2/SuperSU\n"
|
||||||
fprintf(stderr, " --cpio-extract <incpio> <entry> <outfile>\n Extract <entry> to <outfile>\n");
|
" --cpio-patch-dmverity <incpio>\n Remove dm-verity\n"
|
||||||
fprintf(stderr, " --cpio-test <incpio>\n Return value: 0/not patched 1/Magisk 2/SuperSU\n");
|
" --cpio-patch-forceencrypt <incpio>\n Change forceencrypt flag to encryptable\n"
|
||||||
fprintf(stderr, " --cpio-patch-dmverity <incpio>\n Remove dm-verity\n");
|
" --cpio-backup <incpio> <origcpio>\n Create ramdisk backups into <incpio> from <origcpio>\n"
|
||||||
fprintf(stderr, " --cpio-patch-forceencrypt <incpio>\n Change forceencrypt flag to encryptable\n");
|
" --cpio-restore <incpio>\n Restore ramdisk from ramdisk backup within <incpio>\n"
|
||||||
fprintf(stderr, " --cpio-backup <incpio> <origcpio>\n Create ramdisk backups into <incpio> from <origcpio>\n");
|
"\n"
|
||||||
fprintf(stderr, " --cpio-restore <incpio>\n Restore ramdisk from ramdisk backup within <incpio>\n");
|
"%s --compress[=method] <infile> [outfile]\n"
|
||||||
fprintf(stderr, "\n");
|
" Compress <infile> with [method] (default: gzip), optionally to [outfile]\n Supported methods: "
|
||||||
|
, arg0, arg0, arg0, arg0, arg0);
|
||||||
fprintf(stderr, "%s --compress[=method] <infile> [outfile]\n", arg0);
|
for (int i = 0; SUP_LIST[i]; ++i)
|
||||||
fprintf(stderr, " Compress <infile> with [method] (default: gzip), optionally to [outfile]\n Supported methods: " SUP_LIST "\n");
|
fprintf(stderr, "%s ", SUP_LIST[i]);
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr,
|
||||||
|
"\n"
|
||||||
fprintf(stderr, "%s --decompress <infile> [outfile]\n", arg0);
|
"\n"
|
||||||
fprintf(stderr, " Detect method and decompress <infile>, optionally to [outfile]\n Supported methods: " SUP_LIST "\n");
|
"%s --decompress <infile> [outfile]\n"
|
||||||
fprintf(stderr, "\n");
|
" Detect method and decompress <infile>, optionally to [outfile]\n Supported methods: "
|
||||||
|
, arg0);
|
||||||
fprintf(stderr, "%s --sha1 <file>\n", arg0);
|
for (int i = 0; SUP_LIST[i]; ++i)
|
||||||
fprintf(stderr, " Print the SHA1 checksum for <file>\n");
|
fprintf(stderr, "%s ", SUP_LIST[i]);
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr,
|
||||||
|
"\n"
|
||||||
fprintf(stderr, "%s --cleanup\n", arg0);
|
"\n"
|
||||||
fprintf(stderr, " Cleanup the current working directory\n");
|
"%s --sha1 <file>\n"
|
||||||
fprintf(stderr, "\n");
|
" Print the SHA1 checksum for <file>\n"
|
||||||
|
"\n"
|
||||||
|
"%s --cleanup\n"
|
||||||
|
" Cleanup the current working directory\n"
|
||||||
|
"\n"
|
||||||
|
, arg0, arg0);
|
||||||
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
@ -63,7 +68,7 @@ void error(int rc, const char *msg, ...) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
printf("MagiskBoot (by topjohnwu) - Boot Image Modification Tool\n\n");
|
printf("MagiskBoot v" xstr(MAGISK_VERSION) " (by topjohnwu) - Boot Image Modification Tool\n\n");
|
||||||
|
|
||||||
if (argc > 1 && strcmp(argv[1], "--cleanup") == 0) {
|
if (argc > 1 && strcmp(argv[1], "--cleanup") == 0) {
|
||||||
cleanup();
|
cleanup();
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
#include "bootimg.h"
|
#include "bootimg.h"
|
||||||
#include "elf.h"
|
|
||||||
#include "magiskboot.h"
|
#include "magiskboot.h"
|
||||||
|
|
||||||
unsigned char *kernel, *ramdisk, *second, *dtb, *extra;
|
unsigned char *kernel, *ramdisk, *second, *dtb, *extra;
|
||||||
boot_img_hdr hdr;
|
boot_img_hdr hdr;
|
||||||
int mtk_kernel = 0, mtk_ramdisk = 0;
|
int mtk_kernel = 0, mtk_ramdisk = 0;
|
||||||
file_t boot_type, ramdisk_type, dtb_type;
|
file_t ramdisk_type;
|
||||||
|
|
||||||
static void check_headers() {
|
static void check_headers() {
|
||||||
// Check ramdisk compression type
|
// Check ramdisk compression type
|
||||||
@ -22,174 +21,13 @@ static void check_headers() {
|
|||||||
ramdisk_type = check_type(ramdisk + 512);
|
ramdisk_type = check_type(ramdisk + 512);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check dtb if ELF boot
|
|
||||||
if (boot_type == ELF && hdr.dt_size) {
|
|
||||||
dtb_type = check_type(dtb);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Print info
|
// Print info
|
||||||
print_info();
|
print_info();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void elf_header_check(void *elf, int is64) {
|
|
||||||
|
|
||||||
size_t e_size, mach, ver, p_size, p_num, s_size, s_num;
|
|
||||||
size_t r_e_size, r_p_size, r_s_size;
|
|
||||||
|
|
||||||
if (is64) {
|
|
||||||
e_size = ((elf64_ehdr *) elf)->e_ehsize;
|
|
||||||
mach = ((elf64_ehdr *) elf)->e_machine;
|
|
||||||
ver = ((elf64_ehdr *) elf)->e_version;
|
|
||||||
p_size = ((elf64_ehdr *) elf)->e_phentsize;
|
|
||||||
p_num = ((elf64_ehdr *) elf)->e_phnum;
|
|
||||||
s_size = ((elf64_ehdr *) elf)->e_shentsize;
|
|
||||||
s_num = ((elf64_ehdr *) elf)->e_shnum;
|
|
||||||
r_e_size = sizeof(elf64_ehdr);
|
|
||||||
r_p_size = sizeof(elf64_phdr);
|
|
||||||
r_s_size = sizeof(elf64_shdr);
|
|
||||||
} else {
|
|
||||||
e_size = ((elf32_ehdr *) elf)->e_ehsize;
|
|
||||||
mach = ((elf32_ehdr *) elf)->e_machine;
|
|
||||||
ver = ((elf32_ehdr *) elf)->e_version;
|
|
||||||
p_size = ((elf32_ehdr *) elf)->e_phentsize;
|
|
||||||
p_num = ((elf32_ehdr *) elf)->e_phnum;
|
|
||||||
s_size = ((elf32_ehdr *) elf)->e_shentsize;
|
|
||||||
s_num = ((elf32_ehdr *) elf)->e_shnum;
|
|
||||||
r_e_size = sizeof(elf32_ehdr);
|
|
||||||
r_p_size = sizeof(elf32_phdr);
|
|
||||||
r_s_size = sizeof(elf32_shdr);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (e_size != r_e_size)
|
|
||||||
error(1, "Header size not %d", r_e_size);
|
|
||||||
|
|
||||||
if (mach != EM_ARM)
|
|
||||||
error(1, "ELF machine is not ARM");
|
|
||||||
|
|
||||||
if (ver != 1)
|
|
||||||
error(1, "Unknown ELF version");
|
|
||||||
|
|
||||||
if (p_size != r_p_size)
|
|
||||||
error(1, "Program header size not %d", r_p_size);
|
|
||||||
|
|
||||||
if (p_num < 2 || p_num > 4)
|
|
||||||
error(1, "Unexpected number of elements: %d", p_num);
|
|
||||||
|
|
||||||
if (s_num && s_size != r_s_size)
|
|
||||||
error(1, "Section header size not %d", r_s_size);
|
|
||||||
|
|
||||||
if (s_num > 1)
|
|
||||||
error(1, "More than one section header");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void elf_set(int i, unsigned char *base, size_t size, size_t offset, size_t addr) {
|
|
||||||
if (size <= 4096) {
|
|
||||||
// Possible cmdline
|
|
||||||
memset(hdr.cmdline, 0, BOOT_ARGS_SIZE);
|
|
||||||
strncpy((char *) hdr.cmdline, (char *) (base + offset), BOOT_ARGS_SIZE);
|
|
||||||
hdr.cmdline[strcspn((char*) hdr.cmdline, "\n")] = '\0';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
switch(i) {
|
|
||||||
case 0:
|
|
||||||
// kernel
|
|
||||||
kernel = base + offset;
|
|
||||||
hdr.kernel_size = size;
|
|
||||||
hdr.kernel_addr = addr;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
// ramdisk
|
|
||||||
ramdisk = base + offset;
|
|
||||||
hdr.ramdisk_size = size;
|
|
||||||
hdr.ramdisk_addr = addr;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
// dtb
|
|
||||||
dtb = base + offset;
|
|
||||||
hdr.dt_size = size;
|
|
||||||
hdr.tags_addr = addr;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void parse_elf(unsigned char *base) {
|
|
||||||
|
|
||||||
// Reset boot image header
|
|
||||||
memset(&hdr, 0, sizeof(hdr));
|
|
||||||
|
|
||||||
// Hardcode header magic and pagesize
|
|
||||||
memcpy(hdr.magic, BOOT_MAGIC, BOOT_MAGIC_SIZE);
|
|
||||||
hdr.page_size = 4096;
|
|
||||||
|
|
||||||
switch(base[EI_CLASS]) {
|
|
||||||
|
|
||||||
case ELFCLASS32: {
|
|
||||||
|
|
||||||
elf32_ehdr *elf32;
|
|
||||||
elf32_phdr *ph32;
|
|
||||||
elf32_shdr *sh32;
|
|
||||||
|
|
||||||
printf("IMAGE [ELF32]\n");
|
|
||||||
|
|
||||||
elf32 = (elf32_ehdr *) base;
|
|
||||||
|
|
||||||
elf_header_check(elf32, 0);
|
|
||||||
|
|
||||||
ph32 = (elf32_phdr *) (base + elf32->e_phoff);
|
|
||||||
sh32 = (elf32_shdr *) (base + elf32->e_shoff);
|
|
||||||
|
|
||||||
for (int i = 0; i < elf32->e_phnum; ++i) {
|
|
||||||
elf_set(i, base, ph32[i].p_filesz, ph32[i].p_offset, ph32[i].p_paddr);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (elf32->e_shnum) {
|
|
||||||
// cmdline
|
|
||||||
memset(hdr.cmdline, 0, BOOT_ARGS_SIZE);
|
|
||||||
strncpy((char *) hdr.cmdline, (char *) (base + sh32->s_offset + 8), BOOT_ARGS_SIZE);
|
|
||||||
hdr.cmdline[strcspn((char*) hdr.cmdline, "\n")] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case ELFCLASS64: {
|
|
||||||
|
|
||||||
elf64_ehdr *elf64;
|
|
||||||
elf64_phdr *ph64;
|
|
||||||
elf64_shdr *sh64;
|
|
||||||
|
|
||||||
printf("IMAGE [ELF64]\n");
|
|
||||||
|
|
||||||
elf64 = (elf64_ehdr *) base;
|
|
||||||
|
|
||||||
elf_header_check(elf64, 1);
|
|
||||||
|
|
||||||
ph64 = (elf64_phdr *) (base + elf64->e_phoff);
|
|
||||||
sh64 = (elf64_shdr *) (base + elf64->e_shoff);
|
|
||||||
|
|
||||||
for (int i = 0; i < elf64->e_phnum; ++i) {
|
|
||||||
elf_set(i, base, ph64[i].p_filesz, ph64[i].p_offset, ph64[i].p_paddr);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (elf64->e_shnum) {
|
|
||||||
// cmdline
|
|
||||||
memset(hdr.cmdline, 0, BOOT_ARGS_SIZE);
|
|
||||||
strncpy((char *) hdr.cmdline, (char *) (base + sh64->s_offset + 8), BOOT_ARGS_SIZE);
|
|
||||||
hdr.cmdline[strcspn((char*) hdr.cmdline, "\n")] = '\0';
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
error(1, "ELF format error!");
|
|
||||||
}
|
|
||||||
|
|
||||||
check_headers();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void parse_aosp(unsigned char *base, size_t size) {
|
static void parse_aosp(unsigned char *base, size_t size) {
|
||||||
|
|
||||||
printf("IMG [AOSP]\n");
|
// printf("IMG [AOSP]\n");
|
||||||
|
|
||||||
size_t pos = 0;
|
size_t pos = 0;
|
||||||
|
|
||||||
@ -233,17 +71,17 @@ void parse_img(unsigned char *orig, size_t size) {
|
|||||||
for(base = orig, end = orig + size; base < end; base += 256, size -= 256) {
|
for(base = orig, end = orig + size; base < end; base += 256, size -= 256) {
|
||||||
switch (check_type(base)) {
|
switch (check_type(base)) {
|
||||||
case CHROMEOS:
|
case CHROMEOS:
|
||||||
boot_type = CHROMEOS;
|
// The caller should know it's chromeos, as it needs additional signing
|
||||||
|
close(open_new("chromeos"));
|
||||||
continue;
|
continue;
|
||||||
case AOSP:
|
case ELF32:
|
||||||
// Don't override CHROMEOS
|
exit(2);
|
||||||
if (boot_type != CHROMEOS)
|
|
||||||
boot_type = AOSP;
|
|
||||||
parse_aosp(base, size);
|
|
||||||
return;
|
return;
|
||||||
case ELF:
|
case ELF64:
|
||||||
boot_type = ELF;
|
exit(3);
|
||||||
parse_elf(base);
|
return;
|
||||||
|
case AOSP:
|
||||||
|
parse_aosp(base, size);
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
continue;
|
continue;
|
||||||
|
@ -69,7 +69,7 @@ void repack(const char* orig_image, const char* out_image) {
|
|||||||
// If we found raw cpio, compress to original format
|
// If we found raw cpio, compress to original format
|
||||||
|
|
||||||
// Before we start, clean up previous compressed files
|
// Before we start, clean up previous compressed files
|
||||||
for (int i = 0; i < SUP_NUM; ++i) {
|
for (int i = 0; SUP_EXT_LIST[i]; ++i) {
|
||||||
sprintf(name, "%s.%s", RAMDISK_FILE, SUP_EXT_LIST[i]);
|
sprintf(name, "%s.%s", RAMDISK_FILE, SUP_EXT_LIST[i]);
|
||||||
unlink(name);
|
unlink(name);
|
||||||
}
|
}
|
||||||
@ -85,7 +85,7 @@ void repack(const char* orig_image, const char* out_image) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int found = 0;
|
int found = 0;
|
||||||
for (int i = 0; i < SUP_NUM; ++i) {
|
for (int i = 0; SUP_EXT_LIST[i]; ++i) {
|
||||||
sprintf(name, "%s.%s", RAMDISK_FILE, SUP_EXT_LIST[i]);
|
sprintf(name, "%s.%s", RAMDISK_FILE, SUP_EXT_LIST[i]);
|
||||||
if (access(name, R_OK) == 0) {
|
if (access(name, R_OK) == 0) {
|
||||||
ramdisk_type = SUP_TYPE_LIST[i];
|
ramdisk_type = SUP_TYPE_LIST[i];
|
||||||
|
@ -16,11 +16,6 @@ void unpack(const char* image) {
|
|||||||
printf("Parsing boot image: [%s]\n\n", image);
|
printf("Parsing boot image: [%s]\n\n", image);
|
||||||
parse_img(orig, size);
|
parse_img(orig, size);
|
||||||
|
|
||||||
if (boot_type == CHROMEOS) {
|
|
||||||
// The caller should know it's chromeos, as it needs additional signing
|
|
||||||
dump(orig, 0, "chromeos");
|
|
||||||
}
|
|
||||||
|
|
||||||
char name[PATH_MAX];
|
char name[PATH_MAX];
|
||||||
|
|
||||||
// Dump kernel
|
// Dump kernel
|
||||||
@ -47,17 +42,9 @@ void unpack(const char* image) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (hdr.dt_size) {
|
if (hdr.dt_size) {
|
||||||
if (boot_type == ELF && (dtb_type != QCDT && dtb_type != ELF)) {
|
|
||||||
printf("Non QC dtb found in ELF kernel, recreate kernel\n");
|
|
||||||
gzip(1, KERNEL_FILE, kernel, hdr.kernel_size);
|
|
||||||
int kfp = open(KERNEL_FILE, O_WRONLY | O_APPEND);
|
|
||||||
write(kfp, dtb, hdr.dt_size);
|
|
||||||
close(kfp);
|
|
||||||
} else {
|
|
||||||
// Dump dtb
|
// Dump dtb
|
||||||
dump(dtb, hdr.dt_size, DTB_FILE);
|
dump(dtb, hdr.dt_size, DTB_FILE);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
munmap(orig, size);
|
munmap(orig, size);
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
#include "magiskboot.h"
|
#include "magiskboot.h"
|
||||||
#include "elf.h"
|
|
||||||
|
|
||||||
char *SUP_EXT_LIST[SUP_NUM] = { "gz", "xz", "lzma", "bz2", "lz4", "lz4" };
|
char *SUP_LIST[] = { "gzip", "xz", "lzma", "bzip2", "lz4", "lz4_legacy", NULL };
|
||||||
file_t SUP_TYPE_LIST[SUP_NUM] = { GZIP, XZ, LZMA, BZIP2, LZ4, LZ4_LEGACY };
|
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, unsigned char **buf, size_t *size) {
|
||||||
int fd = open(filename, O_RDONLY);
|
int fd = open(filename, O_RDONLY);
|
||||||
@ -25,12 +25,14 @@ void mmap_rw(const char *filename, unsigned char **buf, size_t *size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
file_t check_type(const unsigned char *buf) {
|
file_t check_type(const unsigned char *buf) {
|
||||||
if (memcmp(buf, CHROMEOS_MAGIC, CHROMEOS_MAGIC_SIZE) == 0) {
|
if (memcmp(buf, CHROMEOS_MAGIC, 8) == 0) {
|
||||||
return CHROMEOS;
|
return CHROMEOS;
|
||||||
} else if (memcmp(buf, BOOT_MAGIC, BOOT_MAGIC_SIZE) == 0) {
|
} else if (memcmp(buf, BOOT_MAGIC, BOOT_MAGIC_SIZE) == 0) {
|
||||||
return AOSP;
|
return AOSP;
|
||||||
} else if (memcmp(buf, ELF_MAGIC, ELF_MAGIC_SIZE) == 0) {
|
} else if (memcmp(buf, ELF32_MAGIC, 5) == 0) {
|
||||||
return ELF;
|
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, "\x1f\x8b\x08\x00", 4) == 0) {
|
||||||
return GZIP;
|
return GZIP;
|
||||||
} else if (memcmp(buf, "\x89\x4c\x5a\x4f\x00\x0d\x0a\x1a\x0a", 9) == 0) {
|
} else if (memcmp(buf, "\x89\x4c\x5a\x4f\x00\x0d\x0a\x1a\x0a", 9) == 0) {
|
||||||
@ -48,8 +50,6 @@ file_t check_type(const unsigned char *buf) {
|
|||||||
return LZ4_LEGACY;
|
return LZ4_LEGACY;
|
||||||
} else if (memcmp(buf, "\x88\x16\x88\x58", 4) == 0) {
|
} else if (memcmp(buf, "\x88\x16\x88\x58", 4) == 0) {
|
||||||
return MTK;
|
return MTK;
|
||||||
} else if (memcmp(buf, "QCDT", 4) == 0) {
|
|
||||||
return QCDT;
|
|
||||||
} else {
|
} else {
|
||||||
return UNKNOWN;
|
return UNKNOWN;
|
||||||
}
|
}
|
||||||
@ -147,36 +147,8 @@ void cleanup() {
|
|||||||
unlink(SECOND_FILE);
|
unlink(SECOND_FILE);
|
||||||
unlink(DTB_FILE);
|
unlink(DTB_FILE);
|
||||||
unlink(NEW_BOOT);
|
unlink(NEW_BOOT);
|
||||||
for (int i = 0; i < SUP_NUM; ++i) {
|
for (int i = 0; SUP_EXT_LIST[i]; ++i) {
|
||||||
sprintf(name, "%s.%s", RAMDISK_FILE, SUP_EXT_LIST[i]);
|
sprintf(name, "%s.%s", RAMDISK_FILE, SUP_EXT_LIST[i]);
|
||||||
unlink(name);
|
unlink(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void vec_init(vector *v) {
|
|
||||||
vec_size(v) = 0;
|
|
||||||
vec_cap(v) = 1;
|
|
||||||
vec_entry(v) = malloc(sizeof(void*));
|
|
||||||
}
|
|
||||||
|
|
||||||
void vec_push_back(vector *v, void *p) {
|
|
||||||
if (v == NULL) return;
|
|
||||||
if (vec_size(v) == vec_cap(v)) {
|
|
||||||
vec_cap(v) *= 2;
|
|
||||||
vec_entry(v) = realloc(vec_entry(v), sizeof(void*) * vec_cap(v));
|
|
||||||
}
|
|
||||||
vec_entry(v)[vec_size(v)] = p;
|
|
||||||
++vec_size(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
void vec_sort(vector *v, int (*compar)(const void *, const void *)) {
|
|
||||||
qsort(vec_entry(v), vec_size(v), sizeof(void*), compar);
|
|
||||||
}
|
|
||||||
|
|
||||||
void vec_destroy(vector *v) {
|
|
||||||
// Will not free each entry!
|
|
||||||
// Manually free each entry, then call this function
|
|
||||||
vec_size(v) = 0;
|
|
||||||
vec_cap(v) = 0;
|
|
||||||
free(v->data);
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user