Improve byte_data const correctness

This commit is contained in:
topjohnwu 2023-06-03 03:16:03 -07:00
parent 57afae3425
commit 2a654e5d7f
17 changed files with 186 additions and 161 deletions

View File

@ -433,14 +433,14 @@ 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; });
} }
int byte_data::patch(bool log, str_pairs list) { int byte_data::patch(str_pairs list) {
if (buf == nullptr) if (_buf == nullptr)
return 0; return 0;
int count = 0; int count = 0;
for (uint8_t *p = buf, *eof = buf + sz; p < eof; ++p) { for (uint8_t *p = _buf, *eof = _buf + _sz; p < eof; ++p) {
for (auto [from, to] : list) { for (auto &[from, to] : list) {
if (memcmp(p, from.data(), from.length() + 1) == 0) { if (memcmp(p, from.data(), from.length() + 1) == 0) {
if (log) LOGD("Replace [%s] -> [%s]\n", from.data(), to.data()); LOGD("Patch @ %08X [%s] -> [%s]\n", (unsigned)(p - _buf), from.data(), to.data());
memset(p, 0, from.length()); memset(p, 0, from.length());
memcpy(p, to.data(), to.length()); memcpy(p, to.data(), to.length());
++count; ++count;
@ -451,33 +451,55 @@ int byte_data::patch(bool log, str_pairs list) {
return count; return count;
} }
bool byte_data::contains(string_view pattern, bool log) const { int byte_data::patch(byte_pairs list) {
if (buf == nullptr) 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.buf(), from.sz()) == 0) {
LOGD("Patch @ %08X\n", (unsigned)(p - _buf));
memset(p, 0, from.sz());
memcpy(p, to.buf(), to.sz());
++count;
p += from.sz();
}
}
}
return count;
}
bool byte_view::contains(string_view pattern) const {
if (_buf == nullptr)
return false; return false;
for (uint8_t *p = buf, *eof = buf + sz; p < eof; ++p) { for (uint8_t *p = _buf, *eof = _buf + _sz; p < eof; ++p) {
if (memcmp(p, pattern.data(), pattern.length() + 1) == 0) { if (memcmp(p, pattern.data(), pattern.length() + 1) == 0) {
if (log) LOGD("Found pattern [%s]\n", pattern.data()); LOGD("Found pattern [%s]\n", pattern.data());
return true; return true;
} }
} }
return false; return false;
} }
bool byte_data::equals(const byte_data &o) const { bool byte_view::equals(const byte_view &o) const {
return sz == o.sz && memcmp(buf, o.buf, sz) == 0; return _sz == o._sz && memcmp(_buf, o._buf, _sz) == 0;
} }
void byte_data::swap(byte_data &o) { void byte_view::swap(byte_view &o) {
std::swap(buf, o.buf); std::swap(_buf, o._buf);
std::swap(sz, o.sz); std::swap(_sz, o._sz);
} }
heap_data byte_data::clone() const { heap_data byte_view::clone() const {
heap_data copy(sz); heap_data copy(_sz);
memcpy(copy.buf, buf, sz); memcpy(copy._buf, _buf, _sz);
return copy; return copy;
} }
void heap_data::realloc(size_t sz) {
_buf = static_cast<uint8_t *>(::realloc(_buf, sz));
}
mmap_data::mmap_data(const char *name, bool rw) { mmap_data::mmap_data(const char *name, bool rw) {
int fd = xopen(name, (rw ? O_RDWR : O_RDONLY) | O_CLOEXEC); int fd = xopen(name, (rw ? O_RDWR : O_RDONLY) | O_CLOEXEC);
if (fd < 0) if (fd < 0)
@ -488,15 +510,15 @@ mmap_data::mmap_data(const char *name, bool rw) {
if (S_ISBLK(st.st_mode)) { if (S_ISBLK(st.st_mode)) {
uint64_t size; uint64_t size;
ioctl(fd, BLKGETSIZE64, &size); ioctl(fd, BLKGETSIZE64, &size);
sz = size; _sz = size;
} else { } else {
sz = st.st_size; _sz = st.st_size;
} }
void *b = sz > 0 void *b = _sz > 0
? xmmap(nullptr, sz, PROT_READ | PROT_WRITE, rw ? MAP_SHARED : MAP_PRIVATE, fd, 0) ? xmmap(nullptr, _sz, PROT_READ | PROT_WRITE, rw ? MAP_SHARED : MAP_PRIVATE, fd, 0)
: nullptr; : nullptr;
close(fd); close(fd);
buf = static_cast<uint8_t *>(b); _buf = static_cast<uint8_t *>(b);
} }
string find_apk_path(const char *pkg) { string find_apk_path(const char *pkg) {

View File

@ -45,23 +45,41 @@ struct mount_info {
struct heap_data; struct heap_data;
struct byte_data { struct byte_view {
using str_pairs = std::initializer_list<std::pair<std::string_view, std::string_view>>; byte_view() : _buf(nullptr), _sz(0) {}
byte_view(const void *buf, size_t sz) : _buf((uint8_t *) buf), _sz(sz) {}
byte_view(std::string_view str) : byte_view(str.data(), str.length()) {}
byte_view(const std::vector<uint8_t> &v) : byte_view(v.data(), v.size()) {}
uint8_t *buf; const uint8_t *buf() const { return _buf; }
size_t sz; const size_t &sz() const { return _sz; }
byte_data() : buf(nullptr), sz(0) {} bool contains(std::string_view pattern) const;
byte_data(void *buf, size_t sz) : buf(static_cast<uint8_t *>(buf)), sz(sz) {} bool equals(const byte_view &o) const;
explicit byte_data(std::string_view str) : buf((uint8_t *) str.data()), sz(str.length()) {}
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;
bool equals(const byte_data &o) const;
heap_data clone() const; heap_data clone() const;
protected: protected:
void swap(byte_data &o); uint8_t *_buf;
size_t _sz;
byte_view(uint8_t *buf, size_t sz) : _buf(buf), _sz(sz) {}
void swap(byte_view &o);
};
struct byte_data : public byte_view {
using str_pairs = std::initializer_list<std::pair<std::string_view, std::string_view>>;
using byte_pairs = std::initializer_list<std::pair<byte_view, byte_view>>;
byte_data() = default;
byte_data(void *buf, size_t sz) : byte_view(static_cast<uint8_t *>(buf), sz) {}
using byte_view::buf;
using byte_view::sz;
uint8_t *buf() { return _buf; }
size_t &sz() { return _sz; }
int patch(str_pairs list);
int patch(byte_pairs list);
}; };
#define MOVE_ONLY(clazz) \ #define MOVE_ONLY(clazz) \
@ -73,16 +91,18 @@ clazz& operator=(clazz &&o) { swap(o); return *this; }
struct heap_data : public byte_data { struct heap_data : public byte_data {
MOVE_ONLY(heap_data) MOVE_ONLY(heap_data)
explicit heap_data(size_t sz) : byte_data(new uint8_t[sz], sz) {} explicit heap_data(size_t sz) : byte_data(malloc(sz), sz) {}
heap_data(const void *buf, size_t sz) : heap_data(sz) { memcpy(this->buf, buf, sz); } heap_data(const void *buf, size_t sz) : heap_data(sz) { memcpy(_buf, buf, sz); }
~heap_data() { delete[] buf; } ~heap_data() { free(_buf); }
void realloc(size_t sz);
}; };
struct mmap_data : public byte_data { struct mmap_data : public byte_data {
MOVE_ONLY(mmap_data) MOVE_ONLY(mmap_data)
mmap_data(const char *name, bool rw = false); mmap_data(const char *name, bool rw = false);
~mmap_data() { if (buf) munmap(buf, sz); } ~mmap_data() { if (_buf) munmap(_buf, _sz); }
}; };
extern "C" { extern "C" {

View File

@ -95,9 +95,9 @@ bool chunk_out_stream::write(const void *_in, size_t len) {
// Enough input for a chunk // Enough input for a chunk
const uint8_t *src; const uint8_t *src;
if (buf_off) { if (buf_off) {
src = data.buf; src = data.buf();
auto copy = chunk_sz - buf_off; auto copy = chunk_sz - buf_off;
memcpy(data.buf + buf_off, in, copy); memcpy(data.buf() + buf_off, in, copy);
in += copy; in += copy;
len -= copy; len -= copy;
buf_off = 0; buf_off = 0;
@ -110,7 +110,7 @@ bool chunk_out_stream::write(const void *_in, size_t len) {
return false; return false;
} else { } else {
// Buffer internally // Buffer internally
memcpy(data.buf + buf_off, in, len); memcpy(data.buf() + buf_off, in, len);
buf_off += len; buf_off += len;
break; break;
} }
@ -124,7 +124,7 @@ bool chunk_out_stream::write_chunk(const void *buf, size_t len, bool) {
void chunk_out_stream::finalize() { void chunk_out_stream::finalize() {
if (buf_off) { if (buf_off) {
if (!write_chunk(data.buf, buf_off, true)) { if (!write_chunk(data.buf(), buf_off, true)) {
LOGE("Error in finalize, file truncated\n"); LOGE("Error in finalize, file truncated\n");
} }
buf_off = 0; buf_off = 0;
@ -132,17 +132,17 @@ void chunk_out_stream::finalize() {
} }
ssize_t byte_channel::read(void *buf, size_t len) { ssize_t byte_channel::read(void *buf, size_t len) {
len = std::min((size_t) len, _data.sz - _pos); len = std::min((size_t) len, _data.sz() - _pos);
memcpy(buf, _data.buf + _pos, len); memcpy(buf, _data.buf() + _pos, len);
_pos += len; _pos += len;
return len; return len;
} }
bool byte_channel::write(const void *buf, size_t len) { bool byte_channel::write(const void *buf, size_t len) {
resize(_pos + len); resize(_pos + len);
memcpy(_data.buf + _pos, buf, len); memcpy(_data.buf() + _pos, buf, len);
_pos += len; _pos += len;
_data.sz = std::max(_data.sz, _pos); _data.sz() = std::max(_data.sz(), _pos);
return true; return true;
} }
@ -153,7 +153,7 @@ off_t byte_channel::seek(off_t off, int whence) {
np = _pos + off; np = _pos + off;
break; break;
case SEEK_END: case SEEK_END:
np = _data.sz + off; np = _data.sz() + off;
break; break;
case SEEK_SET: case SEEK_SET:
np = off; np = off;
@ -174,9 +174,9 @@ void byte_channel::resize(size_t new_sz, bool zero) {
resize = true; resize = true;
} }
if (resize) { if (resize) {
_data.buf = (uint8_t *) realloc(_data.buf, _cap); _data.realloc(_cap);
if (zero) if (zero)
memset(_data.buf + old_cap, 0, _cap - old_cap); memset(_data.buf() + old_cap, 0, _cap - old_cap);
} }
} }

View File

@ -151,8 +151,8 @@ void dyn_img_hdr::load_hdr_file() {
boot_img::boot_img(const char *image) : map(image) { boot_img::boot_img(const char *image) : map(image) {
fprintf(stderr, "Parsing boot image: [%s]\n", image); fprintf(stderr, "Parsing boot image: [%s]\n", image);
for (const uint8_t *addr = map.buf; addr < map.buf + map.sz; ++addr) { for (const uint8_t *addr = map.buf(); addr < map.buf() + map.sz(); ++addr) {
format_t fmt = check_fmt(addr, map.sz); format_t fmt = check_fmt(addr, map.sz());
switch (fmt) { switch (fmt) {
case CHROMEOS: case CHROMEOS:
// chromeos require external signing // chromeos require external signing
@ -425,9 +425,9 @@ void boot_img::parse_image(const 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.buf + map.sz) { if (addr + off < map.buf() + map.sz()) {
tail = addr + off; tail = addr + off;
tail_size = map.buf + map.sz - 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)) {
@ -454,18 +454,18 @@ void boot_img::parse_image(const uint8_t *addr, format_t type) {
} }
int split_image_dtb(const char *filename) { int split_image_dtb(const char *filename) {
auto img = mmap_data(filename); mmap_data img(filename);
if (int off = find_dtb_offset(img.buf, img.sz); off > 0) { if (int off = find_dtb_offset(img.buf(), img.sz()); off > 0) {
format_t fmt = check_fmt_lg(img.buf, img.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, img.buf, off); decompress(fmt, fd, img.buf(), off);
close(fd); close(fd);
} else { } else {
dump(img.buf, off, KERNEL_FILE); dump(img.buf(), off, KERNEL_FILE);
} }
dump(img.buf + off, img.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);
@ -569,11 +569,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.buf, 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.buf, 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.buf, ACCLAIM_PRE_HEADER_SZ); xwrite(fd, boot.map.buf(), ACCLAIM_PRE_HEADER_SZ);
} }
// Copy raw header // Copy raw header
@ -591,13 +591,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) {
auto m = mmap_data(KERNEL_FILE); mmap_data m(KERNEL_FILE);
if (!skip_comp && !COMPRESSED_ANY(check_fmt(m.buf, m.sz)) && COMPRESSED(boot.k_fmt)) { if (!skip_comp && !COMPRESSED_ANY(check_fmt(m.buf(), m.sz())) && 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, m.buf, m.sz); hdr->kernel_size() = compress(fmt, fd, m.buf(), m.sz());
} else { } else {
hdr->kernel_size() = xwrite(fd, m.buf, m.sz); hdr->kernel_size() = xwrite(fd, m.buf(), m.sz());
} }
if (boot.flags[ZIMAGE_KERNEL]) { if (boot.flags[ZIMAGE_KERNEL]) {
@ -608,7 +608,7 @@ void repack(const char *src_img, const char *out_img, bool skip_comp) {
} else if (!skip_comp) { } else if (!skip_comp) {
// 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 = m.sz; 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));
} }
@ -638,7 +638,7 @@ 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) {
auto m = mmap_data(RAMDISK_FILE); mmap_data m(RAMDISK_FILE);
auto r_fmt = boot.r_fmt; auto r_fmt = boot.r_fmt;
if (!skip_comp && !hdr->is_vendor && hdr->header_version() == 4 && r_fmt != LZ4_LEGACY) { if (!skip_comp && !hdr->is_vendor && hdr->header_version() == 4 && r_fmt != LZ4_LEGACY) {
// A v4 boot image ramdisk will have to be merged with other vendor ramdisks, // A v4 boot image ramdisk will have to be merged with other vendor ramdisks,
@ -647,10 +647,10 @@ void repack(const char *src_img, const char *out_img, bool skip_comp) {
fprintf(stderr, "RAMDISK_FMT: [%s] -> [%s]\n", fmt2name[r_fmt], fmt2name[LZ4_LEGACY]); fprintf(stderr, "RAMDISK_FMT: [%s] -> [%s]\n", fmt2name[r_fmt], fmt2name[LZ4_LEGACY]);
r_fmt = LZ4_LEGACY; r_fmt = LZ4_LEGACY;
} }
if (!skip_comp && !COMPRESSED_ANY(check_fmt(m.buf, m.sz)) && COMPRESSED(r_fmt)) { if (!skip_comp && !COMPRESSED_ANY(check_fmt(m.buf(), m.sz())) && COMPRESSED(r_fmt)) {
hdr->ramdisk_size() = compress(r_fmt, fd, m.buf, m.sz); hdr->ramdisk_size() = compress(r_fmt, fd, m.buf(), m.sz());
} else { } else {
hdr->ramdisk_size() = xwrite(fd, m.buf, m.sz); hdr->ramdisk_size() = xwrite(fd, m.buf(), m.sz());
} }
file_align(); file_align();
} }
@ -665,11 +665,11 @@ 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) {
auto m = mmap_data(EXTRA_FILE); mmap_data m(EXTRA_FILE);
if (!skip_comp && !COMPRESSED_ANY(check_fmt(m.buf, m.sz)) && COMPRESSED(boot.e_fmt)) { if (!skip_comp && !COMPRESSED_ANY(check_fmt(m.buf(), m.sz())) && COMPRESSED(boot.e_fmt)) {
hdr->extra_size() = compress(boot.e_fmt, fd, m.buf, m.sz); hdr->extra_size() = compress(boot.e_fmt, fd, m.buf(), m.sz());
} else { } else {
hdr->extra_size() = xwrite(fd, m.buf, m.sz); hdr->extra_size() = xwrite(fd, m.buf(), m.sz());
} }
file_align(); file_align();
} }
@ -720,8 +720,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.sz) { if (current < boot.map.sz()) {
write_zero(fd, boot.map.sz - current); write_zero(fd, boot.map.sz() - current);
} }
} }
@ -732,16 +732,16 @@ void repack(const char *src_img, const char *out_img, bool skip_comp) {
******************/ ******************/
// Map output image as rw // Map output image as rw
auto out = mmap_data(out_img, true); mmap_data out(out_img, true);
// MTK headers // MTK headers
if (boot.flags[MTK_KERNEL]) { if (boot.flags[MTK_KERNEL]) {
auto m_hdr = reinterpret_cast<mtk_hdr *>(out.buf + 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 *>(out.buf + 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);
} }
@ -754,28 +754,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, out.buf + 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, out.buf + 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, out.buf + 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, out.buf + 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, out.buf + 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, out.buf + 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);
@ -788,15 +788,15 @@ void repack(const char *src_img, const char *out_img, bool skip_comp) {
// Copy main header // Copy main header
if (boot.flags[AMONET_FLAG]) { if (boot.flags[AMONET_FLAG]) {
auto real_hdr_sz = std::min(hdr->hdr_space() - AMONET_MICROLOADER_SZ, hdr->hdr_size()); auto real_hdr_sz = std::min(hdr->hdr_space() - AMONET_MICROLOADER_SZ, hdr->hdr_size());
memcpy(out.buf + off.header + AMONET_MICROLOADER_SZ, hdr->raw_hdr(), real_hdr_sz); memcpy(out.buf() + off.header + AMONET_MICROLOADER_SZ, hdr->raw_hdr(), real_hdr_sz);
} else { } else {
memcpy(out.buf + 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*>(out.buf + out.sz - sizeof(AvbFooter)); auto footer = reinterpret_cast<AvbFooter*>(out.buf() + out.sz() - sizeof(AvbFooter));
auto vbmeta = reinterpret_cast<AvbVBMetaImageHeader*>(out.buf + 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);
@ -807,13 +807,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 *>(out.buf); 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(out.buf + 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 *>(out.buf); 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);
} }
} }

View File

@ -45,7 +45,7 @@ static uint32_t x8u(const char *hex) {
cpio_entry::cpio_entry(uint32_t mode) : mode(mode), uid(0), gid(0), data(0) {} cpio_entry::cpio_entry(uint32_t mode) : mode(mode), uid(0), gid(0), data(0) {}
cpio_entry::cpio_entry(uint32_t mode, const byte_data &data) : cpio_entry::cpio_entry(uint32_t mode, const byte_view &data) :
mode(mode), uid(0), gid(0), data(data.clone()) {} mode(mode), uid(0), gid(0), data(data.clone()) {}
cpio_entry::cpio_entry(const cpio_newc_header *h) : cpio_entry::cpio_entry(const cpio_newc_header *h) :
@ -89,13 +89,13 @@ static void extract_entry(const cpio::entry_map::value_type &e, const char *file
xmkdir(file, e.second->mode & 0777); xmkdir(file, e.second->mode & 0777);
} else if (S_ISREG(e.second->mode)) { } else if (S_ISREG(e.second->mode)) {
int fd = xopen(file, O_CREAT | O_WRONLY | O_TRUNC, e.second->mode & 0777); int fd = xopen(file, O_CREAT | O_WRONLY | O_TRUNC, e.second->mode & 0777);
xwrite(fd, e.second->data.buf, e.second->data.sz); xwrite(fd, e.second->data.buf(), e.second->data.sz());
fchown(fd, e.second->uid, e.second->gid); fchown(fd, e.second->uid, e.second->gid);
close(fd); close(fd);
} else if (S_ISLNK(e.second->mode) && e.second->data.sz < 4096) { } else if (S_ISLNK(e.second->mode) && e.second->data.sz() < 4096) {
char target[4096]; char target[4096];
memcpy(target, e.second->data.buf, e.second->data.sz); memcpy(target, e.second->data.buf(), e.second->data.sz());
target[e.second->data.sz] = '\0'; target[e.second->data.sz()] = '\0';
symlink(target, file); symlink(target, file);
} }
} }
@ -134,7 +134,7 @@ void cpio::dump(FILE *out) {
e.second->gid, e.second->gid,
1, // e->nlink 1, // e->nlink
0, // e->mtime 0, // e->mtime
(uint32_t) e.second->data.sz, (uint32_t) e.second->data.sz(),
0, // e->devmajor 0, // e->devmajor
0, // e->devminor 0, // e->devminor
0, // e->rdevmajor 0, // e->rdevmajor
@ -145,8 +145,8 @@ void cpio::dump(FILE *out) {
do_out(header, 110); do_out(header, 110);
do_out(e.first.data(), e.first.size() + 1); do_out(e.first.data(), e.first.size() + 1);
out_align(); out_align();
if (e.second->data.sz) { if (e.second->data.sz()) {
do_out(e.second->data.buf, e.second->data.sz); do_out(e.second->data.buf(), e.second->data.sz());
out_align(); out_align();
} }
} }
@ -161,8 +161,8 @@ void cpio::dump(FILE *out) {
void cpio::load_cpio(const char *file) { void cpio::load_cpio(const char *file) {
fprintf(stderr, "Loading cpio: [%s]\n", file); fprintf(stderr, "Loading cpio: [%s]\n", file);
auto m = mmap_data(file); mmap_data m(file);
load_cpio(reinterpret_cast<char *>(m.buf), m.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) {
@ -187,7 +187,7 @@ void cpio::mkdir(mode_t mode, const char *name) {
} }
void cpio::ln(const char *target, const char *name) { void cpio::ln(const char *target, const char *name) {
byte_data link(target); byte_view link(target);
auto e = new cpio_entry(S_IFLNK, link); auto e = new cpio_entry(S_IFLNK, link);
insert(name, e); insert(name, e);
fprintf(stderr, "Create symlink [%s] -> [%s]\n", name, target); fprintf(stderr, "Create symlink [%s] -> [%s]\n", name, target);
@ -234,8 +234,8 @@ void cpio::load_cpio(const char *buf, size_t sz) {
continue; continue;
} }
auto entry = new cpio_entry(hdr); auto entry = new cpio_entry(hdr);
memcpy(entry->data.buf, buf + pos, entry->data.sz); memcpy(entry->data.buf(), buf + pos, entry->data.sz());
pos += entry->data.sz; pos += entry->data.sz();
insert(name, entry); insert(name, entry);
pos_align(pos); pos_align(pos);
} }

View File

@ -17,7 +17,7 @@ struct cpio_entry {
heap_data data; heap_data data;
explicit cpio_entry(uint32_t mode); explicit cpio_entry(uint32_t mode);
explicit cpio_entry(uint32_t mode, const byte_data &data); explicit cpio_entry(uint32_t mode, const byte_view &data);
explicit cpio_entry(const cpio_newc_header *h); explicit cpio_entry(const cpio_newc_header *h);
}; };

View File

@ -95,9 +95,9 @@ static int find_fstab(const void *fdt, int node = 0) {
template<typename Func> template<typename Func>
static void for_each_fdt(const char *file, bool rw, Func fn) { static void for_each_fdt(const char *file, bool rw, Func fn) {
auto m = mmap_data(file, rw); mmap_data m(file, rw);
uint8_t *end = m.buf + m.sz; uint8_t *end = m.buf() + m.sz();
for (uint8_t *fdt = m.buf; 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;
@ -226,7 +226,7 @@ static bool fdt_patch(void *fdt) {
heap_data copy(value, len); heap_data copy(value, len);
if (patch_verity(copy)) { if (patch_verity(copy)) {
modified = true; modified = true;
fdt_setprop(fdt, node, "fsmgr_flags", copy.buf, copy.sz); fdt_setprop(fdt, node, "fsmgr_flags", copy.buf(), copy.sz());
} }
if (name == "system"sv) { if (name == "system"sv) {
fprintf(stderr, "Setting [mnt_point] to [/system_root]\n"); fprintf(stderr, "Setting [mnt_point] to [/system_root]\n");

View File

@ -1,41 +1,24 @@
#include <sys/mman.h>
#include <base.hpp>
#include "magiskboot.hpp" #include "magiskboot.hpp"
using namespace std; using namespace std;
static void hex2byte(const char *hex, uint8_t *buf) { static void hex2byte(string_view hex, uint8_t *buf) {
char high, low; char high, low;
for (int i = 0, length = strlen(hex); i < length; i += 2) { for (int i = 0, length = hex.length(); i < length; i += 2) {
high = toupper(hex[i]) - '0'; high = toupper(hex[i]) - '0';
low = toupper(hex[i + 1]) - '0'; low = toupper(hex[i + 1]) - '0';
buf[i / 2] = ((high > 9 ? high - 7 : high) << 4) + (low > 9 ? low - 7 : low); buf[i / 2] = ((high > 9 ? high - 7 : high) << 4) + (low > 9 ? low - 7 : low);
} }
} }
int hexpatch(const char *file, const char *from, const char *to) { int hexpatch(const char *file, string_view from, string_view to) {
int patched = 1; mmap_data m(file, true);
auto m = mmap_data(file, true); vector<uint8_t> pattern(from.length() / 2);
vector<uint8_t> patch(to.length() / 2);
vector<uint8_t> pattern(strlen(from) / 2);
vector<uint8_t> patch(strlen(to) / 2);
hex2byte(from, pattern.data()); hex2byte(from, pattern.data());
hex2byte(to, patch.data()); hex2byte(to, patch.data());
uint8_t * const end = m.buf + m.sz; return m.patch({ make_pair(pattern, patch) }) > 0 ? 0 : 1;
for (uint8_t *curr = m.buf; curr < end; curr += pattern.size()) {
curr = static_cast<uint8_t*>(memmem(curr, end - curr, pattern.data(), pattern.size()));
if (curr == nullptr)
return patched;
fprintf(stderr, "Patch @ %08X [%s] -> [%s]\n", (unsigned)(curr - m.buf), from, to);
memset(curr, 0, pattern.size());
memcpy(curr, patch.data(), patch.size());
patched = 0;
}
return patched;
} }

View File

@ -19,7 +19,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 *file, const char *from, const char *to); int hexpatch(const char *file, std::string_view from, std::string_view 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[]);

View File

@ -159,8 +159,8 @@ 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];
auto m = mmap_data(argv[2]); mmap_data m(argv[2]);
SHA_hash(m.buf, m.sz, sha1); SHA_hash(m.buf(), m.sz(), sha1);
for (uint8_t i : sha1) for (uint8_t i : sha1)
printf("%02x", i); printf("%02x", i);
printf("\n"); printf("\n");

View File

@ -40,21 +40,21 @@ static int skip_encryption_pattern(const char *s) {
} }
static bool remove_pattern(byte_data &data, int(*pattern_skip)(const char *)) { static bool remove_pattern(byte_data &data, int(*pattern_skip)(const char *)) {
char *src = reinterpret_cast<char *>(data.buf); char *src = reinterpret_cast<char *>(data.buf());
size_t orig_sz = data.sz; size_t orig_sz = data.sz();
int write = 0; int write = 0;
int read = 0; int read = 0;
while (read < orig_sz) { while (read < orig_sz) {
if (int skip = pattern_skip(src + read); skip > 0) { if (int skip = pattern_skip(src + read); skip > 0) {
fprintf(stderr, "Remove pattern [%.*s]\n", skip, src + read); fprintf(stderr, "Remove pattern [%.*s]\n", skip, src + read);
data.sz -= skip; data.sz() -= skip;
read += skip; read += skip;
} else { } else {
src[write++] = src[read++]; src[write++] = src[read++];
} }
} }
memset(src + write, 0, orig_sz - write); memset(src + write, 0, orig_sz - write);
return data.sz != orig_sz; return data.sz() != orig_sz;
} }
bool patch_verity(byte_data &data) { bool patch_verity(byte_data &data) {

View File

@ -111,7 +111,7 @@ void magisk_cpio::restore() {
rm(bk); rm(bk);
rm(mg); rm(mg);
if (rl != entries.end()) { if (rl != entries.end()) {
for_each_str(file, rl->second->data.buf, rl->second->data.sz) { for_each_str(file, rl->second->data.buf(), rl->second->data.sz()) {
rm(file); rm(file);
} }
rm(rl); rm(rl);
@ -186,7 +186,7 @@ void magisk_cpio::backup(const char *orig) {
} }
if (!rm_list.empty()) { if (!rm_list.empty()) {
byte_data rm(rm_list); byte_view rm(rm_list);
auto rm_list_file = new cpio_entry(S_IFREG, rm); auto rm_list_file = new cpio_entry(S_IFREG, rm);
backups.emplace(".backup/.rmlist", rm_list_file); backups.emplace(".backup/.rmlist", rm_list_file);
} }

View File

@ -137,8 +137,8 @@ static void pb_get_prop(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;
auto m = mmap_data(PERSIST_PROP); mmap_data m(PERSIST_PROP);
pb_istream_t stream = pb_istream_from_buffer(m.buf, m.sz); pb_istream_t stream = pb_istream_from_buffer(m.buf(), m.sz());
pb_decode(&stream, &PersistentProperties_msg, &props); pb_decode(&stream, &PersistentProperties_msg, &props);
} }

View File

@ -213,7 +213,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(backup_init()); mmap_data init(backup_init());
return init.contains("selinux_setup"); return init.contains("selinux_setup");
} }

View File

@ -164,27 +164,27 @@ static void extract_files(bool sbin) {
const char *stub_xz = sbin ? "/sbin/stub.xz" : "stub.xz"; const char *stub_xz = sbin ? "/sbin/stub.xz" : "stub.xz";
if (access(m32, F_OK) == 0) { if (access(m32, F_OK) == 0) {
auto magisk = mmap_data(m32); mmap_data magisk(m32);
unlink(m32); unlink(m32);
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);
} }
if (access(m64, F_OK) == 0) { if (access(m64, F_OK) == 0) {
auto magisk = mmap_data(m64); mmap_data magisk(m64);
unlink(m64); unlink(m64);
int fd = xopen("magisk64", O_WRONLY | O_CREAT, 0755); int fd = xopen("magisk64", O_WRONLY | O_CREAT, 0755);
unxz(fd, magisk.buf, magisk.sz); unxz(fd, magisk.buf(), magisk.sz());
close(fd); close(fd);
xsymlink("./magisk64", "magisk"); xsymlink("./magisk64", "magisk");
} else { } else {
xsymlink("./magisk32", "magisk"); xsymlink("./magisk32", "magisk");
} }
if (access(stub_xz, F_OK) == 0) { if (access(stub_xz, F_OK) == 0) {
auto stub = mmap_data(stub_xz); mmap_data stub(stub_xz);
unlink(stub_xz); unlink(stub_xz);
int fd = xopen("stub.apk", O_WRONLY | O_CREAT, 0); int fd = xopen("stub.apk", O_WRONLY | O_CREAT, 0);
unxz(fd, stub.buf, stub.sz); unxz(fd, stub.buf(), stub.sz());
close(fd); close(fd);
} }
} }
@ -242,11 +242,11 @@ void MagiskInit::patch_ro_root() {
// Handle avd hack // Handle avd hack
if (avd_hack) { if (avd_hack) {
int src = xopen("/init", O_RDONLY | O_CLOEXEC); int src = xopen("/init", O_RDONLY | O_CLOEXEC);
auto init = mmap_data("/init"); mmap_data init("/init");
// Force disable early mount on original init // Force disable early mount on original init
init.patch({ make_pair("android,fstab", "xxx") }); init.patch({ make_pair("android,fstab", "xxx") });
int dest = xopen(ROOTOVL "/init", O_CREAT | O_WRONLY | O_CLOEXEC, 0); int dest = xopen(ROOTOVL "/init", O_CREAT | O_WRONLY | O_CLOEXEC, 0);
xwrite(dest, init.buf, init.sz); xwrite(dest, init.buf(), init.sz());
fclone_attr(src, dest); fclone_attr(src, dest);
close(src); close(src);
close(dest); close(dest);

View File

@ -21,9 +21,9 @@ void LegacySARInit::first_stage_prep() {
int src = xopen("/init", O_RDONLY); int src = xopen("/init", O_RDONLY);
int dest = xopen("/data/init", O_CREAT | O_WRONLY, 0); int dest = xopen("/data/init", O_CREAT | O_WRONLY, 0);
{ {
auto init = mmap_data("/init"); mmap_data init("/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);
close(dest); close(dest);
close(src); close(src);

View File

@ -73,8 +73,8 @@ 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) {
auto d = mmap_data(file); mmap_data d(file);
cil_add_file(db, (char *) file, (char *) d.buf, d.sz); cil_add_file(db, file, (const char *) d.buf(), d.sz());
LOGD("cil_add [%s]\n", file); LOGD("cil_add [%s]\n", file);
} }
@ -254,7 +254,7 @@ bool sepolicy::to_file(const char *file) {
if (struct stat st{}; xfstat(fd, &st) == 0 && st.st_size > 0) { if (struct stat st{}; xfstat(fd, &st) == 0 && st.st_size > 0) {
ftruncate(fd, 0); ftruncate(fd, 0);
} }
xwrite(fd, data.buf, data.sz); xwrite(fd, data.buf(), data.sz());
close(fd); close(fd);
return true; return true;