You've already forked ZygiskNext
mirror of
https://github.com/Dr-TSNG/ZygiskNext.git
synced 2025-08-27 23:46:34 +00:00
Add zygiskd
This commit is contained in:
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
.gradle
|
||||
.idea
|
||||
.cxx
|
||||
build
|
||||
local.properties
|
||||
50
build.gradle.kts
Normal file
50
build.gradle.kts
Normal file
@@ -0,0 +1,50 @@
|
||||
import com.android.build.api.dsl.ApplicationExtension
|
||||
import com.android.build.gradle.BaseExtension
|
||||
|
||||
plugins {
|
||||
id("com.android.application") apply false
|
||||
id("com.android.library") apply false
|
||||
}
|
||||
|
||||
val verCode by extra(25207)
|
||||
val verName by extra("25.2-1")
|
||||
val androidMinSdkVersion by extra(29)
|
||||
val androidTargetSdkVersion by extra(33)
|
||||
val androidCompileSdkVersion by extra(33)
|
||||
val androidBuildToolsVersion by extra("33.0.1")
|
||||
val androidCompileNdkVersion by extra("25.1.8937393")
|
||||
val androidSourceCompatibility by extra(JavaVersion.VERSION_11)
|
||||
val androidTargetCompatibility by extra(JavaVersion.VERSION_11)
|
||||
|
||||
tasks.register("Delete", Delete::class) {
|
||||
delete(rootProject.buildDir)
|
||||
}
|
||||
|
||||
fun Project.configureBaseExtension() {
|
||||
extensions.findByType(BaseExtension::class)?.run {
|
||||
compileSdkVersion(androidCompileSdkVersion)
|
||||
ndkVersion = androidCompileNdkVersion
|
||||
buildToolsVersion = androidBuildToolsVersion
|
||||
|
||||
defaultConfig {
|
||||
minSdk = androidMinSdkVersion
|
||||
targetSdk = androidTargetSdkVersion
|
||||
versionCode = verCode
|
||||
versionName = verName
|
||||
}
|
||||
}
|
||||
|
||||
extensions.findByType(ApplicationExtension::class)?.lint {
|
||||
abortOnError = true
|
||||
checkReleaseBuilds = false
|
||||
}
|
||||
}
|
||||
|
||||
subprojects {
|
||||
plugins.withId("com.android.application") {
|
||||
configureBaseExtension()
|
||||
}
|
||||
plugins.withId("com.android.library") {
|
||||
configureBaseExtension()
|
||||
}
|
||||
}
|
||||
23
gradle.properties
Normal file
23
gradle.properties
Normal file
@@ -0,0 +1,23 @@
|
||||
# Project-wide Gradle settings.
|
||||
# IDE (e.g. Android Studio) users:
|
||||
# Gradle settings configured through the IDE *will override*
|
||||
# any settings specified in this file.
|
||||
# For more details on how to configure your build environment visit
|
||||
# http://www.gradle.org/docs/current/userguide/build_environment.html
|
||||
# Specifies the JVM arguments used for the daemon process.
|
||||
# The setting is particularly useful for tweaking memory settings.
|
||||
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
|
||||
# When configured, Gradle will run in incubating parallel mode.
|
||||
# This option should only be used with decoupled projects. More details, visit
|
||||
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
||||
# org.gradle.parallel=true
|
||||
# AndroidX package structure to make it clearer which packages are bundled with the
|
||||
# Android operating system, and which are packaged with your app's APK
|
||||
# https://developer.android.com/topic/libraries/support-library/androidx-rn
|
||||
android.useAndroidX=true
|
||||
# Kotlin code style for this project: "official" or "obsolete":
|
||||
kotlin.code.style=official
|
||||
# Enables namespacing of each library's R class so that its R class includes only the
|
||||
# resources declared in the library itself and none from the library's dependencies,
|
||||
# thereby reducing the size of the R class for that library
|
||||
android.nonTransitiveRClass=true
|
||||
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
5
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
5
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip
|
||||
distributionPath=wrapper/dists
|
||||
zipStorePath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
185
gradlew
vendored
Executable file
185
gradlew
vendored
Executable file
@@ -0,0 +1,185 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#
|
||||
# Copyright 2015 the original author or authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=`expr $i + 1`
|
||||
done
|
||||
case $i in
|
||||
0) set -- ;;
|
||||
1) set -- "$args0" ;;
|
||||
2) set -- "$args0" "$args1" ;;
|
||||
3) set -- "$args0" "$args1" "$args2" ;;
|
||||
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=`save "$@"`
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
89
gradlew.bat
vendored
Normal file
89
gradlew.bat
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
14
module/build.gradle.kts
Normal file
14
module/build.gradle.kts
Normal file
@@ -0,0 +1,14 @@
|
||||
plugins {
|
||||
id("com.android.application")
|
||||
}
|
||||
|
||||
val moduleName = "Zygisk On KernelSU"
|
||||
val moduleBaseId = "zygisksu"
|
||||
val authors = "Nullptr"
|
||||
|
||||
val verCode: Int by rootProject.extra
|
||||
val verName: String by rootProject.extra
|
||||
|
||||
android {
|
||||
namespace = "icu.nullptr.zygisksu"
|
||||
}
|
||||
27
settings.gradle.kts
Normal file
27
settings.gradle.kts
Normal file
@@ -0,0 +1,27 @@
|
||||
enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
|
||||
|
||||
pluginManagement {
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
gradlePluginPortal()
|
||||
}
|
||||
plugins {
|
||||
id("com.android.library") version "7.4.0"
|
||||
id("com.android.application") version "7.4.0"
|
||||
}
|
||||
}
|
||||
|
||||
dependencyResolutionManagement {
|
||||
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
|
||||
rootProject.name = "ZygiskOnKernelSU"
|
||||
include(
|
||||
":module",
|
||||
":zygiskd",
|
||||
)
|
||||
494
zygiskd/Cargo.lock
generated
Normal file
494
zygiskd/Cargo.lock
generated
Normal file
@@ -0,0 +1,494 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.7.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "android_log-sys"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85965b6739a430150bdd138e2374a98af0c3ee0d030b3bb7fc3bddff58d0102e"
|
||||
|
||||
[[package]]
|
||||
name = "android_logger"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "037f3e1da32ddba7770530e69258b742c15ad67bdf90e5f6b35f4b6db9a60eb7"
|
||||
dependencies = [
|
||||
"android_log-sys",
|
||||
"env_logger",
|
||||
"log",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.68"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2cb2f989d18dd141ab8ae82f64d1a8cdd37e0840f73a406896cf5e99502fab61"
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "const_format"
|
||||
version = "0.2.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7309d9b4d3d2c0641e018d449232f2e28f1b22933c137f157d3dbc14228b8c0e"
|
||||
dependencies = [
|
||||
"const_format_proc_macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "const_format_proc_macros"
|
||||
version = "0.2.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d897f47bf7270cf70d370f8f98c1abb6d2d4cf60a6845d30e05bfb90c6568650"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "env_logger"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0"
|
||||
dependencies = [
|
||||
"humantime",
|
||||
"is-terminal",
|
||||
"log",
|
||||
"regex",
|
||||
"termcolor",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.2.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1"
|
||||
dependencies = [
|
||||
"errno-dragonfly",
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "errno-dragonfly"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "humantime"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "1.9.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "io-lifetimes"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e7d6c6f8c91b4b9ed43484ad1a938e393caf35960fce7f82a040497207bd8e9e"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "is-terminal"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "28dfb6c8100ccc63462345b67d1bbc3679177c75ee4bf59bf29c8b1d110b8189"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"io-lifetimes",
|
||||
"rustix",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.139"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
||||
|
||||
[[package]]
|
||||
name = "memfd"
|
||||
version = "0.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b20a59d985586e4a5aef64564ac77299f8586d8be6cf9106a5a40207e8908efb"
|
||||
dependencies = [
|
||||
"rustix",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nix"
|
||||
version = "0.26.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"memoffset",
|
||||
"pin-utils",
|
||||
"static_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nom8"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae01545c9c7fc4486ab7debaf2aad7003ac19431791868fb2e8066df97fad2f8"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_enum"
|
||||
version = "0.5.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8d829733185c1ca374f17e52b762f24f535ec625d2cc1f070e34c8a9068f341b"
|
||||
dependencies = [
|
||||
"num_enum_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_enum_derive"
|
||||
version = "0.5.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2be1598bf1c313dcdd12092e3f1920f463462525a21b7b4e11b4168353d0123e"
|
||||
dependencies = [
|
||||
"proc-macro-crate",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.17.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66"
|
||||
|
||||
[[package]]
|
||||
name = "passfd"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "40937dff86b281e4025fe0614c744d961797552ccf8dc681a297e694db283ef3"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-utils"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-crate"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "66618389e4ec1c7afe67d51a9bf34ff9236480f8d51e7489b7d5ab0303c13f34"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"toml_edit",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.50"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ef7d57beacfaf2d8aee5937dab7b7f28de3cb8b1828479bb5de2a7106f2bae2"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "48aaa5748ba571fb95cd2c85c09f629215d3a6ece942baa100950af03a34f733"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848"
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.36.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d4fdebc4b395b7fbb9ab11e462e20ed9051e7b16e42d24042c776eca0ac81b03"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"errno",
|
||||
"io-lifetimes",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "static_assertions"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.107"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_datetime"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4553f467ac8e3d374bc9a177a26801e5d0f9b211aa1673fb137a403afd1c9cf5"
|
||||
|
||||
[[package]]
|
||||
name = "toml_edit"
|
||||
version = "0.18.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56c59d8dd7d0dcbc6428bf7aa2f0e823e26e43b3c9aca15bbc9475d23e5fa12b"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"nom8",
|
||||
"toml_datetime",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.42.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.42.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.42.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.42.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.42.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.42.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.42.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.42.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd"
|
||||
|
||||
[[package]]
|
||||
name = "zygiskd"
|
||||
version = "1.0.0"
|
||||
dependencies = [
|
||||
"android_logger",
|
||||
"anyhow",
|
||||
"const_format",
|
||||
"env_logger",
|
||||
"log",
|
||||
"memfd",
|
||||
"nix",
|
||||
"num_enum",
|
||||
"passfd",
|
||||
]
|
||||
21
zygiskd/Cargo.toml
Normal file
21
zygiskd/Cargo.toml
Normal file
@@ -0,0 +1,21 @@
|
||||
[package]
|
||||
name = "zygiskd"
|
||||
version = "1.0.0"
|
||||
edition = "2021"
|
||||
rust-version = "1.65"
|
||||
|
||||
[dependencies]
|
||||
android_logger = "0.12.0"
|
||||
anyhow = "1.0.68"
|
||||
const_format = "0.2.5"
|
||||
env_logger = "0.10.0"
|
||||
log = "0.4.17"
|
||||
memfd = "0.6.2"
|
||||
nix = "0.26.2"
|
||||
num_enum = "0.5.9"
|
||||
passfd = "0.1.5"
|
||||
|
||||
[profile.release]
|
||||
strip = true
|
||||
opt-level = "z"
|
||||
lto = true
|
||||
10
zygiskd/build.gradle.kts
Normal file
10
zygiskd/build.gradle.kts
Normal file
@@ -0,0 +1,10 @@
|
||||
plugins {
|
||||
id("com.android.library")
|
||||
}
|
||||
|
||||
val verCode: Int by rootProject.extra
|
||||
val verName: String by rootProject.extra
|
||||
|
||||
android {
|
||||
namespace = "icu.nullptr.zygisksu"
|
||||
}
|
||||
19
zygiskd/src/constants.rs
Normal file
19
zygiskd/src/constants.rs
Normal file
@@ -0,0 +1,19 @@
|
||||
use const_format::concatcp;
|
||||
use num_enum::TryFromPrimitive;
|
||||
|
||||
pub const PROP_NATIVE_BRIDGE: &str = "ro.dalvik.vm.native.bridge";
|
||||
|
||||
pub const KSU_MODULE_DIR: &str = "/data/adb/ksu/modules";
|
||||
pub const ZYGISKSU_DIR: &str = concatcp!(KSU_MODULE_DIR, "/zygisksu");
|
||||
pub const ZYGISKWD: &str = concatcp!(ZYGISKSU_DIR, "/zygiskwd");
|
||||
pub const ZYGISKD32: &str = concatcp!(ZYGISKSU_DIR, "/zygiskd32");
|
||||
pub const ZYGISKD64: &str = concatcp!(ZYGISKSU_DIR, "/zygiskd64");
|
||||
pub const DAEMON_LOCK: &str = concatcp!(ZYGISKSU_DIR, "/zygiskd.lock");
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, TryFromPrimitive)]
|
||||
#[repr(u8)]
|
||||
pub enum DaemonSocketAction {
|
||||
ReadNativeBridge,
|
||||
ReadModules,
|
||||
RequestCompanionSocket,
|
||||
}
|
||||
48
zygiskd/src/main.rs
Normal file
48
zygiskd/src/main.rs
Normal file
@@ -0,0 +1,48 @@
|
||||
#![allow(dead_code)]
|
||||
|
||||
mod watchdog;
|
||||
mod constants;
|
||||
mod zygisk;
|
||||
mod utils;
|
||||
|
||||
use anyhow::{anyhow, Result};
|
||||
use log::LevelFilter;
|
||||
use nix::libc;
|
||||
|
||||
fn init_android_logger(tag: &str) {
|
||||
android_logger::init_once(
|
||||
android_logger::Config::default()
|
||||
.with_max_level(LevelFilter::Trace)
|
||||
.with_tag(tag),
|
||||
);
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let process = std::env::args().next().unwrap();
|
||||
let process = process.split('/').last().unwrap();
|
||||
env_logger::init();
|
||||
// init_android_logger(process);
|
||||
match process {
|
||||
"zygiskwd" => {
|
||||
log::info!("Start zygisksu watchdog");
|
||||
// watchdog::check_permission()?;
|
||||
watchdog::ensure_single_instance()?;
|
||||
watchdog::spawn_daemon()?;
|
||||
}
|
||||
"zygiskd32" => {
|
||||
log::info!("Start zygiskd32");
|
||||
unsafe { libc::prctl(libc::PR_SET_PDEATHSIG, libc::SIGKILL); }
|
||||
zygisk::start(false)?;
|
||||
loop {}
|
||||
}
|
||||
"zygiskd64" => {
|
||||
log::info!("Start zygiskd64");
|
||||
unsafe { libc::prctl(libc::PR_SET_PDEATHSIG, libc::SIGKILL); }
|
||||
zygisk::start(true)?;
|
||||
}
|
||||
_ => return {
|
||||
Err(anyhow!("Unexpected process name: {process}"))
|
||||
},
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
58
zygiskd/src/utils.rs
Normal file
58
zygiskd/src/utils.rs
Normal file
@@ -0,0 +1,58 @@
|
||||
use crate::constants;
|
||||
use anyhow::Result;
|
||||
use nix::unistd::gettid;
|
||||
use std::{fs, io::{Read, Write}, os::unix::net::UnixStream, process::Command};
|
||||
|
||||
pub fn set_socket_create_context(context: &str) -> Result<()> {
|
||||
let path = "/proc/thread-self/attr/sockcreate";
|
||||
match fs::write(path, context) {
|
||||
Ok(_) => Ok(()),
|
||||
Err(_) => {
|
||||
let path = format!("/proc/self/task/{}/attr/sockcreate", gettid().as_raw());
|
||||
fs::write(path, context)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_native_bridge() -> String {
|
||||
std::env::var("NATIVE_BRIDGE").unwrap_or("0".to_string())
|
||||
}
|
||||
|
||||
pub fn restore_native_bridge() -> Result<()> {
|
||||
let exec = format!("resetprop {} {}", constants::PROP_NATIVE_BRIDGE, get_native_bridge());
|
||||
Command::new(exec).spawn()?.wait()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub trait UnixStreamExt {
|
||||
fn read_u8(&mut self) -> Result<u8>;
|
||||
fn read_u32(&mut self) -> Result<u32>;
|
||||
fn read_usize(&mut self) -> Result<usize>;
|
||||
fn write_usize(&mut self, value: usize) -> Result<()>;
|
||||
}
|
||||
|
||||
impl UnixStreamExt for UnixStream {
|
||||
fn read_u8(&mut self) -> Result<u8> {
|
||||
let mut buf = [0u8; 1];
|
||||
self.read_exact(&mut buf)?;
|
||||
Ok(buf[0])
|
||||
}
|
||||
|
||||
fn read_u32(&mut self) -> Result<u32> {
|
||||
let mut buf = [0u8; 4];
|
||||
self.read_exact(&mut buf)?;
|
||||
Ok(u32::from_le_bytes(buf))
|
||||
}
|
||||
|
||||
fn read_usize(&mut self) -> Result<usize> {
|
||||
let mut buf = [0u8; 8];
|
||||
self.read_exact(&mut buf)?;
|
||||
Ok(usize::from_le_bytes(buf))
|
||||
}
|
||||
|
||||
fn write_usize(&mut self, value: usize) -> Result<()> {
|
||||
self.write_all(&value.to_ne_bytes())?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
70
zygiskd/src/watchdog.rs
Normal file
70
zygiskd/src/watchdog.rs
Normal file
@@ -0,0 +1,70 @@
|
||||
use crate::constants;
|
||||
use anyhow::{anyhow, Result};
|
||||
use nix::fcntl::{flock, FlockArg};
|
||||
use nix::unistd::{getgid, getuid};
|
||||
use std::os::unix::prelude::AsRawFd;
|
||||
use std::process::{Child, Command};
|
||||
use std::sync::mpsc;
|
||||
use std::{fs, thread};
|
||||
|
||||
static mut LOCK_FILE: Option<fs::File> = None;
|
||||
|
||||
pub fn check_permission() -> Result<()> {
|
||||
log::info!("Check permission");
|
||||
let uid = getuid();
|
||||
if uid.as_raw() != 0 {
|
||||
return Err(anyhow!("UID is not 0"));
|
||||
}
|
||||
|
||||
let gid = getgid();
|
||||
if gid.as_raw() != 0 {
|
||||
return Err(anyhow!("GID is not 0"));
|
||||
}
|
||||
|
||||
let context = fs::read_to_string("/proc/self/attr/current")?;
|
||||
if context != "u:r:su:s0" {
|
||||
return Err(anyhow!("SELinux context is not u:r:su:s0"));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn ensure_single_instance() -> Result<()> {
|
||||
log::info!("Ensure single instance");
|
||||
let metadata = fs::metadata(constants::ZYGISKSU_DIR);
|
||||
if metadata.is_err() || !metadata.unwrap().is_dir() {
|
||||
return Err(anyhow!("Zygisksu is not installed"));
|
||||
}
|
||||
unsafe {
|
||||
match fs::File::create(constants::DAEMON_LOCK) {
|
||||
Ok(file) => LOCK_FILE = Some(file),
|
||||
Err(e) => return Err(anyhow!("Failed to open lock file: {e}")),
|
||||
};
|
||||
let fd = LOCK_FILE.as_ref().unwrap().as_raw_fd();
|
||||
if let Err(e) = flock(fd, FlockArg::LockExclusiveNonblock) {
|
||||
return Err(anyhow!(
|
||||
"Failed to acquire lock: {e}. Maybe another instance is running?"
|
||||
));
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn spawn_daemon() -> Result<()> {
|
||||
let daemon32 = Command::new(constants::ZYGISKD32).spawn()?;
|
||||
let daemon64 = Command::new(constants::ZYGISKD64).spawn()?;
|
||||
let (sender, receiver) = mpsc::channel();
|
||||
let spawn = |mut daemon: Child| {
|
||||
let sender = sender.clone();
|
||||
thread::spawn(move || {
|
||||
let result = daemon.wait().unwrap();
|
||||
log::error!("Daemon process {} died: {}", daemon.id(), result);
|
||||
drop(daemon);
|
||||
sender.send(()).unwrap();
|
||||
});
|
||||
};
|
||||
spawn(daemon32);
|
||||
spawn(daemon64);
|
||||
let _ = receiver.recv();
|
||||
Err(anyhow!("Daemon process died"))
|
||||
}
|
||||
240
zygiskd/src/zygisk.rs
Normal file
240
zygiskd/src/zygisk.rs
Normal file
@@ -0,0 +1,240 @@
|
||||
use crate::constants::DaemonSocketAction;
|
||||
use crate::utils::{restore_native_bridge, UnixStreamExt};
|
||||
use crate::{constants, utils};
|
||||
use anyhow::{anyhow, Result};
|
||||
use memfd::Memfd;
|
||||
use nix::{
|
||||
libc::{self, dlsym},
|
||||
unistd::getppid,
|
||||
};
|
||||
use passfd::FdPassingExt;
|
||||
use std::cell::Cell;
|
||||
use std::io::Write;
|
||||
use std::sync::Arc;
|
||||
use std::thread;
|
||||
use std::{
|
||||
ffi::c_void,
|
||||
fs,
|
||||
os::unix::{
|
||||
net::{UnixListener, UnixStream},
|
||||
prelude::AsRawFd,
|
||||
},
|
||||
path::PathBuf,
|
||||
};
|
||||
|
||||
type ZygiskCompanionEntryFn = unsafe extern "C" fn(i32);
|
||||
|
||||
struct Module {
|
||||
name: String,
|
||||
memfd: Memfd,
|
||||
companion_entry: Option<ZygiskCompanionEntryFn>,
|
||||
}
|
||||
|
||||
struct Context {
|
||||
native_bridge: String,
|
||||
modules: Arc<Vec<Module>>,
|
||||
stream: Cell<UnixStream>,
|
||||
}
|
||||
|
||||
pub fn start(is64: bool) -> Result<()> {
|
||||
// check_parent()?;
|
||||
let arch = get_arch(is64)?;
|
||||
log::debug!("Daemon architecture: {arch}");
|
||||
|
||||
log::info!("Load modules");
|
||||
let modules = load_modules(arch)?;
|
||||
|
||||
log::info!("Create socket");
|
||||
let listener = create_daemon_socket(is64)?;
|
||||
|
||||
log::info!("Waiting for connection");
|
||||
let (stream, _) = listener.accept()?;
|
||||
drop(listener);
|
||||
|
||||
let context = Context {
|
||||
native_bridge: utils::get_native_bridge(),
|
||||
modules: Arc::new(modules),
|
||||
stream: Cell::new(stream),
|
||||
};
|
||||
|
||||
log::info!("Connection established");
|
||||
restore_native_bridge()?;
|
||||
handle_daemon_actions(context)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn check_parent() -> Result<()> {
|
||||
let parent = fs::read_link(format!("/proc/{}/exe", getppid().as_raw()))?;
|
||||
let parent = parent.file_name().unwrap().to_str().unwrap();
|
||||
if parent != constants::ZYGISKWD {
|
||||
return Err(anyhow!("zygiskd is not started by watchdog"));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_arch(is64: bool) -> Result<&'static str> {
|
||||
// let output = Command::new("getprop ro.product.cpu.abi").output()?;
|
||||
// let system_arch = String::from_utf8(output.stdout)?;
|
||||
let system_arch = "x86_64"; // DEBUGGING
|
||||
let is_arm = system_arch.contains("arm");
|
||||
let is_x86 = system_arch.contains("x86");
|
||||
if is64 {
|
||||
match (is_arm, is_x86) {
|
||||
(true, _) => Ok("arm64-v8a"),
|
||||
(_, true) => Ok("x86_64"),
|
||||
_ => Err(anyhow!("Unsupported system architecture: {}", system_arch)),
|
||||
}
|
||||
} else {
|
||||
match (is_arm, is_x86) {
|
||||
(true, _) => Ok("armeabi-v7a"),
|
||||
(_, true) => Ok("x86"),
|
||||
_ => Err(anyhow!("Unsupported system architecture: {}", system_arch)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn load_modules(arch: &str) -> Result<Vec<Module>> {
|
||||
let mut modules = Vec::new();
|
||||
let dir = match fs::read_dir(constants::KSU_MODULE_DIR) {
|
||||
Ok(dir) => dir,
|
||||
Err(e) => {
|
||||
log::warn!("Failed reading modules directory: {}", e);
|
||||
return Ok(modules);
|
||||
}
|
||||
};
|
||||
for entry_result in dir.into_iter() {
|
||||
let entry = entry_result?;
|
||||
let name = entry.file_name().into_string().unwrap();
|
||||
let so_path = entry.path().join(format!("zygisk/{arch}.so"));
|
||||
if !so_path.exists() {
|
||||
continue;
|
||||
}
|
||||
log::info!(" Loading module `{name}`...");
|
||||
let memfd = match create_memfd(&name, &so_path) {
|
||||
Ok(memfd) => memfd,
|
||||
Err(e) => {
|
||||
log::warn!(" Failed to create memfd for `{name}`: {e}");
|
||||
continue;
|
||||
}
|
||||
};
|
||||
let companion_entry = match preload_module(&memfd) {
|
||||
Ok(companion_entry) => companion_entry,
|
||||
Err(e) => {
|
||||
log::warn!(" Failed to preload `{name}`: {e}");
|
||||
continue;
|
||||
}
|
||||
};
|
||||
let module = Module {
|
||||
name,
|
||||
memfd,
|
||||
companion_entry,
|
||||
};
|
||||
modules.push(module);
|
||||
}
|
||||
|
||||
Ok(modules)
|
||||
}
|
||||
|
||||
fn create_memfd(name: &str, so_path: &PathBuf) -> Result<memfd::Memfd> {
|
||||
let opts = memfd::MemfdOptions::default().allow_sealing(true);
|
||||
let memfd = opts.create(name)?;
|
||||
|
||||
let file = fs::File::open(so_path)?;
|
||||
let mut reader = std::io::BufReader::new(file);
|
||||
let mut writer = memfd.as_file();
|
||||
std::io::copy(&mut reader, &mut writer)?;
|
||||
|
||||
let mut seals = memfd::SealsHashSet::new();
|
||||
seals.insert(memfd::FileSeal::SealShrink);
|
||||
seals.insert(memfd::FileSeal::SealGrow);
|
||||
seals.insert(memfd::FileSeal::SealWrite);
|
||||
seals.insert(memfd::FileSeal::SealSeal);
|
||||
memfd.add_seals(&seals)?;
|
||||
|
||||
Ok(memfd)
|
||||
}
|
||||
|
||||
fn preload_module(memfd: &Memfd) -> Result<Option<ZygiskCompanionEntryFn>> {
|
||||
unsafe {
|
||||
let path = format!("/proc/self/fd/{}", memfd.as_raw_fd());
|
||||
let filename = std::ffi::CString::new(path)?;
|
||||
let handle = libc::dlopen(filename.as_ptr(), libc::RTLD_LAZY);
|
||||
if handle.is_null() {
|
||||
let e = std::ffi::CStr::from_ptr(libc::dlerror())
|
||||
.to_string_lossy()
|
||||
.into_owned();
|
||||
return Err(anyhow!("dlopen failed: {}", e));
|
||||
}
|
||||
let symbol = std::ffi::CString::new("zygisk_companion_entry")?;
|
||||
let entry = dlsym(handle, symbol.as_ptr());
|
||||
if entry.is_null() {
|
||||
return Ok(None);
|
||||
}
|
||||
let fnptr = std::mem::transmute::<*mut c_void, ZygiskCompanionEntryFn>(entry);
|
||||
Ok(Some(fnptr))
|
||||
}
|
||||
}
|
||||
|
||||
fn create_daemon_socket(is64: bool) -> Result<UnixListener> {
|
||||
utils::set_socket_create_context("u:r:zygote:s0")?;
|
||||
let socket_name = if is64 { "zygiskd64" } else { "zygiskd32" };
|
||||
let listener = UnixListener::bind(socket_name)?;
|
||||
Ok(listener)
|
||||
}
|
||||
|
||||
fn handle_daemon_actions(mut context: Context) -> Result<()> {
|
||||
let stream = context.stream.get_mut();
|
||||
loop {
|
||||
let action = stream.read_u8()?;
|
||||
match DaemonSocketAction::try_from(action) {
|
||||
Ok(DaemonSocketAction::ReadNativeBridge) => {
|
||||
stream.write_usize(context.native_bridge.len())?;
|
||||
stream.write_all(context.native_bridge.as_bytes())?;
|
||||
}
|
||||
Ok(DaemonSocketAction::ReadModules) => {
|
||||
stream.write_usize(context.modules.len())?;
|
||||
for module in context.modules.iter() {
|
||||
stream.write_usize(module.name.len())?;
|
||||
stream.write_all(module.name.as_bytes())?;
|
||||
stream.send_fd(module.memfd.as_raw_fd())?;
|
||||
}
|
||||
}
|
||||
Ok(DaemonSocketAction::RequestCompanionSocket) => {
|
||||
let (server, client) = UnixStream::pair()?;
|
||||
stream.send_fd(client.as_raw_fd())?;
|
||||
let modules_ref = Arc::clone(&context.modules);
|
||||
thread::spawn(move || {
|
||||
if let Err(e) = create_companion(server, modules_ref.as_ref()) {
|
||||
log::warn!("Companion thread exited: {e}");
|
||||
}
|
||||
});
|
||||
}
|
||||
Err(_) => {
|
||||
return Err(anyhow!("Invalid action code: {action}"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn create_companion(mut server: UnixStream, modules: &Vec<Module>) -> Result<()> {
|
||||
loop {
|
||||
let index = match server.read_usize() {
|
||||
Ok(index) => index,
|
||||
Err(_) => return Ok(()), // EOF
|
||||
};
|
||||
let module = &modules[index];
|
||||
log::debug!("New companion request from module {}", module.name);
|
||||
|
||||
unsafe {
|
||||
match module.companion_entry {
|
||||
Some(entry) => {
|
||||
let (sock_app, sock_companion) = UnixStream::pair()?;
|
||||
server.send_fd(sock_app.as_raw_fd())?;
|
||||
entry(sock_companion.as_raw_fd());
|
||||
}
|
||||
None => (),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user