mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-11-28 04:25:27 +00:00
Migrate to STL
This commit is contained in:
parent
03c39e692a
commit
3e4c12cf56
@ -13,6 +13,8 @@
|
||||
#include <dirent.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/wait.h>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include "magisk.h"
|
||||
#include "db.h"
|
||||
@ -23,8 +25,10 @@
|
||||
#include "selinux.h"
|
||||
#include "flags.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
static char buf[PATH_MAX], buf2[PATH_MAX];
|
||||
static Vector<CharArray> module_list;
|
||||
static vector<string> module_list;
|
||||
static bool seperate_vendor;
|
||||
|
||||
char *system_block, *vendor_block, *magiskloop;
|
||||
@ -42,9 +46,9 @@ extern void auto_start_magiskhide();
|
||||
#define IS_SKEL 0x04 /* mount from skeleton */
|
||||
#define IS_MODULE 0x08 /* mount from module */
|
||||
|
||||
#define IS_DIR(n) (n->type == DT_DIR)
|
||||
#define IS_LNK(n) (n->type == DT_LNK)
|
||||
#define IS_REG(n) (n->type == DT_REG)
|
||||
#define IS_DIR(n) ((n)->type == DT_DIR)
|
||||
#define IS_LNK(n) ((n)->type == DT_LNK)
|
||||
#define IS_REG(n) ((n)->type == DT_REG)
|
||||
|
||||
class node_entry {
|
||||
public:
|
||||
@ -56,15 +60,15 @@ public:
|
||||
|
||||
private:
|
||||
const char *module; /* Only used when status & IS_MODULE */
|
||||
const CharArray name;
|
||||
const string name;
|
||||
uint8_t type;
|
||||
uint8_t status;
|
||||
node_entry *parent;
|
||||
Vector<node_entry *> children;
|
||||
vector<node_entry *> children;
|
||||
|
||||
node_entry(const char *, const char *, uint8_t type);
|
||||
bool is_root();
|
||||
CharArray get_path();
|
||||
string get_path();
|
||||
node_entry *insert(node_entry *);
|
||||
void clone_skeleton();
|
||||
int get_path(char *path);
|
||||
@ -87,7 +91,7 @@ bool node_entry::is_root() {
|
||||
return parent == nullptr;
|
||||
}
|
||||
|
||||
CharArray node_entry::get_path() {
|
||||
string node_entry::get_path() {
|
||||
get_path(buf);
|
||||
return buf;
|
||||
}
|
||||
@ -123,7 +127,7 @@ void node_entry::create_module_tree(const char *module) {
|
||||
DIR *dir;
|
||||
struct dirent *entry;
|
||||
|
||||
CharArray full_path = get_path();
|
||||
auto full_path = get_path();
|
||||
snprintf(buf, PATH_MAX, "%s/%s%s", MOUNTPOINT, module, full_path.c_str());
|
||||
|
||||
if (!(dir = xopendir(buf)))
|
||||
@ -133,7 +137,7 @@ void node_entry::create_module_tree(const char *module) {
|
||||
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
|
||||
continue;
|
||||
// Create new node
|
||||
node_entry *node = new node_entry(module, entry->d_name, entry->d_type);
|
||||
auto node = new node_entry(module, entry->d_name, entry->d_type);
|
||||
snprintf(buf, PATH_MAX, "%s/%s", full_path.c_str(), entry->d_name);
|
||||
|
||||
/*
|
||||
@ -185,7 +189,7 @@ void node_entry::clone_skeleton() {
|
||||
struct node_entry *dummy;
|
||||
|
||||
// Clone the structure
|
||||
CharArray full_path = get_path();
|
||||
auto full_path = get_path();
|
||||
snprintf(buf, PATH_MAX, "%s%s", MIRRDIR, full_path.c_str());
|
||||
if (!(dir = xopendir(buf)))
|
||||
return;
|
||||
@ -200,10 +204,10 @@ void node_entry::clone_skeleton() {
|
||||
|
||||
if (status & IS_SKEL) {
|
||||
file_attr attr;
|
||||
getattr(full_path, &attr);
|
||||
getattr(full_path.c_str(), &attr);
|
||||
LOGI("mnt_tmpfs : %s\n", full_path.c_str());
|
||||
xmount("tmpfs", full_path, "tmpfs", 0, nullptr);
|
||||
setattr(full_path, &attr);
|
||||
xmount("tmpfs", full_path.c_str(), "tmpfs", 0, nullptr);
|
||||
setattr(full_path.c_str(), &attr);
|
||||
}
|
||||
|
||||
for (auto &child : children) {
|
||||
@ -254,9 +258,9 @@ void node_entry::clone_skeleton() {
|
||||
void node_entry::magic_mount() {
|
||||
if (status & IS_MODULE) {
|
||||
// Mount module item
|
||||
CharArray real_path = get_path();
|
||||
auto real_path = get_path();
|
||||
snprintf(buf, PATH_MAX, "%s/%s%s", MOUNTPOINT, module, real_path.c_str());
|
||||
bind_mount(buf, real_path);
|
||||
bind_mount(buf, real_path.c_str());
|
||||
} else if (status & IS_SKEL) {
|
||||
// The node is labeled to be cloned with skeleton, lets do it
|
||||
clone_skeleton();
|
||||
@ -330,7 +334,8 @@ static void exec_common_script(const char* stage) {
|
||||
}
|
||||
|
||||
static void exec_module_script(const char* stage) {
|
||||
for (const char *module : module_list) {
|
||||
for (const auto &m : module_list) {
|
||||
const auto module = m.c_str();
|
||||
snprintf(buf2, PATH_MAX, "%s/%s/%s.sh", MOUNTPOINT, module, stage);
|
||||
if (access(buf2, F_OK) == -1)
|
||||
continue;
|
||||
@ -364,7 +369,7 @@ static void simple_mount(const char *path) {
|
||||
if (access(buf2, F_OK) == -1)
|
||||
continue;
|
||||
if (entry->d_type == DT_DIR) {
|
||||
simple_mount(CharArray(buf2));
|
||||
simple_mount(string(buf2).c_str());
|
||||
} else if (entry->d_type == DT_REG) {
|
||||
// Actual file path
|
||||
snprintf(buf, PATH_MAX, "%s%s", SIMPLEMOUNT, buf2);
|
||||
@ -431,21 +436,20 @@ static bool magisk_env() {
|
||||
xmkdir(SECURE_DIR "/post-fs-data.d", 0755);
|
||||
xmkdir(SECURE_DIR "/service.d", 0755);
|
||||
|
||||
CharArray sdk_prop = getprop("ro.build.version.sdk");
|
||||
int sdk = sdk_prop.empty() ? -1 : atoi(sdk_prop);
|
||||
auto sdk_prop = getprop("ro.build.version.sdk");
|
||||
int sdk = sdk_prop.empty() ? -1 : atoi(sdk_prop.c_str());
|
||||
|
||||
LOGI("* Mounting mirrors");
|
||||
Vector<CharArray> mounts;
|
||||
file_to_vector("/proc/mounts", mounts);
|
||||
auto mounts = file_to_vector("/proc/mounts");
|
||||
bool system_as_root = false;
|
||||
for (auto &line : mounts) {
|
||||
if (line.contains(" /system_root ")) {
|
||||
if (line.find(" /system_root ") != string::npos) {
|
||||
bind_mount("/system_root/system", MIRRDIR "/system");
|
||||
sscanf(line, "%s", buf);
|
||||
sscanf(line.c_str(), "%s", buf);
|
||||
system_block = strdup2(buf);
|
||||
system_as_root = true;
|
||||
} else if (!system_as_root && line.contains(" /system ")) {
|
||||
sscanf(line, "%s %*s %s", buf, buf2);
|
||||
} else if (!system_as_root && line.find(" /system ") != string::npos) {
|
||||
sscanf(line.c_str(), "%s %*s %s", buf, buf2);
|
||||
system_block = strdup2(buf);
|
||||
xmount(system_block, MIRRDIR "/system", buf2, MS_RDONLY, nullptr);
|
||||
#ifdef MAGISK_DEBUG
|
||||
@ -453,9 +457,9 @@ static bool magisk_env() {
|
||||
#else
|
||||
LOGI("mount: %s\n", MIRRDIR "/system");
|
||||
#endif
|
||||
} else if (line.contains(" /vendor ")) {
|
||||
} else if (line.find(" /vendor ") != string::npos) {
|
||||
seperate_vendor = true;
|
||||
sscanf(line, "%s %*s %s", buf, buf2);
|
||||
sscanf(line.c_str(), "%s %*s %s", buf, buf2);
|
||||
vendor_block = strdup2(buf);
|
||||
xmkdir(MIRRDIR "/vendor", 0755);
|
||||
xmount(buf, MIRRDIR "/vendor", buf2, MS_RDONLY, nullptr);
|
||||
@ -464,7 +468,9 @@ static bool magisk_env() {
|
||||
#else
|
||||
LOGI("mount: %s\n", MIRRDIR "/vendor");
|
||||
#endif
|
||||
} else if (sdk >= 24 && line.contains(" /proc ") && !line.contains("hidepid=2")) {
|
||||
} else if (sdk >= 24 &&
|
||||
line.find(" /proc ") != string::npos &&
|
||||
line.find("hidepid=2") == string::npos) {
|
||||
// Enforce hidepid
|
||||
xmount(nullptr, "/proc", nullptr, MS_REMOUNT, "hidepid=2,gid=3009");
|
||||
}
|
||||
@ -508,7 +514,7 @@ static void collect_modules() {
|
||||
}
|
||||
unlink("update");
|
||||
if (access("disable", F_OK))
|
||||
module_list.push_back(entry->d_name);
|
||||
module_list.emplace_back(entry->d_name);
|
||||
chdir("..");
|
||||
}
|
||||
}
|
||||
@ -559,7 +565,7 @@ static bool prepare_img() {
|
||||
|
||||
static void install_apk(const char *apk) {
|
||||
setfilecon(apk, "u:object_r:" SEPOL_FILE_DOMAIN ":s0");
|
||||
while (1) {
|
||||
while (true) {
|
||||
sleep(5);
|
||||
LOGD("apk_install: attempting to install APK\n");
|
||||
int fd = -1, pid;
|
||||
@ -586,14 +592,14 @@ static void install_apk(const char *apk) {
|
||||
static bool check_data() {
|
||||
bool mnt = false;
|
||||
bool data = false;
|
||||
Vector<CharArray> mounts;
|
||||
file_to_vector("/proc/mounts", mounts);
|
||||
auto mounts = file_to_vector("/proc/mounts");
|
||||
for (auto &line : mounts) {
|
||||
if (line.contains(" /data ") && !line.contains("tmpfs"))
|
||||
if (line.find(" /data ") != string::npos &&
|
||||
line.find("tmpfs") == string::npos)
|
||||
mnt = true;
|
||||
}
|
||||
if (mnt) {
|
||||
CharArray crypto = getprop("ro.crypto.state");
|
||||
auto crypto = getprop("ro.crypto.state");
|
||||
if (!crypto.empty()) {
|
||||
if (crypto == "unencrypted") {
|
||||
// Unencrypted, we can directly access data
|
||||
@ -811,11 +817,11 @@ void post_fs_data(int client) {
|
||||
exec_module_script("post-fs-data");
|
||||
|
||||
// Recollect modules
|
||||
module_list.clear(true);
|
||||
module_list.clear();
|
||||
collect_modules();
|
||||
|
||||
// Create the system root entry
|
||||
node_entry *sys_root = new node_entry("system", IS_INTER);
|
||||
auto sys_root = new node_entry("system", IS_INTER);
|
||||
|
||||
// Vendor root entry
|
||||
node_entry *ven_root = nullptr;
|
||||
@ -823,7 +829,8 @@ void post_fs_data(int client) {
|
||||
bool has_modules = false;
|
||||
|
||||
LOGI("* Loading modules\n");
|
||||
for (const char *module : module_list) {
|
||||
for (const auto &m : module_list) {
|
||||
const auto module = m.c_str();
|
||||
// Read props
|
||||
snprintf(buf, PATH_MAX, "%s/%s/system.prop", MOUNTPOINT, module);
|
||||
if (access(buf, F_OK) == 0) {
|
||||
@ -911,7 +918,7 @@ core_only:
|
||||
}
|
||||
|
||||
// All boot stage done, cleanup
|
||||
module_list.clear(true);
|
||||
module_list.clear();
|
||||
}
|
||||
|
||||
void boot_complete(int client) {
|
||||
|
@ -12,14 +12,17 @@
|
||||
#include <stdlib.h>
|
||||
#include <sys/wait.h>
|
||||
#include <fcntl.h>
|
||||
#include <vector>
|
||||
|
||||
#include "magisk.h"
|
||||
#include "utils.h"
|
||||
#include "daemon.h"
|
||||
#include "flags.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
bool log_daemon_started = false;
|
||||
static Vector<const char *> log_cmd, clear_cmd;
|
||||
static vector<const char *> log_cmd, clear_cmd;
|
||||
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
enum {
|
||||
@ -68,7 +71,7 @@ static void *monitor_thread(void *) {
|
||||
sleep(5);
|
||||
int fd;
|
||||
char b;
|
||||
while (1) {
|
||||
while (true) {
|
||||
fd = connect_daemon();
|
||||
write_int(fd, HANDSHAKE);
|
||||
// This should hold unless the daemon is killed
|
||||
@ -136,11 +139,7 @@ static void log_daemon() {
|
||||
}
|
||||
chmod("/dev/null", 0666);
|
||||
clear_cmd = log_cmd;
|
||||
log_cmd.push_back("-v");
|
||||
log_cmd.push_back("threadtime");
|
||||
log_cmd.push_back("-s");
|
||||
log_cmd.push_back("am_proc_start");
|
||||
log_cmd.push_back("Magisk");
|
||||
log_cmd.insert(log_cmd.end(), { "-v", "threadtime", "-s", "am_proc_start", "Magisk" });
|
||||
#ifdef MAGISK_DEBUG
|
||||
log_cmd.push_back("*:F");
|
||||
#endif
|
||||
@ -163,7 +162,7 @@ static void log_daemon() {
|
||||
if (xbind(sockfd, (struct sockaddr*) &sun, len))
|
||||
exit(1);
|
||||
xlisten(sockfd, 10);
|
||||
while(1) {
|
||||
while(true) {
|
||||
int fd = xaccept4(sockfd, nullptr, nullptr, SOCK_CLOEXEC);
|
||||
switch(read_int(fd)) {
|
||||
case HIDE_CONNECT:
|
||||
|
@ -3,12 +3,11 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CharArray.h"
|
||||
#include <string>
|
||||
|
||||
int prop_exist(const char *name);
|
||||
int setprop(const char *name, const char *value, const bool trigger = true);
|
||||
CharArray getprop(const char *name, bool persist = false);
|
||||
int setprop(const char *name, const char *value, bool trigger = true);
|
||||
std::string getprop(const char *name, bool persist = false);
|
||||
void getprop(void (*callback)(const char *, const char *, void *), void *cookie, bool persist = false);
|
||||
int deleteprop(const char *name, bool persist = false);
|
||||
int load_prop_file(const char *filename, const bool trigger = true);
|
||||
|
||||
int load_prop_file(const char *filename, bool trigger = true);
|
||||
|
@ -2,11 +2,14 @@
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <algorithm>
|
||||
|
||||
#include "cpio.h"
|
||||
#include "utils.h"
|
||||
#include "logging.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
#define parse_align() lseek(fd, align(lseek(fd, 0, SEEK_CUR), 4), SEEK_SET)
|
||||
|
||||
static uint32_t x8u(char *hex) {
|
||||
@ -40,8 +43,8 @@ cpio_entry::cpio_entry(int fd, cpio_newc_header &header) {
|
||||
// rdevminor = x8u(header.rdevminor);
|
||||
uint32_t namesize = x8u(header.namesize);
|
||||
// check = x8u(header.check);
|
||||
filename = CharArray(namesize);
|
||||
xxread(fd, filename, filename.size());
|
||||
filename.resize(namesize - 1);
|
||||
xxread(fd, &filename[0], namesize);
|
||||
parse_align();
|
||||
if (filesize) {
|
||||
data = xmalloc(filesize);
|
||||
@ -54,22 +57,13 @@ cpio_entry::~cpio_entry() {
|
||||
free(data);
|
||||
}
|
||||
|
||||
// Define the way to sort cpio_entry
|
||||
template<>
|
||||
int(*Vector<cpio_entry*>::_cmp)(cpio_entry*&, cpio_entry*&) = [](auto a, auto b) -> int {
|
||||
if (a == b) return 0;
|
||||
if (a == nullptr) return 1;
|
||||
if (b == nullptr) return -1;
|
||||
return a->filename.compare(b->filename);
|
||||
};
|
||||
|
||||
|
||||
cpio::cpio(const char *filename) {
|
||||
int fd = open(filename, O_RDONLY);
|
||||
if (fd < 0) return;
|
||||
fprintf(stderr, "Loading cpio: [%s]\n", filename);
|
||||
cpio_newc_header header;
|
||||
cpio_entry *entry;
|
||||
int i = 0;
|
||||
while(xxread(fd, &header, sizeof(cpio_newc_header)) != -1) {
|
||||
entry = new cpio_entry(fd, header);
|
||||
if (entry->filename == "." || entry->filename == ".." || entry->filename == "TRAILER!!!") {
|
||||
@ -86,7 +80,7 @@ cpio::cpio(const char *filename) {
|
||||
|
||||
cpio::~cpio() {
|
||||
for (auto &e : arr)
|
||||
if (e) delete e;
|
||||
delete e;
|
||||
}
|
||||
|
||||
#define dump_align() write_zero(fd, align_off(lseek(fd, 0, SEEK_CUR), 4))
|
||||
@ -109,11 +103,11 @@ void cpio::dump(const char *file) {
|
||||
0, // e->devminor
|
||||
0, // e->rdevmajor
|
||||
0, // e->rdevminor
|
||||
(uint32_t) e->filename.size(),
|
||||
(uint32_t) e->filename.size() + 1,
|
||||
0 // e->check
|
||||
);
|
||||
xwrite(fd, header, 110);
|
||||
xwrite(fd, e->filename, e->filename.size());
|
||||
xwrite(fd, e->filename.c_str(), e->filename.size() + 1);
|
||||
dump_align();
|
||||
if (e->filesize) {
|
||||
xwrite(fd, e->data, e->filesize);
|
||||
@ -140,7 +134,7 @@ int cpio::find(const char *name) {
|
||||
}
|
||||
|
||||
void cpio::insert(cpio_entry *e) {
|
||||
int i = find(e->filename);
|
||||
int i = find(e->filename.c_str());
|
||||
if (i >= 0) {
|
||||
delete arr[i];
|
||||
arr[i] = e;
|
||||
@ -149,17 +143,12 @@ void cpio::insert(cpio_entry *e) {
|
||||
}
|
||||
}
|
||||
|
||||
void cpio::insert(Vector<cpio_entry *> &arr) {
|
||||
for (auto &e : arr)
|
||||
insert(e);
|
||||
}
|
||||
|
||||
void cpio::rm(const char *name, bool r) {
|
||||
size_t len = strlen(name);
|
||||
for (auto &e : arr) {
|
||||
if (!e)
|
||||
continue;
|
||||
if (e->filename.compare(name, len) == 0 &&
|
||||
if (e->filename.compare(0, len, name) == 0 &&
|
||||
((r && e->filename[len] == '/') || e->filename[len] == '\0')) {
|
||||
fprintf(stderr, "Remove [%s]\n", e->filename.c_str());
|
||||
delete e;
|
||||
@ -171,17 +160,15 @@ void cpio::rm(const char *name, bool r) {
|
||||
}
|
||||
|
||||
void cpio::makedir(mode_t mode, const char *name) {
|
||||
auto e = new cpio_entry();
|
||||
auto e = new cpio_entry(name);
|
||||
e->mode = S_IFDIR | mode;
|
||||
e->filename = name;
|
||||
insert(e);
|
||||
fprintf(stderr, "Create directory [%s] (%04o)\n", name, mode);
|
||||
}
|
||||
|
||||
void cpio::ln(const char *target, const char *name) {
|
||||
auto e = new cpio_entry();
|
||||
auto e = new cpio_entry(name);
|
||||
e->mode = S_IFLNK;
|
||||
e->filename = name;
|
||||
e->filesize = strlen(target);
|
||||
e->data = strdup(target);
|
||||
insert(e);
|
||||
@ -190,9 +177,8 @@ void cpio::ln(const char *target, const char *name) {
|
||||
|
||||
void cpio::add(mode_t mode, const char *name, const char *file) {
|
||||
int fd = xopen(file, O_RDONLY);
|
||||
auto e = new cpio_entry();
|
||||
auto e = new cpio_entry(name);
|
||||
e->mode = S_IFREG | mode;
|
||||
e->filename = name;
|
||||
e->filesize = lseek(fd, 0, SEEK_END);
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
e->data = xmalloc(e->filesize);
|
||||
@ -239,17 +225,15 @@ static void extract_entry(cpio_entry *e, const char *file) {
|
||||
|
||||
void cpio::extract() {
|
||||
for (auto &e : arr) {
|
||||
if (!e)
|
||||
continue;
|
||||
extract_entry(e, e->filename);
|
||||
if (!e) continue;
|
||||
extract_entry(e, e->filename.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
bool cpio::extract(const char *name, const char *file) {
|
||||
int i = find(name);
|
||||
if (i > 0) {
|
||||
auto e = arr[i];
|
||||
extract_entry(e, file);
|
||||
extract_entry(arr[i], file);
|
||||
return true;
|
||||
}
|
||||
fprintf(stderr, "Cannot find the file entry [%s]\n", name);
|
||||
@ -257,7 +241,13 @@ bool cpio::extract(const char *name, const char *file) {
|
||||
}
|
||||
|
||||
void cpio::sort() {
|
||||
arr.sort();
|
||||
std::sort(arr.begin(), arr.end(), [] (auto a, auto b) -> bool {
|
||||
if (a == b || a == nullptr)
|
||||
return false;
|
||||
if (b == nullptr)
|
||||
return true;
|
||||
return a->filename.compare(b->filename) < 0;
|
||||
});
|
||||
while (arr.back() == nullptr)
|
||||
arr.pop_back();
|
||||
}
|
||||
|
@ -2,9 +2,8 @@
|
||||
#define _CPIO_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "Vector.h"
|
||||
#include "CharArray.h"
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
struct cpio_newc_header {
|
||||
char magic[6];
|
||||
@ -38,17 +37,18 @@ struct cpio_entry {
|
||||
// uint32_t namesize;
|
||||
// uint32_t check;
|
||||
// char *filename = nullptr;
|
||||
CharArray filename;
|
||||
std::string filename;
|
||||
void *data = nullptr;
|
||||
|
||||
cpio_entry() {}
|
||||
cpio_entry() = default;
|
||||
explicit cpio_entry(const char *name) : filename(name) {}
|
||||
cpio_entry(int fd, cpio_newc_header &header);
|
||||
~cpio_entry();
|
||||
};
|
||||
|
||||
class cpio {
|
||||
public:
|
||||
cpio(const char *filename);
|
||||
explicit cpio(const char *filename);
|
||||
~cpio();
|
||||
void dump(const char *file);
|
||||
int find(const char *name);
|
||||
@ -57,14 +57,13 @@ public:
|
||||
void makedir(mode_t mode, const char *name);
|
||||
void ln(const char *target, const char *name);
|
||||
void add(mode_t mode, const char *name, const char *file);
|
||||
void insert(Vector<cpio_entry *> &arr);
|
||||
bool mv(const char *from, const char *to);
|
||||
void extract();
|
||||
bool extract(const char *name, const char *file);
|
||||
void sort();
|
||||
|
||||
protected:
|
||||
Vector<cpio_entry *> arr;
|
||||
std::vector<cpio_entry *> arr;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -6,9 +6,11 @@
|
||||
#include "cpio.h"
|
||||
#include "utils.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
class magisk_cpio : public cpio {
|
||||
public:
|
||||
magisk_cpio(const char *filename) : cpio(filename) {}
|
||||
explicit magisk_cpio(const char *filename) : cpio(filename) {}
|
||||
void patch(bool keepverity, bool keepforceencrypt);
|
||||
int test();
|
||||
char * sha1();
|
||||
@ -23,8 +25,8 @@ void magisk_cpio::patch(bool keepverity, bool keepforceencrypt) {
|
||||
if (!e)
|
||||
continue;
|
||||
bool fstab = (!keepverity || !keepforceencrypt) &&
|
||||
!e->filename.starts_with(".backup") &&
|
||||
e->filename.contains("fstab") && S_ISREG(e->mode);
|
||||
!str_starts(e->filename, ".backup") &&
|
||||
str_contains(e->filename, "fstab") && S_ISREG(e->mode);
|
||||
if (!keepverity) {
|
||||
if (fstab) {
|
||||
patch_verity(&e->data, &e->filesize, 1);
|
||||
@ -98,7 +100,7 @@ char *magisk_cpio::sha1() {
|
||||
void magisk_cpio::restore() {
|
||||
for (auto &e : arr) {
|
||||
if (!e) continue;
|
||||
if (e->filename.starts_with(".backup")) {
|
||||
if (str_starts(e->filename, ".backup")) {
|
||||
if (e->filename[7] == '\0') continue;
|
||||
if (e->filename[8] == '.') {
|
||||
if (strcmp(&e->filename[8], ".rmlist") == 0) {
|
||||
@ -106,7 +108,7 @@ void magisk_cpio::restore() {
|
||||
rm((char *) e->data + pos, false);
|
||||
}
|
||||
} else {
|
||||
mv(e->filename, e->filename + 8);
|
||||
mv(e->filename.c_str(), &e->filename[8]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -120,17 +122,15 @@ void magisk_cpio::restore() {
|
||||
}
|
||||
|
||||
void magisk_cpio::backup(const char *orig) {
|
||||
Vector<cpio_entry*> bak;
|
||||
vector<cpio_entry*> bak;
|
||||
cpio_entry *m, *n, *rem;
|
||||
char buf[PATH_MAX];
|
||||
|
||||
m = new cpio_entry();
|
||||
m->filename = ".backup";
|
||||
m = new cpio_entry(".backup");
|
||||
m->mode = S_IFDIR;
|
||||
bak.push_back(m);
|
||||
|
||||
rem = new cpio_entry();
|
||||
rem->filename = ".backup/.rmlist";
|
||||
rem = new cpio_entry(".backup/.rmlist");
|
||||
rem->mode = S_IFREG;
|
||||
|
||||
magisk_cpio o(orig);
|
||||
@ -176,7 +176,7 @@ void magisk_cpio::backup(const char *orig) {
|
||||
// Something new in ramdisk, record in rem
|
||||
++j;
|
||||
rem->data = xrealloc(rem->data, rem->filesize + n->filename.size());
|
||||
memcpy((char *) rem->data + rem->filesize, n->filename, n->filename.size());
|
||||
memcpy((char *) rem->data + rem->filesize, n->filename.c_str(), n->filename.size());
|
||||
rem->filesize += n->filename.size();
|
||||
fprintf(stderr, "Record new entry: [%s] -> [.backup/.rmlist]\n", n->filename.c_str());
|
||||
}
|
||||
@ -196,7 +196,8 @@ void magisk_cpio::backup(const char *orig) {
|
||||
delete rem;
|
||||
|
||||
if (bak.size() > 1)
|
||||
insert(bak);
|
||||
for (auto item : bak)
|
||||
insert(item);
|
||||
}
|
||||
|
||||
|
||||
@ -249,11 +250,11 @@ int cpio_commands(int argc, char *argv[]) {
|
||||
return 0;
|
||||
}
|
||||
} else if (cmdc == 3 && strcmp(cmdv[0], "mkdir") == 0) {
|
||||
cpio.makedir(strtoul(cmdv[1], NULL, 8), cmdv[2]);
|
||||
cpio.makedir(strtoul(cmdv[1], nullptr, 8), cmdv[2]);
|
||||
} else if (cmdc == 3 && strcmp(cmdv[0], "ln") == 0) {
|
||||
cpio.ln(cmdv[1], cmdv[2]);
|
||||
} else if (cmdc == 4 && strcmp(cmdv[0], "add") == 0) {
|
||||
cpio.add(strtoul(cmdv[1], NULL, 8), cmdv[2], cmdv[3]);
|
||||
cpio.add(strtoul(cmdv[1], nullptr, 8), cmdv[2], cmdv[3]);
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
|
@ -15,10 +15,12 @@
|
||||
#include "daemon.h"
|
||||
#include "db.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
#define SAFETYNET_COMPONENT "com.google.android.gms/.droidguard.DroidGuardService"
|
||||
#define SAFETYNET_PROCESS "com.google.android.gms.unstable"
|
||||
|
||||
Vector<CharArray> hide_list;
|
||||
vector<string> hide_list;
|
||||
pthread_mutex_t list_lock;
|
||||
|
||||
static pthread_t proc_monitor_thread;
|
||||
@ -55,7 +57,7 @@ void hide_sensitive_props() {
|
||||
|
||||
// Hide all sensitive props
|
||||
for (int i = 0; prop_key[i]; ++i) {
|
||||
CharArray value = getprop(prop_key[i]);
|
||||
auto value = getprop(prop_key[i]);
|
||||
if (!value.empty() && value != prop_value[i])
|
||||
setprop(prop_key[i], prop_value[i], false);
|
||||
}
|
||||
@ -118,7 +120,7 @@ static bool proc_name_match(int pid, const char *name) {
|
||||
}
|
||||
|
||||
static void kill_proc_cb(int pid, void *v) {
|
||||
ps_arg *args = static_cast<ps_arg *>(v);
|
||||
auto args = static_cast<ps_arg *>(v);
|
||||
if (proc_name_match(pid, args->name))
|
||||
kill(pid, SIGTERM);
|
||||
else if (args->uid > 0) {
|
||||
@ -183,7 +185,7 @@ int add_list(const char *proc) {
|
||||
|
||||
// Critical region
|
||||
pthread_mutex_lock(&list_lock);
|
||||
hide_list.push_back(proc);
|
||||
hide_list.emplace_back(proc);
|
||||
kill_process(proc);
|
||||
pthread_mutex_unlock(&list_lock);
|
||||
|
||||
@ -247,10 +249,9 @@ bool init_list() {
|
||||
|
||||
// Migrate old hide list into database
|
||||
if (access(LEGACY_LIST, R_OK) == 0) {
|
||||
Vector<CharArray> tmp;
|
||||
file_to_vector(LEGACY_LIST, tmp);
|
||||
auto tmp = file_to_vector(LEGACY_LIST);
|
||||
for (auto &s : tmp)
|
||||
add_list(s);
|
||||
add_list(s.c_str());
|
||||
unlink(LEGACY_LIST);
|
||||
}
|
||||
|
||||
|
@ -2,10 +2,10 @@
|
||||
#define MAGISK_HIDE_H
|
||||
|
||||
#include <pthread.h>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include "daemon.h"
|
||||
#include "Vector.h"
|
||||
#include "CharArray.h"
|
||||
|
||||
#define TERM_THREAD SIGUSR1
|
||||
|
||||
@ -30,7 +30,7 @@ bool init_list();
|
||||
|
||||
extern bool hide_enabled;
|
||||
extern pthread_mutex_t list_lock;
|
||||
extern Vector<CharArray> hide_list;
|
||||
extern std::vector<std::string> hide_list;
|
||||
|
||||
enum {
|
||||
LAUNCH_MAGISKHIDE,
|
||||
|
@ -15,19 +15,23 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/mount.h>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include "magisk.h"
|
||||
#include "daemon.h"
|
||||
#include "utils.h"
|
||||
#include "magiskhide.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
static int sockfd = -1;
|
||||
extern char *system_block, *vendor_block, *magiskloop;
|
||||
|
||||
// Workaround for the lack of pthread_cancel
|
||||
static void term_thread(int) {
|
||||
LOGD("proc_monitor: running cleanup\n");
|
||||
hide_list.clear(true);
|
||||
hide_list.clear();
|
||||
hide_enabled = false;
|
||||
close(sockfd);
|
||||
sockfd = -1;
|
||||
@ -64,7 +68,7 @@ static void hide_daemon(int pid) {
|
||||
LOGD("hide_daemon: handling pid=[%d]\n", pid);
|
||||
|
||||
char buffer[4096];
|
||||
Vector<CharArray> mounts;
|
||||
vector<string> mounts;
|
||||
|
||||
manage_selinux();
|
||||
clean_magisk_props();
|
||||
@ -75,24 +79,24 @@ static void hide_daemon(int pid) {
|
||||
snprintf(buffer, sizeof(buffer), "/proc/%d", pid);
|
||||
chdir(buffer);
|
||||
|
||||
file_to_vector("mounts", mounts);
|
||||
mounts = file_to_vector("mounts");
|
||||
// Unmount dummy skeletons and /sbin links
|
||||
for (auto &s : mounts) {
|
||||
if (s.contains("tmpfs /system/") || s.contains("tmpfs /vendor/") || s.contains("tmpfs /sbin")) {
|
||||
sscanf(s, "%*s %4096s", buffer);
|
||||
if (str_contains(s, "tmpfs /system/") || str_contains(s, "tmpfs /vendor/") ||
|
||||
str_contains(s, "tmpfs /sbin")) {
|
||||
sscanf(s.c_str(), "%*s %4096s", buffer);
|
||||
lazy_unmount(buffer);
|
||||
}
|
||||
}
|
||||
mounts.clear();
|
||||
|
||||
// Re-read mount infos
|
||||
file_to_vector("mounts", mounts);
|
||||
mounts = file_to_vector("mounts");
|
||||
|
||||
// Unmount everything under /system, /vendor, and loop mounts
|
||||
for (auto &s : mounts) {
|
||||
if ((s.contains(" /system/") || s.contains(" /vendor/")) &&
|
||||
(s.contains(system_block) || s.contains(vendor_block) || s.contains(magiskloop))) {
|
||||
sscanf(s, "%*s %4096s", buffer);
|
||||
if ((str_contains(s, " /system/") || str_contains(s, " /vendor/")) &&
|
||||
(str_contains(s, system_block) || str_contains(s, vendor_block) || str_contains(s, magiskloop))) {
|
||||
sscanf(s.c_str(), "%*s %4096s", buffer);
|
||||
lazy_unmount(buffer);
|
||||
}
|
||||
}
|
||||
@ -108,13 +112,12 @@ void proc_monitor() {
|
||||
sigset_t block_set;
|
||||
sigemptyset(&block_set);
|
||||
sigaddset(&block_set, TERM_THREAD);
|
||||
pthread_sigmask(SIG_UNBLOCK, &block_set, NULL);
|
||||
pthread_sigmask(SIG_UNBLOCK, &block_set, nullptr);
|
||||
|
||||
// Register the cancel signal
|
||||
struct sigaction act;
|
||||
memset(&act, 0, sizeof(act));
|
||||
struct sigaction act{};
|
||||
act.sa_handler = term_thread;
|
||||
sigaction(TERM_THREAD, &act, NULL);
|
||||
sigaction(TERM_THREAD, &act, nullptr);
|
||||
|
||||
if (access("/proc/1/ns/mnt", F_OK) != 0) {
|
||||
LOGE("proc_monitor: Your kernel doesn't support mount namespace :(\n");
|
||||
@ -155,7 +158,7 @@ void proc_monitor() {
|
||||
bool hide = false;
|
||||
pthread_mutex_lock(&list_lock);
|
||||
for (auto &s : hide_list) {
|
||||
if (strncmp(cpnt, s, s.size() - 1) == 0) {
|
||||
if (strncmp(cpnt, s.c_str(), s.size() - 1) == 0) {
|
||||
hide = true;
|
||||
break;
|
||||
}
|
||||
|
@ -5,6 +5,8 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include "sepolicy.h"
|
||||
#include "magiskpolicy.h"
|
||||
@ -12,6 +14,8 @@
|
||||
#include "utils.h"
|
||||
#include "flags.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
static const char *type_msg_1 =
|
||||
"Type 1:\n"
|
||||
"\"<rule_name> source_type target_type class perm_set\"\n"
|
||||
@ -101,7 +105,7 @@ static const char *type_msg_6 =
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static int parse_bracket(char *tok, char *&stmt, Vector<const char *> *vec) {
|
||||
static int parse_bracket(char *tok, char *&stmt, vector<const char *> *vec) {
|
||||
if (tok == nullptr || tok[0] != '{') {
|
||||
// Not in a bracket
|
||||
vec->push_back(tok);
|
||||
@ -143,10 +147,10 @@ static int parse_pattern_1(int action, const char *action_str, char *stmt) {
|
||||
|
||||
int state = 0;
|
||||
char *cur, *cls;
|
||||
Vector<const char*> source, target, permission;
|
||||
vector<const char*> source, target, permission;
|
||||
while ((cur = strtok_r(nullptr, " ", &stmt)) != nullptr) {
|
||||
if (cur[0] == '*') cur = ALL;
|
||||
Vector<const char *> *vec;
|
||||
vector<const char *> *vec;
|
||||
switch (state) {
|
||||
case 0:
|
||||
vec = &source;
|
||||
@ -200,10 +204,10 @@ static int parse_pattern_2(int action, const char *action_str, char *stmt) {
|
||||
|
||||
int state = 0;
|
||||
char *cur, *range;
|
||||
Vector<const char *> source, target, classes;
|
||||
vector<const char *> source, target, classes;
|
||||
while ((cur = strtok_r(nullptr, " ", &stmt)) != nullptr) {
|
||||
if (cur[0] == '*') cur = ALL;
|
||||
Vector<const char *> *vec;
|
||||
vector<const char *> *vec;
|
||||
switch (state) {
|
||||
case 0:
|
||||
vec = &source;
|
||||
@ -216,7 +220,7 @@ static int parse_pattern_2(int action, const char *action_str, char *stmt) {
|
||||
break;
|
||||
case 3:
|
||||
// Currently only support ioctl
|
||||
if (strcmp(cur, "ioctl"))
|
||||
if (strcmp(cur, "ioctl") != 0)
|
||||
return 1;
|
||||
vec = nullptr;
|
||||
break;
|
||||
@ -262,7 +266,7 @@ static int parse_pattern_3(int action, const char *action_str, char* stmt) {
|
||||
}
|
||||
|
||||
char *cur;
|
||||
Vector<const char *> domains;
|
||||
vector<const char *> domains;
|
||||
while ((cur = strtok_r(nullptr, " {}", &stmt)) != nullptr) {
|
||||
if (cur[0] == '*') cur = ALL;
|
||||
domains.push_back(cur);
|
||||
@ -291,10 +295,10 @@ static int parse_pattern_4(int action, const char *action_str, char *stmt) {
|
||||
|
||||
int state = 0;
|
||||
char *cur;
|
||||
Vector<const char *> classes, attribute;
|
||||
vector<const char *> classes, attribute;
|
||||
while ((cur = strtok_r(nullptr, " ", &stmt)) != nullptr) {
|
||||
if (cur[0] == '*') cur = ALL;
|
||||
Vector<const char *> *vec;
|
||||
vector<const char *> *vec;
|
||||
switch (state) {
|
||||
case 0:
|
||||
vec = &classes;
|
||||
@ -409,7 +413,7 @@ static void parse_statement(char *statement) {
|
||||
char *action, *remain;
|
||||
|
||||
// strtok will modify the origin string, duplicate the statement for error messages
|
||||
CharArray orig(statement);
|
||||
string orig(statement);
|
||||
|
||||
action = strtok_r(statement, " ", &remain);
|
||||
if (remain == nullptr) remain = &action[strlen(action)];
|
||||
|
@ -5,15 +5,15 @@
|
||||
#ifndef MAGISK_PROPS_H
|
||||
#define MAGISK_PROPS_H
|
||||
|
||||
#include <CharArray.h>
|
||||
#include <string>
|
||||
#include "resetprop/private/system_properties.h"
|
||||
#include "logging.h"
|
||||
|
||||
struct prop_t {
|
||||
char *name;
|
||||
char value[PROP_VALUE_MAX];
|
||||
prop_t() = default;
|
||||
prop_t(const char *name) {
|
||||
prop_t() : name(nullptr) {}
|
||||
explicit prop_t(const char *name) {
|
||||
this->name = strdup(name);
|
||||
value[0] = '\0';
|
||||
}
|
||||
@ -21,6 +21,12 @@ struct prop_t {
|
||||
this->name = strdup(name);
|
||||
strcpy(this->value, value);
|
||||
}
|
||||
prop_t(prop_t &&prop): name(nullptr) {
|
||||
operator=(std::move(prop));
|
||||
}
|
||||
bool operator<(const prop_t &prop) const {
|
||||
return strcmp(name, prop.name) < 0;
|
||||
}
|
||||
prop_t& operator= (prop_t &&prop) {
|
||||
if (this != &prop) {
|
||||
free(name);
|
||||
@ -38,7 +44,7 @@ struct prop_t {
|
||||
struct read_cb_t {
|
||||
void (*cb)(const char *, const char *, void *);
|
||||
void *arg;
|
||||
read_cb_t(void (*cb)(const char *, const char *, void *) = nullptr, void *arg = nullptr)
|
||||
explicit read_cb_t(void (*cb)(const char *, const char *, void *) = nullptr, void *arg = nullptr)
|
||||
: cb(cb), arg(arg) {}
|
||||
void exec(const char *name, const char *value) {
|
||||
cb(name, value, arg);
|
||||
@ -49,7 +55,7 @@ struct read_cb_t {
|
||||
|
||||
extern bool use_pb;
|
||||
|
||||
CharArray persist_getprop(const char *name);
|
||||
std::string persist_getprop(const char *name);
|
||||
void persist_getprop(read_cb_t *read_cb);
|
||||
bool persist_deleteprop(const char *name);
|
||||
void collect_props(const char *name, const char *value, void *v_plist);
|
||||
|
@ -5,6 +5,8 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <pb.h>
|
||||
#include <pb_decode.h>
|
||||
#include <pb_encode.h>
|
||||
@ -12,6 +14,8 @@
|
||||
#include "_resetprop.h"
|
||||
#include "utils.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
/* ***********************************************************************
|
||||
* Auto generated header and constant definitions compiled from
|
||||
* android/platform/system/core/master/init/persistent_properties.proto
|
||||
@ -113,7 +117,7 @@ static bool prop_encode(pb_ostream_t *stream, const pb_field_t *field, void * co
|
||||
PersistentProperties_PersistentPropertyRecord prop = {};
|
||||
prop.name.funcs.encode = name_encode;
|
||||
prop.has_value = true;
|
||||
Vector<prop_t> &prop_list = *(Vector<prop_t> *) *arg;
|
||||
auto &prop_list = *(vector<prop_t> *) *arg;
|
||||
for (auto &p : prop_list) {
|
||||
if (!pb_encode_tag_for_field(stream, field))
|
||||
return false;
|
||||
@ -160,16 +164,16 @@ static void pb_getprop(read_cb_t *read_cb) {
|
||||
munmap(buf, size);
|
||||
}
|
||||
|
||||
static void file_getprop(const char *name, char *value) {
|
||||
value[0] = '\0';
|
||||
static bool file_getprop(const char *name, char *value) {
|
||||
char path[PATH_MAX];
|
||||
snprintf(path, sizeof(path), PERSISTENT_PROPERTY_DIR "/%s", name);
|
||||
int fd = open(path, O_RDONLY | O_CLOEXEC);
|
||||
if (fd < 0)
|
||||
return;
|
||||
return false;
|
||||
LOGD("resetprop: read prop from [%s]\n", path);
|
||||
value[read(fd, value, sizeof(PROP_VALUE_MAX))] = '\0'; // Null terminate the read value
|
||||
value[read(fd, value, PROP_VALUE_MAX)] = '\0'; // Null terminate the read value
|
||||
close(fd);
|
||||
return value[0] != '\0';
|
||||
}
|
||||
|
||||
void persist_getprop(read_cb_t *read_cb) {
|
||||
@ -182,14 +186,13 @@ void persist_getprop(read_cb_t *read_cb) {
|
||||
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0 )
|
||||
continue;
|
||||
char value[PROP_VALUE_MAX];
|
||||
file_getprop(entry->d_name, value);
|
||||
if (value[0])
|
||||
if (file_getprop(entry->d_name, value))
|
||||
read_cb->exec(entry->d_name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CharArray persist_getprop(const char *name) {
|
||||
string persist_getprop(const char *name) {
|
||||
prop_t prop(name);
|
||||
if (use_pb) {
|
||||
read_cb_t read_cb(pb_getprop_cb, &prop);
|
||||
@ -199,21 +202,20 @@ CharArray persist_getprop(const char *name) {
|
||||
} else {
|
||||
// Try to read from file
|
||||
char value[PROP_VALUE_MAX];
|
||||
file_getprop(name, value);
|
||||
if (value[0])
|
||||
if (file_getprop(name, value))
|
||||
return value;
|
||||
}
|
||||
return CharArray();
|
||||
return string();
|
||||
}
|
||||
|
||||
bool persist_deleteprop(const char *name) {
|
||||
if (use_pb) {
|
||||
Vector<prop_t> prop_list;
|
||||
vector<prop_t> prop_list;
|
||||
read_cb_t read_cb(collect_props, &prop_list);
|
||||
persist_getprop(&read_cb);
|
||||
|
||||
for (auto it = prop_list.begin(); it != prop_list.end(); ++it) {
|
||||
if (strcmp((*it).name, name) == 0) {
|
||||
if (strcmp(it->name, name) == 0) {
|
||||
prop_list.erase(it);
|
||||
// Dump the props back
|
||||
PersistentProperties props = PersistentProperties_init_zero;
|
||||
|
@ -6,6 +6,8 @@
|
||||
#include <string.h>
|
||||
#include <dirent.h>
|
||||
#include <sys/types.h>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
|
||||
#include "private/_system_properties.h"
|
||||
@ -17,6 +19,8 @@
|
||||
#include "utils.h"
|
||||
#include "flags.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
bool use_pb = false;
|
||||
static bool verbose = false;
|
||||
|
||||
@ -74,12 +78,6 @@ illegal:
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Define the way to sort prop_t
|
||||
template<>
|
||||
int(*Vector<prop_t>::_cmp)(prop_t&, prop_t&) = [](auto a, auto b) -> int {
|
||||
return strcmp(a.name, b.name);
|
||||
};
|
||||
|
||||
static void read_props(const prop_info *pi, void *read_cb) {
|
||||
__system_property_read_callback(
|
||||
pi, [](auto cb, auto name, auto value, auto) -> void
|
||||
@ -89,12 +87,12 @@ static void read_props(const prop_info *pi, void *read_cb) {
|
||||
}
|
||||
|
||||
void collect_props(const char *name, const char *value, void *v_plist) {
|
||||
Vector<prop_t> &prop_list = *static_cast<Vector<prop_t> *>(v_plist);
|
||||
prop_list.push_back(prop_t(name, value));
|
||||
auto &prop_list = *static_cast<vector<prop_t> *>(v_plist);
|
||||
prop_list.emplace_back(name, value);
|
||||
}
|
||||
|
||||
static void collect_unique_props(const char *name, const char *value, void *v_plist) {
|
||||
Vector<prop_t> &prop_list = *static_cast<Vector<prop_t> *>(v_plist);
|
||||
auto &prop_list = *static_cast<vector<prop_t> *>(v_plist);
|
||||
for (auto &prop : prop_list) {
|
||||
if (strcmp(name, prop.name) == 0)
|
||||
return;
|
||||
@ -112,9 +110,9 @@ static int init_resetprop() {
|
||||
}
|
||||
|
||||
static void print_props(bool persist) {
|
||||
Vector<prop_t> prop_list;
|
||||
vector<prop_t> prop_list;
|
||||
getprop(collect_props, &prop_list, persist);
|
||||
prop_list.sort();
|
||||
sort(prop_list.begin(), prop_list.end());
|
||||
for (auto &prop : prop_list)
|
||||
printf("[%s]: [%s]\n", prop.name, prop.value);
|
||||
}
|
||||
@ -128,19 +126,19 @@ int prop_exist(const char *name) {
|
||||
return __system_property_find(name) != nullptr;
|
||||
}
|
||||
|
||||
// Get prop by name, return string (should free manually!)
|
||||
CharArray getprop(const char *name, bool persist) {
|
||||
// Get prop by name, return string
|
||||
string getprop(const char *name, bool persist) {
|
||||
if (!check_legal_property_name(name) || init_resetprop())
|
||||
return nullptr;
|
||||
const prop_info *pi = __system_property_find(name);
|
||||
if (pi == nullptr) {
|
||||
if (persist && strncmp(name, "persist.", 8) == 0) {
|
||||
CharArray value = persist_getprop(name);
|
||||
if (!value.empty())
|
||||
auto value = persist_getprop(name);
|
||||
if (value.empty())
|
||||
LOGD("resetprop: prop [%s] does not exist\n", name);
|
||||
return value;
|
||||
}
|
||||
LOGD("resetprop: prop [%s] does not exist\n", name);
|
||||
return CharArray();
|
||||
return string();
|
||||
} else {
|
||||
char value[PROP_VALUE_MAX];
|
||||
read_cb_t read_cb;
|
||||
@ -162,7 +160,7 @@ void getprop(void (*callback)(const char *, const char *, void *), void *cookie,
|
||||
}
|
||||
}
|
||||
|
||||
int setprop(const char *name, const char *value, const bool trigger) {
|
||||
int setprop(const char *name, const char *value, bool trigger) {
|
||||
if (!check_legal_property_name(name))
|
||||
return 1;
|
||||
if (init_resetprop())
|
||||
@ -170,7 +168,7 @@ int setprop(const char *name, const char *value, const bool trigger) {
|
||||
|
||||
int ret;
|
||||
|
||||
prop_info *pi = (prop_info*) __system_property_find(name);
|
||||
auto pi = (prop_info*) __system_property_find(name);
|
||||
if (pi != nullptr) {
|
||||
if (trigger) {
|
||||
if (strncmp(name, "ro.", 3) == 0) deleteprop(name);
|
||||
@ -208,7 +206,7 @@ int deleteprop(const char *name, bool persist) {
|
||||
return __system_property_del(name) && !(persist && strncmp(name, "persist.", 8) == 0);
|
||||
}
|
||||
|
||||
int load_prop_file(const char *filename, const bool trigger) {
|
||||
int load_prop_file(const char *filename, bool trigger) {
|
||||
if (init_resetprop()) return -1;
|
||||
LOGD("resetprop: Load prop file [%s]\n", filename);
|
||||
FILE *fp = xfopen(filename, "re");
|
||||
@ -254,14 +252,14 @@ int resetprop_main(int argc, char *argv[]) {
|
||||
|
||||
bool trigger = true, persist = false;
|
||||
char *argv0 = argv[0];
|
||||
CharArray prop;
|
||||
string prop;
|
||||
|
||||
--argc;
|
||||
++argv;
|
||||
|
||||
// Parse flags and -- options
|
||||
while (argc && argv[0][0] == '-') {
|
||||
for (int idx = 1; 1; ++idx) {
|
||||
for (int idx = 1; true; ++idx) {
|
||||
switch (argv[0][idx]) {
|
||||
case '-':
|
||||
if (strcmp(argv[0], "--file") == 0 && argc == 2) {
|
||||
@ -275,10 +273,10 @@ int resetprop_main(int argc, char *argv[]) {
|
||||
verbose = true;
|
||||
continue;
|
||||
case 'p':
|
||||
persist = 1;
|
||||
persist = true;
|
||||
continue;
|
||||
case 'n':
|
||||
trigger = 0;
|
||||
trigger = false;
|
||||
continue;
|
||||
case '\0':
|
||||
break;
|
||||
@ -297,8 +295,8 @@ int resetprop_main(int argc, char *argv[]) {
|
||||
print_props(persist);
|
||||
return 0;
|
||||
case 1:
|
||||
prop = utils::move(getprop(argv[0], persist));
|
||||
if (!prop) return 1;
|
||||
prop = getprop(argv[0], persist);
|
||||
if (prop.empty()) return 1;
|
||||
printf("%s\n", prop.c_str());
|
||||
return 0;
|
||||
case 2:
|
||||
|
@ -9,7 +9,6 @@ LOCAL_SRC_FILES := \
|
||||
misc.cpp \
|
||||
selinux.cpp \
|
||||
logging.cpp \
|
||||
xwrap.cpp \
|
||||
CharArray.cpp
|
||||
xwrap.cpp
|
||||
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
|
@ -1,99 +0,0 @@
|
||||
#include "CharArray.h"
|
||||
#include "utils.h"
|
||||
|
||||
CharArray::CharArray() : _buf(nullptr), _size(0){}
|
||||
|
||||
CharArray::CharArray(const char *s) : CharArray() {
|
||||
this->operator=(s);
|
||||
}
|
||||
|
||||
CharArray::CharArray(const CharArray &s) : CharArray() {
|
||||
this->operator=(s);
|
||||
}
|
||||
|
||||
CharArray::CharArray(size_t i) {
|
||||
_size = i;
|
||||
_buf = new char[i](); /* Zero initialize */
|
||||
}
|
||||
|
||||
CharArray::~CharArray() {
|
||||
delete[] _buf;
|
||||
}
|
||||
|
||||
CharArray::operator char *() {
|
||||
return _buf;
|
||||
}
|
||||
|
||||
CharArray::operator const char *() const {
|
||||
return _buf;
|
||||
}
|
||||
|
||||
const char *CharArray::c_str() const {
|
||||
return _buf;
|
||||
}
|
||||
|
||||
size_t CharArray::length() const {
|
||||
return strlen(_buf);
|
||||
}
|
||||
|
||||
size_t CharArray::size() const {
|
||||
return _size;
|
||||
}
|
||||
|
||||
CharArray &CharArray::operator=(const CharArray &s) {
|
||||
delete[] _buf;
|
||||
_size = s._size;
|
||||
_buf = new char[_size];
|
||||
memcpy(_buf, s._buf, _size);
|
||||
return *this;
|
||||
}
|
||||
|
||||
CharArray &CharArray::operator=(const char *s) {
|
||||
delete[] _buf;
|
||||
_buf = strdup2(s, &_size);
|
||||
return *this;
|
||||
}
|
||||
|
||||
CharArray &CharArray::operator=(CharArray &&s) {
|
||||
delete[] _buf;
|
||||
_size = s._size;
|
||||
_buf = s._buf;
|
||||
s._buf = nullptr;
|
||||
s._size = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool CharArray::operator==(const char *s) const {
|
||||
if (_buf == nullptr || s == nullptr)
|
||||
return false;
|
||||
return strcmp(_buf, s) == 0;
|
||||
}
|
||||
|
||||
bool CharArray::operator==(char *s) const {
|
||||
return *this == (const char *) s;
|
||||
}
|
||||
|
||||
bool CharArray::operator!=(const char *s) const {
|
||||
return !(*this == s);
|
||||
}
|
||||
|
||||
int CharArray::compare(const char *s) const {
|
||||
return strcmp(_buf, s);
|
||||
}
|
||||
|
||||
int CharArray::compare(const char *s, size_t len) const {
|
||||
return strncmp(_buf, s, len);
|
||||
}
|
||||
|
||||
bool CharArray::contains(const char *s) const {
|
||||
return s == nullptr ? false : strstr(_buf, s) != nullptr;
|
||||
}
|
||||
|
||||
bool CharArray::starts_with(const char *s) const {
|
||||
return s == nullptr ? false : compare(s, strlen(s)) == 0;
|
||||
}
|
||||
|
||||
bool CharArray::empty() const {
|
||||
return _buf == nullptr || _buf[0] == '\0';
|
||||
}
|
||||
|
@ -15,6 +15,8 @@
|
||||
#include "utils.h"
|
||||
#include "selinux.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
const char **excl_list = nullptr;
|
||||
|
||||
static int is_excl(const char *name) {
|
||||
@ -307,7 +309,7 @@ void clone_attr(const char *source, const char *target) {
|
||||
setattr(target, &a);
|
||||
}
|
||||
|
||||
void fclone_attr(const int sourcefd, const int targetfd) {
|
||||
void fclone_attr(int sourcefd, int targetfd) {
|
||||
struct file_attr a;
|
||||
fgetattr(sourcefd, &a);
|
||||
fsetattr(targetfd, &a);
|
||||
@ -388,24 +390,25 @@ void write_zero(int fd, size_t size) {
|
||||
lseek(fd, pos + size, SEEK_SET);
|
||||
}
|
||||
|
||||
int file_to_vector(const char *filename, Vector<CharArray> &arr) {
|
||||
vector<string> file_to_vector(const char *filename) {
|
||||
auto arr = vector<string>();
|
||||
if (access(filename, R_OK) != 0)
|
||||
return 1;
|
||||
return arr;
|
||||
char *line = nullptr;
|
||||
size_t len = 0;
|
||||
ssize_t read;
|
||||
|
||||
FILE *fp = xfopen(filename, "re");
|
||||
if (fp == nullptr)
|
||||
return 1;
|
||||
return arr;
|
||||
|
||||
while ((read = getline(&line, &len, fp)) != -1) {
|
||||
// Remove end newline
|
||||
if (line[read - 1] == '\n')
|
||||
line[read - 1] = '\0';
|
||||
arr.push_back(line);
|
||||
arr.emplace_back(line);
|
||||
}
|
||||
fclose(fp);
|
||||
free(line);
|
||||
return 0;
|
||||
return arr;
|
||||
}
|
||||
|
@ -1,39 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/* A wrapper around char array */
|
||||
class CharArray {
|
||||
public:
|
||||
CharArray();
|
||||
CharArray(const char *s);
|
||||
CharArray(const CharArray &s);
|
||||
CharArray(size_t i);
|
||||
~CharArray();
|
||||
|
||||
CharArray &operator=(const CharArray &s);
|
||||
CharArray &operator=(CharArray &&s);
|
||||
CharArray &operator=(const char *s);
|
||||
|
||||
operator char *();
|
||||
operator const char *() const;
|
||||
bool operator==(char *s) const;
|
||||
bool operator==(const char *s) const;
|
||||
bool operator!=(const char *s) const;
|
||||
int compare(const char *s) const;
|
||||
int compare(const char *s, size_t len) const;
|
||||
bool starts_with(const char *s) const;
|
||||
bool contains(const char *s) const;
|
||||
bool empty() const;
|
||||
const char *c_str() const;
|
||||
size_t length() const;
|
||||
size_t size() const;
|
||||
|
||||
/* These 2 ops are incompatible with implicit char* conversion */
|
||||
// char &operator[](size_t i);
|
||||
// const char &operator[](size_t i) const;
|
||||
|
||||
private:
|
||||
char *_buf;
|
||||
size_t _size;
|
||||
};
|
@ -1,191 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "cpputils.h"
|
||||
|
||||
template <class T>
|
||||
class Vector {
|
||||
public:
|
||||
Vector() : _data(0), _size(0), _capacity(0) {}
|
||||
~Vector() { delete []_data; }
|
||||
|
||||
class iterator {
|
||||
friend class Vector;
|
||||
|
||||
public:
|
||||
iterator(T* n= 0): _node(n) {}
|
||||
iterator(const iterator& i): _node(i._node) {}
|
||||
~iterator() {} // Should NOT delete _node
|
||||
|
||||
const T& operator * () const { return (*_node); }
|
||||
T& operator * () { return (*_node); }
|
||||
iterator& operator ++ () {
|
||||
++_node;
|
||||
return (*this);
|
||||
}
|
||||
|
||||
iterator operator ++ (int) {
|
||||
iterator temp = *this;
|
||||
++_node;
|
||||
return temp;
|
||||
}
|
||||
|
||||
iterator& operator -- () {
|
||||
--_node;
|
||||
return (*this);
|
||||
}
|
||||
|
||||
iterator operator -- (int) {
|
||||
iterator temp = *this;
|
||||
--_node;
|
||||
return temp;
|
||||
}
|
||||
|
||||
iterator operator + (int i) const {
|
||||
iterator temp = *this;
|
||||
temp += i;
|
||||
return temp;
|
||||
}
|
||||
|
||||
iterator& operator += (int i) {
|
||||
_node += i;
|
||||
return (*this);
|
||||
}
|
||||
|
||||
iterator& operator = (const iterator& i) {
|
||||
_node = i._node;
|
||||
return (*this);
|
||||
}
|
||||
|
||||
bool operator != (const iterator& i) const {
|
||||
return _node != i._node;
|
||||
}
|
||||
|
||||
bool operator == (const iterator& i) const { return !(*this != i); }
|
||||
|
||||
private:
|
||||
T* _node;
|
||||
};
|
||||
|
||||
Vector &operator=(const Vector& a) {
|
||||
delete [] _data;
|
||||
_data = nullptr;
|
||||
_size = a._size;
|
||||
_capacity = a._capacity;
|
||||
if (_capacity) {
|
||||
_data = new T[_capacity];
|
||||
for(int i = 0; i < _size; ++i)
|
||||
_data[i] = a[i];
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vector &operator=(Vector&& a) {
|
||||
delete [] _data;
|
||||
_size = a._size;
|
||||
_capacity = a._capacity;
|
||||
_data = a._data;
|
||||
a._size = 0;
|
||||
a._capacity = 0;
|
||||
a._data = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
iterator begin() const { return iterator(_data); }
|
||||
|
||||
iterator end() const { return iterator(_data + _size); }
|
||||
|
||||
bool empty() const { return !_size; }
|
||||
|
||||
size_t size() const { return _size; }
|
||||
|
||||
T& operator [] (size_t i) { return _data[i]; }
|
||||
|
||||
const T& operator [] (size_t i) const { return _data[i]; }
|
||||
|
||||
const T& back() const { return _data[_size - 1]; }
|
||||
|
||||
void push_back(const T& x) {
|
||||
if(_size == _capacity)
|
||||
expand();
|
||||
_data[_size] = x;
|
||||
++_size;
|
||||
}
|
||||
|
||||
void push_back(T&& x) {
|
||||
if(_size == _capacity)
|
||||
expand();
|
||||
_data[_size] = utils::move(x);
|
||||
++_size;
|
||||
}
|
||||
|
||||
void pop_front() { erase(begin()); }
|
||||
|
||||
void pop_back() { if(_size) --_size; }
|
||||
|
||||
bool erase(iterator pos) {
|
||||
T* d = pos._node;
|
||||
if (_size == 0 || d < _data || d >= _data + _size)
|
||||
return false;
|
||||
for (; d < _data + _size - 1; ++d)
|
||||
*d = utils::move(*(d + 1));
|
||||
--_size;
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool erase(const T& x) {
|
||||
for (T* i = _data; i < _data + _size; ++i) {
|
||||
if(*i == x) {
|
||||
erase(iterator(i));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void clear(bool dealloc = false) {
|
||||
_size = 0;
|
||||
if (dealloc) {
|
||||
_capacity = 0;
|
||||
delete [] _data;
|
||||
_data = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void sort() {
|
||||
qsort(_data, _size, sizeof(T), compare);
|
||||
}
|
||||
|
||||
T* data() { return _data; }
|
||||
|
||||
const T* data() const { return _data; }
|
||||
|
||||
// void reserve(size_t n) { ... }
|
||||
// void resize(size_t n) { ... }
|
||||
|
||||
private:
|
||||
T* _data;
|
||||
size_t _size; // number of valid elements
|
||||
size_t _capacity; // max number of elements
|
||||
static int(*_cmp)(T&, T&);
|
||||
|
||||
static int compare(const void *a, const void *b) {
|
||||
return _cmp ? _cmp(*((T*) a), *((T*) b)) : 0;
|
||||
}
|
||||
|
||||
void expand() {
|
||||
if (_capacity == 0)
|
||||
_capacity = 1;
|
||||
else
|
||||
_capacity *= 2;
|
||||
T* temp = _data;
|
||||
_data = new T[_capacity];
|
||||
for(int i = 0; i < _size; ++i)
|
||||
_data[i] = utils::move(temp[i]);
|
||||
delete [] temp;
|
||||
}
|
||||
};
|
||||
|
||||
template<class T>
|
||||
int(* Vector<T>::_cmp)(T&, T&) = nullptr;
|
@ -1,12 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
namespace utils {
|
||||
template< class T > struct remove_reference {typedef T type;};
|
||||
template< class T > struct remove_reference<T&> {typedef T type;};
|
||||
template< class T > struct remove_reference<T&&> {typedef T type;};
|
||||
|
||||
template< class T >
|
||||
constexpr typename remove_reference<T>::type&& move( T&& t ) noexcept {
|
||||
return static_cast<typename remove_reference<T>::type&&>(t);
|
||||
}
|
||||
}
|
@ -13,15 +13,17 @@
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "Vector.h"
|
||||
#include "CharArray.h"
|
||||
#include "cpputils.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
int file_to_vector(const char *filename, Vector<CharArray> &arr);
|
||||
#define str_contains(s, ss) ((s).find(ss) != string::npos)
|
||||
#define str_starts(s, ss) ((s).compare(0, strlen(ss), ss) == 0)
|
||||
|
||||
std::vector<std::string> file_to_vector(const char *filename);
|
||||
char *strdup2(const char *s, size_t *size = nullptr);
|
||||
|
||||
int exec_array(bool err, int *fd, void (*pre_exec)(void), const char **argv);
|
||||
int exec_command(bool err, int *fd, void (*cb)(void), const char *argv0, ...);
|
||||
int exec_array(bool err, int *fd, void (*pre_exec)(), const char **argv);
|
||||
int exec_command(bool err, int *fd, void (*cb)(), const char *argv0, ...);
|
||||
|
||||
extern "C" {
|
||||
#endif
|
||||
@ -134,7 +136,7 @@ int fgetattr(int fd, struct file_attr *a);
|
||||
int setattr(const char *path, struct file_attr *a);
|
||||
int setattrat(int dirfd, const char *pathname, struct file_attr *a);
|
||||
int fsetattr(int fd, struct file_attr *a);
|
||||
void fclone_attr(const int sourcefd, const int targetfd);
|
||||
void fclone_attr(int sourcefd, int targetfd);
|
||||
void clone_attr(const char *source, const char *target);
|
||||
void mmap_ro(const char *filename, void **buf, size_t *size);
|
||||
void mmap_rw(const char *filename, void **buf, size_t *size);
|
||||
|
@ -11,10 +11,13 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/sysmacros.h>
|
||||
#include <vector>
|
||||
|
||||
#include "logging.h"
|
||||
#include "utils.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
unsigned get_shell_uid() {
|
||||
struct passwd* ppwd = getpwnam("shell");
|
||||
if (nullptr == ppwd)
|
||||
@ -199,7 +202,7 @@ int exec_array(bool err, int *fd, void (*pre_exec)(void), const char **argv) {
|
||||
|
||||
static int v_exec_command(bool err, int *fd, void (*cb)(void), const char *argv0, va_list argv) {
|
||||
// Collect va_list into vector
|
||||
Vector<const char *> args;
|
||||
vector<const char *> args;
|
||||
args.push_back(argv0);
|
||||
for (const char *arg = va_arg(argv, char*); arg; arg = va_arg(argv, char*))
|
||||
args.push_back(arg);
|
||||
|
@ -1,6 +1,9 @@
|
||||
#include <new>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* Override libc++ new implementation
|
||||
* to optimize final build size */
|
||||
|
||||
void* operator new(std::size_t s) { return malloc(s); }
|
||||
void* operator new[](std::size_t s) { return malloc(s); }
|
||||
void operator delete(void *p) { free(p); }
|
||||
|
@ -86,7 +86,7 @@ ssize_t xread(int fd, void *buf, size_t count) {
|
||||
ssize_t xxread(int fd, void *buf, size_t count) {
|
||||
int ret = read(fd, buf, count);
|
||||
if (count != ret) {
|
||||
PLOGE("read");
|
||||
PLOGE("read (%d != %d)", count, ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user