mirror of
https://github.com/topjohnwu/Magisk
synced 2025-10-29 07:20:52 +01:00
Compare commits
23 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e8302dfbe2 | ||
|
|
558f95cf7e | ||
|
|
18f6ead891 | ||
|
|
10bd25be52 | ||
|
|
65511845d2 | ||
|
|
1c743839ea | ||
|
|
bcae9dec41 | ||
|
|
482c9af41f | ||
|
|
2bf2e7461f | ||
|
|
7d1082b1cb | ||
|
|
0dbae83aec | ||
|
|
f927c1b997 | ||
|
|
89ec7dad2b | ||
|
|
4fd61345af | ||
|
|
66cca24453 | ||
|
|
e733484fab | ||
|
|
e5c3183025 | ||
|
|
930c82316a | ||
|
|
3dc22db265 | ||
|
|
d8c51cb286 | ||
|
|
2f79d0c3b3 | ||
|
|
d8bb3af06b | ||
|
|
e139e8777b |
12
README.MD
12
README.MD
@@ -43,12 +43,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
**MagiskManager** (`app`)
|
||||
|
||||
* Copyright 2016-2017, John Wu (@topjohnwu)
|
||||
* Copyright 2016-2018, John Wu (@topjohnwu)
|
||||
* All contributors and translators on Github
|
||||
|
||||
**MagiskSU** (`core/jni/su`)
|
||||
|
||||
* Copyright 2016-2017, John Wu (@topjohnwu)
|
||||
* Copyright 2016-2018, John Wu (@topjohnwu)
|
||||
* Copyright 2015, Pierre-Hugues Husson (phh@phh.me)
|
||||
* Copyright 2013, Koushik Dutta (@koush)
|
||||
* Copyright 2010, Adam Shanks (@ChainsDD)
|
||||
@@ -56,18 +56,18 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
**MagiskPolicy** (`core/jni/magiskpolicy`)
|
||||
|
||||
* Copyright 2016-2017, John Wu (@topjohnwu)
|
||||
* Copyright 2016-2018, John Wu (@topjohnwu)
|
||||
* Copyright 2015, Pierre-Hugues Husson (phh@phh.me)
|
||||
* Copyright 2015, Joshua Brindle (@joshua_brindle)
|
||||
|
||||
**MagiskHide** (`core/jni/magiskhide`)
|
||||
|
||||
* Copyright 2016-2017, John Wu (@topjohnwu)
|
||||
* Copyright 2016-2018, John Wu (@topjohnwu)
|
||||
* Copyright 2016, Pierre-Hugues Husson (phh@phh.me)
|
||||
|
||||
**resetprop** (`core/jni/resetprop`)
|
||||
|
||||
* Copyright 2016-2017 John Wu (@topjohnwu)
|
||||
* Copyright 2016-2018 John Wu (@topjohnwu)
|
||||
* Copyright 2016 nkk71 (nkk71x@gmail.com)
|
||||
|
||||
**External Dependencies** (`core/jni/external`)
|
||||
@@ -78,4 +78,4 @@ All of them are either GPL or GPL compatible.
|
||||
|
||||
**Others Not Mentioned**
|
||||
|
||||
* Copyright 2016-2017, John Wu (@topjohnwu)
|
||||
* Copyright 2016-2018, John Wu (@topjohnwu)
|
||||
|
||||
2
app
2
app
Submodule app updated: de2285d5e9...759e905c3c
@@ -140,14 +140,14 @@ static void pm_setenv(struct vector *v) {
|
||||
static void exec_common_script(const char* stage) {
|
||||
DIR *dir;
|
||||
struct dirent *entry;
|
||||
snprintf(buf, PATH_MAX, "%s/%s.d", COREDIR, stage);
|
||||
snprintf(buf2, PATH_MAX, "%s/%s.d", COREDIR, stage);
|
||||
|
||||
if (!(dir = xopendir(buf)))
|
||||
if (!(dir = xopendir(buf2)))
|
||||
return;
|
||||
|
||||
while ((entry = xreaddir(dir))) {
|
||||
if (entry->d_type == DT_REG) {
|
||||
snprintf(buf2, PATH_MAX, "%s/%s", buf, entry->d_name);
|
||||
snprintf(buf2, PATH_MAX, "%s/%s.d/%s", COREDIR, stage, entry->d_name);
|
||||
if (access(buf2, X_OK) == -1)
|
||||
continue;
|
||||
LOGI("%s.d: exec [%s]\n", stage, entry->d_name);
|
||||
@@ -274,7 +274,7 @@ static void clone_skeleton(struct node_entry *node) {
|
||||
char *con;
|
||||
xstat(full_path, &s);
|
||||
getfilecon(full_path, &con);
|
||||
LOGI("tmpfs: %s\n", full_path);
|
||||
LOGI("mnt_tmpfs : %s\n", full_path);
|
||||
xmount("tmpfs", full_path, "tmpfs", 0, NULL);
|
||||
chmod(full_path, s.st_mode & 0777);
|
||||
chown(full_path, s.st_uid, s.st_gid);
|
||||
@@ -295,7 +295,7 @@ static void clone_skeleton(struct node_entry *node) {
|
||||
if (child->parent->parent == NULL && strcmp(child->name, "vendor") == 0) {
|
||||
if (IS_LNK(child)) {
|
||||
cp_afc(MIRRDIR "/system/vendor", "/system/vendor");
|
||||
LOGI("cplink: %s -> %s\n", MIRRDIR "/system/vendor", "/system/vendor");
|
||||
LOGI("creat_link: %s <- %s\n", "/system/vendor", MIRRDIR "/system/vendor");
|
||||
}
|
||||
// Skip
|
||||
continue;
|
||||
@@ -315,9 +315,9 @@ static void clone_skeleton(struct node_entry *node) {
|
||||
// Copy symlinks directly
|
||||
cp_afc(buf2, buf);
|
||||
#ifdef MAGISK_DEBUG
|
||||
LOGI("cplink: %s -> %s\n",buf2, buf);
|
||||
LOGI("creat_link: %s <- %s\n",buf, buf2);
|
||||
#else
|
||||
LOGI("cplink: %s\n", buf);
|
||||
LOGI("creat_link: %s\n", buf);
|
||||
#endif
|
||||
} else {
|
||||
snprintf(buf, PATH_MAX, "%s/%s", full_path, child->name);
|
||||
@@ -647,23 +647,30 @@ void late_start(int client) {
|
||||
core_only:
|
||||
// Install Magisk Manager if exists
|
||||
if (access(MANAGERAPK, F_OK) == 0) {
|
||||
rename(MANAGERAPK, "/data/magisk.apk");
|
||||
setfilecon("/data/magisk.apk", "u:object_r:su_file:s0");
|
||||
while (1) {
|
||||
sleep(5);
|
||||
int apk_res = -1, pid;
|
||||
pid = exec_command(1, &apk_res, pm_setenv,
|
||||
"app_process",
|
||||
"/system/bin", "com.android.commands.pm.Pm",
|
||||
"install", "-r", MANAGERAPK, NULL);
|
||||
"install", "-r", "/data/magisk.apk", NULL);
|
||||
if (pid != -1) {
|
||||
int err = 0;
|
||||
while (fdgets(buf, PATH_MAX, apk_res) > 0) {
|
||||
LOGD("apk_install: %s", buf);
|
||||
err |= strstr(buf, "Error:") != NULL;
|
||||
}
|
||||
waitpid(pid, NULL, 0);
|
||||
fdgets(buf, PATH_MAX, apk_res);
|
||||
close(apk_res);
|
||||
// Keep trying until pm is started
|
||||
if (strstr(buf, "Error:") == NULL)
|
||||
break;
|
||||
if (err)
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
unlink(MANAGERAPK);
|
||||
unlink("/data/magisk.apk");
|
||||
}
|
||||
|
||||
// All boot stage done, cleanup everything
|
||||
|
||||
@@ -129,11 +129,6 @@ void daemon_init() {
|
||||
unlink("/data/magisk_debug.log");
|
||||
chmod("/data/adb", 0700);
|
||||
|
||||
// Use shell glob to match files
|
||||
exec_command_sync("sh", "-c",
|
||||
"mv -f /data/adb/magisk/stock_*.img.gz /data;"
|
||||
"rm -f /data/user*/*/magisk.db;", NULL);
|
||||
|
||||
LOGI("* Creating /sbin overlay");
|
||||
DIR *dir;
|
||||
struct dirent *entry;
|
||||
@@ -191,7 +186,7 @@ void daemon_init() {
|
||||
// Check whether skip_initramfs device
|
||||
vec_for_each(&mounts, line) {
|
||||
if (strstr(line, " /system_root ")) {
|
||||
xmkdir_p(MIRRDIR "/system", 0755);
|
||||
xmkdirs(MIRRDIR "/system", 0755);
|
||||
bind_mount("/system_root/system", MIRRDIR "/system");
|
||||
skip_initramfs = 1;
|
||||
break;
|
||||
@@ -200,7 +195,7 @@ void daemon_init() {
|
||||
vec_for_each(&mounts, line) {
|
||||
if (!skip_initramfs && strstr(line, " /system ")) {
|
||||
sscanf(line, "%s", buf);
|
||||
xmkdir_p(MIRRDIR "/system", 0755);
|
||||
xmkdirs(MIRRDIR "/system", 0755);
|
||||
xmount(buf, MIRRDIR "/system", "ext4", MS_RDONLY, NULL);
|
||||
#ifdef MAGISK_DEBUG
|
||||
LOGI("mount: %s -> %s\n", buf, MIRRDIR "/system");
|
||||
@@ -210,7 +205,7 @@ void daemon_init() {
|
||||
} else if (strstr(line, " /vendor ")) {
|
||||
seperate_vendor = 1;
|
||||
sscanf(line, "%s", buf);
|
||||
xmkdir_p(MIRRDIR "/vendor", 0755);
|
||||
xmkdirs(MIRRDIR "/vendor", 0755);
|
||||
xmount(buf, MIRRDIR "/vendor", "ext4", MS_RDONLY, NULL);
|
||||
#ifdef MAGISK_DEBUG
|
||||
LOGI("mount: %s -> %s\n", buf, MIRRDIR "/vendor");
|
||||
@@ -229,11 +224,11 @@ void daemon_init() {
|
||||
LOGI("link: %s\n", MIRRDIR "/vendor");
|
||||
#endif
|
||||
}
|
||||
xmkdir_p(MIRRDIR "/bin", 0755);
|
||||
xmkdirs(MIRRDIR "/bin", 0755);
|
||||
bind_mount(DATABIN, MIRRDIR "/bin");
|
||||
|
||||
LOGI("* Setting up internal busybox");
|
||||
xmkdir_p(BBPATH, 0755);
|
||||
xmkdirs(BBPATH, 0755);
|
||||
exec_command_sync(MIRRDIR "/bin/busybox", "--install", "-s", BBPATH, NULL);
|
||||
xsymlink(MIRRDIR "/bin/busybox", BBPATH "/busybox");
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ static void *logger_thread(void *args) {
|
||||
|
||||
while (1) {
|
||||
// Start logcat
|
||||
log_pid = exec_command(0, &log_fd, NULL, "logcat", "-b", "all" , "-v", "threadtime", "-s", "am_proc_start", "Magisk", NULL);
|
||||
log_pid = exec_command(0, &log_fd, NULL, "logcat", "-b", "events", "-b", "main", "-v", "threadtime", "-s", "am_proc_start", "-s", "Magisk", NULL);
|
||||
while (fdgets(line, sizeof(line), log_fd)) {
|
||||
for (int i = 0; i < (sizeof(log_events) / sizeof(struct log_listener)); ++i) {
|
||||
if (log_events[i].fd > 0 && log_events[i].filter(line)) {
|
||||
@@ -74,7 +74,7 @@ static void *logger_thread(void *args) {
|
||||
waitpid(log_pid, NULL, 0);
|
||||
|
||||
// Clear buffer before restart
|
||||
exec_command_sync("logcat", "-b", "all", "-c", NULL);
|
||||
exec_command_sync("logcat", "-b", "events", "-b", "main", "-c", NULL);
|
||||
}
|
||||
|
||||
// Should never be here, but well...
|
||||
|
||||
@@ -77,7 +77,7 @@ static void parse_cmdline(struct cmdline *cmd) {
|
||||
|
||||
char cmdline[4096];
|
||||
mkdir("/proc", 0555);
|
||||
mount("proc", "/proc", "proc", 0, NULL);
|
||||
xmount("proc", "/proc", "proc", 0, NULL);
|
||||
int fd = open("/proc/cmdline", O_RDONLY | O_CLOEXEC);
|
||||
cmdline[read(fd, cmdline, sizeof(cmdline))] = '\0';
|
||||
close(fd);
|
||||
@@ -305,16 +305,20 @@ static int verify_precompiled() {
|
||||
return strcmp(sys_sha, ven_sha) == 0;
|
||||
}
|
||||
|
||||
static void patch_sepolicy() {
|
||||
static int patch_sepolicy() {
|
||||
if (access("/sepolicy", R_OK) == 0)
|
||||
load_policydb("/sepolicy");
|
||||
else if (access(SPLIT_PRECOMPILE, R_OK) == 0 && verify_precompiled())
|
||||
load_policydb(SPLIT_PRECOMPILE);
|
||||
else if (access(SPLIT_PLAT_CIL, R_OK) == 0)
|
||||
compile_cil();
|
||||
else
|
||||
return 1;
|
||||
|
||||
sepol_magisk_rules();
|
||||
dump_policydb("/sepolicy");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define BUFSIZE (1 << 20)
|
||||
@@ -364,7 +368,8 @@ static void magisk_init_daemon() {
|
||||
sepol_allow("su", ALL, ALL, ALL);
|
||||
|
||||
// Wait till init cold boot done
|
||||
wait_till_exists("/dev/.coldboot_done");
|
||||
while (access("/dev/.coldboot_done", F_OK))
|
||||
usleep(1);
|
||||
|
||||
int null = open("/dev/null", O_RDWR | O_CLOEXEC);
|
||||
dup3(null, STDIN_FILENO, O_CLOEXEC);
|
||||
@@ -450,7 +455,7 @@ int main(int argc, char *argv[]) {
|
||||
frm_rf(root);
|
||||
|
||||
mkdir("/sys", 0755);
|
||||
mount("sysfs", "/sys", "sysfs", 0, NULL);
|
||||
xmount("sysfs", "/sys", "sysfs", 0, NULL);
|
||||
|
||||
char partname[32];
|
||||
snprintf(partname, sizeof(partname), "system%s", cmd.slot);
|
||||
@@ -459,20 +464,20 @@ int main(int argc, char *argv[]) {
|
||||
setup_block(&dev, partname);
|
||||
|
||||
mkdir("/system_root", 0755);
|
||||
mount(dev.path, "/system_root", "ext4", MS_RDONLY, NULL);
|
||||
xmount(dev.path, "/system_root", "ext4", MS_RDONLY, NULL);
|
||||
int system_root = open("/system_root", O_RDONLY | O_CLOEXEC);
|
||||
|
||||
// Exclude system folder
|
||||
excl_list = (char *[]) { "system", NULL };
|
||||
clone_dir(system_root, root);
|
||||
mkdir("/system", 0755);
|
||||
mount("/system_root/system", "/system", NULL, MS_BIND, NULL);
|
||||
xmount("/system_root/system", "/system", NULL, MS_BIND, NULL);
|
||||
|
||||
snprintf(partname, sizeof(partname), "vendor%s", cmd.slot);
|
||||
|
||||
// We need to mount independent vendor partition
|
||||
if (setup_block(&dev, partname) == 0)
|
||||
mount(dev.path, "/vendor", "ext4", MS_RDONLY, NULL);
|
||||
xmount(dev.path, "/vendor", "ext4", MS_RDONLY, NULL);
|
||||
|
||||
close(system_root);
|
||||
} else {
|
||||
@@ -507,7 +512,21 @@ int main(int argc, char *argv[]) {
|
||||
mv_dir(overlay, root);
|
||||
|
||||
patch_ramdisk(root);
|
||||
patch_sepolicy();
|
||||
if (patch_sepolicy()) {
|
||||
/* Non skip_initramfs devices using separate sepolicy
|
||||
* Mount /system and try to load again */
|
||||
xmount("sysfs", "/sys", "sysfs", 0, NULL);
|
||||
struct device dev;
|
||||
setup_block(&dev, "system");
|
||||
xmount(dev.path, "/system", "ext4", MS_RDONLY, NULL);
|
||||
// We need to mount independent vendor partition
|
||||
if (setup_block(&dev, "vendor") == 0)
|
||||
xmount(dev.path, "/vendor", "ext4", MS_RDONLY, NULL);
|
||||
|
||||
patch_sepolicy();
|
||||
|
||||
umount("/system");
|
||||
}
|
||||
|
||||
if (fork_dont_care() == 0) {
|
||||
strcpy(argv[0], "magiskinit");
|
||||
|
||||
@@ -61,7 +61,7 @@ int xumount(const char *target);
|
||||
int xumount2(const char *target, int flags);
|
||||
int xrename(const char *oldpath, const char *newpath);
|
||||
int xmkdir(const char *pathname, mode_t mode);
|
||||
int xmkdir_p(const char *pathname, mode_t mode);
|
||||
int xmkdirs(const char *pathname, mode_t mode);
|
||||
int xmkdirat(int dirfd, const char *pathname, mode_t mode);
|
||||
void *xmmap(void *addr, size_t length, int prot, int flags,
|
||||
int fd, off_t offset);
|
||||
@@ -101,7 +101,7 @@ struct file_attr {
|
||||
};
|
||||
|
||||
int fd_getpath(int fd, char *path, size_t size);
|
||||
int mkdir_p(const char *pathname, mode_t mode);
|
||||
int mkdirs(const char *pathname, mode_t mode);
|
||||
void in_order_walk(int dirfd, void (*callback)(int, struct dirent*));
|
||||
void rm_rf(const char *path);
|
||||
void frm_rf(int dirfd);
|
||||
|
||||
@@ -63,8 +63,10 @@ int parse_img(const char *image, boot_img *boot) {
|
||||
|
||||
// Parse image
|
||||
fprintf(stderr, "Parsing boot image: [%s]\n", image);
|
||||
for (size_t pos = 0; pos < boot->map_size; pos += 256) {
|
||||
switch (check_type(boot->map_addr + pos)) {
|
||||
for (void *head = boot->map_addr; head < boot->map_addr + boot->map_size; head += 256) {
|
||||
size_t pos = 0;
|
||||
|
||||
switch (check_type(head)) {
|
||||
case CHROMEOS:
|
||||
// The caller should know it's chromeos, as it needs additional signing
|
||||
boot->flags |= CHROMEOS_FLAG;
|
||||
@@ -75,33 +77,33 @@ int parse_img(const char *image, boot_img *boot) {
|
||||
exit(ELF64_RET);
|
||||
case AOSP:
|
||||
// Read the header
|
||||
memcpy(&boot->hdr, boot->map_addr + pos, sizeof(boot->hdr));
|
||||
memcpy(&boot->hdr, head + pos, sizeof(boot->hdr));
|
||||
pos += boot->hdr.page_size;
|
||||
|
||||
print_hdr(&boot->hdr);
|
||||
|
||||
boot->kernel = boot->map_addr + pos;
|
||||
boot->kernel = head + pos;
|
||||
pos += boot->hdr.kernel_size;
|
||||
mem_align(&pos, boot->hdr.page_size);
|
||||
|
||||
boot->ramdisk = boot->map_addr + pos;
|
||||
boot->ramdisk = head + pos;
|
||||
pos += boot->hdr.ramdisk_size;
|
||||
mem_align(&pos, boot->hdr.page_size);
|
||||
|
||||
if (boot->hdr.second_size) {
|
||||
boot->second = boot->map_addr + pos;
|
||||
boot->second = head + pos;
|
||||
pos += boot->hdr.second_size;
|
||||
mem_align(&pos, boot->hdr.page_size);
|
||||
}
|
||||
|
||||
if (boot->hdr.extra_size) {
|
||||
boot->extra = boot->map_addr + pos;
|
||||
boot->extra = head + pos;
|
||||
pos += boot->hdr.extra_size;
|
||||
mem_align(&pos, boot->hdr.page_size);
|
||||
}
|
||||
|
||||
if (pos < boot->map_size) {
|
||||
boot->tail = boot->map_addr + pos;
|
||||
boot->tail = head + pos;
|
||||
boot->tail_size = boot->map_size - pos;
|
||||
}
|
||||
|
||||
|
||||
@@ -78,8 +78,17 @@ static void dtb_patch(const char *file, int patch) {
|
||||
fdt_for_each_subnode(block, fdt, fstab) {
|
||||
fprintf(stderr, "Found block [%s] in fstab\n", fdt_get_name(fdt, block, NULL));
|
||||
uint32_t value_size;
|
||||
void *value = (char *) fdt_getprop(fdt, block, "fsmgr_flags", &value_size);
|
||||
found |= patch_verity(&value, &value_size, patch);
|
||||
void *value = (void *) fdt_getprop(fdt, block, "fsmgr_flags", &value_size);
|
||||
if (patch) {
|
||||
void *dup = xmalloc(value_size);
|
||||
memcpy(dup, value, value_size);
|
||||
memset(value, 0, value_size);
|
||||
found |= patch_verity(&dup, &value_size, 1);
|
||||
memcpy(value, dup, value_size);
|
||||
free(dup);
|
||||
} else {
|
||||
found |= patch_verity(&value, &value_size, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,12 +73,12 @@ static void usage(char *arg0) {
|
||||
" --dtb-<cmd> <dtb>\n"
|
||||
" Do dtb related cmds to <dtb> (modifications are done directly)\n"
|
||||
" Supported commands:\n"
|
||||
" -dump\n"
|
||||
" dump\n"
|
||||
" Dump all contents from dtb for debugging\n"
|
||||
" -test\n"
|
||||
" test\n"
|
||||
" Check if fstab has verity/avb flags\n"
|
||||
" Return value: 0/no flags 1/flag exists"
|
||||
" -patch\n"
|
||||
" Return value: 0/no flags 1/flag exists\n"
|
||||
" patch\n"
|
||||
" Search for fstab and remove verity/avb\n"
|
||||
"\n"
|
||||
" --compress[=method] <infile> [outfile]\n"
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
#include "cpio.h"
|
||||
|
||||
static void cpio_patch(struct vector *v, int keepverity, int keepforceencrypt) {
|
||||
fprintf(stderr, "Patch with flag KEEPVERITY=[%s] KEEPFORCEENCRYPT=[%s]\n",
|
||||
keepverity ? "true" : "false", keepforceencrypt ? "true" : "false");
|
||||
cpio_entry *e;
|
||||
vec_for_each(v, e) {
|
||||
if (!e) continue;
|
||||
@@ -19,6 +21,7 @@ static void cpio_patch(struct vector *v, int keepverity, int keepforceencrypt) {
|
||||
fprintf(stderr, "Remove [verity_key]\n");
|
||||
cpio_free(e);
|
||||
vec_cur(v) = NULL;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (!keepforceencrypt) {
|
||||
@@ -134,7 +137,7 @@ static void cpio_backup(struct vector *v, struct vector *bak, const char *orig,
|
||||
backup = 1;
|
||||
fprintf(stderr, "Backup mismatch entry: ");
|
||||
} else {
|
||||
// Someting new in ramdisk, record in rem
|
||||
// Something new in ramdisk, record in rem
|
||||
++j;
|
||||
rem->data = xrealloc(rem->data, rem->filesize + strlen(n->filename) + 1);
|
||||
memcpy(rem->data + rem->filesize, n->filename, strlen(n->filename) + 1);
|
||||
|
||||
@@ -70,8 +70,6 @@ static void store_zygote_ns(int pid) {
|
||||
static void lazy_unmount(const char* mountpoint) {
|
||||
if (umount2(mountpoint, MNT_DETACH) != -1)
|
||||
LOGD("hide_daemon: Unmounted (%s)\n", mountpoint);
|
||||
else
|
||||
LOGD("hide_daemon: Unmount Failed (%s)\n", mountpoint);
|
||||
}
|
||||
|
||||
static void hide_daemon(int pid, int ppid) {
|
||||
@@ -176,8 +174,8 @@ void proc_monitor() {
|
||||
// Get the mount namespace of zygote
|
||||
zygote_num = 0;
|
||||
while(!zygote_num) {
|
||||
// Check zygote every 2 secs
|
||||
sleep(2);
|
||||
// Check zygote every 10 ms
|
||||
usleep(10000);
|
||||
ps_filter_proc_name("zygote", store_zygote_ns);
|
||||
}
|
||||
ps_filter_proc_name("zygote64", store_zygote_ns);
|
||||
|
||||
Submodule core/jni/magiskpolicy updated: edab891427...2f4062a923
@@ -34,7 +34,7 @@ int fd_getpath(int fd, char *path, size_t size) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mkdir_p(const char *pathname, mode_t mode) {
|
||||
int mkdirs(const char *pathname, mode_t mode) {
|
||||
char *path = strdup(pathname), *p;
|
||||
errno = 0;
|
||||
for (p = path + 1; *p; ++p) {
|
||||
@@ -107,7 +107,7 @@ void mv_f(const char *source, const char *destination) {
|
||||
struct file_attr a;
|
||||
|
||||
if (S_ISDIR(st.st_mode)) {
|
||||
xmkdir_p(destination, st.st_mode & 0777);
|
||||
xmkdirs(destination, st.st_mode & 0777);
|
||||
src = xopen(source, O_RDONLY | O_CLOEXEC);
|
||||
dest = xopen(destination, O_RDONLY | O_CLOEXEC);
|
||||
fclone_attr(src, dest);
|
||||
@@ -162,7 +162,7 @@ void cp_afc(const char *source, const char *destination) {
|
||||
getattr(source, &a);
|
||||
|
||||
if (S_ISDIR(a.st.st_mode)) {
|
||||
xmkdir_p(destination, a.st.st_mode & 0777);
|
||||
xmkdirs(destination, a.st.st_mode & 0777);
|
||||
src = xopen(source, O_RDONLY | O_CLOEXEC);
|
||||
dest = xopen(destination, O_RDONLY | O_CLOEXEC);
|
||||
fsetattr(dest, &a);
|
||||
|
||||
@@ -139,9 +139,9 @@ char *mount_image(const char *img, const char *target) {
|
||||
if (access(img, F_OK) == -1)
|
||||
return NULL;
|
||||
if (access(target, F_OK) == -1) {
|
||||
if (xmkdir_p(target, 0755) == -1) {
|
||||
if (xmkdirs(target, 0755) == -1) {
|
||||
xmount(NULL, "/", NULL, MS_REMOUNT, NULL);
|
||||
xmkdir_p(target, 0755);
|
||||
xmkdirs(target, 0755);
|
||||
xmount(NULL, "/", NULL, MS_REMOUNT | MS_RDONLY, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,7 +111,12 @@ static int is_num(const char *s) {
|
||||
ssize_t fdgets(char *buf, const size_t size, int fd) {
|
||||
ssize_t len = 0;
|
||||
buf[0] = '\0';
|
||||
while (read(fd, buf + len, 1) >= 0 && len < size - 1) {
|
||||
while (len < size - 1) {
|
||||
int ret = read(fd, buf + len, 1);
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
if (ret == 0)
|
||||
break;
|
||||
if (buf[len] == '\0' || buf[len++] == '\n') {
|
||||
buf[len] = '\0';
|
||||
break;
|
||||
@@ -282,7 +287,7 @@ int exec_command(int err, int *fd, void (*setupenv)(struct vector*), const char
|
||||
int bind_mount(const char *from, const char *to) {
|
||||
int ret = xmount(from, to, NULL, MS_BIND, NULL);
|
||||
#ifdef MAGISK_DEBUG
|
||||
LOGI("bind_mount: %s -> %s\n", from, to);
|
||||
LOGI("bind_mount: %s <- %s\n", to, from);
|
||||
#else
|
||||
LOGI("bind_mount: %s\n", to);
|
||||
#endif
|
||||
@@ -304,7 +309,7 @@ int switch_mnt_ns(int pid) {
|
||||
fd = xopen(mnt, O_RDONLY);
|
||||
if (fd < 0) return 1;
|
||||
// Switch to its namespace
|
||||
ret = setns(fd, 0);
|
||||
ret = xsetns(fd, 0);
|
||||
close(fd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -4,19 +4,19 @@
|
||||
#include "utils.h"
|
||||
|
||||
static int check_verity_pattern(const char *s) {
|
||||
int pos = 0;
|
||||
if (s[0] == ',') ++pos;
|
||||
if (strncmp(s + pos, "verify", 6) == 0)
|
||||
pos += 6;
|
||||
else if (strncmp(s + pos, "avb", 3) == 0)
|
||||
pos += 3;
|
||||
int skip = 0;
|
||||
if (s[0] == ',') ++skip;
|
||||
if (strncmp(s + skip, "verify", 6) == 0)
|
||||
skip += 6;
|
||||
else if (strncmp(s + skip, "avb", 3) == 0)
|
||||
skip += 3;
|
||||
else
|
||||
return -1;
|
||||
|
||||
if (s[pos] == '=') {
|
||||
while (s[pos] != '\0' && s[pos] != ' ' && s[pos] != '\n' && s[pos] != ',') ++pos;
|
||||
if (s[skip] == '=') {
|
||||
while (s[skip] != '\0' && s[skip] != ' ' && s[skip] != '\n' && s[skip] != ',') ++skip;
|
||||
}
|
||||
return pos;
|
||||
return skip;
|
||||
}
|
||||
|
||||
static int check_encryption_pattern(const char *s) {
|
||||
@@ -59,34 +59,41 @@ void patch_init_rc(void **buf, size_t *size) {
|
||||
}
|
||||
|
||||
int patch_verity(void **buf, uint32_t *size, int patch) {
|
||||
int skip, found = 0;
|
||||
for (int pos = 0; pos < *size; ++pos) {
|
||||
if ((skip = check_verity_pattern(*buf + pos)) > 0) {
|
||||
found = 1;
|
||||
fprintf(stderr, "%s pattern [%.*s]\n", patch ? "Remove" : "Found", skip, (char *) *buf + pos);
|
||||
if (patch) {
|
||||
memcpy(*buf + pos, *buf + pos + skip, *size - pos - skip);
|
||||
memset(*buf + *size - skip, '\0', skip);
|
||||
*size -= skip;
|
||||
} else {
|
||||
pos += skip - 1;
|
||||
}
|
||||
int skip, src_size = *size;
|
||||
char *src = *buf, *patched = patch ? xcalloc(src_size, 1) : NULL;
|
||||
for (int read = 0, write = 0; read < src_size; ++read, ++write) {
|
||||
if ((skip = check_verity_pattern(src + read)) > 0) {
|
||||
if (!patch)
|
||||
return 1;
|
||||
fprintf(stderr, "Remove pattern [%.*s]\n", skip, src + read);
|
||||
read += skip;
|
||||
*size -= skip;
|
||||
}
|
||||
if (patch)
|
||||
patched[write] = src[read];
|
||||
}
|
||||
return found;
|
||||
if (patch) {
|
||||
free(*buf);
|
||||
*buf = patched;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void patch_encryption(void **buf, uint32_t *size) {
|
||||
int skip;
|
||||
for (int pos = 0; pos < *size; ++pos) {
|
||||
if ((skip = check_encryption_pattern(*buf + pos)) > 0) {
|
||||
fprintf(stderr, "Replace pattern [%.*s] with [encryptable]\n", skip, (char *) *buf + pos);
|
||||
memcpy(*buf + pos, "encryptable", 11);
|
||||
memcpy(*buf + pos + 11, *buf + pos + skip, *size - pos - skip);
|
||||
memset(*buf + *size - skip + 11, '\0', skip - 11);
|
||||
int skip, src_size = *size;
|
||||
char *src = *buf, *patched = xcalloc(src_size, 1);
|
||||
for (int read = 0, write = 0; read < src_size; ++read, ++write) {
|
||||
if ((skip = check_encryption_pattern(src + read)) > 0) {
|
||||
fprintf(stderr, "Replace pattern [%.*s] with [encryptable]\n", skip, src + read);
|
||||
memcpy(patched + read, "encryptable", 11);
|
||||
read += skip;
|
||||
write += 11;
|
||||
*size -= (skip - 11);
|
||||
}
|
||||
patched[write] = src[read];
|
||||
}
|
||||
free(*buf);
|
||||
*buf = patched;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -156,14 +156,6 @@ int xbind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
int xconnect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) {
|
||||
int ret = connect(sockfd, addr, addrlen);
|
||||
if (ret == -1) {
|
||||
PLOGE("connect");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int xlisten(int sockfd, int backlog) {
|
||||
int ret = listen(sockfd, backlog);
|
||||
if (ret == -1) {
|
||||
@@ -229,14 +221,6 @@ int xpthread_create(pthread_t *thread, const pthread_attr_t *attr,
|
||||
return errno;
|
||||
}
|
||||
|
||||
int xsocketpair(int domain, int type, int protocol, int sv[2]) {
|
||||
int ret = socketpair(domain, type, protocol, sv);
|
||||
if (ret == -1) {
|
||||
PLOGE("socketpair");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int xstat(const char *pathname, struct stat *buf) {
|
||||
int ret = stat(pathname, buf);
|
||||
if (ret == -1) {
|
||||
@@ -292,7 +276,7 @@ int xsymlink(const char *target, const char *linkpath) {
|
||||
int xmount(const char *source, const char *target,
|
||||
const char *filesystemtype, unsigned long mountflags,
|
||||
const void *data) {
|
||||
int ret = mount(source, target, filesystemtype, mountflags, data);
|
||||
int ret = mount(source, target, filesystemtype, MS_SILENT | mountflags, data);
|
||||
if (ret == -1) {
|
||||
PLOGE("mount %s->%s", source, target);
|
||||
}
|
||||
@@ -331,10 +315,10 @@ int xmkdir(const char *pathname, mode_t mode) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
int xmkdir_p(const char *pathname, mode_t mode) {
|
||||
int ret = mkdir_p(pathname, mode);
|
||||
int xmkdirs(const char *pathname, mode_t mode) {
|
||||
int ret = mkdirs(pathname, mode);
|
||||
if (ret == -1) {
|
||||
PLOGE("mkdir_p %s", pathname);
|
||||
PLOGE("mkdirs %s", pathname);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
166
docs/applets.md
166
docs/applets.md
File diff suppressed because one or more lines are too long
@@ -4,3 +4,5 @@
|
||||
- 2017.9.28
|
||||
- Update applets info to Magisk v14.1
|
||||
- Add OTA tips
|
||||
- 2017.1.8
|
||||
- Update to Magisk v15.2
|
||||
File diff suppressed because one or more lines are too long
Binary file not shown.
|
Before Width: | Height: | Size: 258 KiB |
BIN
docs/images/restore_img.png
Normal file
BIN
docs/images/restore_img.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 244 KiB |
@@ -1,76 +0,0 @@
|
||||
# Magisk Modules and Online Repo
|
||||
## Magisk Module Format
|
||||
The Magisk module is a folder under `magisk`, which has a structure as described below:
|
||||
|
||||
```
|
||||
magisk
|
||||
├── .
|
||||
├── .
|
||||
├── a_module <--- The ID of the module, should match with module.prop
|
||||
│ ├── auto_mount <--- If this file exists, auto mount is enabled
|
||||
│ ├── disable <--- If this file exists, the module is disabled
|
||||
│ ├── module.prop <--- This files stores the indentity and properties of the module
|
||||
│ ├── post-fs-data.sh <--- This script will be executed in post-fs-data
|
||||
│ ├── remove <--- If this file exists, the module will be removed next reboot
|
||||
│ ├── service.sh <--- This script will be executed in late_start service
|
||||
│ ├── system.prop <--- This file will be loaded as system props
|
||||
│ ├── system <--- If auto mount is enabled, Magisk will "Magic Mount" this folder
|
||||
│ │ ├── app
|
||||
│ │ ├── .
|
||||
│ │ └── .
|
||||
│ ├── vendor <--- Auto generated. A symlink to $MODID/system/vendor
|
||||
│ ├── . <--- Any other files/folders are allowed
|
||||
│ └── .
|
||||
├── another_module
|
||||
│ ├── .
|
||||
│ └── .
|
||||
├── .
|
||||
├── .
|
||||
```
|
||||
|
||||
## Magisk Module Template
|
||||
The **Magisk Module Template** is hosted **[here](https://github.com/topjohnwu/magisk-module-template)**.
|
||||
|
||||
It is a template to create a flashable zip to install Magisk Modules. It is created to be simple to use so that anyone can create their own modules easily. The template itself contains minimal scripting for installation; most of the functions are located externally in [util_functions.sh](https://github.com/topjohnwu/Magisk/blob/master/scripts/util_functions.sh), which will be installed along with Magisk, and can be upgraded through a Magisk upgrade without the need of a template update.
|
||||
|
||||
The template should meet most modules' needs. Add files into `system`, which will be cloned into `/system` by Magisk after installing the module, and in addition to module files, `system.prop`, `post-fs-data.sh`, `service.sh` are also installable through this template.
|
||||
|
||||
Here are some files you would want to know:
|
||||
|
||||
- `config.sh`: A simple script used as a configuration file for the actual installation file to correctly install your module. It is the place you can select which features your module needs/disables.
|
||||
- `module.prop`: This file contains your module's indentity and properties, including name and versions etc.. This file will be used to identify your module on an actual device and in the [Magisk Modules Repo](https://github.com/Magisk-Modules-Repo)
|
||||
- `common/*`: These files will be installed to the module with the correspond role
|
||||
- `META-INF/com/google/android/update-binary`: The actual installation script. Modify this file for advanced custom behavior
|
||||
|
||||
## Create a Magisk Module With The Template
|
||||
1. Clone / download [this repo](https://github.com/topjohnwu/magisk-module-template)
|
||||
1. Open `config.sh` and carefully read the fully documented file. Follow the instructions within the script
|
||||
1. You should at least have `config.sh` and `module.prop` modified
|
||||
1. Directly zip all files; the result zip file is a flashable zip that can be used in both Magisk Manager and custom recoveries
|
||||
1. Please check [**Notes**](#notes) for several precautions
|
||||
|
||||
## Submit Your Module to Magisk Modules Repo
|
||||
If you want to share your module with others, you can submit your modules to [Magisk Modules Repo](https://github.com/Magisk-Modules-Repo). You would need some basic `git` knowledge here.
|
||||
|
||||
1. Create a module as stated above, and test if it works properly
|
||||
1. Fork [this repo](https://github.com/topjohnwu/magisk-module-template) to your account
|
||||
1. Commit and push your changes to your forked repo
|
||||
1. Open an issue in [topjohnwu/Magisk_Repo_Central](https://github.com/topjohnwu/Magisk_Repo_Central/issues/new) with your repo link
|
||||
1. I will review your module, and once accepted, your repo should be cloned into [Magisk-Modules-Repo](https://github.com/Magisk-Modules-Repo)
|
||||
1. You should receive an email to become the collaborator so you can edit the repo in the future.
|
||||
|
||||
#### Once your module is live on the Modules Repo, the description of your repo should be the ID of your module. Please do NOT change the description, repeat, do NOT change the description.
|
||||
|
||||

|
||||
|
||||
## Notes
|
||||
- The Module Template depends on external scripts, be aware of the minimal required Magisk version of the template.
|
||||
- **Windows users please check here!!** The line endings of all text files should be in the **Unix format**. Please use advanced text editors like Sublime, Atom, Notepad++ etc. to edit **ALL** text files, **NEVER** use Windows Notepad.
|
||||
- In `module.prop`, `version` can be an arbitrary string, so any fancy version name (e.g. ultra-beta-v1.1.1.1) is allowed. However, `versionCode` **MUST** be an integer. The value is used for version comparison.
|
||||
- Make sure your module ID **does not contain any spaces**.
|
||||
|
||||
## Notes For Repo Developers
|
||||
|
||||
- Magisk Manager monitors all repo's `master` branch. Any changes to the branch `master` will be reflected to all users immediately. If you are working on an update for a module, please work on another branch, make sure it works, then finally merge the changes back to `master`.
|
||||
- Once you finished upgrading your repo, increase at least the `versionCode` in `module.prop`. Magisk Manager uses this value to compare with the local installed module to determine whether an update is availible.
|
||||
- The description of your repo should be the same as your module ID. If you changed your description, Magisk Manager will fail to identify your repo, and cannot relate installed module to the online repo together.
|
||||
49
docs/modules.md
Normal file
49
docs/modules.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# Magisk Modules
|
||||
## Magisk Module Format
|
||||
A Magisk module is a folder placed in the root folder in `magisk.img`, which has a structure as described below:
|
||||
|
||||
```
|
||||
$MOUNTPOINT
|
||||
├── .
|
||||
├── .
|
||||
├── $MODID <--- The ID of the module, should match with module.prop
|
||||
│ ├── auto_mount <--- If this file exists, auto mount is enabled
|
||||
│ ├── disable <--- If this file exists, the module is disabled
|
||||
│ ├── module.prop <--- This files stores the identity and properties of the module
|
||||
│ ├── post-fs-data.sh <--- This script will be executed in post-fs-data
|
||||
│ ├── remove <--- If this file exists, the module will be removed next reboot
|
||||
│ ├── service.sh <--- This script will be executed in late_start service
|
||||
│ ├── system.prop <--- This file will be loaded as system props
|
||||
│ ├── system <--- If auto mount is enabled, Magisk will "Magic Mount" this folder
|
||||
│ │ ├── .
|
||||
│ │ ├── .
|
||||
│ │ └── .
|
||||
│ ├── vendor <--- Auto generated. A symlink to $MODID/system/vendor
|
||||
│ ├── . <--- Any other files/folders are allowed
|
||||
│ └── .
|
||||
├── another_module
|
||||
│ ├── .
|
||||
│ └── .
|
||||
├── .
|
||||
├── .
|
||||
```
|
||||
You are not required to use my Magisk Module Template to create a module. As long as you place files with the structure above, it will be recognized as a module.
|
||||
|
||||
## Magisk Module Template
|
||||
The **Magisk Module Template** is hosted **[here](https://github.com/topjohnwu/magisk-module-template)**.
|
||||
|
||||
It is a template to create a flashable zip to install Magisk Modules. It is designed to be simple to use so that anyone can create their own modules easily. The template itself contains minimal scripting for installation; most of the functions are located externally in [util_functions.sh](https://github.com/topjohnwu/Magisk/blob/master/scripts/util_functions.sh), which will be installed along with Magisk, and can be upgraded through a Magisk upgrade without the need of a template update.
|
||||
|
||||
Here are some files you would want to know:
|
||||
|
||||
- `config.sh`: A simple script used as a configuration file. It is the place to configure which features your module needs/disables. A detailed instructions on how to use the template is also written in this file.
|
||||
- `module.prop`: This file contains your module's indentity and properties, including name and versions etc.. This file will be used to identify your module on an actual device and in the [Magisk Modules Repo](https://github.com/Magisk-Modules-Repo)
|
||||
- `common/*`: Boot stage scripts and `system.prop`
|
||||
- `META-INF/com/google/android/update-binary`: The actual installation script. Modify this file for advanced custom behavior
|
||||
|
||||
And here are some notes to be aware of:
|
||||
|
||||
- The template depends on external Magisk scripts, please specify the correct `minMagisk` value in `module.prop` with the template version your module is based on, or the minimum Magisk version your module is tested on.
|
||||
- **Windows users please check here!!** The line endings of all text files should be in the **Unix format**. Please use advanced text editors like Sublime, Atom, Notepad++ etc. to edit **ALL** text files, **NEVER** use Windows Notepad.
|
||||
- In `module.prop`, `version` can be an arbitrary string, so any fancy version name (e.g. `ultra-beta-v1.1.1.1`) is allowed. However, `versionCode` **MUST** be an integer. The value is used for version comparison.
|
||||
- Make sure your module ID **does not contain any spaces**.
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
287
docs/tools.md
Normal file
287
docs/tools.md
Normal file
File diff suppressed because one or more lines are too long
@@ -13,8 +13,6 @@
|
||||
main() {
|
||||
# Magisk binaries
|
||||
MAGISKBIN=/data/adb/magisk
|
||||
# This script always runs in recovery
|
||||
BOOTMODE=false
|
||||
|
||||
mount /data 2>/dev/null
|
||||
|
||||
@@ -41,7 +39,6 @@ main() {
|
||||
|
||||
remove_system_su
|
||||
|
||||
find_boot_image
|
||||
[ -z $BOOTIMAGE ] && abort "! Unable to detect boot image"
|
||||
ui_print "- Found boot image: $BOOTIMAGE"
|
||||
|
||||
@@ -59,13 +56,6 @@ main() {
|
||||
mv stock_boot* /data
|
||||
fi
|
||||
|
||||
patch_dtbo_image
|
||||
|
||||
if [ -f stock_dtbo* ]; then
|
||||
rm -f /data/stock_dtbo* 2>/dev/null
|
||||
mv stock_dtbo* /data
|
||||
fi
|
||||
|
||||
cd /
|
||||
recovery_cleanup
|
||||
|
||||
|
||||
@@ -83,8 +83,6 @@ chmod -R 755 .
|
||||
# Unpack
|
||||
##########################################################################################
|
||||
|
||||
migrate_boot_backup
|
||||
|
||||
CHROMEOS=false
|
||||
|
||||
ui_print "- Unpacking boot image"
|
||||
|
||||
@@ -13,10 +13,6 @@
|
||||
# Preparation
|
||||
##########################################################################################
|
||||
|
||||
# Detect whether in boot mode
|
||||
ps | grep zygote | grep -v grep >/dev/null && BOOTMODE=true || BOOTMODE=false
|
||||
$BOOTMODE || ps -A 2>/dev/null | grep zygote | grep -v grep >/dev/null && BOOTMODE=true
|
||||
|
||||
# This path should work in any cases
|
||||
TMPDIR=/dev/tmp
|
||||
|
||||
@@ -24,7 +20,6 @@ INSTALLER=$TMPDIR/install
|
||||
COMMONDIR=$INSTALLER/common
|
||||
APK=$COMMONDIR/magisk.apk
|
||||
CHROMEDIR=$INSTALLER/chromeos
|
||||
COREDIR=/magisk/.core
|
||||
|
||||
# Default permissions
|
||||
umask 022
|
||||
@@ -83,8 +78,8 @@ if is_mounted /data; then
|
||||
chmod 700 /data/adb 2>/dev/null
|
||||
|
||||
# Some legacy migration
|
||||
mv /data/magisk/stock_boot* /data 2>/dev/null
|
||||
[ -L /data/magisk.img ] || mv /data/magisk.img /data/adb/magisk.img
|
||||
run_migrations
|
||||
[ -L /data/magisk.img ] || mv /data/magisk.img /data/adb/magisk.img 2>/dev/null
|
||||
else
|
||||
MAGISKBIN=/cache/data_bin
|
||||
fi
|
||||
@@ -113,7 +108,6 @@ $BOOTMODE || recovery_actions
|
||||
[ -z $BOOTIMAGE ] && abort "! Unable to detect boot image"
|
||||
ui_print "- Found boot image: $BOOTIMAGE"
|
||||
|
||||
find_dtbo_image
|
||||
if [ ! -z $DTBOIMAGE ]; then
|
||||
ui_print "- Found dtbo image: $DTBOIMAGE"
|
||||
# Disable dtbo patch by default
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user