1
mirror of https://github.com/topjohnwu/Magisk synced 2025-10-29 07:20:52 +01:00

Compare commits

..

23 Commits
v15.0 ... v15.3

Author SHA1 Message Date
topjohnwu
e8302dfbe2 Update Magisk Manager 2018-01-13 06:28:22 +08:00
topjohnwu
558f95cf7e Improve APK installation and add logging 2018-01-13 06:28:07 +08:00
topjohnwu
18f6ead891 Fix alignment when boot image has head offset 2018-01-13 06:28:07 +08:00
topjohnwu
10bd25be52 Suppress harmless error logs 2018-01-12 00:23:38 +08:00
topjohnwu
65511845d2 Fix APK installation on some devices
Close #367. Android 6.0 and before doesn't like the new path
2018-01-11 20:57:05 +08:00
topjohnwu
1c743839ea Add MS_SILENT to xmount and cleanup function wraps 2018-01-11 03:06:20 +08:00
topjohnwu
bcae9dec41 Fix a bug when only one script will run 2018-01-11 02:48:15 +08:00
Shaka Huang
482c9af41f Fix segmentation fault
When both keepverity and keepforceencrypt are false, ‘e’ will be freed after removing ‘verity_key’ and segmentation fault might happened in strstr(e->filename, “fstab”)

Signed-off-by: Shaka Huang <shakalaca@gmail.com>
2018-01-11 02:08:52 +08:00
topjohnwu
2bf2e7461f Update diagram URL 2018-01-09 06:50:03 +08:00
topjohnwu
7d1082b1cb Fix magiskhide in graph 2018-01-09 06:48:58 +08:00
topjohnwu
0dbae83aec Update diagram URL 2018-01-09 06:08:54 +08:00
topjohnwu
f927c1b997 Update procedure diagram 2018-01-09 06:07:12 +08:00
topjohnwu
89ec7dad2b Update documentation to v15.2 2018-01-08 22:33:55 +08:00
topjohnwu
4fd61345af Happy New Year 2018-01-02 01:27:20 +08:00
topjohnwu
66cca24453 Samsung need more rules :) 2018-01-02 00:11:26 +08:00
topjohnwu
e733484fab Some devices don't like all log buffers 2018-01-01 23:58:13 +08:00
topjohnwu
e5c3183025 Update scripts 2018-01-01 16:46:28 +08:00
topjohnwu
930c82316a Slightly change logging style 2017-12-31 21:54:39 +08:00
Shaka Huang
3dc22db265 Support loading split sepolicy on non skip_initramfs devices
For certain device (e.g ZenFone 4 ZE554KL) there’s no sepolicy under rootfs and no a/b partition (implies no vendor partition) Magisk will failed to patch SELinux policy database and the system won’t boot up.

In order to cope with this configuration the status of loading policy db needs to be checked, once it failed we have to mount the system partition and do patch_sepolicy() again.

Signed-off-by: Shaka Huang <shakalaca@gmail.com>
2017-12-31 21:30:56 +08:00
topjohnwu
d8c51cb286 Update sepolicy handling 2017-12-31 19:32:04 +08:00
topjohnwu
2f79d0c3b3 Fix segfault while patching dtb 2017-12-31 19:30:56 +08:00
topjohnwu
d8bb3af06b Miscellaneous 2017-12-29 04:25:30 +08:00
topjohnwu
e139e8777b Fix faulty magiskboot ramdisk patch code 2017-12-29 04:25:03 +08:00
35 changed files with 571 additions and 439 deletions

View File

@@ -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

Submodule app updated: de2285d5e9...759e905c3c

View File

@@ -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

View File

@@ -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");
}

View File

@@ -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...

View File

@@ -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");

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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);
}
}
}
}

View File

@@ -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"

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);
}
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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

File diff suppressed because one or more lines are too long

View File

@@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 244 KiB

View File

@@ -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.
![repo_description.png](images/repo_description.png)
## 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
View 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

File diff suppressed because one or more lines are too long

View File

@@ -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

View File

@@ -83,8 +83,6 @@ chmod -R 755 .
# Unpack
##########################################################################################
migrate_boot_backup
CHROMEOS=false
ui_print "- Unpacking boot image"

View File

@@ -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