Better bytes support in C++

This commit is contained in:
topjohnwu
2023-06-06 17:11:42 -07:00
parent f8c38eab74
commit 5e2ef1b7f4
12 changed files with 89 additions and 75 deletions

View File

@@ -1,3 +1,4 @@
#include <sys/mman.h>
#include <sys/sendfile.h>
#include <sys/sysmacros.h>
#include <linux/fs.h>
@@ -433,55 +434,25 @@ sFILE make_file(FILE *fp) {
return sFILE(fp, [](FILE *fp){ return fp ? fclose(fp) : 1; });
}
int byte_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("Patch @ %08X [%s] -> [%s]\n", (unsigned)(p - _buf), from.data(), to.data());
memset(p, 0, from.length());
memcpy(p, to.data(), to.length());
++count;
p += from.length();
}
}
byte_view::byte_view(string_view s, bool with_nul)
: byte_view(static_cast<const void *>(s.data()), s.length()) {
if (with_nul && s[s.length()] == '\0') {
++_sz;
}
return count;
}
int byte_data::patch(byte_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.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 {
bool byte_view::contains(byte_view pattern) const {
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());
if (memcmp(p, pattern.buf(), pattern.sz()) == 0) {
return true;
}
}
return false;
}
bool byte_view::equals(const byte_view &o) const {
bool byte_view::equals(byte_view o) const {
return _sz == o._sz && memcmp(_buf, o._buf, _sz) == 0;
}
@@ -496,6 +467,24 @@ heap_data byte_view::clone() const {
return copy;
}
vector<size_t> byte_data::patch(byte_view from, byte_view to) {
vector<size_t> v;
if (_buf == nullptr)
return v;
auto p = _buf;
auto eof = _buf + _sz;
while (p < eof) {
p = static_cast<uint8_t *>(memmem(p, eof - p, from.buf(), from.sz()));
if (p == nullptr)
return v;
memset(p, 0, from.sz());
memcpy(p, to.buf(), to.sz());
v.push_back(p - _buf);
p += from.sz();
}
return v;
}
void heap_data::realloc(size_t sz) {
_buf = static_cast<uint8_t *>(::realloc(_buf, sz));
}
@@ -504,23 +493,33 @@ 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;
run_finally g([=] { close(fd); });
struct stat st{};
if (fstat(fd, &st))
return;
if (S_ISBLK(st.st_mode)) {
uint64_t size;
ioctl(fd, BLKGETSIZE64, &size);
_sz = size;
init(fd, size, rw);
} else {
_sz = st.st_size;
init(fd, st.st_size, rw);
}
void *b = _sz > 0
? xmmap(nullptr, _sz, PROT_READ | PROT_WRITE, rw ? MAP_SHARED : MAP_PRIVATE, fd, 0)
}
void mmap_data::init(int fd, size_t sz, bool rw) {
_sz = sz;
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);
}
mmap_data::~mmap_data() {
if (_buf)
munmap(_buf, _sz);
}
string find_apk_path(const char *pkg) {
char buf[PATH_MAX];
size_t len = strlen(pkg);