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
171d68ca
Commit
171d68ca
authored
Aug 21, 2021
by
topjohnwu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Connect to magiskd log daemon
parent
bade4f2c
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
163 additions
and
39 deletions
+163
-39
core.hpp
native/jni/core/core.hpp
+1
-0
logging.cpp
native/jni/core/logging.cpp
+11
-2
daemon.hpp
native/jni/include/daemon.hpp
+4
-1
missing.hpp
native/jni/utils/missing.hpp
+10
-0
entry.cpp
native/jni/zygisk/entry.cpp
+64
-3
hook.cpp
native/jni/zygisk/hook.cpp
+72
-33
inject.hpp
native/jni/zygisk/inject.hpp
+1
-0
No files found.
native/jni/core/core.hpp
View file @
171d68ca
...
...
@@ -10,6 +10,7 @@ void unlock_blocks();
void
reboot
();
void
start_log_daemon
();
void
setup_logfile
(
bool
reset
);
void
magisk_logging
();
// Module stuffs
void
handle_modules
();
...
...
native/jni/core/logging.cpp
View file @
171d68ca
...
...
@@ -17,7 +17,7 @@ struct log_meta {
int
tid
;
};
static
atomic
<
int
>
logd_fd
=
-
1
;
atomic
<
int
>
logd_fd
=
-
1
;
void
setup_logfile
(
bool
reset
)
{
if
(
logd_fd
<
0
)
...
...
@@ -121,7 +121,7 @@ static void logfile_writer(int pipefd) {
}
}
static
int
magisk_log
(
int
prio
,
const
char
*
fmt
,
va_list
ap
)
{
int
magisk_log
(
int
prio
,
const
char
*
fmt
,
va_list
ap
)
{
char
buf
[
MAX_MSG_LEN
+
1
];
int
len
=
vsnprintf
(
buf
,
sizeof
(
buf
),
fmt
,
ap
);
...
...
@@ -172,6 +172,15 @@ void magisk_logging() {
log_cb
.
ex
=
nop_ex
;
}
#define alog(prio) [](auto fmt, auto ap){ return __android_log_vprint(ANDROID_LOG_##prio, "Magisk", fmt, ap); }
void
android_logging
()
{
log_cb
.
d
=
alog
(
DEBUG
);
log_cb
.
i
=
alog
(
INFO
);
log_cb
.
w
=
alog
(
WARN
);
log_cb
.
e
=
alog
(
ERROR
);
log_cb
.
ex
=
nop_ex
;
}
void
start_log_daemon
()
{
int
fds
[
2
];
if
(
pipe2
(
fds
,
O_CLOEXEC
)
==
0
)
{
...
...
native/jni/include/daemon.hpp
View file @
171d68ca
...
...
@@ -3,6 +3,7 @@
#include <pthread.h>
#include <string>
#include <limits>
#include <atomic>
#include <socket.hpp>
...
...
@@ -48,7 +49,9 @@ enum : int {
int
connect_daemon
(
bool
create
=
false
);
void
magisk_logging
();
extern
std
::
atomic
<
int
>
logd_fd
;
int
magisk_log
(
int
prio
,
const
char
*
fmt
,
va_list
ap
);
void
android_logging
();
// Daemon handlers
void
post_fs_data
(
int
client
);
...
...
native/jni/utils/missing.hpp
View file @
171d68ca
...
...
@@ -22,6 +22,7 @@
#define linkat compat_linkat
#define inotify_init1 compat_inotify_init1
#define faccessat compat_faccessat
#define sigtimedwait compat_sigtimedwait
ssize_t
compat_getline
(
char
**
lineptr
,
size_t
*
n
,
FILE
*
stream
);
ssize_t
compat_getdelim
(
char
**
lineptr
,
size_t
*
n
,
int
delim
,
FILE
*
stream
);
...
...
@@ -66,3 +67,12 @@ static inline int compat_inotify_init1(int flags) {
static
inline
int
compat_faccessat
(
int
dirfd
,
const
char
*
pathname
,
int
mode
,
int
flags
)
{
return
syscall
(
__NR_faccessat
,
dirfd
,
pathname
,
mode
,
flags
);
}
static
inline
int
compat_sigtimedwait
(
const
sigset_t
*
set
,
siginfo_t
*
info
,
const
timespec
*
timeout
)
{
union
{
sigset_t
set
;
sigset_t
set64
;
}
s
{};
s
.
set
=
*
set
;
return
syscall
(
__NR_rt_sigtimedwait
,
&
s
.
set64
,
info
,
timeout
,
sizeof
(
sigset64_t
));
}
native/jni/zygisk/entry.cpp
View file @
171d68ca
...
...
@@ -3,6 +3,7 @@
#include <sys/mount.h>
#include <sys/sendfile.h>
#include <sys/prctl.h>
#include <android/log.h>
#include <utils.hpp>
#include <daemon.hpp>
...
...
@@ -16,6 +17,17 @@ using namespace std;
static
void
*
self_handle
=
nullptr
;
static
atomic
<
int
>
active_threads
=
-
1
;
static
int
zygisk_log
(
int
prio
,
const
char
*
fmt
,
va_list
ap
);
#define zlog(prio) [](auto fmt, auto ap){ return zygisk_log(ANDROID_LOG_##prio, fmt, ap); }
static
void
zygisk_logging
()
{
log_cb
.
d
=
zlog
(
DEBUG
);
log_cb
.
i
=
zlog
(
INFO
);
log_cb
.
w
=
zlog
(
WARN
);
log_cb
.
e
=
zlog
(
ERROR
);
log_cb
.
ex
=
nop_ex
;
}
void
self_unload
()
{
LOGD
(
"zygisk: Request to self unload
\n
"
);
// If deny failed, do not unload or else it will cause SIGSEGV
...
...
@@ -81,7 +93,7 @@ static void inject_cleanup_wait() {
__attribute__
((
constructor
))
static
void
inject_init
()
{
if
(
char
*
env
=
getenv
(
INJECT_ENV_2
))
{
ma
gisk_logging
();
zy
gisk_logging
();
LOGD
(
"zygisk: inject 2nd stage
\n
"
);
active_threads
=
1
;
unsetenv
(
INJECT_ENV_2
);
...
...
@@ -100,7 +112,7 @@ static void inject_init() {
active_threads
++
;
new_daemon_thread
(
&
unload_first_stage
,
env
);
}
else
if
(
getenv
(
INJECT_ENV_1
))
{
magisk
_logging
();
android
_logging
();
LOGD
(
"zygisk: inject 1st stage
\n
"
);
char
*
ld
=
getenv
(
"LD_PRELOAD"
);
...
...
@@ -128,7 +140,7 @@ static void inject_init() {
// Start code for magiskd IPC
int
app_process_main
(
int
argc
,
char
*
argv
[])
{
magisk
_logging
();
android
_logging
();
if
(
int
fd
=
connect_daemon
();
fd
>=
0
)
{
write_int
(
fd
,
ZYGISK_REQUEST
);
...
...
@@ -157,6 +169,42 @@ int app_process_main(int argc, char *argv[]) {
return
1
;
}
static
int
zygisk_log
(
int
prio
,
const
char
*
fmt
,
va_list
ap
)
{
// If we don't have log pipe set, ask magiskd for it
// This could happen multiple times in zygote because it was closed to prevent crashing
if
(
logd_fd
<
0
)
{
// Change logging temporarily to prevent infinite recursion and stack overflow
android_logging
();
if
(
int
fd
=
connect_daemon
();
fd
>=
0
)
{
write_int
(
fd
,
ZYGISK_REQUEST
);
write_int
(
fd
,
ZYGISK_GET_LOG_PIPE
);
if
(
read_int
(
fd
)
==
0
)
{
logd_fd
=
recv_fd
(
fd
);
}
close
(
fd
);
}
zygisk_logging
();
}
sigset_t
mask
;
sigset_t
orig_mask
;
bool
sig
=
false
;
// Make sure SIGPIPE won't crash zygote
if
(
logd_fd
>=
0
)
{
sig
=
true
;
sigemptyset
(
&
mask
);
sigaddset
(
&
mask
,
SIGPIPE
);
pthread_sigmask
(
SIG_BLOCK
,
&
mask
,
&
orig_mask
);
}
int
ret
=
magisk_log
(
prio
,
fmt
,
ap
);
if
(
sig
)
{
timespec
ts
{};
sigtimedwait
(
&
mask
,
nullptr
,
&
ts
);
pthread_sigmask
(
SIG_SETMASK
,
&
orig_mask
,
nullptr
);
}
return
ret
;
}
bool
remote_check_denylist
(
int
uid
,
const
char
*
process
)
{
if
(
int
fd
=
connect_daemon
();
fd
>=
0
)
{
write_int
(
fd
,
ZYGISK_REQUEST
);
...
...
@@ -226,6 +274,16 @@ static void do_unmount(int client, ucred *cred) {
}
}
static
void
send_log_pipe
(
int
fd
)
{
// There is race condition here, but we can't really do much about it...
if
(
logd_fd
)
{
write_int
(
fd
,
0
);
send_fd
(
fd
,
logd_fd
);
}
else
{
write_int
(
fd
,
1
);
}
}
void
zygisk_handler
(
int
client
,
ucred
*
cred
)
{
int
code
=
read_int
(
client
);
switch
(
code
)
{
...
...
@@ -238,6 +296,9 @@ void zygisk_handler(int client, ucred *cred) {
case
ZYGISK_UNMOUNT
:
do_unmount
(
client
,
cred
);
break
;
case
ZYGISK_GET_LOG_PIPE
:
send_log_pipe
(
client
);
break
;
}
close
(
client
);
}
native/jni/zygisk/hook.cpp
View file @
171d68ca
...
...
@@ -24,10 +24,12 @@ namespace {
enum
{
DENY_FLAG
,
FORK_AND_SPECIALIZE
,
APP_SPECIALIZE
,
SERVER_SPECIALIZE
,
FLAG_MAX
};
#define DCL_
JNI_FUNC
(name) \
#define DCL_
PRE_POST
(name) \
void name##_pre(); \
void name##_post();
...
...
@@ -44,15 +46,17 @@ struct HookContext {
HookContext
()
:
pid
(
-
1
)
{}
void
pre_fork
();
static
void
post_fork
();
static
void
close_fds
();
DCL_JNI_FUNC
(
nativeForkAndSpecialize
)
DCL_JNI_FUNC
(
nativeSpecializeAppProcess
)
DCL_JNI_FUNC
(
nativeForkSystemServer
)
DCL_PRE_POST
(
fork
)
DCL_PRE_POST
(
run_modules
)
DCL_PRE_POST
(
nativeForkAndSpecialize
)
DCL_PRE_POST
(
nativeSpecializeAppProcess
)
DCL_PRE_POST
(
nativeForkSystemServer
)
};
#undef DCL_
JNI_FUNC
#undef DCL_
PRE_POST
struct
StringCmp
{
using
is_transparent
=
void
;
...
...
@@ -127,15 +131,15 @@ DCL_HOOK_FUNC(int, jniRegisterNativeMethods,
return
old_jniRegisterNativeMethods
(
env
,
className
,
newMethods
.
get
()
?:
methods
,
numMethods
);
}
// Skip actual fork and return cached result if applicable
DCL_HOOK_FUNC
(
int
,
fork
)
{
return
(
g_ctx
&&
g_ctx
->
pid
>=
0
)
?
g_ctx
->
pid
:
old_fork
();
}
// This is the latest point where we can still connect to the magiskd main socket
DCL_HOOK_FUNC
(
int
,
selinux_android_setcontext
,
uid_t
uid
,
int
isSystemServer
,
const
char
*
seinfo
,
const
char
*
pkgname
)
{
if
(
g_ctx
&&
g_ctx
->
flags
[
DENY_FLAG
])
{
// Request magiskd to cleanup our mount namespace before switching secontext
// This is the latest point where we can still connect to the magiskd main socket
if
(
remote_request_unmount
()
==
0
)
{
LOGD
(
"zygisk: mount namespace cleaned up
\n
"
);
}
...
...
@@ -143,6 +147,16 @@ DCL_HOOK_FUNC(int, selinux_android_setcontext,
return
old_selinux_android_setcontext
(
uid
,
isSystemServer
,
seinfo
,
pkgname
);
}
// A place to clean things up before calling into zygote::ForkCommon/SpecializeCommon
DCL_HOOK_FUNC
(
void
,
android_log_close
)
{
HookContext
::
close_fds
();
if
(
g_ctx
&&
g_ctx
->
pid
<=
0
)
{
// In child process, no longer be able to access to magiskd
android_logging
();
}
old_android_log_close
();
}
// -----------------------------------------------------------------
// The original android::AppRuntime virtual table
...
...
@@ -208,8 +222,18 @@ DCL_HOOK_FUNC(void, setArgv0, void *self, const char *argv0, bool setProcName) {
// -----------------------------------------------------------------
void
HookContext
::
run_modules_pre
()
{
/* TODO */
}
void
HookContext
::
run_modules_post
()
{
/* TODO */
}
void
HookContext
::
close_fds
()
{
close
(
logd_fd
.
exchange
(
-
1
));
}
// -----------------------------------------------------------------
void
HookContext
::
nativeSpecializeAppProcess_pre
()
{
g_ctx
=
this
;
flags
[
APP_SPECIALIZE
]
=
true
;
process
=
env
->
GetStringUTFChars
(
args
->
nice_name
,
nullptr
);
if
(
flags
[
FORK_AND_SPECIALIZE
])
{
VLOG
(
"zygisk: pre forkAndSpecialize [%s]
\n
"
,
process
);
...
...
@@ -221,6 +245,8 @@ void HookContext::nativeSpecializeAppProcess_pre() {
if
(
args
->
mount_external
!=
0
&&
remote_check_denylist
(
args
->
uid
,
process
))
{
flags
[
DENY_FLAG
]
=
true
;
LOGI
(
"zygisk: [%s] is on the denylist
\n
"
,
process
);
}
else
{
run_modules_pre
();
}
}
...
...
@@ -232,24 +258,49 @@ void HookContext::nativeSpecializeAppProcess_post() {
}
env
->
ReleaseStringUTFChars
(
args
->
nice_name
,
process
);
if
(
flags
[
DENY_FLAG
])
if
(
flags
[
DENY_FLAG
])
{
self_unload
();
}
else
{
run_modules_post
();
}
g_ctx
=
nullptr
;
}
void
HookContext
::
nativeForkSystemServer_pre
()
{
pre_fork
();
if
(
pid
)
return
;
VLOG
(
"zygisk: pre forkSystemServer
\n
"
);
fork_pre
();
flags
[
SERVER_SPECIALIZE
]
=
true
;
if
(
pid
==
0
)
{
VLOG
(
"zygisk: pre forkSystemServer
\n
"
);
run_modules_pre
();
close_fds
();
}
}
void
HookContext
::
nativeForkSystemServer_post
()
{
run_finally
f
([]{
post_fork
();
});
if
(
pid
)
return
;
VLOG
(
"zygisk: post forkSystemServer
\n
"
);
if
(
pid
==
0
)
{
android_logging
();
VLOG
(
"zygisk: post forkSystemServer
\n
"
);
run_modules_post
();
}
fork_post
();
}
// -----------------------------------------------------------------
void
HookContext
::
nativeForkAndSpecialize_pre
()
{
fork_pre
();
flags
[
FORK_AND_SPECIALIZE
]
=
true
;
if
(
pid
==
0
)
{
nativeSpecializeAppProcess_pre
();
close_fds
();
}
}
void
HookContext
::
nativeForkAndSpecialize_post
()
{
if
(
pid
==
0
)
{
android_logging
();
nativeSpecializeAppProcess_post
();
}
fork_post
();
}
int
sigmask
(
int
how
,
int
signum
)
{
sigset_t
set
;
...
...
@@ -260,31 +311,18 @@ int sigmask(int how, int signum) {
// Do our own fork before loading any 3rd party code
// First block SIGCHLD, unblock after original fork is done
void
HookContext
::
pre_fork
()
{
void
HookContext
::
fork_pre
()
{
g_ctx
=
this
;
sigmask
(
SIG_BLOCK
,
SIGCHLD
);
pid
=
old_fork
();
}
// Unblock SIGCHLD in case the original method didn't
void
HookContext
::
post_fork
()
{
void
HookContext
::
fork_post
()
{
sigmask
(
SIG_UNBLOCK
,
SIGCHLD
);
g_ctx
=
nullptr
;
}
void
HookContext
::
nativeForkAndSpecialize_pre
()
{
pre_fork
();
flags
[
FORK_AND_SPECIALIZE
]
=
true
;
if
(
pid
==
0
)
nativeSpecializeAppProcess_pre
();
}
void
HookContext
::
nativeForkAndSpecialize_post
()
{
if
(
pid
==
0
)
nativeSpecializeAppProcess_post
();
post_fork
();
}
}
// namespace
static
bool
hook_refresh
()
{
...
...
@@ -315,7 +353,7 @@ static int hook_register(const char *path, const char *symbol, void *new_func, v
XHOOK_REGISTER_SYM(PATH_REGEX, #NAME, NAME)
#define ANDROID_RUNTIME ".*/libandroid_runtime.so$"
#define APP_PROCESS "^/system/bin/app_process.*"
#define APP_PROCESS
"^/system/bin/app_process.*"
void
hook_functions
()
{
#ifdef MAGISK_DEBUG
...
...
@@ -329,6 +367,7 @@ void hook_functions() {
XHOOK_REGISTER
(
ANDROID_RUNTIME
,
fork
);
XHOOK_REGISTER
(
ANDROID_RUNTIME
,
selinux_android_setcontext
);
XHOOK_REGISTER
(
ANDROID_RUNTIME
,
jniRegisterNativeMethods
);
XHOOK_REGISTER_SYM
(
ANDROID_RUNTIME
,
"__android_log_close"
,
android_log_close
);
hook_refresh
();
// Remove unhooked methods
...
...
native/jni/zygisk/inject.hpp
View file @
171d68ca
...
...
@@ -10,6 +10,7 @@ enum : int {
ZYGISK_SETUP
,
ZYGISK_CHECK_DENYLIST
,
ZYGISK_UNMOUNT
,
ZYGISK_GET_LOG_PIPE
,
};
// Unmap all pages matching the name
...
...
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