├── .gitignore
├── README.md
├── build.bat
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── local.properties
├── module.gradle
├── module
├── build.gradle
└── src
│ └── main
│ ├── AndroidManifest.xml
│ └── cpp
│ ├── CMakeLists.txt
│ ├── example.cpp
│ └── zygisk.hpp
├── settings.gradle
└── template
└── magisk_module
├── .gitattributes
├── META-INF
└── com
│ └── google
│ └── android
│ ├── update-binary
│ └── updater-script
├── README.md
├── customize.sh
├── module.prop
├── service.sh
├── system
├── etc
│ └── minitool.prop
├── lib
│ ├── libminitool.config.so
│ └── libminitool.so
└── lib64
│ ├── libminitool.config.so
│ └── libminitool.so
├── uninstall.sh
└── verify.sh
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | .idea
4 | /.idea/caches/build_file_checksums.ser
5 | /.idea/libraries
6 | /.idea/modules.xml
7 | /.idea/workspace.xml
8 | .DS_Store
9 | /build
10 | /captures
11 | .externalNativeBuild
12 | .cxx
13 | build
14 | out
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Zygisk-FridaGadget
2 |
3 | ## 说明
4 |
5 | 这是一个根据 zygisk模块 开发的 FridaGadget
6 |
7 | ## 构建
8 |
9 | 修改 local.properties 为自己的sdk路径
10 |
11 | 修改 /module/build.gradle 里面的 ndk 和 cmake 版本为自己的版本
12 |
13 | 需要配置jdk11的环境
14 |
15 | 构建完的文件在 /out 文件夹里
16 |
17 | 把生成zip传到手机里就可以用 magisk 安装了
18 |
19 | ## Zygisk-ModuleTemplate
20 |
21 | [zygisk-module-sample](https://github.com/topjohnwu/zygisk-module-sample)
22 |
23 | https://forum.xda-developers.com/t/discussion-magisk-the-age-of-zygisk.4393877/
24 |
25 | ## Others
26 |
27 | You can install it in Magisk24.0+
28 |
29 | After reboot
30 |
31 | You can find log in logcat
32 |
33 | ```
34 | logcat | grep Frida
35 | netstat -tunlp | grep 26000
36 |
37 | cd /data/local/tmp
38 | echo "com.xxx.xxx" > app.list
39 |
40 | adb forward tcp:27042 tcp:26000
41 |
42 | frida-ps -Ra
43 | frida -R gadget
44 |
45 | objection -Ng gadget explore
46 | ```
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/build.bat:
--------------------------------------------------------------------------------
1 | gradlew :module:assembleRelease
2 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'idea'
3 | }
4 |
5 | idea.module {
6 | excludeDirs += file('out')
7 | resourceDirs += file('template')
8 | resourceDirs += file('scripts')
9 | }
10 |
11 | ext {
12 | min_sdk = 23
13 | target_sdk = 31
14 |
15 | outDir = file("$rootDir/out")
16 | }
17 |
18 | task clean(type: Delete) {
19 | delete rootProject.buildDir, outDir
20 | }
21 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | # org.gradle.jvmargs=-Xmx1536m
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 | # AndroidX package structure to make it clearer which packages are bundled with the
15 | # Android operating system, and which are packaged with your app's APK
16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
17 | android.useAndroidX=true
18 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jussi-sky/Zygisk-FridaGadget/3f1d7cc825bf375cf2f97900a53e2e530694fb5f/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Mon Jul 12 21:05:17 CST 2021
2 | distributionBase=GRADLE_USER_HOME
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-all.zip
4 | distributionPath=wrapper/dists
5 | zipStorePath=wrapper/dists
6 | zipStoreBase=GRADLE_USER_HOME
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Attempt to set APP_HOME
10 | # Resolve links: $0 may be a link
11 | PRG="$0"
12 | # Need this for relative symlinks.
13 | while [ -h "$PRG" ] ; do
14 | ls=`ls -ld "$PRG"`
15 | link=`expr "$ls" : '.*-> \(.*\)$'`
16 | if expr "$link" : '/.*' > /dev/null; then
17 | PRG="$link"
18 | else
19 | PRG=`dirname "$PRG"`"/$link"
20 | fi
21 | done
22 | SAVED="`pwd`"
23 | cd "`dirname \"$PRG\"`/" >/dev/null
24 | APP_HOME="`pwd -P`"
25 | cd "$SAVED" >/dev/null
26 |
27 | APP_NAME="Gradle"
28 | APP_BASE_NAME=`basename "$0"`
29 |
30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 | DEFAULT_JVM_OPTS=""
32 |
33 | # Use the maximum available, or set MAX_FD != -1 to use that value.
34 | MAX_FD="maximum"
35 |
36 | warn () {
37 | echo "$*"
38 | }
39 |
40 | die () {
41 | echo
42 | echo "$*"
43 | echo
44 | exit 1
45 | }
46 |
47 | # OS specific support (must be 'true' or 'false').
48 | cygwin=false
49 | msys=false
50 | darwin=false
51 | nonstop=false
52 | case "`uname`" in
53 | CYGWIN* )
54 | cygwin=true
55 | ;;
56 | Darwin* )
57 | darwin=true
58 | ;;
59 | MINGW* )
60 | msys=true
61 | ;;
62 | NONSTOP* )
63 | nonstop=true
64 | ;;
65 | esac
66 |
67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68 |
69 | # Determine the Java command to use to start the JVM.
70 | if [ -n "$JAVA_HOME" ] ; then
71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 | # IBM's JDK on AIX uses strange locations for the executables
73 | JAVACMD="$JAVA_HOME/jre/sh/java"
74 | else
75 | JAVACMD="$JAVA_HOME/bin/java"
76 | fi
77 | if [ ! -x "$JAVACMD" ] ; then
78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79 |
80 | Please set the JAVA_HOME variable in your environment to match the
81 | location of your Java installation."
82 | fi
83 | else
84 | JAVACMD="java"
85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86 |
87 | Please set the JAVA_HOME variable in your environment to match the
88 | location of your Java installation."
89 | fi
90 |
91 | # Increase the maximum file descriptors if we can.
92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 | MAX_FD_LIMIT=`ulimit -H -n`
94 | if [ $? -eq 0 ] ; then
95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 | MAX_FD="$MAX_FD_LIMIT"
97 | fi
98 | ulimit -n $MAX_FD
99 | if [ $? -ne 0 ] ; then
100 | warn "Could not set maximum file descriptor limit: $MAX_FD"
101 | fi
102 | else
103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 | fi
105 | fi
106 |
107 | # For Darwin, add options to specify how the application appears in the dock
108 | if $darwin; then
109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 | fi
111 |
112 | # For Cygwin, switch paths to Windows format before running java
113 | if $cygwin ; then
114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 | JAVACMD=`cygpath --unix "$JAVACMD"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Escape application args
158 | save () {
159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 | echo " "
161 | }
162 | APP_ARGS=$(save "$@")
163 |
164 | # Collect all arguments for the java command, following the shell quoting and substitution rules
165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166 |
167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 | cd "$(dirname "$0")"
170 | fi
171 |
172 | exec "$JAVACMD" "$@"
173 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/local.properties:
--------------------------------------------------------------------------------
1 | ## This file must *NOT* be checked into Version Control Systems,
2 | # as it contains information specific to your local configuration.
3 | #
4 | # Location of the SDK. This is only used by Gradle.
5 | # For customization when using a Version Control System, please read the
6 | # header note.
7 | #Fri Apr 15 12:33:51 CST 2022
8 | sdk.dir=E\:\\Android\\Sdk
9 | ndk.dir=E\:\\Android\\Sdk\\ndk\\23.1.7779620
10 |
--------------------------------------------------------------------------------
/module.gradle:
--------------------------------------------------------------------------------
1 | ext {
2 | /*
3 | This name will be used in the name of the so file ("lib${moduleLibraryName}.so").
4 | */
5 | moduleLibraryName = "jussigad"
6 | /*
7 | Magisk module ID
8 | Since Magisk use it to distinguish different modules, you should never change it.
9 |
10 | Note, the older version of the template uses '-' instead of '_', if your are upgrading from
11 | the older version, please pay attention.
12 | */
13 | magiskModuleId = "Zygisk-FridaGadget"
14 |
15 | moduleName = "Zygisk-FridaGadget"
16 | moduleAuthor = "Jussi"
17 | moduleDescription = "zygisk module frida gadget"
18 | moduleVersion = "v14.2.2"
19 | moduleVersionCode = 26
20 | }
21 |
--------------------------------------------------------------------------------
/module/build.gradle:
--------------------------------------------------------------------------------
1 | import org.apache.tools.ant.filters.FixCrLfFilter
2 | import org.apache.tools.ant.filters.ReplaceTokens
3 |
4 | import java.security.MessageDigest
5 |
6 | plugins {
7 | id 'com.android.library'
8 | }
9 |
10 | apply from: file(rootProject.file('module.gradle'))
11 |
12 | android {
13 | compileSdk target_sdk
14 | defaultConfig {
15 | minSdk min_sdk
16 | targetSdk target_sdk
17 | externalNativeBuild {
18 | cmake {
19 | arguments "-DMODULE_NAME:STRING=$moduleLibraryName";
20 | }
21 | }
22 | }
23 | buildFeatures {
24 | prefab false
25 | }
26 | externalNativeBuild {
27 | cmake {
28 | path "src/main/cpp/CMakeLists.txt"
29 | // version "3.20.3"
30 | }
31 | }
32 | ndkVersion '23.1.7779620'
33 | }
34 |
35 | afterEvaluate {
36 | android.libraryVariants.forEach { variant ->
37 | def variantCapped = variant.name.capitalize()
38 | def variantLowered = variant.name.toLowerCase()
39 |
40 | def zipName = "${magiskModuleId.replace('_', '-')}-${moduleVersion}-${variantLowered}.zip"
41 | def magiskDir = file("$outDir/magisk_module_$variantLowered")
42 |
43 | task("prepareMagiskFiles${variantCapped}", type: Sync) {
44 | dependsOn("assemble$variantCapped")
45 |
46 | def templatePath = "$rootDir/template/magisk_module"
47 |
48 | into magiskDir
49 | from(templatePath) {
50 | exclude 'module.prop'
51 | }
52 | from(templatePath) {
53 | include 'module.prop'
54 | expand([
55 | id : magiskModuleId,
56 | name : moduleName,
57 | version : moduleVersion,
58 | versionCode: moduleVersionCode.toString(),
59 | author : moduleAuthor,
60 | description: moduleDescription,
61 | ])
62 | filter(FixCrLfFilter.class,
63 | eol: FixCrLfFilter.CrLf.newInstance("lf"))
64 | }
65 | from("$buildDir/intermediates/stripped_native_libs/$variantLowered/out/lib") {
66 | into 'lib'
67 | }
68 | doLast {
69 | fileTree("$magiskDir").visit { f ->
70 | if (f.directory) return
71 | if (f.file.name == '.gitattributes') return
72 |
73 | def md = MessageDigest.getInstance("SHA-256")
74 | f.file.eachByte 4096, { bytes, size ->
75 | md.update(bytes, 0, size)
76 | }
77 | file(f.file.path + ".sha256sum").text = md.digest().encodeHex()
78 | }
79 | }
80 | }
81 |
82 | task("zip${variantCapped}", type: Zip) {
83 | dependsOn("prepareMagiskFiles${variantCapped}")
84 | from magiskDir
85 | archiveName zipName
86 | destinationDir outDir
87 | }
88 |
89 | task("push${variantCapped}", type: Exec) {
90 | dependsOn("zip${variantCapped}")
91 | workingDir outDir
92 | commandLine android.adbExecutable, "push", zipName, "/data/local/tmp/"
93 | }
94 |
95 | task("flash${variantCapped}", type: Exec) {
96 | dependsOn("push${variantCapped}")
97 | commandLine android.adbExecutable, "shell", "su", "-c",
98 | "magisk --install-module /data/local/tmp/${zipName}"
99 | }
100 |
101 | task("flashAndReboot${variantCapped}", type: Exec) {
102 | dependsOn("flash${variantCapped}")
103 | commandLine android.adbExecutable, "shell", "reboot"
104 | }
105 |
106 | variant.assembleProvider.get().finalizedBy("zip${variantCapped}")
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/module/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/module/src/main/cpp/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.4.1)
2 |
3 | if (NOT DEFINED MODULE_NAME)
4 | message(FATAL_ERROR "MODULE_NAME is not set")
5 | else ()
6 | project(${MODULE_NAME})
7 | endif ()
8 |
9 |
10 | message("Build type: ${CMAKE_BUILD_TYPE}")
11 |
12 | set(CMAKE_CXX_STANDARD 17)
13 |
14 | set(LINKER_FLAGS "-ffixed-x18 -Wl,--hash-style=both")
15 | set(C_FLAGS "-Werror=format -fdata-sections -ffunction-sections")
16 | set(CXX_FLAGS "${CXX_FLAGS} -fno-exceptions -fno-rtti")
17 |
18 | if (NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
19 | set(C_FLAGS "${C_FLAGS} -O2 -fvisibility=hidden -fvisibility-inlines-hidden")
20 | set(LINKER_FLAGS "${LINKER_FLAGS} -Wl,-exclude-libs,ALL -Wl,--gc-sections -Wl,--strip-all")
21 | else ()
22 | set(C_FLAGS "${C_FLAGS} -O0")
23 | endif ()
24 |
25 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${C_FLAGS}")
26 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${C_FLAGS} ${CXX_FLAGS}")
27 |
28 | set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${LINKER_FLAGS}")
29 | set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${LINKER_FLAGS}")
30 |
31 | # find_package(REQUIRED CONFIG)
32 |
33 | include_directories(include)
34 |
35 | add_library(${MODULE_NAME} SHARED example.cpp zygisk.hpp)
36 | target_link_libraries(${MODULE_NAME} log)
37 |
38 | if (NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
39 | add_custom_command(TARGET ${MODULE_NAME} POST_BUILD
40 | COMMAND ${CMAKE_STRIP} --strip-all --remove-section=.comment "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/lib${MODULE_NAME}.so")
41 | endif ()
42 |
--------------------------------------------------------------------------------
/module/src/main/cpp/example.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include "zygisk.hpp"
11 | #include
12 |
13 | using zygisk::Api;
14 | using zygisk::AppSpecializeArgs;
15 | using zygisk::ServerSpecializeArgs;
16 |
17 | #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, "Zygisk-FridaGadget", __VA_ARGS__)
18 |
19 | #ifdef __LP64__
20 | constexpr const char* kZygoteNiceName = "zygote64";
21 | constexpr const char* nextLoadSo = "/system/lib64/libminitool.so";
22 | //constexpr const char* nextLoadSo = "/data/data/com.ford.fordpasscn/libfridagadget64.so";
23 | #else
24 | constexpr const char* kZygoteNiceName = "zygote";
25 | constexpr const char* nextLoadSo = "/system/lib/libminitool.so";
26 | #endif
27 |
28 | static char nice_process_name[256] = {0};
29 | static char package_name[256] = {0};
30 |
31 | static bool isApp(int uid) {
32 | if (uid < 0) {
33 | return false;
34 | }
35 | int appId = uid % 100000;
36 |
37 | // limit only regular app, or strange situation will happen, such as zygote process not start (dead for no reason and leave no clues?)
38 | // https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r8/core/java/android/os/UserHandle.java#151
39 | return appId >= 10000 && appId <= 19999;
40 | }
41 |
42 | static void* gadget(void* args){
43 |
44 | sleep(10);
45 | void *handle = dlopen(nextLoadSo, RTLD_LAZY);
46 | if (!handle) {
47 | LOGD(" %s loaded in libgadget error %s", nice_process_name, dlerror());
48 | } else {
49 | LOGD(" %s load ' %s ' success ", nice_process_name,nextLoadSo);
50 | }
51 | return nullptr;
52 | }
53 |
54 | class MyModule : public zygisk::ModuleBase {
55 |
56 | private:
57 | Api *api;
58 | JNIEnv *env;
59 | jint my_uid = 0;
60 |
61 | public:
62 |
63 | void onLoad(Api *api, JNIEnv *env) override {
64 | this->api = api;
65 | this->env = env;
66 |
67 | }
68 |
69 | void preAppSpecialize(AppSpecializeArgs *args) override {
70 |
71 | my_uid = args->uid;
72 | if (!isApp(my_uid)) {
73 | return;
74 | }
75 |
76 | const char *tablePath = (env->GetStringUTFChars(args->nice_name, 0));
77 | sprintf(nice_process_name, "%s", tablePath);
78 | delete tablePath;
79 |
80 | if (!args->app_data_dir) {
81 | LOGD(" forkAndSpecializePre appDataDir null");
82 | return;
83 | }
84 |
85 | const char *app_data_dir = env->GetStringUTFChars(args->app_data_dir, NULL);
86 | if (app_data_dir == nullptr) {
87 | return;
88 | }
89 | LOGD("app_data_dir %s",app_data_dir);
90 |
91 | int user = 0;
92 | if (sscanf(app_data_dir, "/data/%*[^/]/%d/%s", &user, package_name) != 2) {
93 | if (sscanf(app_data_dir, "/data/%*[^/]/%s", package_name) != 1) {
94 | package_name[0] = '\0';
95 | LOGD("can't parse %s", app_data_dir);
96 | }
97 | }
98 | env->ReleaseStringUTFChars(args->app_data_dir, app_data_dir);
99 |
100 | }
101 |
102 | void postAppSpecialize(const AppSpecializeArgs *args) override {
103 | LOGD("=========== jussi ==========");
104 |
105 | if (!isApp(my_uid)) {
106 | return;
107 | }
108 |
109 | // if (!strstr(nice_process_name, "com.ford.fordpasscn")
110 | // && !strstr(nice_process_name, "com.jussi.sslpinning")
111 | // && !strstr(nice_process_name, "com.cmit.irs")
112 | // ) {
113 | // LOGD("nice process name: %s", nice_process_name);
114 | // return;
115 | // }
116 |
117 | char *app_list;
118 | const char *filepath = "/data/local/tmp/app.list";
119 | const char *disable = "/data/local/tmp/finstaller/fs/disable";
120 | FILE *fp = nullptr;
121 | FILE *fp_disable = nullptr;
122 | fp_disable = fopen(disable, "r");
123 |
124 | if(fp_disable!=nullptr){
125 | LOGD("frida is disabled");
126 | return;
127 | }
128 |
129 | fp = fopen(filepath, "r");
130 | if (fp != nullptr) {
131 |
132 | fseek(fp, 0, SEEK_END);
133 | int fileLen = ftell(fp);
134 | app_list = (char *) malloc(sizeof(char) * (fileLen + 1));
135 | fseek(fp, 0, SEEK_SET);
136 | size_t count = fread(app_list, 1, fileLen, fp);
137 | app_list[count] = '\0';
138 | fclose(fp);
139 |
140 | LOGD("app list: %s", app_list);
141 | LOGD("package name: %s", package_name);
142 | } else {
143 | app_list = "";
144 | }
145 |
146 | if (!strstr(app_list, package_name)) {
147 | return;
148 | }
149 |
150 | LOGD(" nice_process_name=%s, pkg=%s,uid=%d, isApp= %d",
151 | nice_process_name, package_name, my_uid,
152 | isApp(my_uid));
153 |
154 | //添加这种机制,就可以提前设置进程名, 从而让frida 的gadget 能够识别到
155 | jclass java_Process = env->FindClass("android/os/Process");
156 | if (java_Process != nullptr && isApp(my_uid)) {
157 | jmethodID mtd_setArgV0 = env->GetStaticMethodID(java_Process, "setArgV0",
158 | "(Ljava/lang/String;)V");
159 | jstring name = env->NewStringUTF(nice_process_name);
160 | env->CallStaticVoidMethod(java_Process, mtd_setArgV0, name);
161 |
162 | pthread_t tid;
163 | int ret = pthread_create(&tid, NULL, gadget, NULL);
164 | if (ret != 0)
165 | {
166 | LOGD("pthread_create error: error_code=%d" ,ret);
167 | }
168 | }
169 | }
170 | };
171 |
172 | static void companion_handler(int i) {
173 | LOGD("Jussi\n");
174 | }
175 |
176 | REGISTER_ZYGISK_MODULE(MyModule)
177 | REGISTER_ZYGISK_COMPANION(companion_handler)
178 |
--------------------------------------------------------------------------------
/module/src/main/cpp/zygisk.hpp:
--------------------------------------------------------------------------------
1 | // This is the public API for Zygisk modules.
2 | // DO NOT MODIFY ANY CODE IN THIS HEADER.
3 |
4 | #pragma once
5 |
6 | #include
7 |
8 | #define ZYGISK_API_VERSION 2
9 |
10 | /*
11 |
12 | Define a class and inherit zygisk::ModuleBase to implement the functionality of your module.
13 | Use the macro REGISTER_ZYGISK_MODULE(className) to register that class to Zygisk.
14 |
15 | Please note that modules will only be loaded after zygote has forked the child process.
16 | THIS MEANS ALL OF YOUR CODE RUNS IN THE APP/SYSTEM SERVER PROCESS, NOT THE ZYGOTE DAEMON!
17 |
18 | Example code:
19 |
20 | static jint (*orig_logger_entry_max)(JNIEnv *env);
21 | static jint my_logger_entry_max(JNIEnv *env) { return orig_logger_entry_max(env); }
22 |
23 | static void example_handler(int socket) { ... }
24 |
25 | class ExampleModule : public zygisk::ModuleBase {
26 | public:
27 | void onLoad(zygisk::Api *api, JNIEnv *env) override {
28 | this->api = api;
29 | this->env = env;
30 | }
31 | void preAppSpecialize(zygisk::AppSpecializeArgs *args) override {
32 | JNINativeMethod methods[] = {
33 | { "logger_entry_max_payload_native", "()I", (void*) my_logger_entry_max },
34 | };
35 | api->hookJniNativeMethods(env, "android/util/Log", methods, 1);
36 | *(void **) &orig_logger_entry_max = methods[0].fnPtr;
37 | }
38 | private:
39 | zygisk::Api *api;
40 | JNIEnv *env;
41 | };
42 |
43 | REGISTER_ZYGISK_MODULE(ExampleModule)
44 |
45 | REGISTER_ZYGISK_COMPANION(example_handler)
46 |
47 | */
48 |
49 | namespace zygisk {
50 |
51 | struct Api;
52 | struct AppSpecializeArgs;
53 | struct ServerSpecializeArgs;
54 |
55 | class ModuleBase {
56 | public:
57 |
58 | // This function is called when the module is loaded into the target process.
59 | // A Zygisk API handle will be sent as an argument; call utility functions or interface
60 | // with Zygisk through this handle.
61 | virtual void onLoad([[maybe_unused]] Api *api, [[maybe_unused]] JNIEnv *env) {}
62 |
63 | // This function is called before the app process is specialized.
64 | // At this point, the process just got forked from zygote, but no app specific specialization
65 | // is applied. This means that the process does not have any sandbox restrictions and
66 | // still runs with the same privilege of zygote.
67 | //
68 | // All the arguments that will be sent and used for app specialization is passed as a single
69 | // AppSpecializeArgs object. You can read and overwrite these arguments to change how the app
70 | // process will be specialized.
71 | //
72 | // If you need to run some operations as superuser, you can call Api::connectCompanion() to
73 | // get a socket to do IPC calls with a root companion process.
74 | // See Api::connectCompanion() for more info.
75 | virtual void preAppSpecialize([[maybe_unused]] AppSpecializeArgs *args) {}
76 |
77 | // This function is called after the app process is specialized.
78 | // At this point, the process has all sandbox restrictions enabled for this application.
79 | // This means that this function runs as the same privilege of the app's own code.
80 | virtual void postAppSpecialize([[maybe_unused]] const AppSpecializeArgs *args) {}
81 |
82 | // This function is called before the system server process is specialized.
83 | // See preAppSpecialize(args) for more info.
84 | virtual void preServerSpecialize([[maybe_unused]] ServerSpecializeArgs *args) {}
85 |
86 | // This function is called after the system server process is specialized.
87 | // At this point, the process runs with the privilege of system_server.
88 | virtual void postServerSpecialize([[maybe_unused]] const ServerSpecializeArgs *args) {}
89 | };
90 |
91 | struct AppSpecializeArgs {
92 | // Required arguments. These arguments are guaranteed to exist on all Android versions.
93 | jint &uid;
94 | jint &gid;
95 | jintArray &gids;
96 | jint &runtime_flags;
97 | jint &mount_external;
98 | jstring &se_info;
99 | jstring &nice_name;
100 | jstring &instruction_set;
101 | jstring &app_data_dir;
102 |
103 | // Optional arguments. Please check whether the pointer is null before de-referencing
104 | jboolean *const is_child_zygote;
105 | jboolean *const is_top_app;
106 | jobjectArray *const pkg_data_info_list;
107 | jobjectArray *const whitelisted_data_info_list;
108 | jboolean *const mount_data_dirs;
109 | jboolean *const mount_storage_dirs;
110 |
111 | AppSpecializeArgs() = delete;
112 | };
113 |
114 | struct ServerSpecializeArgs {
115 | jint &uid;
116 | jint &gid;
117 | jintArray &gids;
118 | jint &runtime_flags;
119 | jlong &permitted_capabilities;
120 | jlong &effective_capabilities;
121 |
122 | ServerSpecializeArgs() = delete;
123 | };
124 |
125 | namespace internal {
126 | struct api_table;
127 | template void entry_impl(api_table *, JNIEnv *);
128 | }
129 |
130 | // These values are used in Api::setOption(Option)
131 | enum Option : int {
132 | // Force Magisk's denylist unmount routines to run on this process.
133 | //
134 | // Setting this option only makes sense in preAppSpecialize.
135 | // The actual unmounting happens during app process specialization.
136 | //
137 | // Set this option to force all Magisk and modules' files to be unmounted from the
138 | // mount namespace of the process, regardless of the denylist enforcement status.
139 | FORCE_DENYLIST_UNMOUNT = 0,
140 |
141 | // When this option is set, your module's library will be dlclose-ed after post[XXX]Specialize.
142 | // Be aware that after dlclose-ing your module, all of your code will be unmapped from memory.
143 | // YOU MUST NOT ENABLE THIS OPTION AFTER HOOKING ANY FUNCTIONS IN THE PROCESS.
144 | DLCLOSE_MODULE_LIBRARY = 1,
145 | };
146 |
147 | // Bit masks of the return value of Api::getFlags()
148 | enum StateFlag : uint32_t {
149 | // The user has granted root access to the current process
150 | PROCESS_GRANTED_ROOT = (1u << 0),
151 |
152 | // The current process was added on the denylist
153 | PROCESS_ON_DENYLIST = (1u << 1),
154 | };
155 |
156 | // All API functions will stop working after post[XXX]Specialize as Zygisk will be unloaded
157 | // from the specialized process afterwards.
158 | struct Api {
159 |
160 | // Connect to a root companion process and get a Unix domain socket for IPC.
161 | //
162 | // This API only works in the pre[XXX]Specialize functions due to SELinux restrictions.
163 | //
164 | // The pre[XXX]Specialize functions run with the same privilege of zygote.
165 | // If you would like to do some operations with superuser permissions, register a handler
166 | // function that would be called in the root process with REGISTER_ZYGISK_COMPANION(func).
167 | // Another good use case for a companion process is that if you want to share some resources
168 | // across multiple processes, hold the resources in the companion process and pass it over.
169 | //
170 | // The root companion process is ABI aware; that is, when calling this function from a 32-bit
171 | // process, you will be connected to a 32-bit companion process, and vice versa for 64-bit.
172 | //
173 | // Returns a file descriptor to a socket that is connected to the socket passed to your
174 | // module's companion request handler. Returns -1 if the connection attempt failed.
175 | int connectCompanion();
176 |
177 | // Get the file descriptor of the root folder of the current module.
178 | //
179 | // This API only works in the pre[XXX]Specialize functions.
180 | // Accessing the directory returned is only possible in the pre[XXX]Specialize functions
181 | // or in the root companion process (assuming that you sent the fd over the socket).
182 | // Both restrictions are due to SELinux and UID.
183 | //
184 | // Returns -1 if errors occurred.
185 | int getModuleDir();
186 |
187 | // Set various options for your module.
188 | // Please note that this function accepts one single option at a time.
189 | // Check zygisk::Option for the full list of options available.
190 | void setOption(Option opt);
191 |
192 | // Get information about the current process.
193 | // Returns bitwise-or'd zygisk::StateFlag values.
194 | uint32_t getFlags();
195 |
196 | // Hook JNI native methods for a class
197 | //
198 | // Lookup all registered JNI native methods and replace it with your own functions.
199 | // The original function pointer will be saved in each JNINativeMethod's fnPtr.
200 | // If no matching class, method name, or signature is found, that specific JNINativeMethod.fnPtr
201 | // will be set to nullptr.
202 | void hookJniNativeMethods(JNIEnv *env, const char *className, JNINativeMethod *methods, int numMethods);
203 |
204 | // For ELFs loaded in memory matching `regex`, replace function `symbol` with `newFunc`.
205 | // If `oldFunc` is not nullptr, the original function pointer will be saved to `oldFunc`.
206 | void pltHookRegister(const char *regex, const char *symbol, void *newFunc, void **oldFunc);
207 |
208 | // For ELFs loaded in memory matching `regex`, exclude hooks registered for `symbol`.
209 | // If `symbol` is nullptr, then all symbols will be excluded.
210 | void pltHookExclude(const char *regex, const char *symbol);
211 |
212 | // Commit all the hooks that was previously registered.
213 | // Returns false if an error occurred.
214 | bool pltHookCommit();
215 |
216 | private:
217 | internal::api_table *impl;
218 | template friend void internal::entry_impl(internal::api_table *, JNIEnv *);
219 | };
220 |
221 | // Register a class as a Zygisk module
222 |
223 | #define REGISTER_ZYGISK_MODULE(clazz) \
224 | void zygisk_module_entry(zygisk::internal::api_table *table, JNIEnv *env) { \
225 | zygisk::internal::entry_impl(table, env); \
226 | }
227 |
228 | // Register a root companion request handler function for your module
229 | //
230 | // The function runs in a superuser daemon process and handles a root companion request from
231 | // your module running in a target process. The function has to accept an integer value,
232 | // which is a socket that is connected to the target process.
233 | // See Api::connectCompanion() for more info.
234 | //
235 | // NOTE: the function can run concurrently on multiple threads.
236 | // Be aware of race conditions if you have a globally shared resource.
237 |
238 | #define REGISTER_ZYGISK_COMPANION(func) \
239 | void zygisk_companion_entry(int client) { func(client); }
240 |
241 | /************************************************************************************
242 | * All the code after this point is internal code used to interface with Zygisk
243 | * and guarantee ABI stability. You do not have to understand what it is doing.
244 | ************************************************************************************/
245 |
246 | namespace internal {
247 |
248 | struct module_abi {
249 | long api_version;
250 | ModuleBase *_this;
251 |
252 | void (*preAppSpecialize)(ModuleBase *, AppSpecializeArgs *);
253 | void (*postAppSpecialize)(ModuleBase *, const AppSpecializeArgs *);
254 | void (*preServerSpecialize)(ModuleBase *, ServerSpecializeArgs *);
255 | void (*postServerSpecialize)(ModuleBase *, const ServerSpecializeArgs *);
256 |
257 | module_abi(ModuleBase *module) : api_version(ZYGISK_API_VERSION), _this(module) {
258 | preAppSpecialize = [](auto self, auto args) { self->preAppSpecialize(args); };
259 | postAppSpecialize = [](auto self, auto args) { self->postAppSpecialize(args); };
260 | preServerSpecialize = [](auto self, auto args) { self->preServerSpecialize(args); };
261 | postServerSpecialize = [](auto self, auto args) { self->postServerSpecialize(args); };
262 | }
263 | };
264 |
265 | struct api_table {
266 | // These first 2 entries are permanent, shall never change
267 | void *_this;
268 | bool (*registerModule)(api_table *, module_abi *);
269 |
270 | // Utility functions
271 | void (*hookJniNativeMethods)(JNIEnv *, const char *, JNINativeMethod *, int);
272 | void (*pltHookRegister)(const char *, const char *, void *, void **);
273 | void (*pltHookExclude)(const char *, const char *);
274 | bool (*pltHookCommit)();
275 |
276 | // Zygisk functions
277 | int (*connectCompanion)(void * /* _this */);
278 | void (*setOption)(void * /* _this */, Option);
279 | int (*getModuleDir)(void * /* _this */);
280 | uint32_t (*getFlags)(void * /* _this */);
281 | };
282 |
283 | template
284 | void entry_impl(api_table *table, JNIEnv *env) {
285 | ModuleBase *module = new T();
286 | if (!table->registerModule(table, new module_abi(module)))
287 | return;
288 | auto api = new Api();
289 | api->impl = table;
290 | module->onLoad(api, env);
291 | }
292 |
293 | } // namespace internal
294 |
295 | inline int Api::connectCompanion() {
296 | return impl->connectCompanion ? impl->connectCompanion(impl->_this) : -1;
297 | }
298 | inline int Api::getModuleDir() {
299 | return impl->getModuleDir ? impl->getModuleDir(impl->_this) : -1;
300 | }
301 | inline void Api::setOption(Option opt) {
302 | if (impl->setOption) impl->setOption(impl->_this, opt);
303 | }
304 | inline uint32_t Api::getFlags() {
305 | return impl->getFlags ? impl->getFlags(impl->_this) : 0;
306 | }
307 | inline void Api::hookJniNativeMethods(JNIEnv *env, const char *className, JNINativeMethod *methods, int numMethods) {
308 | if (impl->hookJniNativeMethods) impl->hookJniNativeMethods(env, className, methods, numMethods);
309 | }
310 | inline void Api::pltHookRegister(const char *regex, const char *symbol, void *newFunc, void **oldFunc) {
311 | if (impl->pltHookRegister) impl->pltHookRegister(regex, symbol, newFunc, oldFunc);
312 | }
313 | inline void Api::pltHookExclude(const char *regex, const char *symbol) {
314 | if (impl->pltHookExclude) impl->pltHookExclude(regex, symbol);
315 | }
316 | inline bool Api::pltHookCommit() {
317 | return impl->pltHookCommit != nullptr && impl->pltHookCommit();
318 | }
319 |
320 | } // namespace zygisk
321 |
322 | [[gnu::visibility("default")]] [[gnu::used]]
323 | extern "C" void zygisk_module_entry(zygisk::internal::api_table *, JNIEnv *);
324 |
325 | [[gnu::visibility("default")]] [[gnu::used]]
326 | extern "C" void zygisk_companion_entry(int);
327 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | import org.apache.tools.ant.DirectoryScanner
2 |
3 | pluginManagement {
4 | repositories {
5 | gradlePluginPortal()
6 | google()
7 | mavenCentral()
8 | }
9 | plugins {
10 | id 'com.android.application' version '7.0.2'
11 | id 'com.android.library' version '7.0.2'
12 | }
13 | }
14 | dependencyResolutionManagement {
15 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
16 | repositories {
17 | mavenLocal()
18 | google()
19 | mavenCentral()
20 | }
21 | }
22 |
23 | DirectoryScanner.removeDefaultExclude('**/.gitattributes')
24 |
25 | include ':module'
26 |
--------------------------------------------------------------------------------
/template/magisk_module/.gitattributes:
--------------------------------------------------------------------------------
1 | # Declare files that will always have LF line endings on checkout.
2 | META-INF/** text eol=lf
3 | *.prop text eol=lf
4 | *.sh text eol=lf
5 | *.md text eol=lf
6 | sepolicy.rule text eol=lf
7 |
8 | # Denote all files that are truly binary and should not be modified.
9 | system/** binary
10 | system_x86/** binary
--------------------------------------------------------------------------------
/template/magisk_module/META-INF/com/google/android/update-binary:
--------------------------------------------------------------------------------
1 | #!/sbin/sh
2 |
3 | #################
4 | # Initialization
5 | #################
6 |
7 | umask 022
8 |
9 | # echo before loading util_functions
10 | ui_print() { echo "$1"; }
11 |
12 | require_new_magisk() {
13 | ui_print "*******************************"
14 | ui_print " Please install Magisk v20.4+! "
15 | ui_print "*******************************"
16 | exit 1
17 | }
18 |
19 | #########################
20 | # Load util_functions.sh
21 | #########################
22 |
23 | OUTFD=$2
24 | ZIPFILE=$3
25 |
26 | mount /data 2>/dev/null
27 |
28 | [ -f /data/adb/magisk/util_functions.sh ] || require_new_magisk
29 | . /data/adb/magisk/util_functions.sh
30 | [ $MAGISK_VER_CODE -lt 20400 ] && require_new_magisk
31 |
32 | install_module
33 | exit 0
34 |
--------------------------------------------------------------------------------
/template/magisk_module/META-INF/com/google/android/updater-script:
--------------------------------------------------------------------------------
1 | #MAGISK
2 |
--------------------------------------------------------------------------------
/template/magisk_module/README.md:
--------------------------------------------------------------------------------
1 | # Riru - Template
--------------------------------------------------------------------------------
/template/magisk_module/customize.sh:
--------------------------------------------------------------------------------
1 | # shellcheck disable=SC2034
2 | SKIPUNZIP=1
3 |
4 | FLAVOR=zygisk
5 |
6 | enforce_install_from_magisk_app() {
7 | if $BOOTMODE; then
8 | ui_print "- Installing from Magisk app"
9 | else
10 | ui_print "*********************************************************"
11 | ui_print "! Install from recovery is NOT supported"
12 | ui_print "! Recovery sucks"
13 | ui_print "! Please install from Magisk app"
14 | abort "*********************************************************"
15 | fi
16 | }
17 |
18 | check_magisk_version() {
19 | ui_print "- Magisk version: $MAGISK_VER_CODE"
20 | if [ "$MAGISK_VER_CODE" -lt 24000 ]; then
21 | ui_print "*********************************************************"
22 | ui_print "! Please install Magisk v24.0+ (24000+)"
23 | abort "*********************************************************"
24 | fi
25 | }
26 |
27 | VERSION=$(grep_prop version "${TMPDIR}/module.prop")
28 | ui_print "- Module version ${VERSION}"
29 |
30 | # Extract verify.sh
31 | ui_print "- Extracting verify.sh"
32 | unzip -o "$ZIPFILE" 'verify.sh' -d "$TMPDIR" >&2
33 | if [ ! -f "$TMPDIR/verify.sh" ]; then
34 | ui_print "*********************************************************"
35 | ui_print "! Unable to extract verify.sh!"
36 | ui_print "! This zip may be corrupted, please try downloading again"
37 | abort "*********************************************************"
38 | fi
39 | . "$TMPDIR/verify.sh"
40 |
41 | extract "$ZIPFILE" 'customize.sh' "$TMPDIR"
42 | extract "$ZIPFILE" 'verify.sh' "$TMPDIR"
43 |
44 | check_magisk_version
45 | enforce_install_from_magisk_app
46 |
47 | # Check architecture
48 | if [ "$ARCH" != "arm" ] && [ "$ARCH" != "arm64" ] && [ "$ARCH" != "x86" ] && [ "$ARCH" != "x64" ]; then
49 | abort "! Unsupported platform: $ARCH"
50 | else
51 | ui_print "- Device platform: $ARCH"
52 | fi
53 |
54 | if [ "$API" -lt 27 ]; then
55 | abort "! Only support SDK 27+ devices"
56 | fi
57 |
58 | extract "$ZIPFILE" 'module.prop' "$MODPATH"
59 | extract "$ZIPFILE" 'service.sh' "$MODPATH"
60 | extract "$ZIPFILE" 'uninstall.sh' "$MODPATH"
61 |
62 | ui_print "- Extracting zygisk libraries"
63 |
64 | if [ "$FLAVOR" == "zygisk" ]; then
65 | mkdir -p "$MODPATH/zygisk"
66 | if [ "$ARCH" = "arm" ] || [ "$ARCH" = "arm64" ]; then
67 | extract "$ZIPFILE" "lib/armeabi-v7a/libjussigad.so" "$MODPATH/zygisk" true
68 | mv "$MODPATH/zygisk/libjussigad.so" "$MODPATH/zygisk/armeabi-v7a.so"
69 |
70 | if [ "$IS64BIT" = true ]; then
71 | extract "$ZIPFILE" "lib/arm64-v8a/libjussigad.so" "$MODPATH/zygisk" true
72 | mv "$MODPATH/zygisk/libjussigad.so" "$MODPATH/zygisk/arm64-v8a.so"
73 | fi
74 | fi
75 |
76 | if [ "$ARCH" = "x86" ] || [ "$ARCH" = "x64" ]; then
77 | extract "$ZIPFILE" "lib/x86_64/libjussigad.so" "$MODPATH/zygisk" true
78 | mv "$MODPATH/zygisk/libjussigad.so" "$MODPATH/zygisk/x86_64.so"
79 |
80 | if [ "$IS64BIT" = true ]; then
81 | extract "$ZIPFILE" "lib/x86/libjussigad.so" "$MODPATH/zygisk" true
82 | mv "$MODPATH/zygisk/libjussigad.so" "$MODPATH/zygisk/x86.so"
83 | fi
84 | fi
85 | fi
86 |
87 |
88 | ui_print "- Extracting system libraries"
89 | mkdir -p "$MODPATH/system"
90 | mkdir -p "$MODPATH/system/lib"
91 | mkdir -p "$MODPATH/system/lib64"
92 | if [ "$ARCH" = "arm" ] || [ "$ARCH" = "arm64" ]; then
93 | ui_print "- Extracting arm libraries"
94 | extract "$ZIPFILE" "system/lib/libminitool.so" "$MODPATH/system/lib" true
95 | extract "$ZIPFILE" "system/lib/libminitool.config.so" "$MODPATH/system/lib" true
96 |
97 | ui_print "- Extracting arm64 libraries"
98 | extract "$ZIPFILE" "system/lib64/libminitool.so" "$MODPATH/system/lib64" true
99 | extract "$ZIPFILE" "system/lib64/libminitool.config.so" "$MODPATH/system/lib64" true
100 | fi
101 |
102 | extract "$ZIPFILE" "system/etc/minitool.prop" "$MODPATH/system/etc" true
103 |
104 | set_perm_recursive "$MODPATH" 0 0 0755 0644
105 |
--------------------------------------------------------------------------------
/template/magisk_module/module.prop:
--------------------------------------------------------------------------------
1 | id=${id}
2 | name=${name}
3 | version=${version}
4 | versionCode=${versionCode}
5 | author=${author}
6 | description=${description}
7 |
--------------------------------------------------------------------------------
/template/magisk_module/service.sh:
--------------------------------------------------------------------------------
1 | MODDIR=${0%/*}
--------------------------------------------------------------------------------
/template/magisk_module/system/etc/minitool.prop:
--------------------------------------------------------------------------------
1 | version=14.2.2
--------------------------------------------------------------------------------
/template/magisk_module/system/lib/libminitool.config.so:
--------------------------------------------------------------------------------
1 | {
2 | "interaction": {
3 | "type": "listen",
4 | "address": "127.0.0.1",
5 | "port": 26000,
6 | "on_port_conflict": "fail",
7 | "on_load": "resume"
8 | }
9 | }
--------------------------------------------------------------------------------
/template/magisk_module/system/lib/libminitool.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jussi-sky/Zygisk-FridaGadget/3f1d7cc825bf375cf2f97900a53e2e530694fb5f/template/magisk_module/system/lib/libminitool.so
--------------------------------------------------------------------------------
/template/magisk_module/system/lib64/libminitool.config.so:
--------------------------------------------------------------------------------
1 | {
2 | "interaction": {
3 | "type": "listen",
4 | "address": "127.0.0.1",
5 | "port": 26000,
6 | "on_port_conflict": "fail",
7 | "on_load": "resume"
8 | }
9 | }
--------------------------------------------------------------------------------
/template/magisk_module/system/lib64/libminitool.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jussi-sky/Zygisk-FridaGadget/3f1d7cc825bf375cf2f97900a53e2e530694fb5f/template/magisk_module/system/lib64/libminitool.so
--------------------------------------------------------------------------------
/template/magisk_module/uninstall.sh:
--------------------------------------------------------------------------------
1 | #!/sbin/sh
2 | # MODDIR=${0%/*}
3 | rm -rf /data/adb/modules/zygisk_shocker
4 |
--------------------------------------------------------------------------------
/template/magisk_module/verify.sh:
--------------------------------------------------------------------------------
1 | TMPDIR_FOR_VERIFY="$TMPDIR/.vunzip"
2 | mkdir "$TMPDIR_FOR_VERIFY"
3 |
4 | abort_verify() {
5 | ui_print "*********************************************************"
6 | ui_print "! $1"
7 | ui_print "! This zip may be corrupted, please try downloading again"
8 | abort "*********************************************************"
9 | }
10 |
11 | # extract
12 | extract() {
13 | zip=$1
14 | file=$2
15 | dir=$3
16 | junk_paths=$4
17 | [ -z "$junk_paths" ] && junk_paths=false
18 | opts="-o"
19 | [ $junk_paths = true ] && opts="-oj"
20 |
21 | file_path=""
22 | hash_path=""
23 | if [ $junk_paths = true ]; then
24 | file_path="$dir/$(basename "$file")"
25 | hash_path="$TMPDIR_FOR_VERIFY/$(basename "$file").sha256sum"
26 | else
27 | file_path="$dir/$file"
28 | hash_path="$TMPDIR_FOR_VERIFY/$file.sha256sum"
29 | fi
30 |
31 | unzip $opts "$zip" "$file" -d "$dir" >&2
32 | [ -f "$file_path" ] || abort_verify "$file not exists"
33 |
34 | unzip $opts "$zip" "$file.sha256sum" -d "$TMPDIR_FOR_VERIFY" >&2
35 | [ -f "$hash_path" ] || abort_verify "$file.sha256sum not exists"
36 |
37 | (echo "$(cat "$hash_path") $file_path" | sha256sum -c -s -) || abort_verify "Failed to verify $file"
38 | ui_print "- Verified $file" >&1
39 | }
40 |
--------------------------------------------------------------------------------