mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-01-12 02:43:36 +00:00
Use mmap_data more widely
This commit is contained in:
parent
2d82ad93dd
commit
1443a5b175
@ -56,7 +56,6 @@ LOCAL_SRC_FILES := \
|
|||||||
init/rootdir.cpp \
|
init/rootdir.cpp \
|
||||||
init/getinfo.cpp \
|
init/getinfo.cpp \
|
||||||
init/twostage.cpp \
|
init/twostage.cpp \
|
||||||
init/raw_data.cpp \
|
|
||||||
core/socket.cpp \
|
core/socket.cpp \
|
||||||
magiskpolicy/sepolicy.cpp \
|
magiskpolicy/sepolicy.cpp \
|
||||||
magiskpolicy/magiskpolicy.cpp \
|
magiskpolicy/magiskpolicy.cpp \
|
||||||
|
@ -252,7 +252,7 @@ bool check_two_stage() {
|
|||||||
if (access("/system/bin/init", F_OK) == 0)
|
if (access("/system/bin/init", F_OK) == 0)
|
||||||
return true;
|
return true;
|
||||||
// If we still have no indication, parse the original init and see what's up
|
// If we still have no indication, parse the original init and see what's up
|
||||||
auto init = mmap_data::ro(backup_init());
|
auto init = mmap_data(backup_init());
|
||||||
return init.contains("selinux_setup");
|
return init.contains("selinux_setup");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
#include <utils.hpp>
|
#include <utils.hpp>
|
||||||
|
|
||||||
#include "raw_data.hpp"
|
|
||||||
|
|
||||||
using kv_pairs = std::vector<std::pair<std::string, std::string>>;
|
using kv_pairs = std::vector<std::pair<std::string, std::string>>;
|
||||||
|
|
||||||
struct BootConfig {
|
struct BootConfig {
|
||||||
|
@ -286,7 +286,7 @@ success:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void RootFSInit::early_mount() {
|
void RootFSInit::early_mount() {
|
||||||
self = mmap_data::ro("/init");
|
self = mmap_data("/init");
|
||||||
|
|
||||||
LOGD("Restoring /init\n");
|
LOGD("Restoring /init\n");
|
||||||
rename(backup_init(), "/init");
|
rename(backup_init(), "/init");
|
||||||
@ -298,9 +298,9 @@ void SARBase::backup_files() {
|
|||||||
if (access("/overlay.d", F_OK) == 0)
|
if (access("/overlay.d", F_OK) == 0)
|
||||||
backup_folder("/overlay.d", overlays);
|
backup_folder("/overlay.d", overlays);
|
||||||
|
|
||||||
self = mmap_data::ro("/proc/self/exe");
|
self = mmap_data("/proc/self/exe");
|
||||||
if (access("/.backup/.magisk", R_OK) == 0)
|
if (access("/.backup/.magisk", R_OK) == 0)
|
||||||
magisk_config = mmap_data::ro("/.backup/.magisk");
|
magisk_config = mmap_data("/.backup/.magisk");
|
||||||
}
|
}
|
||||||
|
|
||||||
void SARBase::mount_system_root() {
|
void SARBase::mount_system_root() {
|
||||||
|
@ -1,52 +0,0 @@
|
|||||||
#include "raw_data.hpp"
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
int mmap_data::patch(str_pairs list) {
|
|
||||||
if (buf == nullptr)
|
|
||||||
return 0;
|
|
||||||
int count = 0;
|
|
||||||
for (uint8_t *p = buf, *eof = buf + sz; p < eof; ++p) {
|
|
||||||
for (auto [from, to] : list) {
|
|
||||||
if (memcmp(p, from.data(), from.length() + 1) == 0) {
|
|
||||||
LOGD("Replace [%s] -> [%s]\n", from.data(), to.data());
|
|
||||||
memset(p, 0, from.length());
|
|
||||||
memcpy(p, to.data(), to.length());
|
|
||||||
++count;
|
|
||||||
p += from.length();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool mmap_data::contains(string_view pattern) {
|
|
||||||
if (buf == nullptr)
|
|
||||||
return false;
|
|
||||||
for (uint8_t *p = buf, *eof = buf + sz; p < eof; ++p) {
|
|
||||||
if (memcmp(p, pattern.data(), pattern.length() + 1) == 0) {
|
|
||||||
LOGD("Found pattern [%s]\n", pattern.data());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mmap_data::consume(mmap_data &other) {
|
|
||||||
buf = other.buf;
|
|
||||||
sz = other.sz;
|
|
||||||
other.buf = nullptr;
|
|
||||||
other.sz = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
mmap_data mmap_data::rw(const char *name) {
|
|
||||||
mmap_data data;
|
|
||||||
mmap_rw(name, data.buf, data.sz);
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
mmap_data mmap_data::ro(const char *name) {
|
|
||||||
mmap_data data;
|
|
||||||
mmap_ro(name, data.buf, data.sz);
|
|
||||||
return data;
|
|
||||||
}
|
|
@ -1,24 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <utils.hpp>
|
|
||||||
|
|
||||||
struct mmap_data {
|
|
||||||
uint8_t *buf = nullptr;
|
|
||||||
size_t sz = 0;
|
|
||||||
|
|
||||||
mmap_data() = default;
|
|
||||||
mmap_data(const mmap_data&) = delete;
|
|
||||||
mmap_data(mmap_data &&other) { consume(other); }
|
|
||||||
~mmap_data() { if (buf) munmap(buf, sz); }
|
|
||||||
mmap_data& operator=(mmap_data &&other) { consume(other); return *this; }
|
|
||||||
|
|
||||||
using str_pairs = std::initializer_list<std::pair<std::string_view, std::string_view>>;
|
|
||||||
int patch(str_pairs list);
|
|
||||||
bool contains(std::string_view pattern);
|
|
||||||
|
|
||||||
static mmap_data rw(const char *name);
|
|
||||||
static mmap_data ro(const char *name);
|
|
||||||
|
|
||||||
private:
|
|
||||||
void consume(mmap_data &other);
|
|
||||||
};
|
|
@ -183,7 +183,7 @@ static void patch_socket_name(const char *path) {
|
|||||||
static char rstr[16] = { 0 };
|
static char rstr[16] = { 0 };
|
||||||
if (rstr[0] == '\0')
|
if (rstr[0] == '\0')
|
||||||
gen_rand_str(rstr, sizeof(rstr));
|
gen_rand_str(rstr, sizeof(rstr));
|
||||||
auto bin = mmap_data::rw(path);
|
auto bin = mmap_data(path, true);
|
||||||
bin.patch({ make_pair(MAIN_SOCKET, rstr) });
|
bin.patch({ make_pair(MAIN_SOCKET, rstr) });
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -224,7 +224,7 @@ void SARBase::patch_rootdir() {
|
|||||||
int patch_count;
|
int patch_count;
|
||||||
{
|
{
|
||||||
int src = xopen("/init", O_RDONLY | O_CLOEXEC);
|
int src = xopen("/init", O_RDONLY | O_CLOEXEC);
|
||||||
auto init = mmap_data::ro("/init");
|
auto init = mmap_data("/init");
|
||||||
patch_count = init.patch({
|
patch_count = init.patch({
|
||||||
make_pair(SPLIT_PLAT_CIL, "xxx"), /* Force loading monolithic sepolicy */
|
make_pair(SPLIT_PLAT_CIL, "xxx"), /* Force loading monolithic sepolicy */
|
||||||
make_pair(MONOPOLICY, sepol) /* Redirect /sepolicy to custom path */
|
make_pair(MONOPOLICY, sepol) /* Redirect /sepolicy to custom path */
|
||||||
@ -248,8 +248,8 @@ void SARBase::patch_rootdir() {
|
|||||||
if (path) {
|
if (path) {
|
||||||
char ovl[128];
|
char ovl[128];
|
||||||
sprintf(ovl, ROOTOVL "%s", path);
|
sprintf(ovl, ROOTOVL "%s", path);
|
||||||
auto lib = mmap_data::ro(path);
|
auto lib = mmap_data(path);
|
||||||
lib.patch({make_pair(MONOPOLICY, sepol)});
|
lib.patch({ make_pair(MONOPOLICY, sepol) });
|
||||||
xmkdirs(dirname(ovl), 0755);
|
xmkdirs(dirname(ovl), 0755);
|
||||||
int dest = xopen(ovl, O_CREAT | O_WRONLY | O_CLOEXEC, 0);
|
int dest = xopen(ovl, O_CREAT | O_WRONLY | O_CLOEXEC, 0);
|
||||||
xwrite(dest, lib.buf, lib.sz);
|
xwrite(dest, lib.buf, lib.sz);
|
||||||
@ -295,14 +295,14 @@ void SARBase::patch_rootdir() {
|
|||||||
|
|
||||||
// Extract magisk
|
// Extract magisk
|
||||||
{
|
{
|
||||||
auto magisk = mmap_data::ro("magisk32.xz");
|
auto magisk = mmap_data("magisk32.xz");
|
||||||
unlink("magisk32.xz");
|
unlink("magisk32.xz");
|
||||||
int fd = xopen("magisk32", O_WRONLY | O_CREAT, 0755);
|
int fd = xopen("magisk32", O_WRONLY | O_CREAT, 0755);
|
||||||
unxz(fd, magisk.buf, magisk.sz);
|
unxz(fd, magisk.buf, magisk.sz);
|
||||||
close(fd);
|
close(fd);
|
||||||
patch_socket_name("magisk32");
|
patch_socket_name("magisk32");
|
||||||
if (access("magisk64.xz", F_OK) == 0) {
|
if (access("magisk64.xz", F_OK) == 0) {
|
||||||
magisk = mmap_data::ro("magisk64.xz");
|
magisk = mmap_data("magisk64.xz");
|
||||||
unlink("magisk64.xz");
|
unlink("magisk64.xz");
|
||||||
fd = xopen("magisk64", O_WRONLY | O_CREAT, 0755);
|
fd = xopen("magisk64", O_WRONLY | O_CREAT, 0755);
|
||||||
unxz(fd, magisk.buf, magisk.sz);
|
unxz(fd, magisk.buf, magisk.sz);
|
||||||
@ -344,13 +344,13 @@ void RootFSBase::patch_rootfs() {
|
|||||||
|
|
||||||
if (patch_sepolicy("/sepolicy")) {
|
if (patch_sepolicy("/sepolicy")) {
|
||||||
if (access("/system/bin/init", F_OK) == 0) {
|
if (access("/system/bin/init", F_OK) == 0) {
|
||||||
auto init = mmap_data::ro("/system/bin/init");
|
auto init = mmap_data("/system/bin/init");
|
||||||
init.patch({ make_pair(SPLIT_PLAT_CIL, "xxx") });
|
init.patch({ make_pair(SPLIT_PLAT_CIL, "xxx") });
|
||||||
int dest = xopen("/init", O_TRUNC | O_WRONLY | O_CLOEXEC, 0);
|
int dest = xopen("/init", O_TRUNC | O_WRONLY | O_CLOEXEC, 0);
|
||||||
xwrite(dest, init.buf, init.sz);
|
xwrite(dest, init.buf, init.sz);
|
||||||
close(dest);
|
close(dest);
|
||||||
} else {
|
} else {
|
||||||
auto init = mmap_data::rw("/init");
|
auto init = mmap_data("/init", true);
|
||||||
init.patch({ make_pair(SPLIT_PLAT_CIL, "xxx") });
|
init.patch({ make_pair(SPLIT_PLAT_CIL, "xxx") });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -376,10 +376,10 @@ void MagiskProxy::start() {
|
|||||||
xmount(nullptr, "/", nullptr, MS_REMOUNT, nullptr);
|
xmount(nullptr, "/", nullptr, MS_REMOUNT, nullptr);
|
||||||
|
|
||||||
// Backup stuffs before removing them
|
// Backup stuffs before removing them
|
||||||
self = mmap_data::ro("/sbin/magisk");
|
self = mmap_data("/sbin/magisk");
|
||||||
magisk_config = mmap_data::ro("/.backup/.magisk");
|
magisk_config = mmap_data("/.backup/.magisk");
|
||||||
auto magisk = mmap_data::ro("/sbin/magisk32.xz");
|
auto magisk = mmap_data("/sbin/magisk32.xz");
|
||||||
auto magisk64 = mmap_data::ro("/sbin/magisk64.xz");
|
auto magisk64 = mmap_data("/sbin/magisk64.xz");
|
||||||
char custom_rules_dir[64];
|
char custom_rules_dir[64];
|
||||||
custom_rules_dir[0] = '\0';
|
custom_rules_dir[0] = '\0';
|
||||||
xreadlink(TMP_RULESDIR, custom_rules_dir, sizeof(custom_rules_dir));
|
xreadlink(TMP_RULESDIR, custom_rules_dir, sizeof(custom_rules_dir));
|
||||||
|
@ -122,7 +122,7 @@ exit_loop:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Patch init to force IsDtFstabCompatible() return false
|
// Patch init to force IsDtFstabCompatible() return false
|
||||||
auto init = mmap_data::rw("/init");
|
auto init = mmap_data("/init", true);
|
||||||
init.patch({ make_pair("android,fstab", "xxx") });
|
init.patch({ make_pair("android,fstab", "xxx") });
|
||||||
} else {
|
} else {
|
||||||
// Parse and load the fstab file
|
// Parse and load the fstab file
|
||||||
@ -192,7 +192,7 @@ void SARInit::first_stage_prep() {
|
|||||||
int src = xopen("/init", O_RDONLY);
|
int src = xopen("/init", O_RDONLY);
|
||||||
int dest = xopen("/dev/init", O_CREAT | O_WRONLY, 0);
|
int dest = xopen("/dev/init", O_CREAT | O_WRONLY, 0);
|
||||||
{
|
{
|
||||||
auto init = mmap_data::ro("/init");
|
auto init = mmap_data("/init");
|
||||||
init.patch({ make_pair(INIT_PATH, REDIR_PATH) });
|
init.patch({ make_pair(INIT_PATH, REDIR_PATH) });
|
||||||
write(dest, init.buf, init.sz);
|
write(dest, init.buf, init.sz);
|
||||||
fclone_attr(src, dest);
|
fclone_attr(src, dest);
|
||||||
|
@ -148,11 +148,10 @@ void dyn_img_hdr::load_hdr_file() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
boot_img::boot_img(const char *image) {
|
boot_img::boot_img(const char *image) : map(image) {
|
||||||
mmap_ro(image, map_addr, map_size);
|
|
||||||
fprintf(stderr, "Parsing boot image: [%s]\n", image);
|
fprintf(stderr, "Parsing boot image: [%s]\n", image);
|
||||||
for (uint8_t *addr = map_addr; addr < map_addr + map_size; ++addr) {
|
for (uint8_t *addr = map.buf; addr < map.buf + map.sz; ++addr) {
|
||||||
format_t fmt = check_fmt(addr, map_size);
|
format_t fmt = check_fmt(addr, map.sz);
|
||||||
switch (fmt) {
|
switch (fmt) {
|
||||||
case CHROMEOS:
|
case CHROMEOS:
|
||||||
// chromeos require external signing
|
// chromeos require external signing
|
||||||
@ -182,7 +181,6 @@ boot_img::boot_img(const char *image) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
boot_img::~boot_img() {
|
boot_img::~boot_img() {
|
||||||
munmap(map_addr, map_size);
|
|
||||||
delete hdr;
|
delete hdr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -405,9 +403,9 @@ void boot_img::parse_image(uint8_t *addr, format_t type) {
|
|||||||
fprintf(stderr, "%-*s [%s]\n", PADDING, "EXTRA_FMT", fmt2name[e_fmt]);
|
fprintf(stderr, "%-*s [%s]\n", PADDING, "EXTRA_FMT", fmt2name[e_fmt]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (addr + off < map_addr + map_size) {
|
if (addr + off < map.buf + map.sz) {
|
||||||
tail = addr + off;
|
tail = addr + off;
|
||||||
tail_size = map_addr + map_size - tail;
|
tail_size = map.buf + map.sz - tail;
|
||||||
|
|
||||||
// Check special flags
|
// Check special flags
|
||||||
if (tail_size >= 16 && BUFFER_MATCH(tail, SEANDROID_MAGIC)) {
|
if (tail_size >= 16 && BUFFER_MATCH(tail, SEANDROID_MAGIC)) {
|
||||||
@ -434,21 +432,18 @@ void boot_img::parse_image(uint8_t *addr, format_t type) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int split_image_dtb(const char *filename) {
|
int split_image_dtb(const char *filename) {
|
||||||
uint8_t *buf;
|
auto img = mmap_data(filename);
|
||||||
size_t sz;
|
|
||||||
mmap_ro(filename, buf, sz);
|
|
||||||
run_finally f([=]{ munmap(buf, sz); });
|
|
||||||
|
|
||||||
if (int off = find_dtb_offset(buf, sz); off > 0) {
|
if (int off = find_dtb_offset(img.buf, img.sz); off > 0) {
|
||||||
format_t fmt = check_fmt_lg(buf, sz);
|
format_t fmt = check_fmt_lg(img.buf, img.sz);
|
||||||
if (COMPRESSED(fmt)) {
|
if (COMPRESSED(fmt)) {
|
||||||
int fd = creat(KERNEL_FILE, 0644);
|
int fd = creat(KERNEL_FILE, 0644);
|
||||||
decompress(fmt, fd, buf, off);
|
decompress(fmt, fd, img.buf, off);
|
||||||
close(fd);
|
close(fd);
|
||||||
} else {
|
} else {
|
||||||
dump(buf, off, KERNEL_FILE);
|
dump(img.buf, off, KERNEL_FILE);
|
||||||
}
|
}
|
||||||
dump(buf + off, sz - off, KER_DTB_FILE);
|
dump(img.buf + off, img.sz - off, KER_DTB_FILE);
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "Cannot find DTB in %s\n", filename);
|
fprintf(stderr, "Cannot find DTB in %s\n", filename);
|
||||||
@ -546,11 +541,11 @@ void repack(const char *src_img, const char *out_img, bool skip_comp) {
|
|||||||
// Skip DHTB header
|
// Skip DHTB header
|
||||||
write_zero(fd, sizeof(dhtb_hdr));
|
write_zero(fd, sizeof(dhtb_hdr));
|
||||||
} else if (boot.flags[BLOB_FLAG]) {
|
} else if (boot.flags[BLOB_FLAG]) {
|
||||||
xwrite(fd, boot.map_addr, sizeof(blob_hdr));
|
xwrite(fd, boot.map.buf, sizeof(blob_hdr));
|
||||||
} else if (boot.flags[NOOKHD_FLAG]) {
|
} else if (boot.flags[NOOKHD_FLAG]) {
|
||||||
xwrite(fd, boot.map_addr, NOOKHD_PRE_HEADER_SZ);
|
xwrite(fd, boot.map.buf, NOOKHD_PRE_HEADER_SZ);
|
||||||
} else if (boot.flags[ACCLAIM_FLAG]) {
|
} else if (boot.flags[ACCLAIM_FLAG]) {
|
||||||
xwrite(fd, boot.map_addr, ACCLAIM_PRE_HEADER_SZ);
|
xwrite(fd, boot.map.buf, ACCLAIM_PRE_HEADER_SZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy raw header
|
// Copy raw header
|
||||||
@ -568,15 +563,13 @@ void repack(const char *src_img, const char *out_img, bool skip_comp) {
|
|||||||
xwrite(fd, boot.z_hdr, boot.z_info.hdr_sz);
|
xwrite(fd, boot.z_hdr, boot.z_info.hdr_sz);
|
||||||
}
|
}
|
||||||
if (access(KERNEL_FILE, R_OK) == 0) {
|
if (access(KERNEL_FILE, R_OK) == 0) {
|
||||||
size_t raw_size;
|
auto m = mmap_data(KERNEL_FILE);
|
||||||
void *raw_buf;
|
if (!COMPRESSED_ANY(check_fmt(m.buf, m.sz)) && COMPRESSED(boot.k_fmt)) {
|
||||||
mmap_ro(KERNEL_FILE, raw_buf, raw_size);
|
|
||||||
if (!COMPRESSED_ANY(check_fmt(raw_buf, raw_size)) && COMPRESSED(boot.k_fmt)) {
|
|
||||||
// Always use zopfli for zImage compression
|
// Always use zopfli for zImage compression
|
||||||
auto fmt = (boot.flags[ZIMAGE_KERNEL] && boot.k_fmt == GZIP) ? ZOPFLI : boot.k_fmt;
|
auto fmt = (boot.flags[ZIMAGE_KERNEL] && boot.k_fmt == GZIP) ? ZOPFLI : boot.k_fmt;
|
||||||
hdr->kernel_size() = compress(fmt, fd, raw_buf, raw_size);
|
hdr->kernel_size() = compress(fmt, fd, m.buf, m.sz);
|
||||||
} else {
|
} else {
|
||||||
hdr->kernel_size() = xwrite(fd, raw_buf, raw_size);
|
hdr->kernel_size() = xwrite(fd, m.buf, m.sz);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (boot.flags[ZIMAGE_KERNEL]) {
|
if (boot.flags[ZIMAGE_KERNEL]) {
|
||||||
@ -587,7 +580,7 @@ void repack(const char *src_img, const char *out_img, bool skip_comp) {
|
|||||||
} else {
|
} else {
|
||||||
// Pad zeros to make sure the zImage file size does not change
|
// Pad zeros to make sure the zImage file size does not change
|
||||||
// Also ensure the last 4 bytes are the uncompressed vmlinux size
|
// Also ensure the last 4 bytes are the uncompressed vmlinux size
|
||||||
uint32_t sz = raw_size;
|
uint32_t sz = m.sz;
|
||||||
write_zero(fd, boot.hdr->kernel_size() - hdr->kernel_size() - sizeof(sz));
|
write_zero(fd, boot.hdr->kernel_size() - hdr->kernel_size() - sizeof(sz));
|
||||||
xwrite(fd, &sz, sizeof(sz));
|
xwrite(fd, &sz, sizeof(sz));
|
||||||
}
|
}
|
||||||
@ -595,8 +588,6 @@ void repack(const char *src_img, const char *out_img, bool skip_comp) {
|
|||||||
// zImage size shall remain the same
|
// zImage size shall remain the same
|
||||||
hdr->kernel_size() = boot.hdr->kernel_size();
|
hdr->kernel_size() = boot.hdr->kernel_size();
|
||||||
}
|
}
|
||||||
|
|
||||||
munmap(raw_buf, raw_size);
|
|
||||||
}
|
}
|
||||||
if (boot.flags[ZIMAGE_KERNEL]) {
|
if (boot.flags[ZIMAGE_KERNEL]) {
|
||||||
// Copy zImage tail and adjust size accordingly
|
// Copy zImage tail and adjust size accordingly
|
||||||
@ -616,15 +607,12 @@ void repack(const char *src_img, const char *out_img, bool skip_comp) {
|
|||||||
xwrite(fd, boot.r_hdr, sizeof(mtk_hdr));
|
xwrite(fd, boot.r_hdr, sizeof(mtk_hdr));
|
||||||
}
|
}
|
||||||
if (access(RAMDISK_FILE, R_OK) == 0) {
|
if (access(RAMDISK_FILE, R_OK) == 0) {
|
||||||
size_t raw_size;
|
auto m = mmap_data(RAMDISK_FILE);
|
||||||
void *raw_buf;
|
if (!skip_comp && !COMPRESSED_ANY(check_fmt(m.buf, m.sz)) && COMPRESSED(boot.r_fmt)) {
|
||||||
mmap_ro(RAMDISK_FILE, raw_buf, raw_size);
|
hdr->ramdisk_size() = compress(boot.r_fmt, fd, m.buf, m.sz);
|
||||||
if (!skip_comp && !COMPRESSED_ANY(check_fmt(raw_buf, raw_size)) && COMPRESSED(boot.r_fmt)) {
|
|
||||||
hdr->ramdisk_size() = compress(boot.r_fmt, fd, raw_buf, raw_size);
|
|
||||||
} else {
|
} else {
|
||||||
hdr->ramdisk_size() = xwrite(fd, raw_buf, raw_size);
|
hdr->ramdisk_size() = xwrite(fd, m.buf, m.sz);
|
||||||
}
|
}
|
||||||
munmap(raw_buf, raw_size);
|
|
||||||
file_align();
|
file_align();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -638,15 +626,12 @@ void repack(const char *src_img, const char *out_img, bool skip_comp) {
|
|||||||
// extra
|
// extra
|
||||||
off.extra = lseek(fd, 0, SEEK_CUR);
|
off.extra = lseek(fd, 0, SEEK_CUR);
|
||||||
if (access(EXTRA_FILE, R_OK) == 0) {
|
if (access(EXTRA_FILE, R_OK) == 0) {
|
||||||
size_t raw_size;
|
auto m = mmap_data(EXTRA_FILE);
|
||||||
void *raw_buf;
|
if (!skip_comp && !COMPRESSED_ANY(check_fmt(m.buf, m.sz)) && COMPRESSED(boot.e_fmt)) {
|
||||||
mmap_ro(EXTRA_FILE, raw_buf, raw_size);
|
hdr->extra_size() = compress(boot.e_fmt, fd, m.buf, m.sz);
|
||||||
if (!skip_comp && !COMPRESSED_ANY(check_fmt(raw_buf, raw_size)) && COMPRESSED(boot.e_fmt)) {
|
|
||||||
hdr->extra_size() = compress(boot.e_fmt, fd, raw_buf, raw_size);
|
|
||||||
} else {
|
} else {
|
||||||
hdr->extra_size() = xwrite(fd, raw_buf, raw_size);
|
hdr->extra_size() = xwrite(fd, m.buf, m.sz);
|
||||||
}
|
}
|
||||||
munmap(raw_buf, raw_size);
|
|
||||||
file_align();
|
file_align();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -696,8 +681,8 @@ void repack(const char *src_img, const char *out_img, bool skip_comp) {
|
|||||||
// Pad image to original size if not chromeos (as it requires post processing)
|
// Pad image to original size if not chromeos (as it requires post processing)
|
||||||
if (!boot.flags[CHROMEOS_FLAG]) {
|
if (!boot.flags[CHROMEOS_FLAG]) {
|
||||||
off_t current = lseek(fd, 0, SEEK_CUR);
|
off_t current = lseek(fd, 0, SEEK_CUR);
|
||||||
if (current < boot.map_size) {
|
if (current < boot.map.sz) {
|
||||||
write_zero(fd, boot.map_size - current);
|
write_zero(fd, boot.map.sz - current);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -708,18 +693,16 @@ void repack(const char *src_img, const char *out_img, bool skip_comp) {
|
|||||||
******************/
|
******************/
|
||||||
|
|
||||||
// Map output image as rw
|
// Map output image as rw
|
||||||
uint8_t *new_addr;
|
auto out = mmap_data(out_img, true);
|
||||||
size_t new_size;
|
|
||||||
mmap_rw(out_img, new_addr, new_size);
|
|
||||||
|
|
||||||
// MTK headers
|
// MTK headers
|
||||||
if (boot.flags[MTK_KERNEL]) {
|
if (boot.flags[MTK_KERNEL]) {
|
||||||
auto m_hdr = reinterpret_cast<mtk_hdr *>(new_addr + off.kernel);
|
auto m_hdr = reinterpret_cast<mtk_hdr *>(out.buf + off.kernel);
|
||||||
m_hdr->size = hdr->kernel_size();
|
m_hdr->size = hdr->kernel_size();
|
||||||
hdr->kernel_size() += sizeof(mtk_hdr);
|
hdr->kernel_size() += sizeof(mtk_hdr);
|
||||||
}
|
}
|
||||||
if (boot.flags[MTK_RAMDISK]) {
|
if (boot.flags[MTK_RAMDISK]) {
|
||||||
auto m_hdr = reinterpret_cast<mtk_hdr *>(new_addr + off.ramdisk);
|
auto m_hdr = reinterpret_cast<mtk_hdr *>(out.buf + off.ramdisk);
|
||||||
m_hdr->size = hdr->ramdisk_size();
|
m_hdr->size = hdr->ramdisk_size();
|
||||||
hdr->ramdisk_size() += sizeof(mtk_hdr);
|
hdr->ramdisk_size() += sizeof(mtk_hdr);
|
||||||
}
|
}
|
||||||
@ -732,28 +715,28 @@ void repack(const char *src_img, const char *out_img, bool skip_comp) {
|
|||||||
HASH_CTX ctx;
|
HASH_CTX ctx;
|
||||||
boot.flags[SHA256_FLAG] ? SHA256_init(&ctx) : SHA_init(&ctx);
|
boot.flags[SHA256_FLAG] ? SHA256_init(&ctx) : SHA_init(&ctx);
|
||||||
uint32_t size = hdr->kernel_size();
|
uint32_t size = hdr->kernel_size();
|
||||||
HASH_update(&ctx, new_addr + off.kernel, size);
|
HASH_update(&ctx, out.buf + off.kernel, size);
|
||||||
HASH_update(&ctx, &size, sizeof(size));
|
HASH_update(&ctx, &size, sizeof(size));
|
||||||
size = hdr->ramdisk_size();
|
size = hdr->ramdisk_size();
|
||||||
HASH_update(&ctx, new_addr + off.ramdisk, size);
|
HASH_update(&ctx, out.buf + off.ramdisk, size);
|
||||||
HASH_update(&ctx, &size, sizeof(size));
|
HASH_update(&ctx, &size, sizeof(size));
|
||||||
size = hdr->second_size();
|
size = hdr->second_size();
|
||||||
HASH_update(&ctx, new_addr + off.second, size);
|
HASH_update(&ctx, out.buf + off.second, size);
|
||||||
HASH_update(&ctx, &size, sizeof(size));
|
HASH_update(&ctx, &size, sizeof(size));
|
||||||
size = hdr->extra_size();
|
size = hdr->extra_size();
|
||||||
if (size) {
|
if (size) {
|
||||||
HASH_update(&ctx, new_addr + off.extra, size);
|
HASH_update(&ctx, out.buf + off.extra, size);
|
||||||
HASH_update(&ctx, &size, sizeof(size));
|
HASH_update(&ctx, &size, sizeof(size));
|
||||||
}
|
}
|
||||||
uint32_t ver = hdr->header_version();
|
uint32_t ver = hdr->header_version();
|
||||||
if (ver == 1 || ver == 2) {
|
if (ver == 1 || ver == 2) {
|
||||||
size = hdr->recovery_dtbo_size();
|
size = hdr->recovery_dtbo_size();
|
||||||
HASH_update(&ctx, new_addr + hdr->recovery_dtbo_offset(), size);
|
HASH_update(&ctx, out.buf + hdr->recovery_dtbo_offset(), size);
|
||||||
HASH_update(&ctx, &size, sizeof(size));
|
HASH_update(&ctx, &size, sizeof(size));
|
||||||
}
|
}
|
||||||
if (ver == 2) {
|
if (ver == 2) {
|
||||||
size = hdr->dtb_size();
|
size = hdr->dtb_size();
|
||||||
HASH_update(&ctx, new_addr + off.dtb, size);
|
HASH_update(&ctx, out.buf + off.dtb, size);
|
||||||
HASH_update(&ctx, &size, sizeof(size));
|
HASH_update(&ctx, &size, sizeof(size));
|
||||||
}
|
}
|
||||||
memset(id, 0, BOOT_ID_SIZE);
|
memset(id, 0, BOOT_ID_SIZE);
|
||||||
@ -764,12 +747,12 @@ void repack(const char *src_img, const char *out_img, bool skip_comp) {
|
|||||||
hdr->print();
|
hdr->print();
|
||||||
|
|
||||||
// Copy main header
|
// Copy main header
|
||||||
memcpy(new_addr + off.header, hdr->raw_hdr(), hdr->hdr_size());
|
memcpy(out.buf + off.header, hdr->raw_hdr(), hdr->hdr_size());
|
||||||
|
|
||||||
if (boot.flags[AVB_FLAG]) {
|
if (boot.flags[AVB_FLAG]) {
|
||||||
// Copy and patch AVB structures
|
// Copy and patch AVB structures
|
||||||
auto footer = reinterpret_cast<AvbFooter*>(new_addr + new_size - sizeof(AvbFooter));
|
auto footer = reinterpret_cast<AvbFooter*>(out.buf + out.sz - sizeof(AvbFooter));
|
||||||
auto vbmeta = reinterpret_cast<AvbVBMetaImageHeader*>(new_addr + off.vbmeta);
|
auto vbmeta = reinterpret_cast<AvbVBMetaImageHeader*>(out.buf + off.vbmeta);
|
||||||
memcpy(footer, boot.avb_footer, sizeof(AvbFooter));
|
memcpy(footer, boot.avb_footer, sizeof(AvbFooter));
|
||||||
footer->original_image_size = __builtin_bswap64(off.total);
|
footer->original_image_size = __builtin_bswap64(off.total);
|
||||||
footer->vbmeta_offset = __builtin_bswap64(off.vbmeta);
|
footer->vbmeta_offset = __builtin_bswap64(off.vbmeta);
|
||||||
@ -780,15 +763,13 @@ void repack(const char *src_img, const char *out_img, bool skip_comp) {
|
|||||||
|
|
||||||
if (boot.flags[DHTB_FLAG]) {
|
if (boot.flags[DHTB_FLAG]) {
|
||||||
// DHTB header
|
// DHTB header
|
||||||
auto d_hdr = reinterpret_cast<dhtb_hdr *>(new_addr);
|
auto d_hdr = reinterpret_cast<dhtb_hdr *>(out.buf);
|
||||||
memcpy(d_hdr, DHTB_MAGIC, 8);
|
memcpy(d_hdr, DHTB_MAGIC, 8);
|
||||||
d_hdr->size = off.total - sizeof(dhtb_hdr);
|
d_hdr->size = off.total - sizeof(dhtb_hdr);
|
||||||
SHA256_hash(new_addr + sizeof(dhtb_hdr), d_hdr->size, d_hdr->checksum);
|
SHA256_hash(out.buf + sizeof(dhtb_hdr), d_hdr->size, d_hdr->checksum);
|
||||||
} else if (boot.flags[BLOB_FLAG]) {
|
} else if (boot.flags[BLOB_FLAG]) {
|
||||||
// Blob header
|
// Blob header
|
||||||
auto b_hdr = reinterpret_cast<blob_hdr *>(new_addr);
|
auto b_hdr = reinterpret_cast<blob_hdr *>(out.buf);
|
||||||
b_hdr->size = off.total - sizeof(blob_hdr);
|
b_hdr->size = off.total - sizeof(blob_hdr);
|
||||||
}
|
}
|
||||||
|
|
||||||
munmap(new_addr, new_size);
|
|
||||||
}
|
}
|
||||||
|
@ -563,8 +563,7 @@ enum {
|
|||||||
|
|
||||||
struct boot_img {
|
struct boot_img {
|
||||||
// Memory map of the whole image
|
// Memory map of the whole image
|
||||||
uint8_t *map_addr;
|
mmap_data map;
|
||||||
size_t map_size;
|
|
||||||
|
|
||||||
// Android image header
|
// Android image header
|
||||||
dyn_img_hdr *hdr;
|
dyn_img_hdr *hdr;
|
||||||
|
@ -151,12 +151,9 @@ void cpio::dump(FILE *out) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void cpio::load_cpio(const char *file) {
|
void cpio::load_cpio(const char *file) {
|
||||||
char *buf;
|
|
||||||
size_t sz;
|
|
||||||
mmap_ro(file, buf, sz);
|
|
||||||
fprintf(stderr, "Loading cpio: [%s]\n", file);
|
fprintf(stderr, "Loading cpio: [%s]\n", file);
|
||||||
load_cpio(buf, sz);
|
auto m = mmap_data(file);
|
||||||
munmap(buf, sz);
|
load_cpio(reinterpret_cast<char *>(m.buf), m.sz);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cpio::insert(string_view name, cpio_entry *e) {
|
void cpio::insert(string_view name, cpio_entry *e) {
|
||||||
@ -169,14 +166,11 @@ void cpio::insert(string_view name, cpio_entry *e) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void cpio::add(mode_t mode, const char *name, const char *file) {
|
void cpio::add(mode_t mode, const char *name, const char *file) {
|
||||||
void *buf;
|
auto m = mmap_data(file);
|
||||||
size_t sz;
|
|
||||||
mmap_ro(file, buf, sz);
|
|
||||||
auto e = new cpio_entry(S_IFREG | mode);
|
auto e = new cpio_entry(S_IFREG | mode);
|
||||||
e->filesize = sz;
|
e->filesize = m.sz;
|
||||||
e->data = xmalloc(sz);
|
e->data = xmalloc(m.sz);
|
||||||
memcpy(e->data, buf, sz);
|
memcpy(e->data, m.buf, m.sz);
|
||||||
munmap(buf, sz);
|
|
||||||
insert(name, e);
|
insert(name, e);
|
||||||
fprintf(stderr, "Add entry [%s] (%04o)\n", name, mode);
|
fprintf(stderr, "Add entry [%s] (%04o)\n", name, mode);
|
||||||
}
|
}
|
||||||
|
@ -94,32 +94,29 @@ static int find_fstab(const void *fdt, int node = 0) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void dtb_print(const char *file, bool fstab) {
|
static void dtb_print(const char *file, bool fstab) {
|
||||||
size_t size;
|
|
||||||
uint8_t *dtb;
|
|
||||||
fprintf(stderr, "Loading dtbs from [%s]\n", file);
|
fprintf(stderr, "Loading dtbs from [%s]\n", file);
|
||||||
mmap_ro(file, dtb, size);
|
auto m = mmap_data(file);
|
||||||
// Loop through all the dtbs
|
// Loop through all the dtbs
|
||||||
int dtb_num = 0;
|
int dtb_num = 0;
|
||||||
uint8_t * const end = dtb + size;
|
uint8_t * const end = m.buf + m.sz;
|
||||||
for (uint8_t *fdt = dtb; fdt < end;) {
|
for (uint8_t *fdt = m.buf; fdt < end;) {
|
||||||
fdt = static_cast<uint8_t*>(memmem(fdt, end - fdt, DTB_MAGIC, sizeof(fdt32_t)));
|
fdt = static_cast<uint8_t*>(memmem(fdt, end - fdt, DTB_MAGIC, sizeof(fdt32_t)));
|
||||||
if (fdt == nullptr)
|
if (fdt == nullptr)
|
||||||
break;
|
break;
|
||||||
if (fstab) {
|
if (fstab) {
|
||||||
int node = find_fstab(fdt);
|
int node = find_fstab(fdt);
|
||||||
if (node >= 0) {
|
if (node >= 0) {
|
||||||
fprintf(stderr, "Found fstab in dtb.%04d\n", dtb_num);
|
fprintf(stderr, "Found fstab in buf.%04d\n", dtb_num);
|
||||||
print_node(fdt, node);
|
print_node(fdt, node);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "Printing dtb.%04d\n", dtb_num);
|
fprintf(stderr, "Printing buf.%04d\n", dtb_num);
|
||||||
print_node(fdt);
|
print_node(fdt);
|
||||||
}
|
}
|
||||||
++dtb_num;
|
++dtb_num;
|
||||||
fdt += fdt_totalsize(fdt);
|
fdt += fdt_totalsize(fdt);
|
||||||
}
|
}
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
munmap(dtb, size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[[maybe_unused]]
|
[[maybe_unused]]
|
||||||
@ -128,14 +125,12 @@ static bool dtb_patch_rebuild(uint8_t *dtb, size_t dtb_sz, const char *file);
|
|||||||
static bool dtb_patch(const char *file) {
|
static bool dtb_patch(const char *file) {
|
||||||
bool keep_verity = check_env("KEEPVERITY");
|
bool keep_verity = check_env("KEEPVERITY");
|
||||||
|
|
||||||
size_t size;
|
|
||||||
uint8_t *dtb;
|
|
||||||
fprintf(stderr, "Loading dtbs from [%s]\n", file);
|
fprintf(stderr, "Loading dtbs from [%s]\n", file);
|
||||||
mmap_rw(file, dtb, size);
|
auto m = mmap_data(file, true);
|
||||||
|
|
||||||
bool patched = false;
|
bool patched = false;
|
||||||
uint8_t * const end = dtb + size;
|
uint8_t * const end = m.buf + m.sz;
|
||||||
for (uint8_t *fdt = dtb; fdt < end;) {
|
for (uint8_t *fdt = m.buf; fdt < end;) {
|
||||||
fdt = static_cast<uint8_t*>(memmem(fdt, end - fdt, DTB_MAGIC, sizeof(fdt32_t)));
|
fdt = static_cast<uint8_t*>(memmem(fdt, end - fdt, DTB_MAGIC, sizeof(fdt32_t)));
|
||||||
if (fdt == nullptr)
|
if (fdt == nullptr)
|
||||||
break;
|
break;
|
||||||
@ -165,8 +160,6 @@ static bool dtb_patch(const char *file) {
|
|||||||
}
|
}
|
||||||
fdt += fdt_totalsize(fdt);
|
fdt += fdt_totalsize(fdt);
|
||||||
}
|
}
|
||||||
|
|
||||||
munmap(dtb, size);
|
|
||||||
return patched;
|
return patched;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,13 +15,10 @@ static void hex2byte(const char *hex, uint8_t *buf) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int hexpatch(const char *image, const char *from, const char *to) {
|
int hexpatch(const char *file, const char *from, const char *to) {
|
||||||
int patched = 1;
|
int patched = 1;
|
||||||
|
|
||||||
uint8_t *buf;
|
auto m = mmap_data(file, true);
|
||||||
size_t sz;
|
|
||||||
mmap_rw(image, buf, sz);
|
|
||||||
run_finally f([=]{ munmap(buf, sz); });
|
|
||||||
|
|
||||||
vector<uint8_t> pattern(strlen(from) / 2);
|
vector<uint8_t> pattern(strlen(from) / 2);
|
||||||
vector<uint8_t> patch(strlen(to) / 2);
|
vector<uint8_t> patch(strlen(to) / 2);
|
||||||
@ -29,12 +26,12 @@ int hexpatch(const char *image, const char *from, const char *to) {
|
|||||||
hex2byte(from, pattern.data());
|
hex2byte(from, pattern.data());
|
||||||
hex2byte(to, patch.data());
|
hex2byte(to, patch.data());
|
||||||
|
|
||||||
uint8_t * const end = buf + sz;
|
uint8_t * const end = m.buf + m.sz;
|
||||||
for (uint8_t *curr = buf; curr < end; curr += pattern.size()) {
|
for (uint8_t *curr = m.buf; curr < end; curr += pattern.size()) {
|
||||||
curr = static_cast<uint8_t*>(memmem(curr, end - curr, pattern.data(), pattern.size()));
|
curr = static_cast<uint8_t*>(memmem(curr, end - curr, pattern.data(), pattern.size()));
|
||||||
if (curr == nullptr)
|
if (curr == nullptr)
|
||||||
return patched;
|
return patched;
|
||||||
fprintf(stderr, "Patch @ %08X [%s] -> [%s]\n", (unsigned)(curr - buf), from, to);
|
fprintf(stderr, "Patch @ %08X [%s] -> [%s]\n", (unsigned)(curr - m.buf), from, to);
|
||||||
memset(curr, 0, pattern.size());
|
memset(curr, 0, pattern.size());
|
||||||
memcpy(curr, patch.data(), patch.size());
|
memcpy(curr, patch.data(), patch.size());
|
||||||
patched = 0;
|
patched = 0;
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
int unpack(const char *image, bool skip_decomp = false, bool hdr = false);
|
int unpack(const char *image, bool skip_decomp = false, bool hdr = false);
|
||||||
void repack(const char *src_img, const char *out_img, bool skip_comp = false);
|
void repack(const char *src_img, const char *out_img, bool skip_comp = false);
|
||||||
int split_image_dtb(const char *filename);
|
int split_image_dtb(const char *filename);
|
||||||
int hexpatch(const char *image, const char *from, const char *to);
|
int hexpatch(const char *file, const char *from, const char *to);
|
||||||
int cpio_commands(int argc, char *argv[]);
|
int cpio_commands(int argc, char *argv[]);
|
||||||
int dtb_commands(int argc, char *argv[]);
|
int dtb_commands(int argc, char *argv[]);
|
||||||
|
|
||||||
|
@ -137,14 +137,11 @@ int main(int argc, char *argv[]) {
|
|||||||
unlink(DTB_FILE);
|
unlink(DTB_FILE);
|
||||||
} else if (argc > 2 && action == "sha1") {
|
} else if (argc > 2 && action == "sha1") {
|
||||||
uint8_t sha1[SHA_DIGEST_SIZE];
|
uint8_t sha1[SHA_DIGEST_SIZE];
|
||||||
void *buf;
|
auto m = mmap_data(argv[2]);
|
||||||
size_t size;
|
SHA_hash(m.buf, m.sz, sha1);
|
||||||
mmap_ro(argv[2], buf, size);
|
|
||||||
SHA_hash(buf, size, sha1);
|
|
||||||
for (uint8_t i : sha1)
|
for (uint8_t i : sha1)
|
||||||
printf("%02x", i);
|
printf("%02x", i);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
munmap(buf, size);
|
|
||||||
} else if (argc > 2 && action == "split") {
|
} else if (argc > 2 && action == "split") {
|
||||||
return split_image_dtb(argv[2]);
|
return split_image_dtb(argv[2]);
|
||||||
} else if (argc > 2 && action == "unpack") {
|
} else if (argc > 2 && action == "unpack") {
|
||||||
|
@ -74,12 +74,9 @@ static bool check_precompiled(const char *precompiled) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void load_cil(struct cil_db *db, const char *file) {
|
static void load_cil(struct cil_db *db, const char *file) {
|
||||||
char *addr;
|
auto d = mmap_data(file);
|
||||||
size_t size;
|
cil_add_file(db, (char *) file, (char *) d.buf, d.sz);
|
||||||
mmap_ro(file, addr, size);
|
|
||||||
cil_add_file(db, (char *) file, addr, size);
|
|
||||||
LOGD("cil_add [%s]\n", file);
|
LOGD("cil_add [%s]\n", file);
|
||||||
munmap(addr, size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sepolicy *sepolicy::from_file(const char *file) {
|
sepolicy *sepolicy::from_file(const char *file) {
|
||||||
|
@ -137,12 +137,9 @@ static void pb_getprop(prop_cb *prop_cb) {
|
|||||||
PersistentProperties props = {};
|
PersistentProperties props = {};
|
||||||
props.properties.funcs.decode = prop_decode;
|
props.properties.funcs.decode = prop_decode;
|
||||||
props.properties.arg = prop_cb;
|
props.properties.arg = prop_cb;
|
||||||
pb_byte_t *buf;
|
auto m = mmap_data(PERSISTENT_PROPERTY_DIR "/persistent_properties");
|
||||||
size_t size;
|
pb_istream_t stream = pb_istream_from_buffer(m.buf, m.sz);
|
||||||
mmap_ro(PERSISTENT_PROPERTY_DIR "/persistent_properties", buf, size);
|
|
||||||
pb_istream_t stream = pb_istream_from_buffer(buf, size);
|
|
||||||
pb_decode(&stream, &PersistentProperties_msg, &props);
|
pb_decode(&stream, &PersistentProperties_msg, &props);
|
||||||
munmap(buf, size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool file_getprop(const char *name, char *value) {
|
static bool file_getprop(const char *name, char *value) {
|
||||||
|
@ -272,28 +272,6 @@ void fclone_attr(int src, int dest) {
|
|||||||
fsetattr(dest, &a);
|
fsetattr(dest, &a);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *__mmap(const char *filename, size_t *size, bool rw) {
|
|
||||||
int fd = xopen(filename, (rw ? O_RDWR : O_RDONLY) | O_CLOEXEC);
|
|
||||||
if (fd < 0) {
|
|
||||||
*size = 0;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
struct stat st;
|
|
||||||
if (fstat(fd, &st)) {
|
|
||||||
*size = 0;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
if (S_ISBLK(st.st_mode))
|
|
||||||
ioctl(fd, BLKGETSIZE64, size);
|
|
||||||
else
|
|
||||||
*size = st.st_size;
|
|
||||||
void *buf = *size > 0 ?
|
|
||||||
xmmap(nullptr, *size, PROT_READ | PROT_WRITE, rw ? MAP_SHARED : MAP_PRIVATE, fd, 0) :
|
|
||||||
nullptr;
|
|
||||||
close(fd);
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
void fd_full_read(int fd, void **buf, size_t *size) {
|
void fd_full_read(int fd, void **buf, size_t *size) {
|
||||||
*size = lseek(fd, 0, SEEK_END);
|
*size = lseek(fd, 0, SEEK_END);
|
||||||
lseek(fd, 0, SEEK_SET);
|
lseek(fd, 0, SEEK_SET);
|
||||||
@ -439,15 +417,58 @@ sFILE make_file(FILE *fp) {
|
|||||||
return sFILE(fp, [](FILE *fp){ return fp ? fclose(fp) : 1; });
|
return sFILE(fp, [](FILE *fp){ return fp ? fclose(fp) : 1; });
|
||||||
}
|
}
|
||||||
|
|
||||||
raw_file::raw_file(raw_file &&o) {
|
int byte_data::patch(bool log, str_pairs list) {
|
||||||
path.swap(o.path);
|
if (buf == nullptr)
|
||||||
attr = o.attr;
|
return 0;
|
||||||
buf = o.buf;
|
int count = 0;
|
||||||
sz = o.sz;
|
for (uint8_t *p = buf, *eof = buf + sz; p < eof; ++p) {
|
||||||
o.buf = nullptr;
|
for (auto [from, to] : list) {
|
||||||
o.sz = 0;
|
if (memcmp(p, from.data(), from.length() + 1) == 0) {
|
||||||
|
if (log) LOGD("Replace [%s] -> [%s]\n", from.data(), to.data());
|
||||||
|
memset(p, 0, from.length());
|
||||||
|
memcpy(p, to.data(), to.length());
|
||||||
|
++count;
|
||||||
|
p += from.length();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
raw_file::~raw_file() {
|
bool byte_data::contains(string_view pattern, bool log) const {
|
||||||
free(buf);
|
if (buf == nullptr)
|
||||||
|
return false;
|
||||||
|
for (uint8_t *p = buf, *eof = buf + sz; p < eof; ++p) {
|
||||||
|
if (memcmp(p, pattern.data(), pattern.length() + 1) == 0) {
|
||||||
|
if (log) LOGD("Found pattern [%s]\n", pattern.data());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void byte_data::swap(byte_data &o) {
|
||||||
|
std::swap(buf, o.buf);
|
||||||
|
std::swap(sz, o.sz);
|
||||||
|
}
|
||||||
|
|
||||||
|
mmap_data::mmap_data(const char *name, bool rw) {
|
||||||
|
int fd = xopen(name, (rw ? O_RDWR : O_RDONLY) | O_CLOEXEC);
|
||||||
|
if (fd < 0)
|
||||||
|
return;
|
||||||
|
struct stat st;
|
||||||
|
if (fstat(fd, &st))
|
||||||
|
return;
|
||||||
|
if (S_ISBLK(st.st_mode)) {
|
||||||
|
uint64_t size;
|
||||||
|
ioctl(fd, BLKGETSIZE64, &size);
|
||||||
|
sz = size;
|
||||||
|
} else {
|
||||||
|
sz = st.st_size;
|
||||||
|
}
|
||||||
|
void *b = sz > 0
|
||||||
|
? xmmap(nullptr, sz, PROT_READ | PROT_WRITE, rw ? MAP_SHARED : MAP_PRIVATE, fd, 0)
|
||||||
|
: nullptr;
|
||||||
|
close(fd);
|
||||||
|
buf = static_cast<uint8_t *>(b);
|
||||||
}
|
}
|
||||||
|
@ -26,16 +26,36 @@ struct file_attr {
|
|||||||
char con[128];
|
char con[128];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct raw_file {
|
struct byte_data {
|
||||||
|
using str_pairs = std::initializer_list<std::pair<std::string_view, std::string_view>>;
|
||||||
|
|
||||||
|
uint8_t *buf = nullptr;
|
||||||
|
size_t sz = 0;
|
||||||
|
|
||||||
|
int patch(str_pairs list) { return patch(true, list); }
|
||||||
|
int patch(bool log, str_pairs list);
|
||||||
|
bool contains(std::string_view pattern, bool log = true) const;
|
||||||
|
protected:
|
||||||
|
void swap(byte_data &o);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct raw_file : public byte_data {
|
||||||
std::string path;
|
std::string path;
|
||||||
file_attr attr;
|
file_attr attr;
|
||||||
uint8_t *buf;
|
|
||||||
size_t sz;
|
|
||||||
|
|
||||||
raw_file() : attr({}), buf(nullptr), sz(0) {}
|
raw_file() : attr{} {}
|
||||||
raw_file(const raw_file&) = delete;
|
raw_file(const raw_file&) = delete;
|
||||||
raw_file(raw_file &&o);
|
raw_file(raw_file &&o) : path(std::move(o.path)), attr(o.attr) { swap(o); }
|
||||||
~raw_file();
|
~raw_file() { free(buf); }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mmap_data : public byte_data {
|
||||||
|
mmap_data() = default;
|
||||||
|
mmap_data(const mmap_data&) = delete;
|
||||||
|
mmap_data(mmap_data &&o) { swap(o); }
|
||||||
|
mmap_data(const char *name, bool rw = false);
|
||||||
|
~mmap_data() { if (buf) munmap(buf, sz); }
|
||||||
|
mmap_data& operator=(mmap_data &&other) { swap(other); return *this; }
|
||||||
};
|
};
|
||||||
|
|
||||||
ssize_t fd_path(int fd, char *path, size_t size);
|
ssize_t fd_path(int fd, char *path, size_t size);
|
||||||
@ -67,7 +87,6 @@ static inline void file_readline(const char *file,
|
|||||||
}
|
}
|
||||||
void parse_prop_file(const char *file,
|
void parse_prop_file(const char *file,
|
||||||
const std::function<bool(std::string_view, std::string_view)> &fn);
|
const std::function<bool(std::string_view, std::string_view)> &fn);
|
||||||
void *__mmap(const char *filename, size_t *size, bool rw);
|
|
||||||
void frm_rf(int dirfd);
|
void frm_rf(int dirfd);
|
||||||
void clone_dir(int src, int dest);
|
void clone_dir(int src, int dest);
|
||||||
void parse_mnt(const char *file, const std::function<bool(mntent*)> &fn);
|
void parse_mnt(const char *file, const std::function<bool(mntent*)> &fn);
|
||||||
@ -86,30 +105,6 @@ void fd_full_read(int fd, T &buf, size_t &size) {
|
|||||||
fd_full_read(fd, reinterpret_cast<void**>(&buf), &size);
|
fd_full_read(fd, reinterpret_cast<void**>(&buf), &size);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
void mmap_ro(const char *filename, B &buf, size_t &sz) {
|
|
||||||
buf = (B) __mmap(filename, &sz, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename B, typename L>
|
|
||||||
void mmap_ro(const char *filename, B &buf, L &sz) {
|
|
||||||
size_t __sz;
|
|
||||||
buf = (B) __mmap(filename, &__sz, false);
|
|
||||||
sz = __sz;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
void mmap_rw(const char *filename, B &buf, size_t &sz) {
|
|
||||||
buf = (B) __mmap(filename, &sz, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename B, typename L>
|
|
||||||
void mmap_rw(const char *filename, B &buf, L &sz) {
|
|
||||||
size_t __sz;
|
|
||||||
buf = (B) __mmap(filename, &__sz, true);
|
|
||||||
sz = __sz;
|
|
||||||
}
|
|
||||||
|
|
||||||
using sFILE = std::unique_ptr<FILE, decltype(&fclose)>;
|
using sFILE = std::unique_ptr<FILE, decltype(&fclose)>;
|
||||||
using sDIR = std::unique_ptr<DIR, decltype(&closedir)>;
|
using sDIR = std::unique_ptr<DIR, decltype(&closedir)>;
|
||||||
sDIR make_dir(DIR *dp);
|
sDIR make_dir(DIR *dp);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user