You've already forked Magisk
mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-09-06 06:36:58 +00:00
Better bytes support in C++
This commit is contained in:
+42
-43
@@ -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);
|
||||
|
||||
+22
-16
@@ -1,8 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <mntent.h>
|
||||
#include <functional>
|
||||
#include <string_view>
|
||||
#include <string>
|
||||
@@ -48,38 +46,44 @@ struct heap_data;
|
||||
struct byte_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, or any of its sub-type, can be copied as byte_view
|
||||
byte_view(const byte_view &o) : _buf(o._buf), _sz(o._sz) {}
|
||||
|
||||
// String as bytes
|
||||
byte_view(std::string_view s, bool with_nul = true);
|
||||
byte_view(const char *s, bool with_nul = true)
|
||||
: byte_view(std::string_view(s), with_nul) {}
|
||||
byte_view(const std::string &s, bool with_nul = true)
|
||||
: byte_view(std::string_view(s), with_nul) {}
|
||||
|
||||
// Vector as bytes
|
||||
byte_view(const std::vector<uint8_t> &v) : byte_view(v.data(), v.size()) {}
|
||||
|
||||
const uint8_t *buf() const { return _buf; }
|
||||
const size_t &sz() const { return _sz; }
|
||||
size_t sz() const { return _sz; }
|
||||
|
||||
bool contains(std::string_view pattern) const;
|
||||
bool equals(const byte_view &o) const;
|
||||
bool contains(byte_view pattern) const;
|
||||
bool equals(byte_view o) const;
|
||||
heap_data clone() const;
|
||||
|
||||
protected:
|
||||
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) {}
|
||||
byte_data(void *buf, size_t sz) : byte_view(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);
|
||||
std::vector<size_t> patch(byte_view from, byte_view to);
|
||||
};
|
||||
|
||||
#define MOVE_ONLY(clazz) \
|
||||
@@ -92,7 +96,6 @@ struct heap_data : public byte_data {
|
||||
MOVE_ONLY(heap_data)
|
||||
|
||||
explicit heap_data(size_t sz) : byte_data(malloc(sz), sz) {}
|
||||
heap_data(const void *buf, size_t sz) : heap_data(sz) { memcpy(_buf, buf, sz); }
|
||||
~heap_data() { free(_buf); }
|
||||
|
||||
void realloc(size_t sz);
|
||||
@@ -101,8 +104,11 @@ struct heap_data : public byte_data {
|
||||
struct mmap_data : public byte_data {
|
||||
MOVE_ONLY(mmap_data)
|
||||
|
||||
mmap_data(const char *name, bool rw = false);
|
||||
~mmap_data() { if (_buf) munmap(_buf, _sz); }
|
||||
explicit mmap_data(const char *name, bool rw = false);
|
||||
mmap_data(int fd, size_t sz, bool rw = false) { init(fd, sz, rw); }
|
||||
~mmap_data();
|
||||
private:
|
||||
void init(int fd, size_t sz, bool rw);
|
||||
};
|
||||
|
||||
extern "C" {
|
||||
|
||||
Reference in New Issue
Block a user