mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-11-23 18:15:30 +00:00
Support patching header in magiskboot
This commit is contained in:
parent
d2cb638fcd
commit
1287372f5a
@ -269,11 +269,35 @@ void boot_img::print_hdr() {
|
|||||||
fprintf(stderr, "]\n");
|
fprintf(stderr, "]\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
int unpack(const char *image) {
|
int unpack(const char *image, bool hdr) {
|
||||||
boot_img boot {};
|
boot_img boot {};
|
||||||
int ret = boot.parse_file(image);
|
int ret = boot.parse_file(image);
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
|
if (hdr) {
|
||||||
|
FILE *fp = xfopen(HEADER_FILE, "w");
|
||||||
|
fprintf(fp, "pagesize=%u\n", boot.hdr.page_size());
|
||||||
|
fprintf(fp, "name=%s\n", boot.hdr.name());
|
||||||
|
fprintf(fp, "cmdline=%.512s%.1024s\n", boot.hdr.cmdline(), boot.hdr.extra_cmdline());
|
||||||
|
uint32_t ver = boot.hdr.os_version();
|
||||||
|
if (ver) {
|
||||||
|
int a, b, c, y, m = 0;
|
||||||
|
int version, patch_level;
|
||||||
|
version = ver >> 11;
|
||||||
|
patch_level = ver & 0x7ff;
|
||||||
|
|
||||||
|
a = (version >> 14) & 0x7f;
|
||||||
|
b = (version >> 7) & 0x7f;
|
||||||
|
c = version & 0x7f;
|
||||||
|
fprintf(fp, "os_version=%d.%d.%d\n", a, b, c);
|
||||||
|
|
||||||
|
y = (patch_level >> 4) + 2000;
|
||||||
|
m = patch_level & 0xf;
|
||||||
|
fprintf(fp, "patch_level=%d-%02d\n", y, m);
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
|
||||||
// Dump kernel
|
// Dump kernel
|
||||||
if (COMPRESSED(boot.k_fmt)) {
|
if (COMPRESSED(boot.k_fmt)) {
|
||||||
fd = creat(KERNEL_FILE, 0644);
|
fd = creat(KERNEL_FILE, 0644);
|
||||||
@ -338,6 +362,40 @@ void repack(const char* orig_image, const char* out_image) {
|
|||||||
restore_buf(fd, boot.map_addr, ACCLAIM_PRE_HEADER_SZ);
|
restore_buf(fd, boot.map_addr, ACCLAIM_PRE_HEADER_SZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// header
|
||||||
|
if (access(HEADER_FILE, R_OK) == 0) {
|
||||||
|
int os_version = 0;
|
||||||
|
parse_prop_file(HEADER_FILE, [&](string_view key, string_view value) -> bool {
|
||||||
|
if (key == "page_size") {
|
||||||
|
boot.hdr.page_size() = parse_int(value);
|
||||||
|
} else if (key == "name") {
|
||||||
|
memset(boot.hdr.name(), 0, 16);
|
||||||
|
memcpy(boot.hdr.name(), value.data(), value.length() + 1);
|
||||||
|
} else if (key == "cmdline") {
|
||||||
|
memset(boot.hdr.cmdline(), 0, 512);
|
||||||
|
memset(boot.hdr.extra_cmdline(), 0, 1024);
|
||||||
|
if (value.length() > 512) {
|
||||||
|
memcpy(boot.hdr.cmdline(), value.data(), 512);
|
||||||
|
memcpy(boot.hdr.extra_cmdline(), &value[512], value.length() - 511);
|
||||||
|
} else {
|
||||||
|
memcpy(boot.hdr.cmdline(), value.data(), value.length() + 1);
|
||||||
|
}
|
||||||
|
} else if (key == "os_version") {
|
||||||
|
int a, b, c;
|
||||||
|
sscanf(value.data(), "%d.%d.%d", &a, &b, &c);
|
||||||
|
os_version |= ((a << 14) | (b << 7) | c) << 11;
|
||||||
|
} else if (key == "patch_level") {
|
||||||
|
int y, m;
|
||||||
|
sscanf(value.data(), "%d-%d", &y, &m);
|
||||||
|
y -= 2000;
|
||||||
|
os_version |= (y << 4) | m;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
if (os_version)
|
||||||
|
boot.hdr.os_version() = os_version;
|
||||||
|
}
|
||||||
|
|
||||||
// Skip a page for header
|
// Skip a page for header
|
||||||
header_off = lseek(fd, 0, SEEK_CUR);
|
header_off = lseek(fd, 0, SEEK_CUR);
|
||||||
write_zero(fd, boot.hdr.page_size());
|
write_zero(fd, boot.hdr.page_size());
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#define HEADER_FILE "header"
|
||||||
#define KERNEL_FILE "kernel"
|
#define KERNEL_FILE "kernel"
|
||||||
#define RAMDISK_FILE "ramdisk.cpio"
|
#define RAMDISK_FILE "ramdisk.cpio"
|
||||||
#define SECOND_FILE "second"
|
#define SECOND_FILE "second"
|
||||||
@ -11,7 +12,7 @@
|
|||||||
#define NEW_BOOT "new-boot.img"
|
#define NEW_BOOT "new-boot.img"
|
||||||
|
|
||||||
// Main entries
|
// Main entries
|
||||||
int unpack(const char *image);
|
int unpack(const char *image, bool hdr = false);
|
||||||
void repack(const char* orig_image, const char* out_image);
|
void repack(const char* orig_image, const char* out_image);
|
||||||
void hexpatch(const char *image, const char *from, const char *to);
|
void hexpatch(const char *image, const char *from, const char *to);
|
||||||
int cpio_commands(int argc, char *argv[]);
|
int cpio_commands(int argc, char *argv[]);
|
||||||
|
@ -18,9 +18,11 @@ static void usage(char *arg0) {
|
|||||||
"Usage: %s <action> [args...]\n"
|
"Usage: %s <action> [args...]\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Supported actions:\n"
|
"Supported actions:\n"
|
||||||
" unpack <bootimg>\n"
|
" unpack [-h] <bootimg>\n"
|
||||||
" Unpack <bootimg> to, if available, kernel, ramdisk.cpio, \n"
|
" Unpack <bootimg> to, if available, kernel, ramdisk.cpio,\n"
|
||||||
" second, dtb, extra, and recovery_dtbo into current directory.\n"
|
" second, dtb, extra, and recovery_dtbo into current directory.\n"
|
||||||
|
" If '-h' is provided, it will dump header info to 'header',\n"
|
||||||
|
" which will be parsed when repacking.\n"
|
||||||
" Return values:\n"
|
" Return values:\n"
|
||||||
" 0:valid 1:error 2:chromeos 3:ELF32 4:ELF64\n"
|
" 0:valid 1:error 2:chromeos 3:ELF32 4:ELF64\n"
|
||||||
"\n"
|
"\n"
|
||||||
@ -116,6 +118,7 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
if (strcmp(argv[1], "cleanup") == 0) {
|
if (strcmp(argv[1], "cleanup") == 0) {
|
||||||
fprintf(stderr, "Cleaning up...\n");
|
fprintf(stderr, "Cleaning up...\n");
|
||||||
|
unlink(HEADER_FILE);
|
||||||
unlink(KERNEL_FILE);
|
unlink(KERNEL_FILE);
|
||||||
unlink(RAMDISK_FILE);
|
unlink(RAMDISK_FILE);
|
||||||
unlink(SECOND_FILE);
|
unlink(SECOND_FILE);
|
||||||
@ -133,7 +136,13 @@ int main(int argc, char *argv[]) {
|
|||||||
printf("\n");
|
printf("\n");
|
||||||
munmap(buf, size);
|
munmap(buf, size);
|
||||||
} else if (argc > 2 && strcmp(argv[1], "unpack") == 0) {
|
} else if (argc > 2 && strcmp(argv[1], "unpack") == 0) {
|
||||||
return unpack(argv[2]);
|
if (strcmp(argv[2], "-h") == 0) {
|
||||||
|
if (argc == 3)
|
||||||
|
usage(argv[0]);
|
||||||
|
return unpack(argv[3], true);
|
||||||
|
} else {
|
||||||
|
return unpack(argv[2]);
|
||||||
|
}
|
||||||
} else if (argc > 2 && strcmp(argv[1], "repack") == 0) {
|
} else if (argc > 2 && strcmp(argv[1], "repack") == 0) {
|
||||||
repack(argv[2], argv[3] ? argv[3] : NEW_BOOT);
|
repack(argv[2], argv[3] ? argv[3] : NEW_BOOT);
|
||||||
} else if (argc > 2 && strcmp(argv[1], "decompress") == 0) {
|
} else if (argc > 2 && strcmp(argv[1], "decompress") == 0) {
|
||||||
|
Loading…
Reference in New Issue
Block a user