2017-02-27 21:37:47 +00:00
|
|
|
#include "magiskboot.h"
|
|
|
|
|
2017-03-04 13:16:59 +00:00
|
|
|
static size_t restore(const char *filename, int fd) {
|
|
|
|
int ifd = open(filename, O_RDONLY);
|
|
|
|
if (ifd < 0)
|
|
|
|
error(1, "Cannot open %s\n", filename);
|
2016-09-08 12:59:48 +00:00
|
|
|
|
2017-03-04 13:16:59 +00:00
|
|
|
size_t size = lseek(ifd, 0, SEEK_END);
|
|
|
|
lseek(ifd, 0, SEEK_SET);
|
|
|
|
if (sendfile(fd, ifd, NULL, size) != size) {
|
|
|
|
error(1, "Cannot write %s\n", filename);
|
2016-09-08 12:59:48 +00:00
|
|
|
}
|
2017-03-04 13:16:59 +00:00
|
|
|
close(ifd);
|
|
|
|
return size;
|
2016-09-08 12:59:48 +00:00
|
|
|
}
|
|
|
|
|
2017-03-12 20:19:30 +00:00
|
|
|
static void restore_buf(int fd, const void *buf, size_t size) {
|
2017-03-04 13:16:59 +00:00
|
|
|
if (write(fd, buf, size) != size) {
|
|
|
|
error(1, "Cannot dump from input file\n");
|
2017-02-23 23:45:48 +00:00
|
|
|
}
|
|
|
|
}
|
2016-09-08 12:59:48 +00:00
|
|
|
|
2017-03-07 16:54:23 +00:00
|
|
|
void repack(const char* orig_image, const char* out_image) {
|
2017-03-12 20:19:30 +00:00
|
|
|
zero = open("/dev/zero", O_RDONLY);
|
|
|
|
if (zero < 0) error(1, "Cannot open /dev/zero");
|
|
|
|
|
2017-03-04 13:16:59 +00:00
|
|
|
size_t size;
|
|
|
|
unsigned char *orig;
|
|
|
|
char name[PATH_MAX];
|
|
|
|
|
2017-03-12 20:19:30 +00:00
|
|
|
// There are possible two MTK headers
|
|
|
|
mtk_hdr mtk_kernel_hdr, mtk_ramdisk_hdr;
|
|
|
|
size_t mtk_kernel_off, mtk_ramdisk_off;
|
|
|
|
|
2017-02-27 21:37:47 +00:00
|
|
|
// Load original image
|
2017-03-07 16:54:23 +00:00
|
|
|
mmap_ro(orig_image, &orig, &size);
|
2017-02-24 19:29:12 +00:00
|
|
|
|
2017-02-27 21:37:47 +00:00
|
|
|
// Parse original image
|
2017-03-09 20:08:17 +00:00
|
|
|
printf("Parsing boot image: [%s]\n\n", orig_image);
|
2017-03-04 13:16:59 +00:00
|
|
|
parse_img(orig, size);
|
2017-02-23 23:45:48 +00:00
|
|
|
|
2017-03-12 20:19:30 +00:00
|
|
|
printf("Repack to boot image: [%s]\n\n", out_image);
|
|
|
|
|
2017-03-04 13:16:59 +00:00
|
|
|
// Create new image
|
2017-03-07 16:54:23 +00:00
|
|
|
int fd = open_new(out_image);
|
2017-02-23 23:45:48 +00:00
|
|
|
|
|
|
|
// Set all sizes to 0
|
|
|
|
hdr.kernel_size = 0;
|
|
|
|
hdr.ramdisk_size = 0;
|
|
|
|
hdr.second_size = 0;
|
|
|
|
hdr.dt_size = 0;
|
|
|
|
|
2017-02-24 19:29:12 +00:00
|
|
|
// Skip a page for header
|
2017-03-12 20:19:30 +00:00
|
|
|
sendfile(fd, zero, NULL, hdr.page_size);
|
2017-02-23 23:45:48 +00:00
|
|
|
|
2017-02-24 19:29:12 +00:00
|
|
|
// Restore kernel
|
2017-02-27 21:37:47 +00:00
|
|
|
if (mtk_kernel) {
|
2017-03-12 20:19:30 +00:00
|
|
|
mtk_kernel_off = lseek(fd, 0, SEEK_CUR);
|
|
|
|
sendfile(fd, zero, NULL, 512);
|
|
|
|
memcpy(&mtk_kernel_hdr, kernel, sizeof(mtk_kernel_hdr));
|
2017-02-23 23:45:48 +00:00
|
|
|
}
|
2017-03-12 20:19:30 +00:00
|
|
|
hdr.kernel_size = restore(KERNEL_FILE, fd);
|
2017-03-07 16:54:23 +00:00
|
|
|
file_align(fd, hdr.page_size, 1);
|
2017-02-23 23:45:48 +00:00
|
|
|
|
2017-02-27 21:37:47 +00:00
|
|
|
// Restore ramdisk
|
|
|
|
if (mtk_ramdisk) {
|
2017-03-12 20:19:30 +00:00
|
|
|
mtk_ramdisk_off = lseek(fd, 0, SEEK_CUR);
|
|
|
|
sendfile(fd, zero, NULL, 512);
|
|
|
|
memcpy(&mtk_ramdisk_hdr, ramdisk, sizeof(mtk_ramdisk_hdr));
|
2017-02-23 23:45:48 +00:00
|
|
|
}
|
2017-02-27 21:37:47 +00:00
|
|
|
if (access(RAMDISK_FILE, R_OK) == 0) {
|
2017-03-02 13:59:37 +00:00
|
|
|
// If we found raw cpio, compress to original format
|
2017-03-04 17:50:36 +00:00
|
|
|
|
|
|
|
// Before we start, clean up previous compressed files
|
|
|
|
for (int i = 0; i < SUP_NUM; ++i) {
|
|
|
|
sprintf(name, "%s.%s", RAMDISK_FILE, SUP_EXT_LIST[i]);
|
|
|
|
unlink(name);
|
|
|
|
}
|
|
|
|
|
2017-03-04 13:16:59 +00:00
|
|
|
size_t cpio_size;
|
|
|
|
unsigned char *cpio;
|
|
|
|
mmap_ro(RAMDISK_FILE, &cpio, &cpio_size);
|
2017-02-27 21:37:47 +00:00
|
|
|
|
2017-03-02 13:59:37 +00:00
|
|
|
if (comp(ramdisk_type, RAMDISK_FILE, cpio, cpio_size))
|
2017-03-04 17:50:36 +00:00
|
|
|
error(1, "Unsupported ramdisk format!");
|
2017-02-27 21:37:47 +00:00
|
|
|
|
|
|
|
munmap(cpio, cpio_size);
|
2017-03-02 13:59:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int found = 0;
|
2017-03-04 17:50:36 +00:00
|
|
|
for (int i = 0; i < SUP_NUM; ++i) {
|
|
|
|
sprintf(name, "%s.%s", RAMDISK_FILE, SUP_EXT_LIST[i]);
|
2017-03-02 13:59:37 +00:00
|
|
|
if (access(name, R_OK) == 0) {
|
2017-03-04 17:50:36 +00:00
|
|
|
ramdisk_type = SUP_TYPE_LIST[i];
|
2017-03-02 13:59:37 +00:00
|
|
|
found = 1;
|
|
|
|
break;
|
2017-02-27 21:37:47 +00:00
|
|
|
}
|
2016-09-08 12:59:48 +00:00
|
|
|
}
|
2017-03-02 13:59:37 +00:00
|
|
|
if (!found)
|
|
|
|
error(1, "No ramdisk exists!");
|
2017-03-12 20:19:30 +00:00
|
|
|
hdr.ramdisk_size = restore(name, fd);
|
2017-03-07 16:54:23 +00:00
|
|
|
file_align(fd, hdr.page_size, 1);
|
2016-09-08 12:59:48 +00:00
|
|
|
|
2017-02-27 21:37:47 +00:00
|
|
|
// Restore second
|
|
|
|
if (access(SECOND_FILE, R_OK) == 0) {
|
2017-03-12 20:19:30 +00:00
|
|
|
hdr.second_size = restore(SECOND_FILE, fd);
|
2017-03-07 16:54:23 +00:00
|
|
|
file_align(fd, hdr.page_size, 1);
|
2016-09-08 12:59:48 +00:00
|
|
|
}
|
|
|
|
|
2017-02-27 21:37:47 +00:00
|
|
|
// Restore dtb
|
|
|
|
if (access(DTB_FILE, R_OK) == 0) {
|
2017-03-12 20:19:30 +00:00
|
|
|
hdr.dt_size = restore(DTB_FILE, fd);
|
2017-03-07 16:54:23 +00:00
|
|
|
file_align(fd, hdr.page_size, 1);
|
2016-09-08 12:59:48 +00:00
|
|
|
}
|
|
|
|
|
2017-03-12 10:12:16 +00:00
|
|
|
// 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 ) {
|
2017-03-12 20:19:30 +00:00
|
|
|
restore_buf(fd, extra, 16);
|
2017-03-12 10:12:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-03-12 20:19:30 +00:00
|
|
|
// Write headers back
|
|
|
|
if (mtk_kernel) {
|
|
|
|
lseek(fd, mtk_kernel_off, SEEK_SET);
|
|
|
|
mtk_kernel_hdr.size = hdr.kernel_size;
|
|
|
|
hdr.kernel_size += 512;
|
|
|
|
restore_buf(fd, &mtk_kernel_hdr, sizeof(mtk_kernel_hdr));
|
|
|
|
}
|
|
|
|
if (mtk_ramdisk) {
|
|
|
|
lseek(fd, mtk_ramdisk_off, SEEK_SET);
|
|
|
|
mtk_ramdisk_hdr.size = hdr.ramdisk_size;
|
|
|
|
hdr.ramdisk_size += 512;
|
|
|
|
restore_buf(fd, &mtk_ramdisk_hdr, sizeof(mtk_ramdisk_hdr));
|
|
|
|
}
|
|
|
|
// Main header
|
2017-03-04 13:16:59 +00:00
|
|
|
lseek(fd, 0, SEEK_SET);
|
2017-03-12 20:19:30 +00:00
|
|
|
restore_buf(fd, &hdr, sizeof(hdr));
|
|
|
|
|
|
|
|
// Print new image info
|
|
|
|
print_info();
|
2016-09-08 12:59:48 +00:00
|
|
|
|
2017-03-04 13:16:59 +00:00
|
|
|
munmap(orig, size);
|
2017-03-12 20:19:30 +00:00
|
|
|
if (lseek(fd, 0, SEEK_END) > size) {
|
2017-02-27 21:37:47 +00:00
|
|
|
error(2, "Boot partition too small!");
|
|
|
|
}
|
2017-03-04 13:16:59 +00:00
|
|
|
close(fd);
|
2017-02-23 23:45:48 +00:00
|
|
|
}
|