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 verName by extra("25.2-1")
|
||||
val moduleId by extra("zygisksu")
|
||||
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 androidTargetSdkVersion by extra(33)
|
||||
val androidCompileSdkVersion by extra(33)
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace zygiskd {
|
||||
|
||||
while (retry--) {
|
||||
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");
|
||||
sleep(1);
|
||||
}
|
||||
@@ -27,11 +27,13 @@ namespace zygiskd {
|
||||
}
|
||||
|
||||
bool PingHeartbeat() {
|
||||
LOGD("Daemon socket: %s", kZygiskSocket);
|
||||
auto fd = Connect(5);
|
||||
if (fd == -1) {
|
||||
PLOGE("Connect to zygiskd");
|
||||
return false;
|
||||
}
|
||||
socket_utils::write_u8(fd, (uint8_t) SocketAction::PingHeartBeat);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -45,16 +47,6 @@ namespace zygiskd {
|
||||
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> modules;
|
||||
auto fd = Connect(1);
|
||||
|
||||
@@ -75,9 +75,9 @@ namespace socket_utils {
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline T read_exact(int fd) {
|
||||
inline T read_exact_or(int fd, T fail) {
|
||||
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>
|
||||
@@ -86,11 +86,11 @@ namespace socket_utils {
|
||||
}
|
||||
|
||||
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) {
|
||||
auto len = read_exact<size_t>(fd);
|
||||
auto len = read_usize(fd);
|
||||
char buf[len + 1];
|
||||
buf[len] = '\0';
|
||||
xread(fd, buf, len);
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
# define LP_SELECT(lp32, lp64) lp32
|
||||
#endif
|
||||
|
||||
constexpr std::string_view kZygiskSocket = LP_SELECT("zygisk32", "zygisk64") "placeholder123456";
|
||||
constexpr std::string_view kZygiskSocket = LP_SELECT("zygiskd32", "zygiskd64") "socket_placeholder";
|
||||
|
||||
class UniqueFd {
|
||||
using Fd = int;
|
||||
@@ -52,9 +52,8 @@ namespace zygiskd {
|
||||
};
|
||||
|
||||
enum class SocketAction {
|
||||
HeartBeat,
|
||||
PingHeartBeat,
|
||||
ReadNativeBridge,
|
||||
ReadInjector,
|
||||
ReadModules,
|
||||
RequestCompanionSocket,
|
||||
};
|
||||
@@ -63,7 +62,5 @@ namespace zygiskd {
|
||||
|
||||
std::string ReadNativeBridge();
|
||||
|
||||
UniqueFd ReadInjector();
|
||||
|
||||
std::vector<Module> ReadModules();
|
||||
}
|
||||
|
||||
@@ -12,7 +12,8 @@ extern "C" [[gnu::visibility("default")]]
|
||||
uint8_t NativeBridgeItf[sizeof(NativeBridgeCallbacks<__ANDROID_API_R__>) * 2]{0};
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -31,9 +32,8 @@ void Constructor() {
|
||||
}
|
||||
|
||||
std::string_view cmdline = getprogname();
|
||||
if (std::any_of(
|
||||
kZygoteProcesses.begin(),
|
||||
kZygoteProcesses.end(),
|
||||
if (std::none_of(
|
||||
kZygoteProcesses.begin(), kZygoteProcesses.end(),
|
||||
[&](const char* p) { return cmdline == p; }
|
||||
)) {
|
||||
LOGW("Not started as zygote (cmdline=%s)", cmdline.data());
|
||||
@@ -49,10 +49,7 @@ void Constructor() {
|
||||
native_bridge = zygiskd::ReadNativeBridge();
|
||||
|
||||
LOGI("Load injector");
|
||||
auto injector = zygiskd::ReadInjector();
|
||||
if (injector != -1) break;
|
||||
|
||||
auto handle = DlopenMem(injector, RTLD_NOW);
|
||||
auto handle = DlopenExt(kInjector, RTLD_NOW);
|
||||
if (handle == nullptr) {
|
||||
LOGE("Failed to dlopen injector: %s", dlerror());
|
||||
break;
|
||||
@@ -60,12 +57,13 @@ void Constructor() {
|
||||
auto entry = dlsym(handle, "entry");
|
||||
if (entry == nullptr) {
|
||||
LOGE("Failed to dlsym injector entry: %s", dlerror());
|
||||
dlclose(handle);
|
||||
break;
|
||||
}
|
||||
reinterpret_cast<void (*)()>(entry)();
|
||||
reinterpret_cast<void (*)(void*)>(entry)(handle);
|
||||
} while (false);
|
||||
|
||||
if (native_bridge.empty()) return;
|
||||
if (native_bridge.empty() || native_bridge == "0") return;
|
||||
LOGI("Load original native bridge: %s", native_bridge.data());
|
||||
sOriginalBridge = dlopen(native_bridge.data(), RTLD_NOW);
|
||||
if (sOriginalBridge == nullptr) {
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
import java.security.MessageDigest
|
||||
import org.apache.tools.ant.filters.ReplaceTokens
|
||||
|
||||
plugins {
|
||||
id("com.android.library")
|
||||
}
|
||||
|
||||
val moduleId: String by rootProject.extra
|
||||
val moduleName: String by rootProject.extra
|
||||
val verCode: Int by rootProject.extra
|
||||
val verName: String by rootProject.extra
|
||||
|
||||
@@ -9,3 +14,95 @@ android.buildFeatures {
|
||||
androidResources = 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") }
|
||||
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 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_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, "/zygiskd32");
|
||||
pub const PATH_ZYGISKD64: &str = concatcp!(PATH_ZYGISKSU_DIR, "/zygiskd64");
|
||||
pub const PATH_INJECTOR: &str = concatcp!(PATH_ZYGISKSU_DIR, "/libinjector.so");
|
||||
pub const PATH_ZYGISKD32: &str = concatcp!(PATH_ZYGISKSU_DIR, "/bin/zygiskd32");
|
||||
pub const PATH_ZYGISKD64: &str = concatcp!(PATH_ZYGISKSU_DIR, "/bin/zygiskd64");
|
||||
pub const PATH_DAEMON_LOCK: &str = concatcp!(PATH_ZYGISKSU_DIR, "/zygiskd.lock");
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, TryFromPrimitive)]
|
||||
@@ -18,7 +16,6 @@ pub const PATH_DAEMON_LOCK: &str = concatcp!(PATH_ZYGISKSU_DIR, "/zygiskd.lock")
|
||||
pub enum DaemonSocketAction {
|
||||
PingHeartbeat,
|
||||
ReadNativeBridge,
|
||||
ReadInjector,
|
||||
ReadModules,
|
||||
RequestCompanionSocket,
|
||||
}
|
||||
|
||||
@@ -28,8 +28,10 @@ pub fn get_native_bridge() -> String {
|
||||
}
|
||||
|
||||
pub fn restore_native_bridge() -> Result<()> {
|
||||
let exec = format!("resetprop {} {}", constants::PROP_NATIVE_BRIDGE, get_native_bridge());
|
||||
Command::new(exec).spawn()?.wait()?;
|
||||
Command::new("/data/adb/ksu/resetprop")
|
||||
.arg(constants::PROP_NATIVE_BRIDGE)
|
||||
.arg(get_native_bridge())
|
||||
.spawn()?.wait()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@ use std::sync::Arc;
|
||||
use std::thread;
|
||||
use std::ffi::c_void;
|
||||
use std::fs;
|
||||
use std::os::fd::IntoRawFd;
|
||||
use std::os::unix::{
|
||||
net::{UnixListener, UnixStream},
|
||||
prelude::AsRawFd,
|
||||
@@ -57,7 +56,7 @@ pub fn start(is64: bool) -> Result<()> {
|
||||
let context = Arc::clone(&context);
|
||||
thread::spawn(move || {
|
||||
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 name = String::from(suffix) + constants::SOCKET_PLACEHOLDER;
|
||||
let listener = utils::abstract_namespace_socket(&name)?;
|
||||
log::debug!("Daemon socket: {name}");
|
||||
Ok(listener)
|
||||
}
|
||||
|
||||
@@ -182,18 +182,12 @@ fn handle_daemon_action(mut stream: UnixStream, context: &Context) -> Result<()>
|
||||
let action = stream.read_u8()?;
|
||||
match DaemonSocketAction::try_from(action) {
|
||||
Ok(DaemonSocketAction::PingHeartbeat) => {
|
||||
// Do nothing
|
||||
restore_native_bridge()?;
|
||||
}
|
||||
Ok(DaemonSocketAction::ReadNativeBridge) => {
|
||||
restore_native_bridge()?;
|
||||
stream.write_usize(context.native_bridge.len())?;
|
||||
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) => {
|
||||
stream.write_usize(context.modules.len())?;
|
||||
for module in context.modules.iter() {
|
||||
|
||||
Reference in New Issue
Block a user