mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-12-25 08:27:43 +00:00
Separate utility functions
This commit is contained in:
parent
9f91c8b59d
commit
c6d4740b0c
@ -4,14 +4,16 @@ include $(CLEAR_VARS)
|
|||||||
LOCAL_MODULE := magiskboot
|
LOCAL_MODULE := magiskboot
|
||||||
LOCAL_STATIC_LIBRARIES := liblzma liblz4 libbz2
|
LOCAL_STATIC_LIBRARIES := liblzma liblz4 libbz2
|
||||||
LOCAL_C_INCLUDES := \
|
LOCAL_C_INCLUDES := \
|
||||||
|
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
|
LOCAL_SRC_FILES := main.c unpack.c repack.c hexpatch.c parseimg.c compress.c utils.c cpio.c
|
||||||
LOCAL_LDLIBS += -lz
|
LOCAL_LDLIBS += -lz
|
||||||
include $(BUILD_EXECUTABLE)
|
include $(BUILD_EXECUTABLE)
|
||||||
|
|
||||||
|
include jni/ndk-compression/zlib/Android.mk
|
||||||
include jni/ndk-compression/xz/src/liblzma/Android.mk
|
include jni/ndk-compression/xz/src/liblzma/Android.mk
|
||||||
include jni/ndk-compression/lz4/lib/Android.mk
|
include jni/ndk-compression/lz4/lib/Android.mk
|
||||||
include jni/ndk-compression/bzip2/Android.mk
|
include jni/ndk-compression/bzip2/Android.mk
|
||||||
|
@ -5,13 +5,6 @@
|
|||||||
|
|
||||||
#include "magiskboot.h"
|
#include "magiskboot.h"
|
||||||
|
|
||||||
static int open_new(const char *filename) {
|
|
||||||
int fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0644);
|
|
||||||
if (fd < 0)
|
|
||||||
error(1, "Unable to create %s", filename);
|
|
||||||
return fd;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void write_file(const int fd, const void *buf, const size_t size, const char *filename) {
|
static void write_file(const int fd, const void *buf, const size_t size, const char *filename) {
|
||||||
if (write(fd, buf, size) != size)
|
if (write(fd, buf, size) != size)
|
||||||
error(1, "Error in writing %s", filename);
|
error(1, "Error in writing %s", filename);
|
||||||
@ -29,7 +22,7 @@ static void report(const int mode, const char* filename) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Mode: 0 = decode; 1 = encode
|
// Mode: 0 = decode; 1 = encode
|
||||||
void gzip(int mode, const char* filename, unsigned char* buf, size_t size) {
|
void gzip(int mode, const char* filename, const unsigned char* buf, size_t size) {
|
||||||
size_t ret = 0, flush, have, pos = 0;
|
size_t ret = 0, flush, have, pos = 0;
|
||||||
z_stream strm;
|
z_stream strm;
|
||||||
unsigned char out[CHUNK];
|
unsigned char out[CHUNK];
|
||||||
@ -100,7 +93,7 @@ void gzip(int mode, const char* filename, unsigned char* buf, size_t size) {
|
|||||||
|
|
||||||
|
|
||||||
// Mode: 0 = decode xz/lzma; 1 = encode xz; 2 = encode lzma
|
// Mode: 0 = decode xz/lzma; 1 = encode xz; 2 = encode lzma
|
||||||
void lzma(int mode, const char* filename, unsigned char* buf, size_t size) {
|
void lzma(int mode, const char* filename, const unsigned char* buf, size_t size) {
|
||||||
size_t have, pos = 0;
|
size_t have, pos = 0;
|
||||||
lzma_ret ret = 0;
|
lzma_ret ret = 0;
|
||||||
lzma_stream strm = LZMA_STREAM_INIT;
|
lzma_stream strm = LZMA_STREAM_INIT;
|
||||||
@ -164,7 +157,7 @@ void lzma(int mode, const char* filename, unsigned char* buf, size_t size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Mode: 0 = decode; 1 = encode
|
// Mode: 0 = decode; 1 = encode
|
||||||
void lz4(int mode, const char* filename, unsigned char* buf, size_t size) {
|
void lz4(int mode, const char* filename, const unsigned char* buf, size_t size) {
|
||||||
LZ4F_decompressionContext_t dctx;
|
LZ4F_decompressionContext_t dctx;
|
||||||
LZ4F_compressionContext_t cctx;
|
LZ4F_compressionContext_t cctx;
|
||||||
LZ4F_frameInfo_t info;
|
LZ4F_frameInfo_t info;
|
||||||
@ -275,7 +268,7 @@ void lz4(int mode, const char* filename, unsigned char* buf, size_t size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Mode: 0 = decode; 1 = encode
|
// Mode: 0 = decode; 1 = encode
|
||||||
void bzip2(int mode, const char* filename, unsigned char* buf, size_t size) {
|
void bzip2(int mode, const char* filename, const unsigned char* buf, size_t size) {
|
||||||
size_t ret = 0, action, have, pos = 0;
|
size_t ret = 0, action, have, pos = 0;
|
||||||
bz_stream strm;
|
bz_stream strm;
|
||||||
char out[CHUNK];
|
char out[CHUNK];
|
||||||
@ -342,7 +335,7 @@ void bzip2(int mode, const char* filename, unsigned char* buf, size_t size) {
|
|||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
int decomp(file_t type, const char *to, unsigned char *from, size_t size) {
|
int decomp(file_t type, const char *to, const unsigned char *from, size_t size) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case GZIP:
|
case GZIP:
|
||||||
gzip(0, to, from, size);
|
gzip(0, to, from, size);
|
||||||
@ -366,7 +359,7 @@ int decomp(file_t type, const char *to, unsigned char *from, size_t size) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int comp(file_t type, const char *to, unsigned char *from, size_t size) {
|
int comp(file_t type, const char *to, const unsigned char *from, size_t size) {
|
||||||
char name[PATH_MAX];
|
char name[PATH_MAX];
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case GZIP:
|
case GZIP:
|
||||||
|
@ -14,7 +14,7 @@ static unsigned hex2ascii(char c, char d) {
|
|||||||
return high + low;
|
return high + low;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void hexstr2str(char *hex, unsigned char *str) {
|
static void hexstr2str(const char *hex, unsigned char *str) {
|
||||||
char buf = 0;
|
char buf = 0;
|
||||||
for(int i = 0, length = strlen(hex); i < length; ++i){
|
for(int i = 0, length = strlen(hex); i < length; ++i){
|
||||||
if(i % 2){
|
if(i % 2){
|
||||||
@ -25,12 +25,11 @@ static void hexstr2str(char *hex, unsigned char *str) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void hexpatch(char * image, char *from, char *to) {
|
void hexpatch(const char *image, const char *from, const char *to) {
|
||||||
int fd = open(image, O_RDWR), patternsize = strlen(from) / 2, patchsize = strlen(to) / 2;
|
int patternsize = strlen(from) / 2, patchsize = strlen(to) / 2;
|
||||||
size_t filesize = lseek(fd, 0, SEEK_END);
|
size_t filesize;
|
||||||
lseek(fd, 0, SEEK_SET);
|
|
||||||
unsigned char *file, *pattern, *patch;
|
unsigned char *file, *pattern, *patch;
|
||||||
file = mmap(NULL, filesize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
mmap_rw(image, &file, &filesize);
|
||||||
pattern = malloc(patternsize);
|
pattern = malloc(patternsize);
|
||||||
patch = malloc(patchsize);
|
patch = malloc(patchsize);
|
||||||
hexstr2str(from, pattern);
|
hexstr2str(from, pattern);
|
||||||
@ -46,5 +45,4 @@ void hexpatch(char * image, char *from, char *to) {
|
|||||||
munmap(file, filesize);
|
munmap(file, filesize);
|
||||||
free(pattern);
|
free(pattern);
|
||||||
free(patch);
|
free(patch);
|
||||||
close(fd);
|
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ typedef enum {
|
|||||||
} file_t;
|
} file_t;
|
||||||
|
|
||||||
// Global variables
|
// Global variables
|
||||||
extern unsigned char *base, *kernel, *ramdisk, *second, *dtb;
|
extern unsigned char *kernel, *ramdisk, *second, *dtb;
|
||||||
extern boot_img_hdr hdr;
|
extern boot_img_hdr hdr;
|
||||||
extern file_t boot_type, ramdisk_type, dtb_type;
|
extern file_t boot_type, ramdisk_type, dtb_type;
|
||||||
extern int mtk_kernel, mtk_ramdisk;
|
extern int mtk_kernel, mtk_ramdisk;
|
||||||
@ -53,17 +53,25 @@ extern int mtk_kernel, mtk_ramdisk;
|
|||||||
// Main entries
|
// Main entries
|
||||||
void unpack(const char *image);
|
void unpack(const char *image);
|
||||||
void repack(const char *image);
|
void repack(const char *image);
|
||||||
void hexpatch(char *image, char *from, char *to);
|
void hexpatch(const char *image, const char *from, const char *to);
|
||||||
|
void cpio(const char *filename);
|
||||||
void error(int rc, const char *msg, ...);
|
void error(int rc, const char *msg, ...);
|
||||||
void parse_img(unsigned char *orig, size_t size);
|
void parse_img(unsigned char *orig, size_t size);
|
||||||
file_t check_type(unsigned char *buf);
|
|
||||||
|
|
||||||
// Compressions
|
// Compressions
|
||||||
void gzip(int mode, const char* filename, unsigned char* buf, size_t size);
|
void gzip(int mode, const char* filename, const unsigned char* buf, size_t size);
|
||||||
void lzma(int mode, const char* filename, 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, 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, unsigned char* buf, size_t size);
|
void bzip2(int mode, const char* filename, const unsigned char* buf, size_t size);
|
||||||
int comp(file_t type, const char *to, unsigned char *from, size_t size);
|
int comp(file_t type, const char *to, const unsigned char *from, size_t size);
|
||||||
int decomp(file_t type, const char *to, unsigned char *from, size_t size);
|
int decomp(file_t type, const char *to, const unsigned char *from, size_t size);
|
||||||
|
|
||||||
|
// 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 mem_align(size_t *pos, size_t align);
|
||||||
|
void file_align(int fd, size_t align);
|
||||||
|
int open_new(const char *filename);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,49 +1,12 @@
|
|||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "bootimg.h"
|
#include "bootimg.h"
|
||||||
#include "elf.h"
|
#include "elf.h"
|
||||||
#include "magiskboot.h"
|
#include "magiskboot.h"
|
||||||
|
|
||||||
unsigned char *base, *kernel, *ramdisk, *second, *dtb;
|
unsigned char *kernel, *ramdisk, *second, *dtb;
|
||||||
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 boot_type, ramdisk_type, dtb_type;
|
||||||
|
|
||||||
file_t check_type(unsigned char *buf) {
|
|
||||||
if (memcmp(buf, CHROMEOS_MAGIC, CHROMEOS_MAGIC_SIZE) == 0) {
|
|
||||||
return CHROMEOS;
|
|
||||||
} else if (memcmp(buf, BOOT_MAGIC, BOOT_MAGIC_SIZE) == 0) {
|
|
||||||
return AOSP;
|
|
||||||
} else if (memcmp(buf, ELF_MAGIC, ELF_MAGIC_SIZE) == 0) {
|
|
||||||
return ELF;
|
|
||||||
} else if (memcmp(buf, "\x1f\x8b\x08\x00", 4) == 0) {
|
|
||||||
return GZIP;
|
|
||||||
} else if (memcmp(buf, "\x89\x4c\x5a\x4f\x00\x0d\x0a\x1a\x0a", 9) == 0) {
|
|
||||||
return LZOP;
|
|
||||||
} else if (memcmp(buf, "\xfd""7zXZ\x00", 6) == 0) {
|
|
||||||
return XZ;
|
|
||||||
} else if (memcmp(buf, "\x5d\x00\x00", 3) == 0
|
|
||||||
&& (buf[12] == (unsigned char) '\xff' || buf[12] == (unsigned char) '\x00')) {
|
|
||||||
return LZMA;
|
|
||||||
} else if (memcmp(buf, "BZh", 3) == 0) {
|
|
||||||
return BZIP2;
|
|
||||||
} else if ( ( memcmp(buf, "\x04\x22\x4d\x18", 4) == 0
|
|
||||||
|| memcmp(buf, "\x03\x21\x4c\x18", 4) == 0)
|
|
||||||
|| memcmp(buf, "\x02\x21\x4c\x18", 4) == 0) {
|
|
||||||
return LZ4;
|
|
||||||
} else if (memcmp(buf, "\x88\x16\x88\x58", 4) == 0) {
|
|
||||||
return MTK;
|
|
||||||
} else if (memcmp(buf, "QCDT", 4) == 0) {
|
|
||||||
return QCDT;
|
|
||||||
} else {
|
|
||||||
return UNKNOWN;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void check_headers() {
|
static void check_headers() {
|
||||||
printf("KERNEL [%d] @ 0x%08x\n", hdr.kernel_size, hdr.kernel_addr);
|
printf("KERNEL [%d] @ 0x%08x\n", hdr.kernel_size, hdr.kernel_addr);
|
||||||
printf("RAMDISK [%d] @ 0x%08x\n", hdr.ramdisk_size, hdr.ramdisk_addr);
|
printf("RAMDISK [%d] @ 0x%08x\n", hdr.ramdisk_size, hdr.ramdisk_addr);
|
||||||
@ -109,13 +72,6 @@ static void check_headers() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void page_align(unsigned char **pos) {
|
|
||||||
uint32_t itemsize = *pos - base, pagemask = hdr.page_size - 1L;
|
|
||||||
if (itemsize & pagemask) {
|
|
||||||
*pos += hdr.page_size - (itemsize & pagemask);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void elf_header_check(void *elf, int is64) {
|
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 e_size, mach, ver, p_size, p_num, s_size, s_num;
|
||||||
@ -167,7 +123,7 @@ static void elf_header_check(void *elf, int is64) {
|
|||||||
error(1, "More than one section header");
|
error(1, "More than one section header");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void elf_set(int i, size_t size, size_t offset, size_t addr) {
|
static void elf_set(int i, unsigned char *base, size_t size, size_t offset, size_t addr) {
|
||||||
if (size <= 4096) {
|
if (size <= 4096) {
|
||||||
// Possible cmdline
|
// Possible cmdline
|
||||||
memset(hdr.cmdline, 0, BOOT_ARGS_SIZE);
|
memset(hdr.cmdline, 0, BOOT_ARGS_SIZE);
|
||||||
@ -197,7 +153,7 @@ static void elf_set(int i, size_t size, size_t offset, size_t addr) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void parse_elf() {
|
static void parse_elf(unsigned char *base) {
|
||||||
|
|
||||||
// Reset boot image header
|
// Reset boot image header
|
||||||
memset(&hdr, 0, sizeof(hdr));
|
memset(&hdr, 0, sizeof(hdr));
|
||||||
@ -224,7 +180,7 @@ static void parse_elf() {
|
|||||||
sh32 = (elf32_shdr *) (base + elf32->e_shoff);
|
sh32 = (elf32_shdr *) (base + elf32->e_shoff);
|
||||||
|
|
||||||
for (int i = 0; i < elf32->e_phnum; ++i) {
|
for (int i = 0; i < elf32->e_phnum; ++i) {
|
||||||
elf_set(i, ph32[i].p_filesz, ph32[i].p_offset, ph32[i].p_paddr);
|
elf_set(i, base, ph32[i].p_filesz, ph32[i].p_offset, ph32[i].p_paddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (elf32->e_shnum) {
|
if (elf32->e_shnum) {
|
||||||
@ -253,7 +209,7 @@ static void parse_elf() {
|
|||||||
sh64 = (elf64_shdr *) (base + elf64->e_shoff);
|
sh64 = (elf64_shdr *) (base + elf64->e_shoff);
|
||||||
|
|
||||||
for (int i = 0; i < elf64->e_phnum; ++i) {
|
for (int i = 0; i < elf64->e_phnum; ++i) {
|
||||||
elf_set(i, ph64[i].p_filesz, ph64[i].p_offset, ph64[i].p_paddr);
|
elf_set(i, base, ph64[i].p_filesz, ph64[i].p_offset, ph64[i].p_paddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (elf64->e_shnum) {
|
if (elf64->e_shnum) {
|
||||||
@ -272,44 +228,45 @@ static void parse_elf() {
|
|||||||
check_headers();
|
check_headers();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void parse_aosp() {
|
static void parse_aosp(unsigned char *base) {
|
||||||
|
|
||||||
printf("IMG [AOSP]\n");
|
printf("IMG [AOSP]\n");
|
||||||
|
|
||||||
unsigned char *pos = base;
|
size_t pos = 0;
|
||||||
|
|
||||||
// Read the header
|
// Read the header
|
||||||
memcpy(&hdr, pos, sizeof(hdr));
|
memcpy(&hdr, base, sizeof(hdr));
|
||||||
pos += hdr.page_size;
|
pos += hdr.page_size;
|
||||||
|
|
||||||
// Kernel position
|
// Kernel position
|
||||||
kernel = pos;
|
kernel = base + pos;
|
||||||
pos += hdr.kernel_size;
|
pos += hdr.kernel_size;
|
||||||
page_align(&pos);
|
mem_align(&pos, hdr.page_size);
|
||||||
|
|
||||||
// Ramdisk position
|
// Ramdisk position
|
||||||
ramdisk = pos;
|
ramdisk = base + pos;
|
||||||
pos += hdr.ramdisk_size;
|
pos += hdr.ramdisk_size;
|
||||||
page_align(&pos);
|
mem_align(&pos, hdr.page_size);
|
||||||
|
|
||||||
if (hdr.second_size) {
|
if (hdr.second_size) {
|
||||||
// Second position
|
// Second position
|
||||||
second = pos;
|
second = base + pos;
|
||||||
pos += hdr.second_size;
|
pos += hdr.second_size;
|
||||||
page_align(&pos);
|
mem_align(&pos, hdr.page_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hdr.dt_size) {
|
if (hdr.dt_size) {
|
||||||
// dtb position
|
// dtb position
|
||||||
dtb = pos;
|
dtb = base + pos;
|
||||||
pos += hdr.dt_size;
|
pos += hdr.dt_size;
|
||||||
page_align(&pos);
|
mem_align(&pos, hdr.page_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
check_headers();
|
check_headers();
|
||||||
}
|
}
|
||||||
|
|
||||||
void parse_img(unsigned char *orig, size_t size) {
|
void parse_img(unsigned char *orig, size_t size) {
|
||||||
|
unsigned char *base;
|
||||||
for(base = orig; base < (orig + size); base += 256) {
|
for(base = orig; base < (orig + size); base += 256) {
|
||||||
switch (check_type(base)) {
|
switch (check_type(base)) {
|
||||||
case CHROMEOS:
|
case CHROMEOS:
|
||||||
@ -319,11 +276,11 @@ void parse_img(unsigned char *orig, size_t size) {
|
|||||||
// Don't override CHROMEOS
|
// Don't override CHROMEOS
|
||||||
if (boot_type != CHROMEOS)
|
if (boot_type != CHROMEOS)
|
||||||
boot_type = AOSP;
|
boot_type = AOSP;
|
||||||
parse_aosp();
|
parse_aosp(base);
|
||||||
return;
|
return;
|
||||||
case ELF:
|
case ELF:
|
||||||
boot_type = ELF;
|
boot_type = ELF;
|
||||||
parse_elf();
|
parse_elf(base);
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
continue;
|
continue;
|
||||||
|
@ -1,61 +1,41 @@
|
|||||||
#include "magiskboot.h"
|
#include "magiskboot.h"
|
||||||
|
|
||||||
// Global pointer of output
|
static size_t restore(const char *filename, int fd) {
|
||||||
static int ofd, opos;
|
int ifd = open(filename, O_RDONLY);
|
||||||
|
if (ifd < 0)
|
||||||
|
error(1, "Cannot open %s\n", filename);
|
||||||
|
|
||||||
static size_t restore(const char *filename) {
|
size_t size = lseek(ifd, 0, SEEK_END);
|
||||||
int fd = open(filename, O_RDONLY);
|
lseek(ifd, 0, SEEK_SET);
|
||||||
if (fd < 0) {
|
if (sendfile(fd, ifd, NULL, size) != size) {
|
||||||
fprintf(stderr, "Cannot open %s\n", filename);
|
error(1, "Cannot write %s\n", filename);
|
||||||
exit(1);
|
|
||||||
}
|
}
|
||||||
size_t size = lseek(fd, 0, SEEK_END);
|
close(ifd);
|
||||||
lseek(fd, 0, SEEK_SET);
|
|
||||||
if (sendfile(ofd, fd, NULL, size) < 0) {
|
|
||||||
fprintf(stderr, "Cannot write %s\n", filename);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
close(fd);
|
|
||||||
opos += size;
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void restore_buf(size_t size, const void *buf) {
|
static void restore_buf(const void *buf, size_t size, int fd) {
|
||||||
if (write(ofd, buf, size) != size) {
|
if (write(fd, buf, size) != size) {
|
||||||
fprintf(stderr, "Cannot dump from input file\n");
|
error(1, "Cannot dump from input file\n");
|
||||||
exit(1);
|
|
||||||
}
|
}
|
||||||
opos += size;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void page_align() {
|
|
||||||
uint32_t pagemask = hdr.page_size - 1L;
|
|
||||||
if (opos & pagemask) {
|
|
||||||
opos += hdr.page_size - (opos & pagemask);
|
|
||||||
}
|
|
||||||
ftruncate(ofd, opos);
|
|
||||||
lseek(ofd, 0, SEEK_END);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void repack(const char* image) {
|
void repack(const char* image) {
|
||||||
// Load original image
|
size_t size;
|
||||||
int ifd = open(image, O_RDONLY);
|
unsigned char *orig;
|
||||||
if (ifd < 0)
|
|
||||||
error(1, "Cannot open %s", image);
|
|
||||||
size_t isize = lseek(ifd, 0, SEEK_END);
|
|
||||||
lseek(ifd, 0, SEEK_SET);
|
|
||||||
unsigned char *orig = mmap(NULL, isize, PROT_READ, MAP_SHARED, ifd, 0);
|
|
||||||
|
|
||||||
// Parse original image
|
|
||||||
parse_img(orig, isize);
|
|
||||||
|
|
||||||
// Create new boot image
|
|
||||||
ofd = open("new-boot.img", O_RDWR | O_CREAT | O_TRUNC, 0644);
|
|
||||||
|
|
||||||
char name[PATH_MAX];
|
char name[PATH_MAX];
|
||||||
#define EXT_NUM 6
|
#define EXT_NUM 6
|
||||||
char *ext_list[EXT_NUM] = { "gz", "lzo", "xz", "lzma", "bz2", "lz4" };
|
char *ext_list[EXT_NUM] = { "gz", "lzo", "xz", "lzma", "bz2", "lz4" };
|
||||||
|
|
||||||
|
// Load original image
|
||||||
|
mmap_ro(image, &orig, &size);
|
||||||
|
|
||||||
|
// Parse original image
|
||||||
|
parse_img(orig, size);
|
||||||
|
|
||||||
|
// Create new image
|
||||||
|
int fd = open_new("new-boot.img");
|
||||||
|
|
||||||
// Set all sizes to 0
|
// Set all sizes to 0
|
||||||
hdr.kernel_size = 0;
|
hdr.kernel_size = 0;
|
||||||
hdr.ramdisk_size = 0;
|
hdr.ramdisk_size = 0;
|
||||||
@ -63,39 +43,33 @@ void repack(const char* image) {
|
|||||||
hdr.dt_size = 0;
|
hdr.dt_size = 0;
|
||||||
|
|
||||||
// Skip a page for header
|
// Skip a page for header
|
||||||
ftruncate(ofd, hdr.page_size);
|
ftruncate(fd, hdr.page_size);
|
||||||
lseek(ofd, 0, SEEK_END);
|
lseek(fd, 0, SEEK_END);
|
||||||
opos += hdr.page_size;
|
|
||||||
|
|
||||||
// Restore kernel
|
// Restore kernel
|
||||||
if (mtk_kernel) {
|
if (mtk_kernel) {
|
||||||
restore_buf(512, kernel);
|
restore_buf(kernel, 512, fd);
|
||||||
hdr.kernel_size += 512;
|
hdr.kernel_size += 512;
|
||||||
}
|
}
|
||||||
hdr.kernel_size += restore(KERNEL_FILE);
|
hdr.kernel_size += restore(KERNEL_FILE, fd);
|
||||||
page_align();
|
file_align(fd, hdr.page_size);
|
||||||
|
|
||||||
// Restore ramdisk
|
// Restore ramdisk
|
||||||
if (mtk_ramdisk) {
|
if (mtk_ramdisk) {
|
||||||
restore_buf(512, ramdisk);
|
restore_buf(ramdisk, 512, fd);
|
||||||
hdr.ramdisk_size += 512;
|
hdr.ramdisk_size += 512;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (access(RAMDISK_FILE, R_OK) == 0) {
|
if (access(RAMDISK_FILE, R_OK) == 0) {
|
||||||
// If we found raw cpio, compress to original format
|
// If we found raw cpio, compress to original format
|
||||||
int rfd = open(RAMDISK_FILE, O_RDONLY);
|
size_t cpio_size;
|
||||||
if (rfd < 0)
|
unsigned char *cpio;
|
||||||
error(1, "Cannot open " RAMDISK_FILE);
|
mmap_ro(RAMDISK_FILE, &cpio, &cpio_size);
|
||||||
|
|
||||||
size_t cpio_size = lseek(rfd, 0, SEEK_END);
|
|
||||||
lseek(rfd, 0, SEEK_SET);
|
|
||||||
unsigned char *cpio = mmap(NULL, cpio_size, PROT_READ, MAP_SHARED, rfd, 0);
|
|
||||||
|
|
||||||
if (comp(ramdisk_type, RAMDISK_FILE, cpio, cpio_size))
|
if (comp(ramdisk_type, RAMDISK_FILE, cpio, cpio_size))
|
||||||
error(1, "Unsupported format! Please compress manually!\n");
|
error(1, "Unsupported format! Please compress manually!");
|
||||||
|
|
||||||
munmap(cpio, cpio_size);
|
munmap(cpio, cpio_size);
|
||||||
close(rfd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int found = 0;
|
int found = 0;
|
||||||
@ -109,29 +83,28 @@ void repack(const char* image) {
|
|||||||
if (!found)
|
if (!found)
|
||||||
error(1, "No ramdisk exists!");
|
error(1, "No ramdisk exists!");
|
||||||
|
|
||||||
hdr.ramdisk_size += restore(name);
|
hdr.ramdisk_size += restore(name, fd);
|
||||||
page_align();
|
file_align(fd, hdr.page_size);
|
||||||
|
|
||||||
// Restore second
|
// Restore second
|
||||||
if (access(SECOND_FILE, R_OK) == 0) {
|
if (access(SECOND_FILE, R_OK) == 0) {
|
||||||
hdr.second_size += restore(SECOND_FILE);
|
hdr.second_size += restore(SECOND_FILE, fd);
|
||||||
page_align();
|
file_align(fd, hdr.page_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Restore dtb
|
// Restore dtb
|
||||||
if (access(DTB_FILE, R_OK) == 0) {
|
if (access(DTB_FILE, R_OK) == 0) {
|
||||||
hdr.dt_size += restore(DTB_FILE);
|
hdr.dt_size += restore(DTB_FILE, fd);
|
||||||
page_align();
|
file_align(fd, hdr.page_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write header back
|
// Write header back
|
||||||
lseek(ofd, 0, SEEK_SET);
|
lseek(fd, 0, SEEK_SET);
|
||||||
write(ofd, &hdr, sizeof(hdr));
|
write(fd, &hdr, sizeof(hdr));
|
||||||
|
|
||||||
munmap(orig, isize);
|
munmap(orig, size);
|
||||||
close(ifd);
|
if (lseek(fd, 0, SEEK_CUR) > size) {
|
||||||
close(ofd);
|
|
||||||
if (opos > isize) {
|
|
||||||
error(2, "Boot partition too small!");
|
error(2, "Boot partition too small!");
|
||||||
}
|
}
|
||||||
|
close(fd);
|
||||||
}
|
}
|
||||||
|
@ -1,29 +1,23 @@
|
|||||||
#include "magiskboot.h"
|
#include "magiskboot.h"
|
||||||
|
|
||||||
static void dump(unsigned char *buf, size_t size, const char *filename) {
|
static void dump(unsigned char *buf, size_t size, const char *filename) {
|
||||||
int ofd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0644);
|
int fd = open_new(filename);
|
||||||
if (ofd < 0)
|
if (write(fd, buf, size) != size)
|
||||||
error(1, "Cannot open %s", filename);
|
|
||||||
if (write(ofd, buf, size) != size)
|
|
||||||
error(1, "Cannot dump %s", filename);
|
error(1, "Cannot dump %s", filename);
|
||||||
close(ofd);
|
close(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void unpack(const char* image) {
|
void unpack(const char* image) {
|
||||||
int fd = open(image, O_RDONLY);
|
size_t size;
|
||||||
if (fd < 0)
|
unsigned char *orig;
|
||||||
error(1, "Cannot open %s", image);
|
mmap_ro(image, &orig, &size);
|
||||||
|
|
||||||
size_t size = lseek(fd, 0, SEEK_END);
|
|
||||||
lseek(fd, 0, SEEK_SET);
|
|
||||||
unsigned char *orig = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
|
|
||||||
|
|
||||||
// Parse image
|
// Parse image
|
||||||
parse_img(orig, size);
|
parse_img(orig, size);
|
||||||
|
|
||||||
if (boot_type == CHROMEOS) {
|
if (boot_type == CHROMEOS) {
|
||||||
// The caller should know it's chromeos, as it needs additional signing
|
// The caller should know it's chromeos, as it needs additional signing
|
||||||
dump(base, 0, "chromeos");
|
dump(orig, 0, "chromeos");
|
||||||
}
|
}
|
||||||
|
|
||||||
char name[PATH_MAX];
|
char name[PATH_MAX];
|
||||||
@ -74,6 +68,5 @@ void unpack(const char* image) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
munmap(orig, size);
|
munmap(orig, size);
|
||||||
close(fd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
77
jni/magiskboot/utils.c
Normal file
77
jni/magiskboot/utils.c
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
#include "magiskboot.h"
|
||||||
|
#include "elf.h"
|
||||||
|
|
||||||
|
void mmap_ro(const char *filename, unsigned char **buf, size_t *size) {
|
||||||
|
int fd = open(filename, O_RDONLY);
|
||||||
|
if (fd < 0)
|
||||||
|
error(1, "Cannot open %s", filename);
|
||||||
|
*size = lseek(fd, 0, SEEK_END);
|
||||||
|
lseek(fd, 0, SEEK_SET);
|
||||||
|
*buf = mmap(NULL, *size, PROT_READ, MAP_SHARED, fd, 0);
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mmap_rw(const char *filename, unsigned char **buf, size_t *size) {
|
||||||
|
int fd = open(filename, O_RDWR);
|
||||||
|
if (fd < 0)
|
||||||
|
error(1, "Cannot open %s", filename);
|
||||||
|
*size = lseek(fd, 0, SEEK_END);
|
||||||
|
lseek(fd, 0, SEEK_SET);
|
||||||
|
*buf = mmap(NULL, *size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
file_t check_type(const unsigned char *buf) {
|
||||||
|
if (memcmp(buf, CHROMEOS_MAGIC, CHROMEOS_MAGIC_SIZE) == 0) {
|
||||||
|
return CHROMEOS;
|
||||||
|
} else if (memcmp(buf, BOOT_MAGIC, BOOT_MAGIC_SIZE) == 0) {
|
||||||
|
return AOSP;
|
||||||
|
} else if (memcmp(buf, ELF_MAGIC, ELF_MAGIC_SIZE) == 0) {
|
||||||
|
return ELF;
|
||||||
|
} else if (memcmp(buf, "\x1f\x8b\x08\x00", 4) == 0) {
|
||||||
|
return GZIP;
|
||||||
|
} else if (memcmp(buf, "\x89\x4c\x5a\x4f\x00\x0d\x0a\x1a\x0a", 9) == 0) {
|
||||||
|
return LZOP;
|
||||||
|
} else if (memcmp(buf, "\xfd""7zXZ\x00", 6) == 0) {
|
||||||
|
return XZ;
|
||||||
|
} else if (memcmp(buf, "\x5d\x00\x00", 3) == 0
|
||||||
|
&& (buf[12] == (unsigned char) '\xff' || buf[12] == (unsigned char) '\x00')) {
|
||||||
|
return LZMA;
|
||||||
|
} else if (memcmp(buf, "BZh", 3) == 0) {
|
||||||
|
return BZIP2;
|
||||||
|
} else if ( ( memcmp(buf, "\x04\x22\x4d\x18", 4) == 0
|
||||||
|
|| memcmp(buf, "\x03\x21\x4c\x18", 4) == 0)
|
||||||
|
|| memcmp(buf, "\x02\x21\x4c\x18", 4) == 0) {
|
||||||
|
return LZ4;
|
||||||
|
} else if (memcmp(buf, "\x88\x16\x88\x58", 4) == 0) {
|
||||||
|
return MTK;
|
||||||
|
} else if (memcmp(buf, "QCDT", 4) == 0) {
|
||||||
|
return QCDT;
|
||||||
|
} else {
|
||||||
|
return UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void mem_align(size_t *pos, size_t align) {
|
||||||
|
size_t mask = align - 1;
|
||||||
|
if (*pos & mask) {
|
||||||
|
*pos += align - (*pos & mask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void file_align(int fd, size_t align) {
|
||||||
|
size_t pos = lseek(fd, 0, SEEK_CUR);
|
||||||
|
size_t mask = align - 1;
|
||||||
|
if (pos & mask) {
|
||||||
|
pos += align - (pos & mask);
|
||||||
|
ftruncate(fd, pos);
|
||||||
|
lseek(fd, 0, SEEK_END);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int open_new(const char *filename) {
|
||||||
|
int fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0644);
|
||||||
|
if (fd < 0)
|
||||||
|
error(1, "Unable to create %s", filename);
|
||||||
|
return fd;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user