You've already forked ReZygisk
mirror of
https://github.com/PerformanC/ReZygisk.git
synced 2025-09-06 06:37:01 +00:00
Add flashable module
This commit is contained in:
@@ -14,8 +14,11 @@ buildscript {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val verCode by extra(25207)
|
val moduleId by extra("zygisksu")
|
||||||
val verName by extra("25.2-1")
|
val moduleName by extra("Zygisk on KernelSU")
|
||||||
|
val verName by extra("v4.0.0")
|
||||||
|
val verCode by extra(4000)
|
||||||
|
|
||||||
val androidMinSdkVersion by extra(29)
|
val androidMinSdkVersion by extra(29)
|
||||||
val androidTargetSdkVersion by extra(33)
|
val androidTargetSdkVersion by extra(33)
|
||||||
val androidCompileSdkVersion by extra(33)
|
val androidCompileSdkVersion by extra(33)
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ namespace zygiskd {
|
|||||||
|
|
||||||
while (retry--) {
|
while (retry--) {
|
||||||
int r = connect(fd, reinterpret_cast<struct sockaddr*>(&addr), socklen);
|
int r = connect(fd, reinterpret_cast<struct sockaddr*>(&addr), socklen);
|
||||||
if (r != -1) return r;
|
if (r == 0) return fd;
|
||||||
LOGW("retrying to connect to zygiskd, sleep 1s");
|
LOGW("retrying to connect to zygiskd, sleep 1s");
|
||||||
sleep(1);
|
sleep(1);
|
||||||
}
|
}
|
||||||
@@ -27,11 +27,13 @@ namespace zygiskd {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool PingHeartbeat() {
|
bool PingHeartbeat() {
|
||||||
|
LOGD("Daemon socket: %s", kZygiskSocket);
|
||||||
auto fd = Connect(5);
|
auto fd = Connect(5);
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
PLOGE("Connect to zygiskd");
|
PLOGE("Connect to zygiskd");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
socket_utils::write_u8(fd, (uint8_t) SocketAction::PingHeartBeat);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,16 +47,6 @@ namespace zygiskd {
|
|||||||
return socket_utils::read_string(fd);
|
return socket_utils::read_string(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
UniqueFd ReadInjector() {
|
|
||||||
auto fd = Connect(1);
|
|
||||||
if (fd == -1) {
|
|
||||||
PLOGE("ReadInjector");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
socket_utils::write_u8(fd, (uint8_t) SocketAction::ReadInjector);
|
|
||||||
return socket_utils::recv_fd(fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<Module> ReadModules() {
|
std::vector<Module> ReadModules() {
|
||||||
std::vector<Module> modules;
|
std::vector<Module> modules;
|
||||||
auto fd = Connect(1);
|
auto fd = Connect(1);
|
||||||
|
|||||||
@@ -75,9 +75,9 @@ namespace socket_utils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline T read_exact(int fd) {
|
inline T read_exact_or(int fd, T fail) {
|
||||||
T res;
|
T res;
|
||||||
return sizeof(T) == xread(fd, &res, sizeof(T)) ? res : -1;
|
return sizeof(T) == xread(fd, &res, sizeof(T)) ? res : fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
@@ -86,11 +86,11 @@ namespace socket_utils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t read_usize(int fd) {
|
size_t read_usize(int fd) {
|
||||||
return read_exact<size_t>(fd);
|
return read_exact_or<size_t>(fd, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string read_string(int fd) {
|
std::string read_string(int fd) {
|
||||||
auto len = read_exact<size_t>(fd);
|
auto len = read_usize(fd);
|
||||||
char buf[len + 1];
|
char buf[len + 1];
|
||||||
buf[len] = '\0';
|
buf[len] = '\0';
|
||||||
xread(fd, buf, len);
|
xread(fd, buf, len);
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
# define LP_SELECT(lp32, lp64) lp32
|
# define LP_SELECT(lp32, lp64) lp32
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
constexpr std::string_view kZygiskSocket = LP_SELECT("zygisk32", "zygisk64") "placeholder123456";
|
constexpr std::string_view kZygiskSocket = LP_SELECT("zygiskd32", "zygiskd64") "socket_placeholder";
|
||||||
|
|
||||||
class UniqueFd {
|
class UniqueFd {
|
||||||
using Fd = int;
|
using Fd = int;
|
||||||
@@ -52,9 +52,8 @@ namespace zygiskd {
|
|||||||
};
|
};
|
||||||
|
|
||||||
enum class SocketAction {
|
enum class SocketAction {
|
||||||
HeartBeat,
|
PingHeartBeat,
|
||||||
ReadNativeBridge,
|
ReadNativeBridge,
|
||||||
ReadInjector,
|
|
||||||
ReadModules,
|
ReadModules,
|
||||||
RequestCompanionSocket,
|
RequestCompanionSocket,
|
||||||
};
|
};
|
||||||
@@ -63,7 +62,5 @@ namespace zygiskd {
|
|||||||
|
|
||||||
std::string ReadNativeBridge();
|
std::string ReadNativeBridge();
|
||||||
|
|
||||||
UniqueFd ReadInjector();
|
|
||||||
|
|
||||||
std::vector<Module> ReadModules();
|
std::vector<Module> ReadModules();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,8 @@ extern "C" [[gnu::visibility("default")]]
|
|||||||
uint8_t NativeBridgeItf[sizeof(NativeBridgeCallbacks<__ANDROID_API_R__>) * 2]{0};
|
uint8_t NativeBridgeItf[sizeof(NativeBridgeCallbacks<__ANDROID_API_R__>) * 2]{0};
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
constexpr std::array kZygoteProcesses = {"zygote", "zygote32""zygote64", "usap32", "usap64"};
|
constexpr auto kZygoteProcesses = {"zygote", "zygote32", "zygote64", "usap32", "usap64"};
|
||||||
|
constexpr auto kInjector = "/system/" LP_SELECT("lib", "lib64") "/libinjector.so";
|
||||||
|
|
||||||
void* sOriginalBridge = nullptr;
|
void* sOriginalBridge = nullptr;
|
||||||
}
|
}
|
||||||
@@ -31,9 +32,8 @@ void Constructor() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string_view cmdline = getprogname();
|
std::string_view cmdline = getprogname();
|
||||||
if (std::any_of(
|
if (std::none_of(
|
||||||
kZygoteProcesses.begin(),
|
kZygoteProcesses.begin(), kZygoteProcesses.end(),
|
||||||
kZygoteProcesses.end(),
|
|
||||||
[&](const char* p) { return cmdline == p; }
|
[&](const char* p) { return cmdline == p; }
|
||||||
)) {
|
)) {
|
||||||
LOGW("Not started as zygote (cmdline=%s)", cmdline.data());
|
LOGW("Not started as zygote (cmdline=%s)", cmdline.data());
|
||||||
@@ -49,10 +49,7 @@ void Constructor() {
|
|||||||
native_bridge = zygiskd::ReadNativeBridge();
|
native_bridge = zygiskd::ReadNativeBridge();
|
||||||
|
|
||||||
LOGI("Load injector");
|
LOGI("Load injector");
|
||||||
auto injector = zygiskd::ReadInjector();
|
auto handle = DlopenExt(kInjector, RTLD_NOW);
|
||||||
if (injector != -1) break;
|
|
||||||
|
|
||||||
auto handle = DlopenMem(injector, RTLD_NOW);
|
|
||||||
if (handle == nullptr) {
|
if (handle == nullptr) {
|
||||||
LOGE("Failed to dlopen injector: %s", dlerror());
|
LOGE("Failed to dlopen injector: %s", dlerror());
|
||||||
break;
|
break;
|
||||||
@@ -60,12 +57,13 @@ void Constructor() {
|
|||||||
auto entry = dlsym(handle, "entry");
|
auto entry = dlsym(handle, "entry");
|
||||||
if (entry == nullptr) {
|
if (entry == nullptr) {
|
||||||
LOGE("Failed to dlsym injector entry: %s", dlerror());
|
LOGE("Failed to dlsym injector entry: %s", dlerror());
|
||||||
|
dlclose(handle);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
reinterpret_cast<void (*)()>(entry)();
|
reinterpret_cast<void (*)(void*)>(entry)(handle);
|
||||||
} while (false);
|
} while (false);
|
||||||
|
|
||||||
if (native_bridge.empty()) return;
|
if (native_bridge.empty() || native_bridge == "0") return;
|
||||||
LOGI("Load original native bridge: %s", native_bridge.data());
|
LOGI("Load original native bridge: %s", native_bridge.data());
|
||||||
sOriginalBridge = dlopen(native_bridge.data(), RTLD_NOW);
|
sOriginalBridge = dlopen(native_bridge.data(), RTLD_NOW);
|
||||||
if (sOriginalBridge == nullptr) {
|
if (sOriginalBridge == nullptr) {
|
||||||
|
|||||||
@@ -1,7 +1,12 @@
|
|||||||
|
import java.security.MessageDigest
|
||||||
|
import org.apache.tools.ant.filters.ReplaceTokens
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("com.android.library")
|
id("com.android.library")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val moduleId: String by rootProject.extra
|
||||||
|
val moduleName: String by rootProject.extra
|
||||||
val verCode: Int by rootProject.extra
|
val verCode: Int by rootProject.extra
|
||||||
val verName: String by rootProject.extra
|
val verName: String by rootProject.extra
|
||||||
|
|
||||||
@@ -9,3 +14,95 @@ android.buildFeatures {
|
|||||||
androidResources = false
|
androidResources = false
|
||||||
buildConfig = false
|
buildConfig = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
androidComponents.onVariants { variant ->
|
||||||
|
val variantLowered = variant.name.toLowerCase()
|
||||||
|
val variantCapped = variant.name.capitalize()
|
||||||
|
val buildTypeLowered = variant.buildType?.toLowerCase()
|
||||||
|
|
||||||
|
val moduleDir = "$buildDir/outputs/module/$variantLowered"
|
||||||
|
val zipFileName = "$moduleName-$verName-$buildTypeLowered.zip".replace(' ', '-')
|
||||||
|
|
||||||
|
val prepareModuleFilesTask = task<Sync>("prepareModuleFiles$variantCapped") {
|
||||||
|
group = "module"
|
||||||
|
dependsOn(
|
||||||
|
":loader:assemble$variantCapped",
|
||||||
|
":zygiskd:cargoBuild",
|
||||||
|
)
|
||||||
|
into(moduleDir)
|
||||||
|
from("${rootProject.projectDir}/README.md")
|
||||||
|
from("$projectDir/src") {
|
||||||
|
exclude("module.prop", "customize.sh", "daemon.sh")
|
||||||
|
}
|
||||||
|
from("$projectDir/src") {
|
||||||
|
include("module.prop")
|
||||||
|
expand(
|
||||||
|
"moduleId" to moduleId,
|
||||||
|
"moduleName" to moduleName,
|
||||||
|
"versionName" to verName,
|
||||||
|
"versionCode" to verCode,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
from("$projectDir/src") {
|
||||||
|
include("customize.sh", "daemon.sh")
|
||||||
|
val tokens = mapOf(
|
||||||
|
"ZYGISK_API" to (verCode / 1000).toString(),
|
||||||
|
"DEBUG" to if (buildTypeLowered == "debug") "true" else "false"
|
||||||
|
)
|
||||||
|
filter<ReplaceTokens>("tokens" to tokens)
|
||||||
|
}
|
||||||
|
into("bin") {
|
||||||
|
from(project(":zygiskd").buildDir.path + "/rustJniLibs/android")
|
||||||
|
}
|
||||||
|
into("lib") {
|
||||||
|
from("${project(":loader").buildDir}/intermediates/stripped_native_libs/$variantLowered/out/lib")
|
||||||
|
}
|
||||||
|
|
||||||
|
doLast {
|
||||||
|
fileTree(moduleDir).visit {
|
||||||
|
if (isDirectory) return@visit
|
||||||
|
val md = MessageDigest.getInstance("SHA-256")
|
||||||
|
file.forEachBlock(4096) { bytes, size ->
|
||||||
|
md.update(bytes, 0, size)
|
||||||
|
}
|
||||||
|
file(file.path + ".sha256").writeText(org.apache.commons.codec.binary.Hex.encodeHexString(md.digest()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val zipTask = task<Zip>("zip$variantCapped") {
|
||||||
|
group = "module"
|
||||||
|
dependsOn(prepareModuleFilesTask)
|
||||||
|
archiveFileName.set(zipFileName)
|
||||||
|
destinationDirectory.set(file("$buildDir/outputs/release"))
|
||||||
|
from(moduleDir)
|
||||||
|
}
|
||||||
|
|
||||||
|
val pushTask = task<Exec>("push$variantCapped") {
|
||||||
|
group = "module"
|
||||||
|
dependsOn(zipTask)
|
||||||
|
commandLine("adb", "push", zipTask.outputs.files.singleFile.path, "/data/local/tmp")
|
||||||
|
}
|
||||||
|
|
||||||
|
val installTask = task("install$variantCapped") {
|
||||||
|
group = "module"
|
||||||
|
dependsOn(pushTask)
|
||||||
|
doLast {
|
||||||
|
exec {
|
||||||
|
commandLine(
|
||||||
|
"adb", "shell", "echo",
|
||||||
|
"""su -c \"/data/adb/ksud module install /data/local/tmp/$zipFileName\"""",
|
||||||
|
"> /data/local/tmp/install.sh"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
exec { commandLine("adb", "shell", "chmod", "755", "/data/local/tmp/install.sh") }
|
||||||
|
exec { commandLine("adb", "shell", "su", "-c", "/data/local/tmp/install.sh") }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
task<Exec>("installAndReboot$variantCapped") {
|
||||||
|
group = "module"
|
||||||
|
dependsOn(installTask)
|
||||||
|
commandLine("adb", "reboot")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
190
module/src/META-INF/com/google/android/update-binary
Normal file
190
module/src/META-INF/com/google/android/update-binary
Normal file
@@ -0,0 +1,190 @@
|
|||||||
|
#!/sbin/sh
|
||||||
|
|
||||||
|
#################
|
||||||
|
# Initialization
|
||||||
|
#################
|
||||||
|
|
||||||
|
umask 022
|
||||||
|
|
||||||
|
# echo before loading util_functions
|
||||||
|
ui_print() { echo "$1"; }
|
||||||
|
|
||||||
|
require_new_magisk() {
|
||||||
|
ui_print "*******************************"
|
||||||
|
ui_print " Please install Magisk v19.0+! "
|
||||||
|
ui_print "*******************************"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
#########################
|
||||||
|
# Load util_functions.sh
|
||||||
|
#########################
|
||||||
|
|
||||||
|
OUTFD=$2
|
||||||
|
ZIPFILE=$3
|
||||||
|
|
||||||
|
mount /data 2>/dev/null
|
||||||
|
|
||||||
|
[ -f /data/adb/magisk/util_functions.sh ] || require_new_magisk
|
||||||
|
. /data/adb/magisk/util_functions.sh
|
||||||
|
[ $MAGISK_VER_CODE -lt 19000 ] && require_new_magisk
|
||||||
|
|
||||||
|
if [ $MAGISK_VER_CODE -ge 20400 ]; then
|
||||||
|
# New Magisk have complete installation logic within util_functions.sh
|
||||||
|
install_module
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
#################
|
||||||
|
# Legacy Support
|
||||||
|
#################
|
||||||
|
|
||||||
|
TMPDIR=/dev/tmp
|
||||||
|
PERSISTDIR=/sbin/.magisk/mirror/persist
|
||||||
|
|
||||||
|
is_legacy_script() {
|
||||||
|
unzip -l "$ZIPFILE" install.sh | grep -q install.sh
|
||||||
|
return $?
|
||||||
|
}
|
||||||
|
|
||||||
|
print_modname() {
|
||||||
|
local len
|
||||||
|
len=`echo -n $MODNAME | wc -c`
|
||||||
|
len=$((len + 2))
|
||||||
|
local pounds=`printf "%${len}s" | tr ' ' '*'`
|
||||||
|
ui_print "$pounds"
|
||||||
|
ui_print " $MODNAME "
|
||||||
|
ui_print "$pounds"
|
||||||
|
ui_print "*******************"
|
||||||
|
ui_print " Powered by Magisk "
|
||||||
|
ui_print "*******************"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Override abort as old scripts have some issues
|
||||||
|
abort() {
|
||||||
|
ui_print "$1"
|
||||||
|
$BOOTMODE || recovery_cleanup
|
||||||
|
[ -n $MODPATH ] && rm -rf $MODPATH
|
||||||
|
rm -rf $TMPDIR
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
rm -rf $TMPDIR 2>/dev/null
|
||||||
|
mkdir -p $TMPDIR
|
||||||
|
|
||||||
|
# Preperation for flashable zips
|
||||||
|
setup_flashable
|
||||||
|
|
||||||
|
# Mount partitions
|
||||||
|
mount_partitions
|
||||||
|
|
||||||
|
# Detect version and architecture
|
||||||
|
api_level_arch_detect
|
||||||
|
|
||||||
|
# Setup busybox and binaries
|
||||||
|
$BOOTMODE && boot_actions || recovery_actions
|
||||||
|
|
||||||
|
##############
|
||||||
|
# Preparation
|
||||||
|
##############
|
||||||
|
|
||||||
|
# Extract prop file
|
||||||
|
unzip -o "$ZIPFILE" module.prop -d $TMPDIR >&2
|
||||||
|
[ ! -f $TMPDIR/module.prop ] && abort "! Unable to extract zip file!"
|
||||||
|
|
||||||
|
$BOOTMODE && MODDIRNAME=modules_update || MODDIRNAME=modules
|
||||||
|
MODULEROOT=$NVBASE/$MODDIRNAME
|
||||||
|
MODID=`grep_prop id $TMPDIR/module.prop`
|
||||||
|
MODPATH=$MODULEROOT/$MODID
|
||||||
|
MODNAME=`grep_prop name $TMPDIR/module.prop`
|
||||||
|
|
||||||
|
# Create mod paths
|
||||||
|
rm -rf $MODPATH 2>/dev/null
|
||||||
|
mkdir -p $MODPATH
|
||||||
|
|
||||||
|
##########
|
||||||
|
# Install
|
||||||
|
##########
|
||||||
|
|
||||||
|
if is_legacy_script; then
|
||||||
|
unzip -oj "$ZIPFILE" module.prop install.sh uninstall.sh 'common/*' -d $TMPDIR >&2
|
||||||
|
|
||||||
|
# Load install script
|
||||||
|
. $TMPDIR/install.sh
|
||||||
|
|
||||||
|
# Callbacks
|
||||||
|
print_modname
|
||||||
|
on_install
|
||||||
|
|
||||||
|
# Custom uninstaller
|
||||||
|
[ -f $TMPDIR/uninstall.sh ] && cp -af $TMPDIR/uninstall.sh $MODPATH/uninstall.sh
|
||||||
|
|
||||||
|
# Skip mount
|
||||||
|
$SKIPMOUNT && touch $MODPATH/skip_mount
|
||||||
|
|
||||||
|
# prop file
|
||||||
|
$PROPFILE && cp -af $TMPDIR/system.prop $MODPATH/system.prop
|
||||||
|
|
||||||
|
# Module info
|
||||||
|
cp -af $TMPDIR/module.prop $MODPATH/module.prop
|
||||||
|
|
||||||
|
# post-fs-data scripts
|
||||||
|
$POSTFSDATA && cp -af $TMPDIR/post-fs-data.sh $MODPATH/post-fs-data.sh
|
||||||
|
|
||||||
|
# service scripts
|
||||||
|
$LATESTARTSERVICE && cp -af $TMPDIR/service.sh $MODPATH/service.sh
|
||||||
|
|
||||||
|
ui_print "- Setting permissions"
|
||||||
|
set_permissions
|
||||||
|
else
|
||||||
|
print_modname
|
||||||
|
|
||||||
|
unzip -o "$ZIPFILE" customize.sh -d $MODPATH >&2
|
||||||
|
|
||||||
|
if ! grep -q '^SKIPUNZIP=1$' $MODPATH/customize.sh 2>/dev/null; then
|
||||||
|
ui_print "- Extracting module files"
|
||||||
|
unzip -o "$ZIPFILE" -x 'META-INF/*' -d $MODPATH >&2
|
||||||
|
|
||||||
|
# Default permissions
|
||||||
|
set_perm_recursive $MODPATH 0 0 0755 0644
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Load customization script
|
||||||
|
[ -f $MODPATH/customize.sh ] && . $MODPATH/customize.sh
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Handle replace folders
|
||||||
|
for TARGET in $REPLACE; do
|
||||||
|
ui_print "- Replace target: $TARGET"
|
||||||
|
mktouch $MODPATH$TARGET/.replace
|
||||||
|
done
|
||||||
|
|
||||||
|
if $BOOTMODE; then
|
||||||
|
# Update info for Magisk Manager
|
||||||
|
mktouch $NVBASE/modules/$MODID/update
|
||||||
|
cp -af $MODPATH/module.prop $NVBASE/modules/$MODID/module.prop
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Copy over custom sepolicy rules
|
||||||
|
if [ -f $MODPATH/sepolicy.rule -a -e $PERSISTDIR ]; then
|
||||||
|
ui_print "- Installing custom sepolicy patch"
|
||||||
|
PERSISTMOD=$PERSISTDIR/magisk/$MODID
|
||||||
|
mkdir -p $PERSISTMOD
|
||||||
|
cp -af $MODPATH/sepolicy.rule $PERSISTMOD/sepolicy.rule
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Remove stuffs that don't belong to modules
|
||||||
|
rm -rf \
|
||||||
|
$MODPATH/system/placeholder $MODPATH/customize.sh \
|
||||||
|
$MODPATH/README.md $MODPATH/.git* 2>/dev/null
|
||||||
|
|
||||||
|
#############
|
||||||
|
# Finalizing
|
||||||
|
#############
|
||||||
|
|
||||||
|
cd /
|
||||||
|
$BOOTMODE || recovery_cleanup
|
||||||
|
rm -rf $TMPDIR
|
||||||
|
|
||||||
|
ui_print "- Done"
|
||||||
|
exit 0
|
||||||
1
module/src/META-INF/com/google/android/updater-script
Normal file
1
module/src/META-INF/com/google/android/updater-script
Normal file
@@ -0,0 +1 @@
|
|||||||
|
#MAGISK
|
||||||
123
module/src/customize.sh
Normal file
123
module/src/customize.sh
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
# shellcheck disable=SC2034
|
||||||
|
SKIPUNZIP=1
|
||||||
|
|
||||||
|
ZYGISK_API="@ZYGISK_API@"
|
||||||
|
|
||||||
|
if [ $BOOTMODE ] && [ "$KSU" == "true" ]; then
|
||||||
|
ui_print "- Installing from KernelSU app"
|
||||||
|
else
|
||||||
|
ui_print "*********************************************************"
|
||||||
|
ui_print "! Install from recovery or Magisk is NOT supported"
|
||||||
|
ui_print "! Please install from KernelSU app"
|
||||||
|
abort "*********************************************************"
|
||||||
|
fi
|
||||||
|
|
||||||
|
VERSION=$(grep_prop version "${TMPDIR}/module.prop")
|
||||||
|
ui_print "- Installing Zygisksu $VERSION (ZYGISK API $ZYGISK_API)"
|
||||||
|
|
||||||
|
# check KernelSU
|
||||||
|
# ui_print "- KernelSU version: $KSU_VER ($KSU_VER_CODE)"
|
||||||
|
|
||||||
|
# check android
|
||||||
|
if [ "$API" -lt 29 ]; then
|
||||||
|
ui_print "! Unsupported sdk: $API"
|
||||||
|
abort "! Minimal supported sdk is 29 (Android 10.0)"
|
||||||
|
else
|
||||||
|
ui_print "- Device sdk: $API"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# check architecture
|
||||||
|
if [ "$ARCH" != "arm" ] && [ "$ARCH" != "arm64" ] && [ "$ARCH" != "x86" ] && [ "$ARCH" != "x64" ]; then
|
||||||
|
abort "! Unsupported platform: $ARCH"
|
||||||
|
else
|
||||||
|
ui_print "- Device platform: $ARCH"
|
||||||
|
fi
|
||||||
|
|
||||||
|
ui_print "- Extracting verify.sh"
|
||||||
|
unzip -o "$ZIPFILE" 'verify.sh' -d "$TMPDIR" >&2
|
||||||
|
if [ ! -f "$TMPDIR/verify.sh" ]; then
|
||||||
|
ui_print "*********************************************************"
|
||||||
|
ui_print "! Unable to extract verify.sh!"
|
||||||
|
ui_print "! This zip may be corrupted, please try downloading again"
|
||||||
|
abort "*********************************************************"
|
||||||
|
fi
|
||||||
|
. "$TMPDIR/verify.sh"
|
||||||
|
extract "$ZIPFILE" 'customize.sh' "$TMPDIR/.vunzip"
|
||||||
|
extract "$ZIPFILE" 'verify.sh' "$TMPDIR/.vunzip"
|
||||||
|
|
||||||
|
ui_print "- Extracting module files"
|
||||||
|
extract "$ZIPFILE" 'daemon.sh' "$MODPATH"
|
||||||
|
extract "$ZIPFILE" 'module.prop' "$MODPATH"
|
||||||
|
extract "$ZIPFILE" 'post-fs-data.sh' "$MODPATH"
|
||||||
|
extract "$ZIPFILE" 'service.sh' "$MODPATH"
|
||||||
|
|
||||||
|
HAS32BIT=false && [ -d "/system/lib" ] && HAS32BIT=true
|
||||||
|
HAS64BIT=false && [ -d "/system/lib64" ] && HAS64BIT=true
|
||||||
|
|
||||||
|
mkdir "$MODPATH/bin"
|
||||||
|
mkdir "$MODPATH/system"
|
||||||
|
[ "$HAS32BIT" = true ] && mkdir "$MODPATH/system/lib"
|
||||||
|
[ "$HAS64BIT" = true ] && mkdir "$MODPATH/system/lib64"
|
||||||
|
|
||||||
|
if [ "$ARCH" = "x86" ] || [ "$ARCH" = "x64" ]; then
|
||||||
|
if [ "$HAS32BIT" = ture ]; then
|
||||||
|
ui_print "- Extracting x86 libraries"
|
||||||
|
extract "$ZIPFILE" 'bin/x86/zygiskd' "$MODPATH/bin/zygiskd32" true
|
||||||
|
rename "$MODPATH/bin/zygiskd" "$MODPATH/bin/zygiskd32"
|
||||||
|
extract "$ZIPFILE" 'lib/x86/libinjector.so' "$MODPATH/system/lib" true
|
||||||
|
extract "$ZIPFILE" 'lib/x86/libzygiskloader.so' "$MODPATH/system/lib" true
|
||||||
|
ln -sf "zygiskd32" "$MODPATH/bin/zygiskwd"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$HAS64BIT" = true ]; then
|
||||||
|
ui_print "- Extracting x64 libraries"
|
||||||
|
extract "$ZIPFILE" 'bin/x86_64/zygiskd' "$MODPATH/bin/zygiskd64" true
|
||||||
|
rename "$MODPATH/bin/zygiskd" "$MODPATH/bin/zygiskd64"
|
||||||
|
extract "$ZIPFILE" 'lib/x86_64/libinjector.so' "$MODPATH/system/lib64" true
|
||||||
|
extract "$ZIPFILE" 'lib/x86_64/libzygiskloader.so' "$MODPATH/system/lib64" true
|
||||||
|
ln -sf "zygiskd64" "$MODPATH/bin/zygiskwd"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
if [ "$HAS32BIT" = true ]; then
|
||||||
|
ui_print "- Extracting arm libraries"
|
||||||
|
extract "$ZIPFILE" 'bin/armeabi-v7a/zygiskd' "$MODPATH/bin" true
|
||||||
|
rename "$MODPATH/bin/zygiskd" "$MODPATH/bin/zygiskd32"
|
||||||
|
extract "$ZIPFILE" 'lib/armeabi-v7a/libinjector.so' "$MODPATH/system/lib" true
|
||||||
|
extract "$ZIPFILE" 'lib/armeabi-v7a/libzygiskloader.so' "$MODPATH/system/lib" true
|
||||||
|
ln -sf "zygiskd32" "$MODPATH/bin/zygiskwd"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$HAS64BIT" = true ]; then
|
||||||
|
ui_print "- Extracting arm64 libraries"
|
||||||
|
extract "$ZIPFILE" 'bin/arm64-v8a/zygiskd' "$MODPATH/bin" true
|
||||||
|
rename "$MODPATH/bin/zygiskd" "$MODPATH/bin/zygiskd64"
|
||||||
|
extract "$ZIPFILE" 'lib/arm64-v8a/libinjector.so' "$MODPATH/system/lib64" true
|
||||||
|
extract "$ZIPFILE" 'lib/arm64-v8a/libzygiskloader.so' "$MODPATH/system/lib64" true
|
||||||
|
ln -sf "zygiskd64" "$MODPATH/bin/zygiskwd"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
ui_print "- Hex patching"
|
||||||
|
SOCKET_PATCH=$(tr -dc 'a-f0-9' </dev/urandom | head -c 18)
|
||||||
|
if [ "$HAS32BIT" = true ]; then
|
||||||
|
sed -i "s/socket_placeholder/$SOCKET_PATCH/g" "$MODPATH/bin/zygiskd32"
|
||||||
|
sed -i "s/socket_placeholder/$SOCKET_PATCH/g" "$MODPATH/system/lib/libinjector.so"
|
||||||
|
sed -i "s/socket_placeholder/$SOCKET_PATCH/g" "$MODPATH/system/lib/libzygiskloader.so"
|
||||||
|
fi
|
||||||
|
if [ "$HAS64BIT" = true ]; then
|
||||||
|
sed -i "s/socket_placeholder/$SOCKET_PATCH/g" "$MODPATH/bin/zygiskd64"
|
||||||
|
sed -i "s/socket_placeholder/$SOCKET_PATCH/g" "$MODPATH/system/lib64/libinjector.so"
|
||||||
|
sed -i "s/socket_placeholder/$SOCKET_PATCH/g" "$MODPATH/system/lib64/libzygiskloader.so"
|
||||||
|
fi
|
||||||
|
|
||||||
|
ui_print "- Setting permissions"
|
||||||
|
chmod 0744 "$MODPATH/daemon.sh"
|
||||||
|
set_perm_recursive "$MODPATH/bin" 0 2000 0755 0755
|
||||||
|
set_perm_recursive "$MODPATH/system/lib" 0 0 0755 0644 u:object_r:system_lib_file:s0
|
||||||
|
|
||||||
|
# If Huawei's Maple is enabled, system_server is created with a special way which is out of Zygisk's control
|
||||||
|
HUAWEI_MAPLE_ENABLED=$(grep_prop ro.maple.enable)
|
||||||
|
if [ "$HUAWEI_MAPLE_ENABLED" == "1" ]; then
|
||||||
|
ui_print "- Add ro.maple.enable=0"
|
||||||
|
echo "ro.maple.enable=0" >>"$MODPATH/system.prop"
|
||||||
|
fi
|
||||||
12
module/src/daemon.sh
Normal file
12
module/src/daemon.sh
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
#!/system/bin/sh
|
||||||
|
|
||||||
|
DEBUG=@DEBUG@
|
||||||
|
MODDIR=${0%/*}
|
||||||
|
|
||||||
|
# shellcheck disable=SC2155
|
||||||
|
export NATIVE_BRIDGE=$(getprop ro.dalvik.vm.native.bridge)
|
||||||
|
[ "$DEBUG" = true ] && export RUST_BACKTRACE=1
|
||||||
|
|
||||||
|
log -p i -t "zygisksu" "Start watchdog"
|
||||||
|
/data/adb/ksu/resetprop ro.dalvik.vm.native.bridge libzygiskloader.so
|
||||||
|
exec "$MODDIR/bin/zygiskwd" >/dev/null 2>&1
|
||||||
6
module/src/module.prop
Normal file
6
module/src/module.prop
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
id=${moduleId}
|
||||||
|
name=${moduleName}
|
||||||
|
version=${versionName}
|
||||||
|
versionCode=${versionCode}
|
||||||
|
author=Nullptr
|
||||||
|
description=Run Zygisk on KernelSU.
|
||||||
5
module/src/post-fs-data.sh
Normal file
5
module/src/post-fs-data.sh
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
#!/system/bin/sh
|
||||||
|
|
||||||
|
MODDIR=${0%/*}
|
||||||
|
export NATIVE_BRIDGE=$(getprop ro.dalvik.vm.native.bridge)
|
||||||
|
unshare -m sh -c "$MODDIR/daemon.sh $@&"
|
||||||
1
module/src/service.sh
Normal file
1
module/src/service.sh
Normal file
@@ -0,0 +1 @@
|
|||||||
|
#!/system/bin/sh
|
||||||
51
module/src/verify.sh
Normal file
51
module/src/verify.sh
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
TMPDIR_FOR_VERIFY="$TMPDIR/.vunzip"
|
||||||
|
mkdir "$TMPDIR_FOR_VERIFY"
|
||||||
|
|
||||||
|
abort_verify() {
|
||||||
|
ui_print "*********************************************************"
|
||||||
|
ui_print "! $1"
|
||||||
|
ui_print "! This zip may be corrupted, please try downloading again"
|
||||||
|
abort "*********************************************************"
|
||||||
|
}
|
||||||
|
|
||||||
|
# extract <zip> <file> <target dir> <junk paths>
|
||||||
|
extract() {
|
||||||
|
zip=$1
|
||||||
|
file=$2
|
||||||
|
dir=$3
|
||||||
|
junk_paths=$4
|
||||||
|
[ -z "$junk_paths" ] && junk_paths=false
|
||||||
|
opts="-o"
|
||||||
|
[ $junk_paths = true ] && opts="-oj"
|
||||||
|
|
||||||
|
file_path=""
|
||||||
|
hash_path=""
|
||||||
|
if [ $junk_paths = true ]; then
|
||||||
|
file_path="$dir/$(basename "$file")"
|
||||||
|
hash_path="$TMPDIR_FOR_VERIFY/$(basename "$file").sha256"
|
||||||
|
else
|
||||||
|
file_path="$dir/$file"
|
||||||
|
hash_path="$TMPDIR_FOR_VERIFY/$file.sha256"
|
||||||
|
fi
|
||||||
|
|
||||||
|
unzip $opts "$zip" "$file" -d "$dir" >&2
|
||||||
|
[ -f "$file_path" ] || abort_verify "$file not exists"
|
||||||
|
|
||||||
|
unzip $opts "$zip" "$file.sha256" -d "$TMPDIR_FOR_VERIFY" >&2
|
||||||
|
[ -f "$hash_path" ] || abort_verify "$file.sha256 not exists"
|
||||||
|
|
||||||
|
(echo "$(cat "$hash_path") $file_path" | sha256sum -c -s -) || abort_verify "Failed to verify $file"
|
||||||
|
ui_print "- Verified $file" >&1
|
||||||
|
}
|
||||||
|
|
||||||
|
file="META-INF/com/google/android/update-binary"
|
||||||
|
file_path="$TMPDIR_FOR_VERIFY/$file"
|
||||||
|
hash_path="$file_path.sha256"
|
||||||
|
unzip -o "$ZIPFILE" "META-INF/com/google/android/*" -d "$TMPDIR_FOR_VERIFY" >&2
|
||||||
|
[ -f "$file_path" ] || abort_verify "$file not exists"
|
||||||
|
if [ -f "$hash_path" ]; then
|
||||||
|
(echo "$(cat "$hash_path") $file_path" | sha256sum -c -s -) || abort_verify "Failed to verify $file"
|
||||||
|
ui_print "- Verified $file" >&1
|
||||||
|
else
|
||||||
|
ui_print "- Download from Magisk app"
|
||||||
|
fi
|
||||||
@@ -17,26 +17,3 @@ cargo {
|
|||||||
val isDebug = gradle.startParameter.taskNames.any { it.toLowerCase().contains("debug") }
|
val isDebug = gradle.startParameter.taskNames.any { it.toLowerCase().contains("debug") }
|
||||||
profile = if (isDebug) "debug" else "release"
|
profile = if (isDebug) "debug" else "release"
|
||||||
}
|
}
|
||||||
|
|
||||||
androidComponents.onVariants { variant ->
|
|
||||||
val variantCapped = variant.name.capitalize()
|
|
||||||
task("build$variantCapped") {
|
|
||||||
group = "zygiskd"
|
|
||||||
cargo.targets?.forEach {
|
|
||||||
dependsOn("cargoBuild${it.capitalize()}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
task("push$variantCapped") {
|
|
||||||
group = "zygiskd"
|
|
||||||
dependsOn("cargoBuildArm", "cargoBuildArm64")
|
|
||||||
doLast {
|
|
||||||
val moduleDir = "/data/adb/ksu/modules/zygisksu"
|
|
||||||
exec { commandLine("adb", "push", "build/rustJniLibs/android/armeabi-v7a/zygiskd", "/data/local/tmp/zygiskd32") }
|
|
||||||
exec { commandLine("adb", "push", "build/rustJniLibs/android/arm64-v8a/zygiskd", "/data/local/tmp/zygiskd64") }
|
|
||||||
exec { commandLine("adb", "shell", "su", "-c", "mv /data/local/tmp/zygiskd32 $moduleDir/zygiskd32") }
|
|
||||||
exec { commandLine("adb", "shell", "su", "-c", "mv /data/local/tmp/zygiskd64 $moduleDir/zygiskd64") }
|
|
||||||
exec { commandLine("adb", "shell", "su", "-c", "ln -sf zygiskd64 $moduleDir/zygiskwd") }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -3,14 +3,12 @@ use num_enum::TryFromPrimitive;
|
|||||||
|
|
||||||
pub const PROP_NATIVE_BRIDGE: &str = "ro.dalvik.vm.native.bridge";
|
pub const PROP_NATIVE_BRIDGE: &str = "ro.dalvik.vm.native.bridge";
|
||||||
|
|
||||||
pub const SOCKET_PLACEHOLDER: &str = "placeholder123456";
|
pub const SOCKET_PLACEHOLDER: &str = "socket_placeholder";
|
||||||
|
|
||||||
pub const PATH_KSU_MODULE_DIR: &str = "/data/adb/ksu/modules";
|
pub const PATH_KSU_MODULE_DIR: &str = "/data/adb/ksu/modules";
|
||||||
pub const PATH_ZYGISKSU_DIR: &str = concatcp!(PATH_KSU_MODULE_DIR, "/zygisksu");
|
pub const PATH_ZYGISKSU_DIR: &str = concatcp!(PATH_KSU_MODULE_DIR, "/zygisksu");
|
||||||
pub const PATH_ZYGISKWD: &str = concatcp!(PATH_ZYGISKSU_DIR, "/zygiskwd");
|
pub const PATH_ZYGISKD32: &str = concatcp!(PATH_ZYGISKSU_DIR, "/bin/zygiskd32");
|
||||||
pub const PATH_ZYGISKD32: &str = concatcp!(PATH_ZYGISKSU_DIR, "/zygiskd32");
|
pub const PATH_ZYGISKD64: &str = concatcp!(PATH_ZYGISKSU_DIR, "/bin/zygiskd64");
|
||||||
pub const PATH_ZYGISKD64: &str = concatcp!(PATH_ZYGISKSU_DIR, "/zygiskd64");
|
|
||||||
pub const PATH_INJECTOR: &str = concatcp!(PATH_ZYGISKSU_DIR, "/libinjector.so");
|
|
||||||
pub const PATH_DAEMON_LOCK: &str = concatcp!(PATH_ZYGISKSU_DIR, "/zygiskd.lock");
|
pub const PATH_DAEMON_LOCK: &str = concatcp!(PATH_ZYGISKSU_DIR, "/zygiskd.lock");
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq, TryFromPrimitive)]
|
#[derive(Debug, Eq, PartialEq, TryFromPrimitive)]
|
||||||
@@ -18,7 +16,6 @@ pub const PATH_DAEMON_LOCK: &str = concatcp!(PATH_ZYGISKSU_DIR, "/zygiskd.lock")
|
|||||||
pub enum DaemonSocketAction {
|
pub enum DaemonSocketAction {
|
||||||
PingHeartbeat,
|
PingHeartbeat,
|
||||||
ReadNativeBridge,
|
ReadNativeBridge,
|
||||||
ReadInjector,
|
|
||||||
ReadModules,
|
ReadModules,
|
||||||
RequestCompanionSocket,
|
RequestCompanionSocket,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,8 +28,10 @@ pub fn get_native_bridge() -> String {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn restore_native_bridge() -> Result<()> {
|
pub fn restore_native_bridge() -> Result<()> {
|
||||||
let exec = format!("resetprop {} {}", constants::PROP_NATIVE_BRIDGE, get_native_bridge());
|
Command::new("/data/adb/ksu/resetprop")
|
||||||
Command::new(exec).spawn()?.wait()?;
|
.arg(constants::PROP_NATIVE_BRIDGE)
|
||||||
|
.arg(get_native_bridge())
|
||||||
|
.spawn()?.wait()?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ use std::sync::Arc;
|
|||||||
use std::thread;
|
use std::thread;
|
||||||
use std::ffi::c_void;
|
use std::ffi::c_void;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::os::fd::IntoRawFd;
|
|
||||||
use std::os::unix::{
|
use std::os::unix::{
|
||||||
net::{UnixListener, UnixStream},
|
net::{UnixListener, UnixStream},
|
||||||
prelude::AsRawFd,
|
prelude::AsRawFd,
|
||||||
@@ -57,7 +56,7 @@ pub fn start(is64: bool) -> Result<()> {
|
|||||||
let context = Arc::clone(&context);
|
let context = Arc::clone(&context);
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
if let Err(e) = handle_daemon_action(stream, &context) {
|
if let Err(e) = handle_daemon_action(stream, &context) {
|
||||||
log::warn!("Error handling daemon action: {e}");
|
log::warn!("Error handling daemon action: {}", e.backtrace());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -175,6 +174,7 @@ fn create_daemon_socket(is64: bool) -> Result<UnixListener> {
|
|||||||
let suffix = if is64 { "zygiskd64" } else { "zygiskd32" };
|
let suffix = if is64 { "zygiskd64" } else { "zygiskd32" };
|
||||||
let name = String::from(suffix) + constants::SOCKET_PLACEHOLDER;
|
let name = String::from(suffix) + constants::SOCKET_PLACEHOLDER;
|
||||||
let listener = utils::abstract_namespace_socket(&name)?;
|
let listener = utils::abstract_namespace_socket(&name)?;
|
||||||
|
log::debug!("Daemon socket: {name}");
|
||||||
Ok(listener)
|
Ok(listener)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -182,18 +182,12 @@ fn handle_daemon_action(mut stream: UnixStream, context: &Context) -> Result<()>
|
|||||||
let action = stream.read_u8()?;
|
let action = stream.read_u8()?;
|
||||||
match DaemonSocketAction::try_from(action) {
|
match DaemonSocketAction::try_from(action) {
|
||||||
Ok(DaemonSocketAction::PingHeartbeat) => {
|
Ok(DaemonSocketAction::PingHeartbeat) => {
|
||||||
// Do nothing
|
restore_native_bridge()?;
|
||||||
}
|
}
|
||||||
Ok(DaemonSocketAction::ReadNativeBridge) => {
|
Ok(DaemonSocketAction::ReadNativeBridge) => {
|
||||||
restore_native_bridge()?;
|
|
||||||
stream.write_usize(context.native_bridge.len())?;
|
stream.write_usize(context.native_bridge.len())?;
|
||||||
stream.write_all(context.native_bridge.as_bytes())?;
|
stream.write_all(context.native_bridge.as_bytes())?;
|
||||||
}
|
}
|
||||||
Ok(DaemonSocketAction::ReadInjector) => {
|
|
||||||
let so_path = PathBuf::from(constants::PATH_INJECTOR);
|
|
||||||
let memfd = create_memfd("injector", &so_path)?;
|
|
||||||
stream.send_fd(memfd.into_raw_fd())?;
|
|
||||||
}
|
|
||||||
Ok(DaemonSocketAction::ReadModules) => {
|
Ok(DaemonSocketAction::ReadModules) => {
|
||||||
stream.write_usize(context.modules.len())?;
|
stream.write_usize(context.modules.len())?;
|
||||||
for module in context.modules.iter() {
|
for module in context.modules.iter() {
|
||||||
|
|||||||
Reference in New Issue
Block a user