Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
M
Magisk
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
Magisk
Commits
ea75a09f
Commit
ea75a09f
authored
Oct 27, 2021
by
topjohnwu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Make zygisk survive zygote restarts
Close #4777
parent
4c747c41
Show whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
340 additions
and
61 deletions
+340
-61
Android.mk
native/jni/Android.mk
+1
-1
applets.cpp
native/jni/core/applets.cpp
+5
-4
core.hpp
native/jni/core/core.hpp
+0
-3
daemon.cpp
native/jni/core/daemon.cpp
+1
-0
magisk.cpp
native/jni/core/magisk.cpp
+0
-3
module.cpp
native/jni/core/module.cpp
+15
-12
daemon.hpp
native/jni/include/daemon.hpp
+3
-0
magisk.hpp
native/jni/include/magisk.hpp
+1
-0
connect.cpp
native/jni/su/connect.cpp
+15
-3
entry.cpp
native/jni/zygisk/entry.cpp
+88
-34
hook.cpp
native/jni/zygisk/hook.cpp
+12
-0
main.cpp
native/jni/zygisk/main.cpp
+199
-0
zygisk.hpp
native/jni/zygisk/zygisk.hpp
+0
-1
No files found.
native/jni/Android.mk
View file @
ea75a09f
...
@@ -29,10 +29,10 @@ LOCAL_SRC_FILES := \
...
@@ -29,10 +29,10 @@ LOCAL_SRC_FILES := \
su/pts.cpp \
su/pts.cpp \
su/su_daemon.cpp \
su/su_daemon.cpp \
zygisk/entry.cpp \
zygisk/entry.cpp \
zygisk/main.cpp \
zygisk/utils.cpp \
zygisk/utils.cpp \
zygisk/hook.cpp \
zygisk/hook.cpp \
zygisk/memory.cpp \
zygisk/memory.cpp \
zygisk/companion.cpp \
zygisk/deny/cli.cpp \
zygisk/deny/cli.cpp \
zygisk/deny/utils.cpp \
zygisk/deny/utils.cpp \
zygisk/deny/revert.cpp
zygisk/deny/revert.cpp
...
...
native/jni/core/applets.cpp
View file @
ea75a09f
...
@@ -10,14 +10,15 @@ using namespace std;
...
@@ -10,14 +10,15 @@ using namespace std;
using
main_fun
=
int
(
*
)(
int
,
char
*
[]);
using
main_fun
=
int
(
*
)(
int
,
char
*
[]);
static
main_fun
applet_main
[]
=
{
su_client_main
,
resetprop_main
,
nullptr
};
constexpr
const
char
*
applets
[]
=
{
"su"
,
"resetprop"
,
"zygisk"
,
nullptr
};
static
main_fun
applet_mains
[]
=
{
su_client_main
,
resetprop_main
,
zygisk_main
,
nullptr
};
static
int
call_applet
(
int
argc
,
char
*
argv
[])
{
static
int
call_applet
(
int
argc
,
char
*
argv
[])
{
// Applets
// Applets
string_view
base
=
basename
(
argv
[
0
]);
string_view
base
=
basename
(
argv
[
0
]);
for
(
int
i
=
0
;
applet
_name
s
[
i
];
++
i
)
{
for
(
int
i
=
0
;
applets
[
i
];
++
i
)
{
if
(
base
==
applet
_name
s
[
i
])
{
if
(
base
==
applets
[
i
])
{
return
(
*
applet_main
[
i
])(
argc
,
argv
);
return
(
*
applet_main
s
[
i
])(
argc
,
argv
);
}
}
}
}
if
(
str_starts
(
base
,
"app_process"
))
{
if
(
str_starts
(
base
,
"app_process"
))
{
...
...
native/jni/core/core.hpp
View file @
ea75a09f
...
@@ -34,6 +34,3 @@ void exec_common_scripts(const char *stage);
...
@@ -34,6 +34,3 @@ void exec_common_scripts(const char *stage);
void
exec_module_scripts
(
const
char
*
stage
,
const
std
::
vector
<
std
::
string_view
>
&
modules
);
void
exec_module_scripts
(
const
char
*
stage
,
const
std
::
vector
<
std
::
string_view
>
&
modules
);
void
install_apk
(
const
char
*
apk
);
void
install_apk
(
const
char
*
apk
);
[[
noreturn
]]
void
install_module
(
const
char
*
file
);
[[
noreturn
]]
void
install_module
(
const
char
*
file
);
// Zygisk companion entrypoint
[[
noreturn
]]
void
zygiskd
(
int
socket
);
native/jni/core/daemon.cpp
View file @
ea75a09f
...
@@ -157,6 +157,7 @@ static void handle_request_async(int client, int code, const sock_cred &cred) {
...
@@ -157,6 +157,7 @@ static void handle_request_async(int client, int code, const sock_cred &cred) {
reboot
();
reboot
();
break
;
break
;
case
ZYGISK_REQUEST
:
case
ZYGISK_REQUEST
:
case
ZYGISK_PASSTHROUGH
:
zygisk_handler
(
client
,
&
cred
);
zygisk_handler
(
client
,
&
cred
);
break
;
break
;
default
:
default
:
...
...
native/jni/core/magisk.cpp
View file @
ea75a09f
...
@@ -39,7 +39,6 @@ Advanced Options (Internal APIs):
...
@@ -39,7 +39,6 @@ Advanced Options (Internal APIs):
--sqlite SQL exec SQL commands to Magisk database
--sqlite SQL exec SQL commands to Magisk database
--path print Magisk tmpfs mount path
--path print Magisk tmpfs mount path
--denylist ARGS denylist config CLI
--denylist ARGS denylist config CLI
--companion FD start zygisk root companion
Available applets:
Available applets:
)EOF"
);
)EOF"
);
...
@@ -128,8 +127,6 @@ int magisk_main(int argc, char *argv[]) {
...
@@ -128,8 +127,6 @@ int magisk_main(int argc, char *argv[]) {
return
0
;
return
0
;
}
else
if
(
argc
>=
3
&&
argv
[
1
]
==
"--install-module"
sv
)
{
}
else
if
(
argc
>=
3
&&
argv
[
1
]
==
"--install-module"
sv
)
{
install_module
(
argv
[
2
]);
install_module
(
argv
[
2
]);
}
else
if
(
argc
>=
3
&&
argv
[
1
]
==
"--companion"
sv
)
{
zygiskd
(
parse_int
(
argv
[
2
]));
}
}
#if 0
#if 0
/* Entry point for testing stuffs */
/* Entry point for testing stuffs */
...
...
native/jni/core/module.cpp
View file @
ea75a09f
...
@@ -550,9 +550,12 @@ struct module_info {
...
@@ -550,9 +550,12 @@ struct module_info {
};
};
static
vector
<
module_info
>
*
modules
;
static
vector
<
module_info
>
*
modules
;
int
app_process_32
=
-
1
;
int
app_process_64
=
-
1
;
#define mount_zygisk(bit) \
#define mount_zygisk(bit) \
if (access("/system/bin/app_process" #bit, F_OK) == 0) { \
if (access("/system/bin/app_process" #bit, F_OK) == 0) { \
app_process_##bit = xopen("/system/bin/app_process" #bit, O_RDONLY | O_CLOEXEC); \
string zbin = zygisk_bin + "/app_process" #bit; \
string zbin = zygisk_bin + "/app_process" #bit; \
string mbin = MAGISKTMP + "/magisk" #bit; \
string mbin = MAGISKTMP + "/magisk" #bit; \
int src = xopen(mbin.data(), O_RDONLY | O_CLOEXEC); \
int src = xopen(mbin.data(), O_RDONLY | O_CLOEXEC); \
...
...
native/jni/include/daemon.hpp
View file @
ea75a09f
...
@@ -30,6 +30,7 @@ enum : int {
...
@@ -30,6 +30,7 @@ enum : int {
SQLITE_CMD
,
SQLITE_CMD
,
REMOVE_MODULES
,
REMOVE_MODULES
,
ZYGISK_REQUEST
,
ZYGISK_REQUEST
,
ZYGISK_PASSTHROUGH
,
DAEMON_CODE_END
,
DAEMON_CODE_END
,
};
};
...
@@ -42,6 +43,8 @@ enum : int {
...
@@ -42,6 +43,8 @@ enum : int {
};
};
extern
bool
zygisk_enabled
;
extern
bool
zygisk_enabled
;
extern
int
app_process_32
;
extern
int
app_process_64
;
int
connect_daemon
(
bool
create
=
false
);
int
connect_daemon
(
bool
create
=
false
);
...
...
native/jni/include/magisk.hpp
View file @
ea75a09f
...
@@ -43,3 +43,4 @@ int magiskpolicy_main(int argc, char *argv[]);
...
@@ -43,3 +43,4 @@ int magiskpolicy_main(int argc, char *argv[]);
int
su_client_main
(
int
argc
,
char
*
argv
[]);
int
su_client_main
(
int
argc
,
char
*
argv
[]);
int
resetprop_main
(
int
argc
,
char
*
argv
[]);
int
resetprop_main
(
int
argc
,
char
*
argv
[]);
int
app_process_main
(
int
argc
,
char
*
argv
[]);
int
app_process_main
(
int
argc
,
char
*
argv
[]);
int
zygisk_main
(
int
argc
,
char
*
argv
[]);
native/jni/su/connect.cpp
View file @
ea75a09f
...
@@ -5,6 +5,7 @@
...
@@ -5,6 +5,7 @@
#include <selinux.hpp>
#include <selinux.hpp>
#include "su.hpp"
#include "su.hpp"
#include "daemon.hpp"
using
namespace
std
;
using
namespace
std
;
...
@@ -15,11 +16,11 @@ enum {
...
@@ -15,11 +16,11 @@ enum {
};
};
#define CALL_PROVIDER \
#define CALL_PROVIDER \
"/system/bin/app_process"
, "/system/bin", "com.android.commands.content.Content", \
exe
, "/system/bin", "com.android.commands.content.Content", \
"call", "--uri", target, "--user", user, "--method", action
"call", "--uri", target, "--user", user, "--method", action
#define START_ACTIVITY \
#define START_ACTIVITY \
"/system/bin/app_process"
, "/system/bin", "com.android.commands.am.Am", \
exe
, "/system/bin", "com.android.commands.am.Am", \
"start", "-p", target, "--user", user, "-a", "android.intent.action.VIEW", \
"start", "-p", target, "--user", user, "-a", "android.intent.action.VIEW", \
"-f", "0x18000020", "--es", "action", action
"-f", "0x18000020", "--es", "action", action
...
@@ -100,9 +101,20 @@ static bool check_no_error(int fd) {
...
@@ -100,9 +101,20 @@ static bool check_no_error(int fd) {
static
void
exec_cmd
(
const
char
*
action
,
vector
<
Extra
>
&
data
,
static
void
exec_cmd
(
const
char
*
action
,
vector
<
Extra
>
&
data
,
const
shared_ptr
<
su_info
>
&
info
,
int
mode
=
CONTENT_PROVIDER
)
{
const
shared_ptr
<
su_info
>
&
info
,
int
mode
=
CONTENT_PROVIDER
)
{
char
exe
[
128
];
char
target
[
128
];
char
target
[
128
];
char
user
[
4
];
char
user
[
4
];
sprintf
(
user
,
"%d"
,
get_user
(
info
));
snprintf
(
user
,
sizeof
(
user
),
"%d"
,
get_user
(
info
));
if
(
zygisk_enabled
)
{
#if defined(__LP64__)
snprintf
(
exe
,
sizeof
(
exe
),
"/proc/self/fd/%d"
,
app_process_64
);
#else
snprintf
(
exe
,
sizeof
(
exe
),
"/proc/self/fd/%d"
,
app_process_32
);
#endif
}
else
{
strlcpy
(
exe
,
"/system/bin/app_process"
,
sizeof
(
exe
));
}
// First try content provider call method
// First try content provider call method
if
(
mode
>=
CONTENT_PROVIDER
)
{
if
(
mode
>=
CONTENT_PROVIDER
)
{
...
...
native/jni/zygisk/entry.cpp
View file @
ea75a09f
#include <libgen.h>
#include <libgen.h>
#include <dlfcn.h>
#include <dlfcn.h>
#include <sys/mount.h>
#include <sys/sendfile.h>
#include <sys/prctl.h>
#include <sys/prctl.h>
#include <android/log.h>
#include <android/log.h>
...
@@ -145,37 +143,7 @@ static void zygisk_init() {
...
@@ -145,37 +143,7 @@ static void zygisk_init() {
}
}
}
}
// Start code for magiskd IPC
// The following code runs in zygote/app process
int
app_process_main
(
int
argc
,
char
*
argv
[])
{
android_logging
();
if
(
int
fd
=
connect_daemon
();
fd
>=
0
)
{
write_int
(
fd
,
ZYGISK_REQUEST
);
write_int
(
fd
,
ZYGISK_SETUP
);
if
(
read_int
(
fd
)
==
0
)
{
string
path
=
read_string
(
fd
);
string
lib
=
path
+
".1.so"
;
if
(
char
*
ld
=
getenv
(
"LD_PRELOAD"
))
{
char
env
[
256
];
sprintf
(
env
,
"%s:%s"
,
ld
,
lib
.
data
());
setenv
(
"LD_PRELOAD"
,
env
,
1
);
}
else
{
setenv
(
"LD_PRELOAD"
,
lib
.
data
(),
1
);
}
setenv
(
INJECT_ENV_1
,
"1"
,
1
);
}
close
(
fd
);
}
// Execute real app_process
char
buf
[
256
];
xreadlink
(
"/proc/self/exe"
,
buf
,
sizeof
(
buf
));
xumount2
(
"/proc/self/exe"
,
MNT_DETACH
);
execve
(
buf
,
argv
,
environ
);
return
1
;
}
static
int
zygisk_log
(
int
prio
,
const
char
*
fmt
,
va_list
ap
)
{
static
int
zygisk_log
(
int
prio
,
const
char
*
fmt
,
va_list
ap
)
{
// If we don't have log pipe set, ask magiskd for it
// If we don't have log pipe set, ask magiskd for it
...
@@ -248,6 +216,50 @@ static bool get_exe(int pid, char *buf, size_t sz) {
...
@@ -248,6 +216,50 @@ static bool get_exe(int pid, char *buf, size_t sz) {
return
xreadlink
(
buf
,
buf
,
sz
)
>
0
;
return
xreadlink
(
buf
,
buf
,
sz
)
>
0
;
}
}
static
int
zygiskd_sockets
[]
=
{
-
1
,
-
1
};
#define zygiskd_socket zygiskd_sockets[is_64_bit]
static
void
connect_companion
(
int
client
,
bool
is_64_bit
)
{
if
(
zygiskd_socket
>=
0
)
{
// Make sure the socket is still valid
pollfd
pfd
=
{
zygiskd_socket
,
0
,
0
};
poll
(
&
pfd
,
1
,
0
);
if
(
pfd
.
revents
)
{
// Any revent means error
close
(
zygiskd_socket
);
zygiskd_socket
=
-
1
;
}
}
if
(
zygiskd_socket
<
0
)
{
int
fds
[
2
];
socketpair
(
AF_UNIX
,
SOCK_STREAM
|
SOCK_CLOEXEC
,
0
,
fds
);
zygiskd_socket
=
fds
[
0
];
if
(
fork_dont_care
()
==
0
)
{
string
exe
=
MAGISKTMP
+
"/magisk"
+
(
is_64_bit
?
"64"
:
"32"
);
// This fd has to survive exec
fcntl
(
fds
[
1
],
F_SETFD
,
0
);
char
buf
[
16
];
snprintf
(
buf
,
sizeof
(
buf
),
"%d"
,
fds
[
1
]);
execl
(
exe
.
data
(),
"zygisk"
,
"companion"
,
buf
,
(
char
*
)
nullptr
);
exit
(
-
1
);
}
close
(
fds
[
1
]);
vector
<
int
>
module_fds
=
zygisk_module_fds
(
is_64_bit
);
send_fds
(
zygiskd_socket
,
module_fds
.
data
(),
module_fds
.
size
());
// Wait for ack
if
(
read_int
(
zygiskd_socket
)
!=
0
)
{
return
;
}
}
send_fd
(
zygiskd_socket
,
client
);
}
static
timespec
last_zygote_start
;
static
int
zygote_start_counts
[]
=
{
0
,
0
};
#define zygote_start_count zygote_start_counts[is_64_bit]
#define zygote_started (zygote_start_counts[0] + zygote_start_counts[1])
#define zygote_start_reset(val) { zygote_start_counts[0] = val; zygote_start_counts[1] = val; }
static
void
setup_files
(
int
client
,
const
sock_cred
*
cred
)
{
static
void
setup_files
(
int
client
,
const
sock_cred
*
cred
)
{
LOGD
(
"zygisk: setup files for pid=[%d]
\n
"
,
cred
->
pid
);
LOGD
(
"zygisk: setup files for pid=[%d]
\n
"
,
cred
->
pid
);
...
@@ -257,15 +269,54 @@ static void setup_files(int client, const sock_cred *cred) {
...
@@ -257,15 +269,54 @@ static void setup_files(int client, const sock_cred *cred) {
return
;
return
;
}
}
bool
is_64_bit
=
str_ends
(
buf
,
"64"
);
if
(
!
zygote_started
)
{
// First zygote launch, record time
clock_gettime
(
CLOCK_MONOTONIC
,
&
last_zygote_start
);
}
if
(
zygote_start_count
)
{
// This zygote ABI had started before, kill existing zygiskd
close
(
zygiskd_sockets
[
0
]);
close
(
zygiskd_sockets
[
1
]);
zygiskd_sockets
[
0
]
=
-
1
;
zygiskd_sockets
[
1
]
=
-
1
;
}
++
zygote_start_count
;
if
(
zygote_start_count
>=
5
)
{
// Bootloop prevention
timespec
ts
;
clock_gettime
(
CLOCK_MONOTONIC
,
&
ts
);
if
(
ts
.
tv_sec
-
last_zygote_start
.
tv_sec
>
60
)
{
// This is very likely manual soft reboot
memcpy
(
&
last_zygote_start
,
&
ts
,
sizeof
(
ts
));
zygote_start_reset
(
1
);
}
else
{
// If any zygote relaunched more than 5 times within a minute,
// don't do any setups further to prevent bootloop.
zygote_start_reset
(
999
);
write_int
(
client
,
1
);
return
;
}
}
write_int
(
client
,
0
);
write_int
(
client
,
0
);
send_fd
(
client
,
is_64_bit
?
app_process_64
:
app_process_32
);
string
path
=
MAGISKTMP
+
"/"
ZYGISKBIN
"/zygisk."
+
basename
(
buf
);
string
path
=
MAGISKTMP
+
"/"
ZYGISKBIN
"/zygisk."
+
basename
(
buf
);
cp_afc
(
buf
,
(
path
+
".1.so"
).
data
());
cp_afc
(
buf
,
(
path
+
".1.so"
).
data
());
cp_afc
(
buf
,
(
path
+
".2.so"
).
data
());
cp_afc
(
buf
,
(
path
+
".2.so"
).
data
());
write_string
(
client
,
path
);
write_string
(
client
,
path
);
}
}
static
void
magiskd_passthrough
(
int
client
)
{
bool
is_64_bit
=
read_int
(
client
);
write_int
(
client
,
0
);
send_fd
(
client
,
is_64_bit
?
app_process_64
:
app_process_32
);
}
int
cached_manager_app_id
=
-
1
;
int
cached_manager_app_id
=
-
1
;
static
time_t
last_modified
=
0
;
static
time_t
last_modified
=
0
;
...
@@ -344,6 +395,9 @@ void zygisk_handler(int client, const sock_cred *cred) {
...
@@ -344,6 +395,9 @@ void zygisk_handler(int client, const sock_cred *cred) {
case
ZYGISK_SETUP
:
case
ZYGISK_SETUP
:
setup_files
(
client
,
cred
);
setup_files
(
client
,
cred
);
break
;
break
;
case
ZYGISK_PASSTHROUGH
:
magiskd_passthrough
(
client
);
break
;
case
ZYGISK_GET_INFO
:
case
ZYGISK_GET_INFO
:
get_process_info
(
client
,
cred
);
get_process_info
(
client
,
cred
);
break
;
break
;
...
...
native/jni/zygisk/hook.cpp
View file @
ea75a09f
#include <dlfcn.h>
#include <dlfcn.h>
#include <sys/mount.h>
#include <xhook.h>
#include <xhook.h>
#include <bitset>
#include <bitset>
...
@@ -143,6 +144,16 @@ DCL_HOOK_FUNC(int, fork) {
...
@@ -143,6 +144,16 @@ DCL_HOOK_FUNC(int, fork) {
return
(
g_ctx
&&
g_ctx
->
pid
>=
0
)
?
g_ctx
->
pid
:
old_fork
();
return
(
g_ctx
&&
g_ctx
->
pid
>=
0
)
?
g_ctx
->
pid
:
old_fork
();
}
}
// Unmount app_process overlays in the process's private mount namespace
DCL_HOOK_FUNC
(
int
,
unshare
,
int
flags
)
{
int
res
=
old_unshare
(
flags
);
if
(
g_ctx
&&
res
==
0
)
{
umount2
(
"/system/bin/app_process64"
,
MNT_DETACH
);
umount2
(
"/system/bin/app_process32"
,
MNT_DETACH
);
}
return
res
;
}
// This is the latest point where we can still connect to the magiskd main socket
// This is the latest point where we can still connect to the magiskd main socket
DCL_HOOK_FUNC
(
int
,
selinux_android_setcontext
,
DCL_HOOK_FUNC
(
int
,
selinux_android_setcontext
,
uid_t
uid
,
int
isSystemServer
,
const
char
*
seinfo
,
const
char
*
pkgname
)
{
uid_t
uid
,
int
isSystemServer
,
const
char
*
seinfo
,
const
char
*
pkgname
)
{
...
@@ -501,6 +512,7 @@ void hook_functions() {
...
@@ -501,6 +512,7 @@ void hook_functions() {
default_new
(
jni_method_map
);
default_new
(
jni_method_map
);
XHOOK_REGISTER
(
ANDROID_RUNTIME
,
fork
);
XHOOK_REGISTER
(
ANDROID_RUNTIME
,
fork
);
XHOOK_REGISTER
(
ANDROID_RUNTIME
,
unshare
);
XHOOK_REGISTER
(
ANDROID_RUNTIME
,
selinux_android_setcontext
);
XHOOK_REGISTER
(
ANDROID_RUNTIME
,
selinux_android_setcontext
);
XHOOK_REGISTER
(
ANDROID_RUNTIME
,
jniRegisterNativeMethods
);
XHOOK_REGISTER
(
ANDROID_RUNTIME
,
jniRegisterNativeMethods
);
XHOOK_REGISTER_SYM
(
ANDROID_RUNTIME
,
"__android_log_close"
,
android_log_close
);
XHOOK_REGISTER_SYM
(
ANDROID_RUNTIME
,
"__android_log_close"
,
android_log_close
);
...
...
native/jni/zygisk/
companio
n.cpp
→
native/jni/zygisk/
mai
n.cpp
View file @
ea75a09f
#include <sys/mount.h>
#include <dlfcn.h>
#include <dlfcn.h>
#include <fcntl.h>
#include <magisk.hpp>
#include <utils.hpp>
#include <utils.hpp>
#include <socket.hpp>
#include <socket.hpp>
#include <daemon.hpp>
#include <daemon.hpp>
#include <magisk.hpp>
#include "zygisk.hpp"
#include "zygisk.hpp"
using
namespace
std
;
using
namespace
std
;
void
zygiskd
(
int
socket
)
{
// Entrypoint for app_process overlay
int
app_process_main
(
int
argc
,
char
*
argv
[])
{
android_logging
();
char
buf
[
256
];
bool
zygote
=
false
;
if
(
auto
fp
=
open_file
(
"/proc/self/attr/current"
,
"r"
))
{
fscanf
(
fp
.
get
(),
"%s"
,
buf
);
zygote
=
(
buf
==
"u:r:zygote:s0"
sv
);
}
if
(
!
zygote
)
{
// For the non zygote case, we need to get real app_process via passthrough
// We have to connect magiskd via exec-ing magisk due to SELinux restrictions
// This is actually only relevant for calling app_process via ADB shell
// because zygisk shall already have the app_process overlays unmounted
// during app process specialization within its private mount namespace.
int
fds
[
2
];
socketpair
(
AF_UNIX
,
SOCK_STREAM
|
SOCK_CLOEXEC
,
0
,
fds
);
if
(
fork_dont_care
()
==
0
)
{
// This fd has to survive exec
fcntl
(
fds
[
1
],
F_SETFD
,
0
);
snprintf
(
buf
,
sizeof
(
buf
),
"%d"
,
fds
[
1
]);
#if defined(__LP64__)
execlp
(
"magisk"
,
"zygisk"
,
"passthrough"
,
buf
,
"1"
,
(
char
*
)
nullptr
);
#else
execlp
(
"magisk"
,
"zygisk"
,
"passthrough"
,
buf
,
"0"
,
(
char
*
)
nullptr
);
#endif
exit
(
-
1
);
}
close
(
fds
[
1
]);
if
(
read_int
(
fds
[
0
])
!=
0
)
return
1
;
int
app_proc_fd
=
recv_fd
(
fds
[
0
]);
if
(
app_proc_fd
<
0
)
return
1
;
close
(
fds
[
0
]);
snprintf
(
buf
,
sizeof
(
buf
),
"/proc/self/fd/%d"
,
app_proc_fd
);
fcntl
(
app_proc_fd
,
F_SETFD
,
FD_CLOEXEC
);
execve
(
buf
,
argv
,
environ
);
return
1
;
}
if
(
int
socket
=
connect_daemon
();
socket
>=
0
)
{
do
{
write_int
(
socket
,
ZYGISK_REQUEST
);
write_int
(
socket
,
ZYGISK_SETUP
);
if
(
read_int
(
socket
)
!=
0
)
break
;
int
app_proc_fd
=
recv_fd
(
socket
);
if
(
app_proc_fd
<
0
)
break
;
string
path
=
read_string
(
socket
);
string
lib
=
path
+
".1.so"
;
if
(
char
*
ld
=
getenv
(
"LD_PRELOAD"
))
{
char
env
[
256
];
sprintf
(
env
,
"%s:%s"
,
ld
,
lib
.
data
());
setenv
(
"LD_PRELOAD"
,
env
,
1
);
}
else
{
setenv
(
"LD_PRELOAD"
,
lib
.
data
(),
1
);
}
setenv
(
INJECT_ENV_1
,
"1"
,
1
);
close
(
socket
);
snprintf
(
buf
,
sizeof
(
buf
),
"/proc/self/fd/%d"
,
app_proc_fd
);
fcntl
(
app_proc_fd
,
F_SETFD
,
FD_CLOEXEC
);
execve
(
buf
,
argv
,
environ
);
}
while
(
false
);
close
(
socket
);
}
// If encountering any errors, unmount and execute the original app_process
xreadlink
(
"/proc/self/exe"
,
buf
,
sizeof
(
buf
));
xumount2
(
"/proc/self/exe"
,
MNT_DETACH
);
execve
(
buf
,
argv
,
environ
);
return
1
;
}
static
void
zygiskd
(
int
socket
)
{
if
(
getuid
()
!=
0
||
fcntl
(
socket
,
F_GETFD
)
<
0
)
if
(
getuid
()
!=
0
||
fcntl
(
socket
,
F_GETFD
)
<
0
)
exit
(
-
1
);
exit
(
-
1
);
android_logging
();
#if defined(__LP64__)
#if defined(__LP64__)
set_nice_name
(
"zygiskd64"
);
set_nice_name
(
"zygiskd64"
);
...
@@ -46,13 +132,17 @@ void zygiskd(int socket) {
...
@@ -46,13 +132,17 @@ void zygiskd(int socket) {
pollfd
pfd
=
{
socket
,
POLLIN
,
0
};
pollfd
pfd
=
{
socket
,
POLLIN
,
0
};
for
(;;)
{
for
(;;)
{
poll
(
&
pfd
,
1
,
-
1
);
poll
(
&
pfd
,
1
,
-
1
);
if
(
!
(
pfd
.
revents
&
POLLIN
))
{
if
(
pfd
.
revents
&&
!
(
pfd
.
revents
&
POLLIN
))
{
// Something bad happened in magiskd, terminate zygiskd
// Something bad happened in magiskd, terminate zygiskd
exit
(
0
);
exit
(
0
);
}
}
int
client
=
recv_fd
(
socket
);
int
client
=
recv_fd
(
socket
);
if
(
client
<
0
)
{
// Something bad happened in magiskd, terminate zygiskd
exit
(
0
);
}
int
module_id
=
read_int
(
client
);
int
module_id
=
read_int
(
client
);
if
(
module_id
<
modules
.
size
()
&&
modules
[
module_id
])
{
if
(
module_id
>=
0
&&
module_id
<
modules
.
size
()
&&
modules
[
module_id
])
{
exec_task
([
=
,
entry
=
modules
[
module_id
]]
{
exec_task
([
=
,
entry
=
modules
[
module_id
]]
{
int
dup
=
fcntl
(
client
,
F_DUPFD_CLOEXEC
);
int
dup
=
fcntl
(
client
,
F_DUPFD_CLOEXEC
);
entry
(
client
);
entry
(
client
);
...
@@ -75,40 +165,35 @@ void zygiskd(int socket) {
...
@@ -75,40 +165,35 @@ void zygiskd(int socket) {
}
}
}
}
static
int
zygiskd_sockets
[]
=
{
-
1
,
-
1
};
// Entrypoint where we need to re-exec ourselves
#define zygiskd_socket zygiskd_sockets[is_64_bit]
// This should only ever be called internally
int
zygisk_main
(
int
argc
,
char
*
argv
[])
{
android_logging
();
void
connect_companion
(
int
client
,
bool
is_64_bit
)
{
if
(
argc
==
3
&&
argv
[
1
]
==
"companion"
sv
)
{
if
(
zygiskd_socket
>=
0
)
{
zygiskd
(
parse_int
(
argv
[
2
]));
// Make sure the socket is still valid
}
else
if
(
argc
==
4
&&
argv
[
1
]
==
"passthrough"
sv
)
{
pollfd
pfd
=
{
zygiskd_socket
,
0
,
0
};
int
client
=
parse_int
(
argv
[
2
]);
poll
(
&
pfd
,
1
,
0
);
int
is_64_bit
=
parse_int
(
argv
[
3
]);
if
(
pfd
.
revents
)
{
if
(
fcntl
(
client
,
F_GETFD
)
<
0
)
// Any revent means error
return
1
;
close
(
zygiskd_socket
);
if
(
int
magiskd
=
connect_daemon
();
magiskd
>=
0
)
{
zygiskd_socket
=
-
1
;
write_int
(
magiskd
,
ZYGISK_PASSTHROUGH
);
}
write_int
(
magiskd
,
ZYGISK_PASSTHROUGH
);
}
write_int
(
magiskd
,
is_64_bit
);
if
(
zygiskd_socket
<
0
)
{
int
fds
[
2
];
if
(
read_int
(
magiskd
)
!=
0
)
{
socketpair
(
AF_UNIX
,
SOCK_STREAM
|
SOCK_CLOEXEC
,
0
,
fds
);
write_int
(
client
,
1
);
zygiskd_socket
=
fds
[
0
];
return
0
;
if
(
fork_dont_care
()
==
0
)
{
string
exe
=
MAGISKTMP
+
"/magisk"
+
(
is_64_bit
?
"64"
:
"32"
);
// This fd has to survive exec
fcntl
(
fds
[
1
],
F_SETFD
,
0
);
char
buf
[
16
];
snprintf
(
buf
,
sizeof
(
buf
),
"%d"
,
fds
[
1
]);
execlp
(
exe
.
data
(),
"magisk"
,
"--companion"
,
buf
,
(
char
*
)
nullptr
);
exit
(
-
1
);
}
}
close
(
fds
[
1
]);
vector
<
int
>
module_fds
=
zygisk_module_fds
(
is_64_bit
);
write_int
(
client
,
0
);
send_fds
(
zygiskd_socket
,
module_fds
.
data
(),
module_fds
.
size
());
int
real_app_fd
=
recv_fd
(
magiskd
);
// Wait for ack
send_fd
(
client
,
real_app_fd
);
if
(
read_int
(
zygiskd_socket
)
!=
0
)
{
}
else
{
return
;
write_int
(
client
,
1
);
return
0
;
}
}
}
}
send_fd
(
zygiskd_socket
,
client
)
;
return
0
;
}
}
native/jni/zygisk/zygisk.hpp
View file @
ea75a09f
...
@@ -47,4 +47,3 @@ void hook_functions();
...
@@ -47,4 +47,3 @@ void hook_functions();
bool
unhook_functions
();
bool
unhook_functions
();
std
::
vector
<
int
>
remote_get_info
(
int
uid
,
const
char
*
process
,
AppInfo
*
info
);
std
::
vector
<
int
>
remote_get_info
(
int
uid
,
const
char
*
process
,
AppInfo
*
info
);
int
remote_request_unmount
();
int
remote_request_unmount
();
void
connect_companion
(
int
client
,
bool
is_64_bit
);
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment