mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-08-14 11:17:28 +00:00
Compare commits
13 Commits
canary-270
...
canary-270
Author | SHA1 | Date | |
---|---|---|---|
![]() |
0495468d02 | ||
![]() |
300a2a242c | ||
![]() |
33aebb5976 | ||
![]() |
b3d6809c0b | ||
![]() |
461f7e9f89 | ||
![]() |
9cc50b20d8 | ||
![]() |
f488e9df8f | ||
![]() |
0dc596e206 | ||
![]() |
c3bf03190b | ||
![]() |
021ae891a9 | ||
![]() |
9c03514eb1 | ||
![]() |
eb74b266e1 | ||
![]() |
80eb6ff25a |
@@ -22,8 +22,7 @@ Click the icon below to download Magisk apk.
|
||||
|
||||
[](https://github.com/topjohnwu/Magisk/releases/tag/v27.0)
|
||||
[](https://github.com/topjohnwu/Magisk/releases/tag/v27.0)
|
||||
[](https://raw.githubusercontent.com/topjohnwu/magisk-files/canary/app-release.apk)
|
||||
[](https://raw.githubusercontent.com/topjohnwu/magisk-files/canary/app-debug.apk)
|
||||
[](https://github.com/topjohnwu/Magisk/releases/tag/canary-27006)
|
||||
|
||||
## Useful Links
|
||||
|
||||
@@ -31,8 +30,6 @@ Click the icon below to download Magisk apk.
|
||||
- [Building and Development](https://topjohnwu.github.io/Magisk/build.html)
|
||||
- [Magisk Documentation](https://topjohnwu.github.io/Magisk/)
|
||||
- [Zygisk module sample](https://github.com/topjohnwu/zygisk-module-sample)
|
||||
- [Canary channel changelog](https://github.com/topjohnwu/magisk-files/blob/canary/notes.md)
|
||||
|
||||
|
||||
## Bug Reports
|
||||
|
||||
|
@@ -59,8 +59,8 @@ dependencies {
|
||||
implementation("androidx.constraintlayout:constraintlayout:2.1.4")
|
||||
implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0")
|
||||
implementation("androidx.recyclerview:recyclerview:1.3.2")
|
||||
implementation("androidx.transition:transition:1.5.0")
|
||||
implementation("androidx.fragment:fragment-ktx:1.8.1")
|
||||
implementation("androidx.transition:transition:1.5.1")
|
||||
implementation("androidx.fragment:fragment-ktx:1.8.2")
|
||||
implementation("androidx.appcompat:appcompat:1.7.0")
|
||||
implementation("com.google.android.material:material:1.12.0")
|
||||
|
||||
|
5
app/build.gradle.kts
Normal file
5
app/build.gradle.kts
Normal file
@@ -0,0 +1,5 @@
|
||||
tasks.register("clean") {
|
||||
subprojects.forEach {
|
||||
dependsOn(":app:${it.name}:clean")
|
||||
}
|
||||
}
|
@@ -61,8 +61,8 @@ dependencies {
|
||||
|
||||
implementation("androidx.core:core-splashscreen:1.0.1")
|
||||
implementation("androidx.core:core-ktx:1.13.1")
|
||||
implementation("androidx.activity:activity:1.9.0")
|
||||
implementation("androidx.collection:collection-ktx:1.4.1")
|
||||
implementation("androidx.activity:activity:1.9.1")
|
||||
implementation("androidx.collection:collection-ktx:1.4.2")
|
||||
implementation("androidx.profileinstaller:profileinstaller:1.3.1")
|
||||
implementation("androidx.lifecycle:lifecycle-process:2.8.3")
|
||||
implementation("androidx.lifecycle:lifecycle-process:2.8.4")
|
||||
}
|
||||
|
@@ -176,6 +176,8 @@
|
||||
<string name="setting_add_shortcut_summary">在隐藏后难以识别名称和图标的情况下,添加快捷方式到桌面</string>
|
||||
<string name="settings_doh_title">安全 DNS(DoH)</string>
|
||||
<string name="settings_doh_description">解决某些地区的 DNS 污染问题</string>
|
||||
<string name="settings_random_name_title">随机文件名</string>
|
||||
<string name="settings_random_name_description">随机修补镜像和 tar 文件的文件名以防止检测</string>
|
||||
|
||||
<string name="multiuser_mode">多用户模式</string>
|
||||
<string name="settings_owner_only">仅设备所有者</string>
|
||||
|
@@ -6,7 +6,7 @@ plugins {
|
||||
lsparanoid {
|
||||
seed = if (RAND_SEED != 0) RAND_SEED else null
|
||||
includeDependencies = true
|
||||
global = true
|
||||
classFilter = { true }
|
||||
}
|
||||
|
||||
android {
|
||||
|
215
build.py
215
build.py
@@ -81,9 +81,9 @@ triples = [
|
||||
"x86_64-linux-android",
|
||||
"riscv64-linux-android",
|
||||
]
|
||||
default_targets = ["magisk", "magiskinit", "magiskboot", "magiskpolicy"]
|
||||
support_targets = default_targets + ["resetprop"]
|
||||
rust_targets = ["magisk", "magiskinit", "magiskboot", "magiskpolicy"]
|
||||
default_targets = {"magisk", "magiskinit", "magiskboot", "magiskpolicy"}
|
||||
support_targets = default_targets | {"resetprop"}
|
||||
rust_targets = {"magisk", "magiskinit", "magiskboot", "magiskpolicy"}
|
||||
|
||||
ndk_root = sdk_path / "ndk"
|
||||
ndk_path = ndk_root / "magisk"
|
||||
@@ -243,13 +243,54 @@ def run_ndk_build(args, flags):
|
||||
if proc.returncode != 0:
|
||||
error("Build binary failed!")
|
||||
os.chdir("..")
|
||||
|
||||
for arch in archs:
|
||||
for tgt in support_targets + ["libinit-ld.so"]:
|
||||
source = Path("native", "libs", arch, tgt)
|
||||
target = Path("native", "out", arch, tgt)
|
||||
arch_dir = Path("native", "libs", arch)
|
||||
out_dir = Path("native", "out", arch)
|
||||
for source in arch_dir.iterdir():
|
||||
target = out_dir / source.name
|
||||
mv(source, target)
|
||||
|
||||
|
||||
def build_cpp_src(args, targets: set):
|
||||
dump_flag_header()
|
||||
|
||||
flags = ""
|
||||
clean = False
|
||||
|
||||
if "magisk" in targets:
|
||||
flags += " B_MAGISK=1"
|
||||
clean = True
|
||||
|
||||
if "magiskpolicy" in targets:
|
||||
flags += " B_POLICY=1"
|
||||
clean = True
|
||||
|
||||
if "magiskinit" in targets:
|
||||
flags += " B_PRELOAD=1"
|
||||
|
||||
if "resetprop" in targets:
|
||||
flags += " B_PROP=1"
|
||||
|
||||
if flags:
|
||||
run_ndk_build(args, flags)
|
||||
|
||||
flags = ""
|
||||
|
||||
if "magiskinit" in targets:
|
||||
flags += " B_INIT=1"
|
||||
|
||||
if "magiskboot" in targets:
|
||||
flags += " B_BOOT=1"
|
||||
|
||||
if flags:
|
||||
flags += " B_CRT0=1"
|
||||
run_ndk_build(args, flags)
|
||||
|
||||
if clean:
|
||||
clean_elf()
|
||||
|
||||
|
||||
def run_cargo(cmds):
|
||||
env = os.environ.copy()
|
||||
env["PATH"] = f'{rust_bin}{os.pathsep}{env["PATH"]}'
|
||||
@@ -258,17 +299,19 @@ def run_cargo(cmds):
|
||||
return execv([cargo, *cmds], env)
|
||||
|
||||
|
||||
def run_cargo_build(args):
|
||||
def build_rust_src(args, targets: set):
|
||||
targets = targets.copy()
|
||||
if "resetprop" in targets:
|
||||
targets.add("magisk")
|
||||
targets = targets & rust_targets
|
||||
if not targets:
|
||||
return
|
||||
|
||||
os.chdir(Path("native", "src"))
|
||||
|
||||
native_out = Path("..", "out")
|
||||
native_out.mkdir(mode=0o755, exist_ok=True)
|
||||
|
||||
targets = set(args.target) & set(rust_targets)
|
||||
if "resetprop" in args.target:
|
||||
targets.add("magisk")
|
||||
|
||||
if len(targets) == 0:
|
||||
return
|
||||
|
||||
# Start building the actual build commands
|
||||
cmds = ["build", "-p", ""]
|
||||
rust_out = "debug"
|
||||
@@ -289,8 +332,8 @@ def run_cargo_build(args):
|
||||
)
|
||||
cmds[-1] = rust_triple
|
||||
|
||||
for target in targets:
|
||||
cmds[2] = target
|
||||
for tgt in targets:
|
||||
cmds[2] = tgt
|
||||
proc = run_cargo(cmds)
|
||||
if proc.returncode != 0:
|
||||
error("Build binary failed!")
|
||||
@@ -302,6 +345,8 @@ def run_cargo_build(args):
|
||||
target = arch_out / f"lib{tgt}-rs.a"
|
||||
mv(source, target)
|
||||
|
||||
os.chdir(Path("..", ".."))
|
||||
|
||||
|
||||
def run_cargo_cmd(args):
|
||||
global STDOUT
|
||||
@@ -324,25 +369,6 @@ def write_if_diff(file_name: Path, text: str):
|
||||
f.write(text)
|
||||
|
||||
|
||||
def binary_dump(src, var_name, compressor=xz):
|
||||
out_str = f"constexpr unsigned char {var_name}[] = {{"
|
||||
for i, c in enumerate(compressor(src.read())):
|
||||
if i % 16 == 0:
|
||||
out_str += "\n"
|
||||
out_str += f"0x{c:02X},"
|
||||
out_str += "\n};\n"
|
||||
return out_str
|
||||
|
||||
|
||||
def dump_bin_header(args):
|
||||
native_gen_path.mkdir(mode=0o755, parents=True, exist_ok=True)
|
||||
for arch in archs:
|
||||
preload = Path("native", "out", arch, "libinit-ld.so")
|
||||
with open(preload, "rb") as src:
|
||||
text = binary_dump(src, "init_ld_xz")
|
||||
write_if_diff(Path(native_gen_path, f"{arch}_binaries.h"), text)
|
||||
|
||||
|
||||
def dump_flag_header():
|
||||
flag_txt = textwrap.dedent(
|
||||
"""\
|
||||
@@ -369,65 +395,17 @@ def build_binary(args):
|
||||
except:
|
||||
error('Unmatched NDK. Please install/upgrade NDK with "build.py ndk"')
|
||||
|
||||
if "target" not in vars(args):
|
||||
vars(args)["target"] = []
|
||||
|
||||
if args.target:
|
||||
args.target = set(args.target) & set(support_targets)
|
||||
if not args.target:
|
||||
return
|
||||
if "targets" not in vars(args) or not args.targets:
|
||||
targets = default_targets
|
||||
else:
|
||||
args.target = default_targets
|
||||
targets = set(args.targets) & support_targets
|
||||
if not targets:
|
||||
return
|
||||
|
||||
header("* Building binaries: " + " ".join(args.target))
|
||||
header("* Building binaries: " + " ".join(targets))
|
||||
|
||||
os.chdir(Path("native", "src"))
|
||||
run_cargo_build(args)
|
||||
os.chdir(Path("..", ".."))
|
||||
|
||||
dump_flag_header()
|
||||
|
||||
flag = ""
|
||||
clean = False
|
||||
|
||||
if "magisk" in args.target:
|
||||
flag += " B_MAGISK=1"
|
||||
clean = True
|
||||
|
||||
if "magiskpolicy" in args.target:
|
||||
flag += " B_POLICY=1"
|
||||
clean = True
|
||||
|
||||
if "magiskinit" in args.target:
|
||||
flag += " B_PRELOAD=1"
|
||||
|
||||
if "resetprop" in args.target:
|
||||
flag += " B_PROP=1"
|
||||
|
||||
if flag:
|
||||
run_ndk_build(args, flag)
|
||||
|
||||
flag = ""
|
||||
|
||||
if "magiskinit" in args.target:
|
||||
# magiskinit embeds preload.so
|
||||
dump_bin_header(args)
|
||||
flag += " B_INIT=1"
|
||||
|
||||
if "magiskboot" in args.target:
|
||||
flag += " B_BOOT=1"
|
||||
|
||||
if flag:
|
||||
flag += " B_CRT0=1"
|
||||
run_ndk_build(args, flag)
|
||||
|
||||
if clean:
|
||||
clean_elf()
|
||||
|
||||
# BusyBox is built with different API level
|
||||
|
||||
if "busybox" in args.target:
|
||||
run_ndk_build(args, "B_BB=1")
|
||||
build_rust_src(args, targets)
|
||||
build_cpp_src(args, targets)
|
||||
|
||||
|
||||
def find_jdk():
|
||||
@@ -513,21 +491,21 @@ def build_stub(args):
|
||||
|
||||
def cleanup(args):
|
||||
support_targets = {"native", "cpp", "rust", "java"}
|
||||
if args.target:
|
||||
args.target = set(args.target) & support_targets
|
||||
if "native" in args.target:
|
||||
args.target.add("cpp")
|
||||
args.target.add("rust")
|
||||
if args.targets:
|
||||
targets = set(args.targets) & support_targets
|
||||
if "native" in targets:
|
||||
targets.add("cpp")
|
||||
targets.add("rust")
|
||||
else:
|
||||
args.target = support_targets
|
||||
targets = support_targets
|
||||
|
||||
if "cpp" in args.target:
|
||||
if "cpp" in targets:
|
||||
header("* Cleaning C++")
|
||||
rm_rf(Path("native", "libs"))
|
||||
rm_rf(Path("native", "obj"))
|
||||
rm_rf(Path("native", "out"))
|
||||
|
||||
if "rust" in args.target:
|
||||
if "rust" in targets:
|
||||
header("* Cleaning Rust")
|
||||
rm_rf(Path("native", "src", "target"))
|
||||
rm(Path("native", "src", "boot", "proto", "mod.rs"))
|
||||
@@ -535,18 +513,9 @@ def cleanup(args):
|
||||
for rs_gen in glob.glob("native/**/*-rs.*pp", recursive=True):
|
||||
rm(rs_gen)
|
||||
|
||||
if "java" in args.target:
|
||||
if "java" in targets:
|
||||
header("* Cleaning java")
|
||||
execv(
|
||||
[
|
||||
gradlew,
|
||||
":app:apk:clean",
|
||||
":app:core:clean",
|
||||
":app:shared:clean",
|
||||
":app:stub:clean",
|
||||
],
|
||||
env=find_jdk(),
|
||||
)
|
||||
execv([gradlew, ":app:clean"], env=find_jdk())
|
||||
|
||||
|
||||
def setup_ndk(args):
|
||||
@@ -611,22 +580,22 @@ def setup_avd(args):
|
||||
|
||||
def patch_avd_file(args):
|
||||
if not args.skip:
|
||||
args.release = False
|
||||
build_all(args)
|
||||
|
||||
args.target = Path(args.target)
|
||||
src_file = f"/data/local/tmp/{args.target.name}"
|
||||
out_file = f"{src_file}.magisk"
|
||||
input = Path(args.image)
|
||||
if args.output:
|
||||
args.output = Path(args.output)
|
||||
output = Path(args.output)
|
||||
else:
|
||||
args.output = args.target.parent / f"{args.target.name}.magisk"
|
||||
output = input.parent / f"{input.name}.magisk"
|
||||
|
||||
header(f"* Patching {args.target.name}")
|
||||
src_file = f"/data/local/tmp/{input.name}"
|
||||
out_file = f"{src_file}.magisk"
|
||||
|
||||
header(f"* Patching {input.name}")
|
||||
|
||||
push_files(args, Path("scripts", "avd_patch.sh"))
|
||||
|
||||
proc = execv([adb_path, "push", args.target, "/data/local/tmp"])
|
||||
proc = execv([adb_path, "push", input, "/data/local/tmp"])
|
||||
if proc.returncode != 0:
|
||||
error("adb push failed!")
|
||||
|
||||
@@ -634,11 +603,11 @@ def patch_avd_file(args):
|
||||
if proc.returncode != 0:
|
||||
error("avd_patch.sh failed!")
|
||||
|
||||
proc = execv([adb_path, "pull", out_file, args.output])
|
||||
proc = execv([adb_path, "pull", out_file, output])
|
||||
if proc.returncode != 0:
|
||||
error("adb pull failed!")
|
||||
|
||||
header(f"Output: {args.output}")
|
||||
header(f"Output: {output}")
|
||||
|
||||
|
||||
def build_all(args):
|
||||
@@ -693,7 +662,7 @@ all_parser.set_defaults(func=build_all)
|
||||
|
||||
binary_parser = subparsers.add_parser("binary", help="build binaries")
|
||||
binary_parser.add_argument(
|
||||
"target",
|
||||
"targets",
|
||||
nargs="*",
|
||||
help=f"{', '.join(support_targets)}, \
|
||||
or empty for defaults ({', '.join(default_targets)})",
|
||||
@@ -723,7 +692,7 @@ avd_parser.set_defaults(func=setup_avd)
|
||||
avd_patch_parser = subparsers.add_parser(
|
||||
"avd_patch", help="patch AVD ramdisk.img or init_boot.img"
|
||||
)
|
||||
avd_patch_parser.add_argument("target", help="path to ramdisk.img or init_boot.img")
|
||||
avd_patch_parser.add_argument("image", help="path to ramdisk.img or init_boot.img")
|
||||
avd_patch_parser.add_argument("output", help="optional output file name", nargs="?")
|
||||
avd_patch_parser.add_argument(
|
||||
"-s", "--skip", action="store_true", help="skip building binaries and the app"
|
||||
@@ -732,7 +701,7 @@ avd_patch_parser.set_defaults(func=patch_avd_file)
|
||||
|
||||
clean_parser = subparsers.add_parser("clean", help="cleanup")
|
||||
clean_parser.add_argument(
|
||||
"target", nargs="*", help="native, cpp, rust, java, or empty to clean all"
|
||||
"targets", nargs="*", help="native, cpp, rust, java, or empty to clean all"
|
||||
)
|
||||
clean_parser.set_defaults(func=cleanup)
|
||||
|
||||
|
@@ -29,6 +29,6 @@ dependencies {
|
||||
implementation("com.android.tools.build:gradle:8.5.1")
|
||||
implementation("com.google.devtools.ksp:com.google.devtools.ksp.gradle.plugin:2.0.0-1.0.23")
|
||||
implementation("androidx.navigation:navigation-safe-args-gradle-plugin:2.7.7")
|
||||
implementation("org.lsposed.lsparanoid:gradle-plugin:0.5.2")
|
||||
implementation("org.lsposed.lsparanoid:gradle-plugin:0.6.0")
|
||||
implementation("org.eclipse.jgit:org.eclipse.jgit:6.10.0.202406032230-r")
|
||||
}
|
||||
|
@@ -126,13 +126,13 @@ fun Project.setupCoreLib() {
|
||||
for (abi in arrayOf("armeabi-v7a", "x86", "arm64-v8a", "x86_64", "riscv64")) {
|
||||
into(abi) {
|
||||
from(rootProject.file("native/out/$abi")) {
|
||||
include("magiskboot", "magiskinit", "magiskpolicy", "magisk")
|
||||
rename { "lib$it.so" }
|
||||
include("magiskboot", "magiskinit", "magiskpolicy", "magisk", "libinit-ld.so")
|
||||
rename { if (it.endsWith(".so")) it else "lib$it.so" }
|
||||
}
|
||||
}
|
||||
}
|
||||
onlyIf {
|
||||
if (inputs.sourceFiles.files.size != 20)
|
||||
if (inputs.sourceFiles.files.size != 25)
|
||||
throw StopExecutionException("Please build binaries first! (./build.py binary)")
|
||||
true
|
||||
}
|
||||
|
@@ -20,6 +20,9 @@ org.gradle.parallel=true
|
||||
# Enable build cache
|
||||
org.gradle.caching=true
|
||||
|
||||
# Use K2 in kapt
|
||||
kapt.use.k2=true
|
||||
|
||||
# Android
|
||||
android.useAndroidX=true
|
||||
android.injected.testOnly=false
|
||||
@@ -27,5 +30,5 @@ android.nonFinalResIds=false
|
||||
|
||||
# Magisk
|
||||
magisk.stubVersion=40
|
||||
magisk.versionCode=27005
|
||||
magisk.versionCode=27006
|
||||
magisk.ondkVersion=r27.2
|
||||
|
@@ -7,7 +7,7 @@ LOCAL_MODULE := libbase
|
||||
LOCAL_C_INCLUDES := \
|
||||
src/include \
|
||||
$(LOCAL_PATH)/include \
|
||||
$(LOCAL_PATH)/../external/cxx-rs/include \
|
||||
src/external/cxx-rs/include \
|
||||
out/generated
|
||||
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_C_INCLUDES)
|
||||
LOCAL_EXPORT_STATIC_LIBRARIES := libcxx
|
||||
|
@@ -1,13 +0,0 @@
|
||||
#if defined(__arm__)
|
||||
#include <armeabi-v7a_binaries.h>
|
||||
#elif defined(__aarch64__)
|
||||
#include <arm64-v8a_binaries.h>
|
||||
#elif defined(__i386__)
|
||||
#include <x86_binaries.h>
|
||||
#elif defined(__x86_64__)
|
||||
#include <x86_64_binaries.h>
|
||||
#elif defined(__riscv)
|
||||
#include <riscv64_binaries.h>
|
||||
#else
|
||||
#error Unsupported ABI
|
||||
#endif
|
@@ -201,12 +201,16 @@ pub fn find_preinit_device() -> String {
|
||||
let (_, preinit_info, _) = matched_info.select_nth_unstable_by(
|
||||
0,
|
||||
|(ap, MountInfo { fs_type: at, .. }), (bp, MountInfo { fs_type: bt, .. })| match (
|
||||
ap,
|
||||
bp,
|
||||
at.as_str() == "ext4",
|
||||
bt.as_str() == "ext4",
|
||||
) {
|
||||
// take ext4 over others (f2fs) because f2fs has a kernel bug that causes kernel panic
|
||||
(true, false) => Less,
|
||||
(false, true) => Greater,
|
||||
// metadata is not affected by f2fs kernel bug
|
||||
(PartId::Metadata, _, _, true) | (_, PartId::Metadata, true, _) => ap.cmp(bp),
|
||||
// otherwise, take ext4 f2fs because f2fs has a kernel bug that causes kernel panic
|
||||
(_, _, true, false) => Less,
|
||||
(_, _, false, true) => Greater,
|
||||
// if both has the same fs type, compare the mount point
|
||||
_ => ap.cmp(bp),
|
||||
},
|
||||
|
@@ -6,7 +6,6 @@
|
||||
#include <xz.h>
|
||||
|
||||
#include <base.hpp>
|
||||
#include <embed.hpp>
|
||||
|
||||
#include "init.hpp"
|
||||
|
||||
|
@@ -189,6 +189,7 @@ static void magic_mount(const string &sdir, const string &ddir = "") {
|
||||
static void extract_files(bool sbin) {
|
||||
const char *magisk_xz = sbin ? "/sbin/magisk.xz" : "magisk.xz";
|
||||
const char *stub_xz = sbin ? "/sbin/stub.xz" : "stub.xz";
|
||||
const char *init_ld_xz = sbin ? "/sbin/init-ld.xz" : "init-ld.xz";
|
||||
|
||||
if (access(magisk_xz, F_OK) == 0) {
|
||||
mmap_data magisk(magisk_xz);
|
||||
@@ -206,6 +207,14 @@ static void extract_files(bool sbin) {
|
||||
unxz(ch, stub);
|
||||
close(fd);
|
||||
}
|
||||
if (access(init_ld_xz, F_OK) == 0) {
|
||||
mmap_data init_ld(init_ld_xz);
|
||||
unlink(init_ld_xz);
|
||||
int fd = xopen("init-ld", O_WRONLY | O_CREAT, 0);
|
||||
fd_stream ch(fd);
|
||||
unxz(ch, init_ld);
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
|
||||
void MagiskInit::parse_config_file() {
|
||||
@@ -279,16 +288,19 @@ void MagiskInit::patch_ro_root() {
|
||||
patch_rc_scripts("/", tmp_dir.data(), false);
|
||||
}
|
||||
|
||||
// Extract magisk
|
||||
// Extract overlay archives
|
||||
extract_files(false);
|
||||
|
||||
// Oculus Go will use a special sepolicy if unlocked
|
||||
if (access("/sepolicy.unlocked", F_OK) == 0) {
|
||||
patch_sepolicy("/sepolicy.unlocked", ROOTOVL "/sepolicy.unlocked");
|
||||
} else if ((access(SPLIT_PLAT_CIL, F_OK) != 0 && access("/sepolicy", F_OK) == 0) ||
|
||||
!hijack_sepolicy()) {
|
||||
patch_sepolicy("/sepolicy", ROOTOVL "/sepolicy");
|
||||
} else {
|
||||
bool patch = access(SPLIT_PLAT_CIL, F_OK) != 0 && access("/sepolicy", F_OK) == 0;
|
||||
if (patch || !hijack_sepolicy()) {
|
||||
patch_sepolicy("/sepolicy", ROOTOVL "/sepolicy");
|
||||
}
|
||||
}
|
||||
unlink("init-ld");
|
||||
|
||||
// Mount rootdir
|
||||
magic_mount(ROOTOVL);
|
||||
@@ -338,12 +350,14 @@ void MagiskInit::patch_rw_root() {
|
||||
setup_tmp(PRE_TMPDIR);
|
||||
chdir(PRE_TMPDIR);
|
||||
|
||||
// Extract magisk
|
||||
// Extract overlay archives
|
||||
extract_files(true);
|
||||
|
||||
if ((!treble && access("/sepolicy", F_OK) == 0) || !hijack_sepolicy()) {
|
||||
bool patch = !treble && access("/sepolicy", F_OK) == 0;
|
||||
if (patch || !hijack_sepolicy()) {
|
||||
patch_sepolicy("/sepolicy", "/sepolicy");
|
||||
}
|
||||
unlink("init-ld");
|
||||
|
||||
chdir("/");
|
||||
|
||||
|
@@ -2,7 +2,6 @@
|
||||
|
||||
#include <consts.hpp>
|
||||
#include <sepolicy.hpp>
|
||||
#include <embed.hpp>
|
||||
|
||||
#include "init.hpp"
|
||||
|
||||
@@ -31,16 +30,6 @@ void MagiskInit::patch_sepolicy(const char *in, const char *out) {
|
||||
}
|
||||
}
|
||||
|
||||
static void dump_preload() {
|
||||
int fd = xopen("/dev/preload.so", O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, 0644);
|
||||
if (fd < 0)
|
||||
return;
|
||||
fd_stream ch(fd);
|
||||
if (!unxz(ch, byte_view(init_ld_xz, sizeof(init_ld_xz))))
|
||||
return;
|
||||
close(fd);
|
||||
}
|
||||
|
||||
#define MOCK_COMPAT SELINUXMOCK "/compatible"
|
||||
#define MOCK_LOAD SELINUXMOCK "/load"
|
||||
#define MOCK_ENFORCE SELINUXMOCK "/enforce"
|
||||
@@ -53,7 +42,7 @@ bool MagiskInit::hijack_sepolicy() {
|
||||
// This meant that instead of going through convoluted methods trying to alter
|
||||
// and block init's control flow, we can just LD_PRELOAD and replace the
|
||||
// security_load_policy function with our own implementation.
|
||||
dump_preload();
|
||||
cp_afc("init-ld", "/dev/preload.so");
|
||||
setenv("LD_PRELOAD", "/dev/preload.so", 1);
|
||||
}
|
||||
|
||||
@@ -100,18 +89,10 @@ bool MagiskInit::hijack_sepolicy() {
|
||||
|
||||
// Read all custom rules into memory
|
||||
string rules;
|
||||
if (auto dir = xopen_dir("/data/" PREINITMIRR)) {
|
||||
for (dirent *entry; (entry = xreaddir(dir.get()));) {
|
||||
auto name = "/data/" PREINITMIRR "/"s + entry->d_name;
|
||||
auto rule_file = name + "/sepolicy.rule";
|
||||
if (xaccess(rule_file.data(), R_OK) == 0 &&
|
||||
access((name + "/disable").data(), F_OK) != 0 &&
|
||||
access((name + "/remove").data(), F_OK) != 0) {
|
||||
LOGD("Load custom sepolicy patch: [%s]\n", rule_file.data());
|
||||
full_read(rule_file.data(), rules);
|
||||
rules += '\n';
|
||||
}
|
||||
}
|
||||
auto rule = "/data/" PREINITMIRR "/sepolicy.rule";
|
||||
if (xaccess(rule, R_OK) == 0) {
|
||||
LOGD("Loading custom sepolicy patch: [%s]\n", rule);
|
||||
rules = full_read(rule);
|
||||
}
|
||||
// Create a new process waiting for init operations
|
||||
if (xfork()) {
|
||||
|
@@ -118,10 +118,6 @@ impl SepolicyExt for sepolicy {
|
||||
|
||||
fn load_rules_from_reader<T: BufRead>(mut self: Pin<&mut sepolicy>, reader: &mut T) {
|
||||
reader.foreach_lines(|line| {
|
||||
let line = line.trim();
|
||||
if line.is_empty() {
|
||||
return true;
|
||||
}
|
||||
parse_statement(self.as_mut(), line);
|
||||
true
|
||||
});
|
||||
|
@@ -3,7 +3,6 @@ use std::io::stderr;
|
||||
use std::{iter::Peekable, pin::Pin, vec::IntoIter};
|
||||
|
||||
use base::{error, warn, FmtAdaptor};
|
||||
|
||||
use crate::ffi::Xperm;
|
||||
use crate::sepolicy;
|
||||
|
||||
@@ -436,15 +435,16 @@ fn extract_token<'a>(s: &'a str, tokens: &mut Vec<Token<'a>>) {
|
||||
fn tokenize_statement(statement: &str) -> Vec<Token> {
|
||||
let mut tokens = Vec::new();
|
||||
for s in statement.split_whitespace() {
|
||||
if s.starts_with('#') {
|
||||
break;
|
||||
}
|
||||
extract_token(s, &mut tokens);
|
||||
}
|
||||
tokens
|
||||
}
|
||||
|
||||
pub fn parse_statement(sepolicy: Pin<&mut sepolicy>, statement: &str) {
|
||||
let statement = statement.trim();
|
||||
if statement.is_empty() || statement.starts_with('#') {
|
||||
return;
|
||||
}
|
||||
let mut tokens = tokenize_statement(statement).into_iter().peekable();
|
||||
let result = exec_statement(sepolicy, &mut tokens);
|
||||
if let Err(e) = result {
|
||||
|
@@ -71,13 +71,14 @@ export KEEPFORCEENCRYPT=true
|
||||
echo "KEEPVERITY=$KEEPVERITY" > config
|
||||
echo "KEEPFORCEENCRYPT=$KEEPFORCEENCRYPT" >> config
|
||||
echo "PREINITDEVICE=$(./magisk --preinit-device)" >> config
|
||||
# For API 28, we also patch advancedFeatures.ini to disable SAR
|
||||
# Manually override skip_initramfs by setting RECOVERYMODE=true
|
||||
# For API 28, we also manually disable SystemAsRoot
|
||||
# Explicitly override skip_initramfs by setting RECOVERYMODE=true
|
||||
[ $API = "28" ] && echo 'RECOVERYMODE=true' >> config
|
||||
cat config
|
||||
|
||||
./magiskboot compress=xz magisk magisk.xz
|
||||
./magiskboot compress=xz stub.apk stub.xz
|
||||
./magiskboot compress=xz init-ld init-ld.xz
|
||||
|
||||
./magiskboot cpio ramdisk.cpio \
|
||||
"add 0750 init magiskinit" \
|
||||
@@ -85,12 +86,13 @@ cat config
|
||||
"mkdir 0750 overlay.d/sbin" \
|
||||
"add 0644 overlay.d/sbin/magisk.xz magisk.xz" \
|
||||
"add 0644 overlay.d/sbin/stub.xz stub.xz" \
|
||||
"add 0644 overlay.d/sbin/init-ld.xz init-ld.xz" \
|
||||
"patch" \
|
||||
"backup ramdisk.cpio.orig" \
|
||||
"mkdir 000 .backup" \
|
||||
"add 000 .backup/.magisk config"
|
||||
|
||||
rm -f ramdisk.cpio.orig config magisk*.xz stub.xz
|
||||
rm -f ramdisk.cpio.orig config *.xz
|
||||
if $IS_RAMDISK; then
|
||||
./magiskboot compress=gzip ramdisk.cpio "$OUTPUT_FILE"
|
||||
else
|
||||
|
@@ -221,7 +221,7 @@ else
|
||||
# Android 15 Beta
|
||||
run_test 35 google_apis
|
||||
# Run 16k page tests
|
||||
run_test VanillaIceCream google_apis_ps16k
|
||||
run_test 35 google_apis_ps16k
|
||||
fi
|
||||
|
||||
"$avd" delete avd -n test
|
||||
|
@@ -20,6 +20,7 @@
|
||||
# magiskinit binary The binary to replace /init.
|
||||
# magisk binary The magisk binary.
|
||||
# magiskboot binary A tool to manipulate boot images.
|
||||
# init-ld binary The library that will be LD_PRELOAD of /init
|
||||
# stub.apk binary The stub Magisk app to embed into ramdisk.
|
||||
# chromeos folder This folder includes the utility and keys to sign
|
||||
# (optional) chromeos boot images. Only used for Pixel C.
|
||||
@@ -161,6 +162,7 @@ $BOOTMODE && [ -z "$PREINITDEVICE" ] && PREINITDEVICE=$(./magisk --preinit-devic
|
||||
# Compress to save precious ramdisk space
|
||||
./magiskboot compress=xz magisk magisk.xz
|
||||
./magiskboot compress=xz stub.apk stub.xz
|
||||
./magiskboot compress=xz init-ld init-ld.xz
|
||||
|
||||
echo "KEEPVERITY=$KEEPVERITY" > config
|
||||
echo "KEEPFORCEENCRYPT=$KEEPFORCEENCRYPT" >> config
|
||||
@@ -177,13 +179,14 @@ fi
|
||||
"mkdir 0750 overlay.d/sbin" \
|
||||
"add 0644 overlay.d/sbin/magisk.xz magisk.xz" \
|
||||
"add 0644 overlay.d/sbin/stub.xz stub.xz" \
|
||||
"add 0644 overlay.d/sbin/init-ld.xz init-ld.xz" \
|
||||
"patch" \
|
||||
"$SKIP_BACKUP backup ramdisk.cpio.orig" \
|
||||
"mkdir 000 .backup" \
|
||||
"add 000 .backup/.magisk config" \
|
||||
|| abort "! Unable to patch ramdisk"
|
||||
|
||||
rm -f ramdisk.cpio.orig config magisk*.xz stub.xz
|
||||
rm -f ramdisk.cpio.orig config *.xz
|
||||
|
||||
#################
|
||||
# Binary Patches
|
||||
|
248
scripts/release.sh
Executable file
248
scripts/release.sh
Executable file
@@ -0,0 +1,248 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
# On macOS, gsed is required (brew install gnu-sed)
|
||||
# Required tools: jq, gh
|
||||
# The GitHub cli (gh) has to be properly authenticated
|
||||
|
||||
# These variables can be modified as needed
|
||||
MAGISK_FILES=../magisk-files
|
||||
CONFIG=config.prop
|
||||
NOTES=notes.md
|
||||
|
||||
# These are constants, do not modify
|
||||
GCONFIG=gradle.properties
|
||||
README=README.MD
|
||||
BUILDCMD="./build.py -c $CONFIG"
|
||||
CWD=$(pwd)
|
||||
|
||||
grep_prop() {
|
||||
local REGEX="s/^$1=//p"
|
||||
shift
|
||||
local FILES=$@
|
||||
sed -n "$REGEX" $FILES | head -n 1
|
||||
}
|
||||
|
||||
enable_version_config() {
|
||||
# Make sure version is not commented out and exists
|
||||
sed -i "s:^# version=:version=:g" $CONFIG
|
||||
if ! grep -qE '^version=' $CONFIG; then
|
||||
echo 'version=' >> $CONFIG
|
||||
fi
|
||||
}
|
||||
|
||||
disable_version_config() {
|
||||
# Comment out version config
|
||||
sed -i "s:^version=:# version=:g" $CONFIG
|
||||
}
|
||||
|
||||
# $1 = tag
|
||||
update_readme_stable() {
|
||||
sed -i "s:badge/Magisk-v.*:badge/Magisk-${1}-blue)](https\://github.com/topjohnwu/Magisk/releases/tag/$1):g" $README
|
||||
}
|
||||
|
||||
# $1 = tag
|
||||
update_readme_beta() {
|
||||
sed -i "s:badge/Magisk%20Beta.*:badge/Magisk%20Beta-${1}-blue)](https\://github.com/topjohnwu/Magisk/releases/tag/$1):g" $README
|
||||
}
|
||||
|
||||
# $1 = tag
|
||||
update_readme_canary() {
|
||||
sed -i "s:badge/Magisk-Canary.*:badge/Magisk-Canary-red)](https\://github.com/topjohnwu/Magisk/releases/tag/$1):g" $README
|
||||
}
|
||||
|
||||
gen_link() {
|
||||
echo "https://github.com/topjohnwu/Magisk/releases/download/$1/$2"
|
||||
}
|
||||
|
||||
update_canary_json() {
|
||||
local ver=$(grep_prop version $CONFIG)
|
||||
local code=$(grep_prop magisk.versionCode $GCONFIG)
|
||||
local tag="canary-$code"
|
||||
local json
|
||||
|
||||
json=$MAGISK_FILES/canary.json
|
||||
jq ".magisk.version=\"$ver\"|.magisk.versionCode=\"$code\"|
|
||||
.magisk.link=\"$(gen_link $tag app-release.apk)\"|
|
||||
.magisk.note=\"$(gen_link $tag notes.md)\"" $json > ${json}.tmp
|
||||
mv ${json}.tmp $json
|
||||
|
||||
json=$MAGISK_FILES/debug.json
|
||||
jq ".magisk.version=\"$ver\"|.magisk.versionCode=\"$code\"|
|
||||
.magisk.link=\"$(gen_link $tag app-debug.apk)\"|
|
||||
.magisk.note=\"$(gen_link $tag notes.md)\"" $json > ${json}.tmp
|
||||
mv ${json}.tmp $json
|
||||
}
|
||||
|
||||
# $1 = json path
|
||||
update_release_json() {
|
||||
local json=$1
|
||||
local ver=$(grep_prop version $CONFIG)
|
||||
local code=$(grep_prop magisk.versionCode $GCONFIG)
|
||||
|
||||
jq ".magisk.version=\"$ver\"|.magisk.versionCode=\"$code\"|
|
||||
.magisk.link=\"$(gen_link v${ver} Magisk-v${ver}.apk)\"|
|
||||
.magisk.note=\"https://topjohnwu.github.io/Magisk/releases/${code}.md\"" $json > ${json}.tmp
|
||||
mv ${json}.tmp $json
|
||||
}
|
||||
|
||||
build_canary() {
|
||||
enable_version_config
|
||||
|
||||
# Update version code
|
||||
local code=$(grep_prop magisk.versionCode $GCONFIG)
|
||||
code=$((code + 1))
|
||||
local tag="canary-$code"
|
||||
sed -i "s:versionCode=.*:versionCode=${code}:g" $GCONFIG
|
||||
update_readme_canary $tag
|
||||
|
||||
# Commit version code changes
|
||||
git add -u .
|
||||
git status
|
||||
git commit -m "Release new canary build"
|
||||
git tag $tag
|
||||
|
||||
# Update version name
|
||||
local ver=$(git rev-parse --short=8 HEAD)
|
||||
sed -i "s:version=.*:version=${ver}:g" $CONFIG
|
||||
sed -i "s:## Magisk (.*:## Magisk (${ver}) (${code}):g" $NOTES
|
||||
|
||||
# Update and commit JSON
|
||||
update_canary_json
|
||||
cd $MAGISK_FILES
|
||||
git add -u .
|
||||
git status
|
||||
git commit -m "Update Canary Channel: Upstream to $ver"
|
||||
cd $CWD
|
||||
|
||||
# Build
|
||||
$BUILDCMD clean
|
||||
$BUILDCMD all
|
||||
$BUILDCMD -r all
|
||||
|
||||
disable_version_config
|
||||
}
|
||||
|
||||
# $1 = ver, $2 = stable?
|
||||
build_release() {
|
||||
enable_version_config
|
||||
|
||||
# Update version configs
|
||||
local ver=$1
|
||||
local stable=$2
|
||||
local code=$(echo - | awk "{ print $ver * 1000 }")
|
||||
local tag="v$ver"
|
||||
sed -i "s:versionCode=.*:versionCode=${code}:g" $GCONFIG
|
||||
sed -i "s:version=.*:version=${ver}:g" $CONFIG
|
||||
|
||||
# Update and commit JSON
|
||||
if $stable; then
|
||||
update_readme_stable $tag
|
||||
update_readme_beta $tag
|
||||
update_release_json $MAGISK_FILES/stable.json
|
||||
cp -vf $MAGISK_FILES/stable.json $MAGISK_FILES/beta.json
|
||||
else
|
||||
update_readme_beta $tag
|
||||
update_release_json $MAGISK_FILES/beta.json
|
||||
fi
|
||||
cd $MAGISK_FILES
|
||||
git add -u .
|
||||
git status
|
||||
git commit -m "Release Magisk v$ver"
|
||||
cd $CWD
|
||||
|
||||
# Commit version code changes
|
||||
git add -u .
|
||||
git status
|
||||
git commit -m "Release Magisk v$ver"
|
||||
git tag $tag
|
||||
|
||||
# Build
|
||||
$BUILDCMD clean
|
||||
$BUILDCMD -r all
|
||||
|
||||
disable_version_config
|
||||
}
|
||||
|
||||
stable() {
|
||||
[ -z $1 ] && exit 1
|
||||
local ver=$1
|
||||
build_release $ver true
|
||||
}
|
||||
|
||||
beta() {
|
||||
[ -z $1 ] && exit 1
|
||||
local ver=$1
|
||||
build_release $ver false
|
||||
}
|
||||
|
||||
pub() {
|
||||
gh auth status
|
||||
|
||||
local latest_tag=$(git describe --abbrev=0 --tags)
|
||||
local ver=$(grep_prop version $CONFIG)
|
||||
local code=$(grep_prop magisk.versionCode $GCONFIG)
|
||||
local out=$(grep_prop outdir $CONFIG)
|
||||
local tag title
|
||||
|
||||
if [ -z $out ]; then
|
||||
out=out
|
||||
fi
|
||||
|
||||
git push origin master
|
||||
git push --tags
|
||||
|
||||
if [ $(($code % 100)) -ne 0 ]; then
|
||||
tag="canary-$code"
|
||||
title="Magisk ($ver) ($code)"
|
||||
|
||||
# Assert tag format
|
||||
[ $latest_tag = $tag ]
|
||||
|
||||
# Publish release
|
||||
tail -n +3 $NOTES > release.md
|
||||
gh release create --verify-tag $tag -p -t "$title" -F release.md $out/app-release.apk $out/app-debug.apk $NOTES
|
||||
else
|
||||
tag="v$ver"
|
||||
title="Magisk v$ver"
|
||||
|
||||
# Assert tag format
|
||||
[ $latest_tag = $tag ]
|
||||
|
||||
# Publish release
|
||||
tail -n +3 docs/releases/$code.md > release.md
|
||||
gh release create --verify-tag $tag -t "$title" -F release.md "$out/app-release.apk#Magisk-v${ver}.apk"
|
||||
fi
|
||||
|
||||
rm -f release.md
|
||||
cd $MAGISK_FILES
|
||||
git push origin master
|
||||
cd $CWD
|
||||
}
|
||||
|
||||
revert() {
|
||||
local latest_tag=$(git describe --abbrev=0 --tags)
|
||||
|
||||
git tag -d $latest_tag
|
||||
git reset --hard HEAD~
|
||||
cd $MAGISK_FILES
|
||||
git reset --hard HEAD~
|
||||
cd $CWD
|
||||
}
|
||||
|
||||
# Use GNU sed on macOS
|
||||
if command -v gsed >/dev/null; then
|
||||
function sed() { gsed "$@"; }
|
||||
export -f sed
|
||||
fi
|
||||
|
||||
git pull
|
||||
|
||||
case $1 in
|
||||
"canary" ) build_canary ;;
|
||||
"stable" ) stable $2 ;;
|
||||
"beta" ) beta $2 ;;
|
||||
"pub" ) pub ;;
|
||||
"revert" ) revert ;;
|
||||
* ) exit 1 ;;
|
||||
esac
|
Reference in New Issue
Block a user