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
504a9b47
Commit
504a9b47
authored
Jul 10, 2017
by
topjohnwu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
MagiskHide refactor
parent
cccb5a3e
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
125 additions
and
190 deletions
+125
-190
Android.mk
jni/Android.mk
+0
-1
hide_daemon.c
jni/magiskhide/hide_daemon.c
+0
-129
hide_utils.c
jni/magiskhide/hide_utils.c
+2
-2
magiskhide.h
jni/magiskhide/magiskhide.h
+2
-5
proc_monitor.c
jni/magiskhide/proc_monitor.c
+121
-53
No files found.
jni/Android.mk
View file @
504a9b47
...
@@ -25,7 +25,6 @@ LOCAL_SRC_FILES := \
...
@@ -25,7 +25,6 @@ LOCAL_SRC_FILES := \
daemon/log_monitor.c \
daemon/log_monitor.c \
daemon/bootstages.c \
daemon/bootstages.c \
magiskhide/magiskhide.c \
magiskhide/magiskhide.c \
magiskhide/hide_daemon.c \
magiskhide/proc_monitor.c \
magiskhide/proc_monitor.c \
magiskhide/hide_utils.c \
magiskhide/hide_utils.c \
magiskpolicy/magiskpolicy.c \
magiskpolicy/magiskpolicy.c \
...
...
jni/magiskhide/hide_daemon.c
deleted
100644 → 0
View file @
cccb5a3e
/* hide_daemon.c - MagiskHide daemon
*
* A dedicated process to join the target namespace,
* and hide all traces in that particular namespace
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mount.h>
#include "magisk.h"
#include "utils.h"
#include "magiskhide.h"
static
int
pid
;
static
void
lazy_unmount
(
const
char
*
mountpoint
)
{
if
(
umount2
(
mountpoint
,
MNT_DETACH
)
!=
-
1
)
LOGI
(
"hide_daemon: Unmounted (%s)
\n
"
,
mountpoint
);
else
LOGI
(
"hide_daemon: Unmount Failed (%s)
\n
"
,
mountpoint
);
}
static
void
hide_daemon_err
()
{
LOGD
(
"hide_daemon: error occured, stopping magiskhide services
\n
"
);
// Resume process if possible
kill
(
pid
,
SIGCONT
);
int
err
=
1
;
write
(
sv
[
1
],
&
err
,
sizeof
(
err
));
_exit
(
-
1
);
}
int
hide_daemon
()
{
// Fork to a new process
hide_pid
=
fork
();
switch
(
hide_pid
)
{
case
-
1
:
PLOGE
(
"fork"
);
return
1
;
case
0
:
break
;
default:
return
0
;
}
close
(
sv
[
0
]);
// Set the process name
strcpy
(
argv0
,
"magiskhide_daemon"
);
LOGD
(
"hide_daemon: listening for hide requests"
);
// When an error occurs, report its failure to main process
err_handler
=
hide_daemon_err
;
char
buffer
[
4096
],
cache_block
[
256
],
*
line
;
struct
vector
mount_list
;
cache_block
[
0
]
=
'\0'
;
while
(
1
)
{
xxread
(
sv
[
1
],
&
pid
,
sizeof
(
pid
));
// Termination called
if
(
pid
==
-
1
)
{
LOGD
(
"hide_daemon: received termination request
\n
"
);
_exit
(
0
);
}
manage_selinux
();
relink_sbin
();
if
(
switch_mnt_ns
(
pid
))
continue
;
snprintf
(
buffer
,
sizeof
(
buffer
),
"/proc/%d/mounts"
,
pid
);
vec_init
(
&
mount_list
);
file_to_vector
(
buffer
,
&
mount_list
);
// Find the cache block name if not found yet
if
(
strlen
(
cache_block
)
==
0
)
{
vec_for_each
(
&
mount_list
,
line
)
{
if
(
strstr
(
line
,
" /cache "
))
{
sscanf
(
line
,
"%256s"
,
cache_block
);
break
;
}
}
}
// First unmount dummy skeletons, /sbin links, cache mounts, and mirrors
vec_for_each
(
&
mount_list
,
line
)
{
if
(
strstr
(
line
,
"tmpfs /system"
)
||
strstr
(
line
,
"tmpfs /vendor"
)
||
strstr
(
line
,
"tmpfs /sbin"
)
||
(
strstr
(
line
,
cache_block
)
&&
(
strstr
(
line
,
" /system"
)
||
strstr
(
line
,
" /vendor"
)))
||
strstr
(
line
,
MIRRDIR
))
{
sscanf
(
line
,
"%*s %512s"
,
buffer
);
lazy_unmount
(
buffer
);
}
free
(
line
);
}
vec_destroy
(
&
mount_list
);
// Re-read mount infos
snprintf
(
buffer
,
sizeof
(
buffer
),
"/proc/%d/mounts"
,
pid
);
vec_init
(
&
mount_list
);
file_to_vector
(
buffer
,
&
mount_list
);
// Unmount any loop mounts and dummy mounts
vec_for_each
(
&
mount_list
,
line
)
{
if
(
strstr
(
line
,
"/dev/block/loop"
)
||
strstr
(
line
,
DUMMDIR
))
{
sscanf
(
line
,
"%*s %512s"
,
buffer
);
lazy_unmount
(
buffer
);
}
free
(
line
);
}
vec_destroy
(
&
mount_list
);
// All done, send resume signal
kill
(
pid
,
SIGCONT
);
// Tell main process all is well
pid
=
0
;
xwrite
(
sv
[
1
],
&
pid
,
sizeof
(
pid
));
}
// Should never go here
}
jni/magiskhide/hide_utils.c
View file @
504a9b47
...
@@ -44,7 +44,7 @@ void manage_selinux() {
...
@@ -44,7 +44,7 @@ void manage_selinux() {
}
}
void
hide_sensitive_props
()
{
void
hide_sensitive_props
()
{
LOGI
(
"hide_
pre_proc
: Hiding sensitive props
\n
"
);
LOGI
(
"hide_
utils
: Hiding sensitive props
\n
"
);
// Hide all sensitive props
// Hide all sensitive props
char
*
value
;
char
*
value
;
...
@@ -66,7 +66,7 @@ void relink_sbin() {
...
@@ -66,7 +66,7 @@ void relink_sbin() {
struct
dirent
*
entry
;
struct
dirent
*
entry
;
char
from
[
PATH_MAX
],
to
[
PATH_MAX
];
char
from
[
PATH_MAX
],
to
[
PATH_MAX
];
LOGI
(
"hide_
pre_proc
: Re-linking /sbin
\n
"
);
LOGI
(
"hide_
utils
: Re-linking /sbin
\n
"
);
xmount
(
NULL
,
"/"
,
NULL
,
MS_REMOUNT
,
NULL
);
xmount
(
NULL
,
"/"
,
NULL
,
MS_REMOUNT
,
NULL
);
xrename
(
"/sbin"
,
"/sbin_orig"
);
xrename
(
"/sbin"
,
"/sbin_orig"
);
...
...
jni/magiskhide/magiskhide.h
View file @
504a9b47
...
@@ -6,13 +6,10 @@
...
@@ -6,13 +6,10 @@
// Kill process
// Kill process
void
kill_proc
(
int
pid
);
void
kill_proc
(
int
pid
);
// Hide daemon
int
hide_daemon
();
// Process monitor
// Process monitor
void
proc_monitor
();
void
proc_monitor
();
//
Preproces
s
//
Utility function
s
void
manage_selinux
();
void
manage_selinux
();
void
hide_sensitive_props
();
void
hide_sensitive_props
();
void
relink_sbin
();
void
relink_sbin
();
...
@@ -23,7 +20,7 @@ int rm_list(char *proc);
...
@@ -23,7 +20,7 @@ int rm_list(char *proc);
int
init_list
();
int
init_list
();
int
destroy_list
();
int
destroy_list
();
extern
int
sv
[
2
],
hide_pid
,
hideEnabled
;
extern
int
hideEnabled
;
extern
struct
vector
*
hide_list
;
extern
struct
vector
*
hide_list
;
extern
pthread_mutex_t
hide_lock
,
file_lock
;
extern
pthread_mutex_t
hide_lock
,
file_lock
;
...
...
jni/magiskhide/proc_monitor.c
View file @
504a9b47
/* proc_monitor.c - Monitor am_proc_start events
/* proc_monitor.c - Monitor am_proc_start events
and unmount
*
*
* We monitor the logcat am_proc_start events, pause it,
* We monitor the logcat am_proc_start events. When a target starts up,
* and send the target PID to hide daemon ASAP
* we pause it ASAP, and fork a new process to join its mount namespace
* and do all the unmounting/mocking
*/
*/
#include <stdlib.h>
#include <stdlib.h>
...
@@ -12,18 +13,17 @@
...
@@ -12,18 +13,17 @@
#include <pthread.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/wait.h>
#include <sys/mount.h>
#include "magisk.h"
#include "magisk.h"
#include "utils.h"
#include "utils.h"
#include "magiskhide.h"
#include "magiskhide.h"
static
int
zygote_num
;
static
int
zygote_num
;
static
char
init_ns
[
32
],
zygote_ns
[
2
][
32
];
static
char
init_ns
[
32
],
zygote_ns
[
2
][
32
]
,
cache_block
[
256
]
;
static
int
log_pid
,
log_fd
;
static
int
log_pid
,
log_fd
,
target_pid
;
static
char
*
buffer
;
static
char
*
buffer
;
int
sv
[
2
],
hide_pid
=
-
1
;
// Workaround for the lack of pthread_cancel
// Workaround for the lack of pthread_cancel
static
void
quit_pthread
(
int
sig
)
{
static
void
quit_pthread
(
int
sig
)
{
err_handler
=
do_nothing
;
err_handler
=
do_nothing
;
...
@@ -32,17 +32,14 @@ static void quit_pthread(int sig) {
...
@@ -32,17 +32,14 @@ static void quit_pthread(int sig) {
free
(
buffer
);
free
(
buffer
);
hideEnabled
=
0
;
hideEnabled
=
0
;
// Kill the logging if needed
// Kill the logging if needed
if
(
log_pid
)
{
if
(
log_pid
>
0
)
{
kill
(
log_pid
,
SIGTERM
);
kill
(
log_pid
,
SIGTERM
);
waitpid
(
log_pid
,
NULL
,
0
);
waitpid
(
log_pid
,
NULL
,
0
);
close
(
log_fd
);
close
(
log_fd
);
log_fd
=
log_pid
=
0
;
}
}
int
kill
=
-
1
;
// Resume process if possible
// If process monitor dies, kill hide daemon too
if
(
target_pid
>
0
)
write
(
sv
[
0
],
&
kill
,
sizeof
(
kill
));
kill
(
target_pid
,
SIGCONT
);
close
(
sv
[
0
]);
waitpid
(
hide_pid
,
NULL
,
0
);
pthread_mutex_destroy
(
&
hide_lock
);
pthread_mutex_destroy
(
&
hide_lock
);
pthread_mutex_destroy
(
&
file_lock
);
pthread_mutex_destroy
(
&
file_lock
);
LOGD
(
"proc_monitor: terminating...
\n
"
);
LOGD
(
"proc_monitor: terminating...
\n
"
);
...
@@ -54,15 +51,13 @@ static void proc_monitor_err() {
...
@@ -54,15 +51,13 @@ static void proc_monitor_err() {
quit_pthread
(
SIGUSR1
);
quit_pthread
(
SIGUSR1
);
}
}
static
void
read_namespace
(
const
int
pid
,
char
*
target
,
const
size_t
size
)
{
static
int
read_namespace
(
const
int
pid
,
char
*
target
,
const
size_t
size
)
{
char
path
[
32
];
char
path
[
32
];
snprintf
(
path
,
sizeof
(
path
),
"/proc/%d/ns/mnt"
,
pid
);
snprintf
(
path
,
sizeof
(
path
),
"/proc/%d/ns/mnt"
,
pid
);
if
(
access
(
path
,
R_OK
)
==
-
1
)
{
if
(
access
(
path
,
R_OK
)
==
-
1
)
LOGE
(
"proc_monitor: Your kernel doesn't support mount namespace :(
\n
"
);
return
1
;
proc_monitor_err
();
return
;
}
xreadlink
(
path
,
target
,
size
);
xreadlink
(
path
,
target
,
size
);
return
0
;
}
}
static
void
store_zygote_ns
(
int
pid
)
{
static
void
store_zygote_ns
(
int
pid
)
{
...
@@ -74,6 +69,76 @@ static void store_zygote_ns(int pid) {
...
@@ -74,6 +69,76 @@ static void store_zygote_ns(int pid) {
++
zygote_num
;
++
zygote_num
;
}
}
static
void
lazy_unmount
(
const
char
*
mountpoint
)
{
if
(
umount2
(
mountpoint
,
MNT_DETACH
)
!=
-
1
)
LOGD
(
"hide_daemon: Unmounted (%s)
\n
"
,
mountpoint
);
else
LOGD
(
"hide_daemon: Unmount Failed (%s)
\n
"
,
mountpoint
);
}
static
void
hide_daemon_err
()
{
LOGD
(
"hide_daemon: error occured, stopping magiskhide services
\n
"
);
_exit
(
-
1
);
}
static
void
hide_daemon
(
int
pid
)
{
LOGD
(
"hide_daemon: start unmount for pid=[%d]
\n
"
,
pid
);
// When an error occurs, report its failure to main process
err_handler
=
hide_daemon_err
;
char
*
line
;
struct
vector
mount_list
;
manage_selinux
();
relink_sbin
();
if
(
switch_mnt_ns
(
pid
))
return
;
snprintf
(
buffer
,
PATH_MAX
,
"/proc/%d/mounts"
,
pid
);
vec_init
(
&
mount_list
);
file_to_vector
(
buffer
,
&
mount_list
);
// Find the cache block name if not found yet
if
(
cache_block
[
0
]
==
'\0'
)
{
vec_for_each
(
&
mount_list
,
line
)
{
if
(
strstr
(
line
,
" /cache "
))
{
sscanf
(
line
,
"%256s"
,
cache_block
);
break
;
}
}
}
// First unmount dummy skeletons, /sbin links, cache mounts, and mirrors
vec_for_each
(
&
mount_list
,
line
)
{
if
(
strstr
(
line
,
"tmpfs /system"
)
||
strstr
(
line
,
"tmpfs /vendor"
)
||
strstr
(
line
,
"tmpfs /sbin"
)
||
(
strstr
(
line
,
cache_block
)
&&
(
strstr
(
line
,
" /system"
)
||
strstr
(
line
,
" /vendor"
)))
||
strstr
(
line
,
MIRRDIR
))
{
sscanf
(
line
,
"%*s %4096s"
,
buffer
);
lazy_unmount
(
buffer
);
}
free
(
line
);
}
vec_destroy
(
&
mount_list
);
// Re-read mount infos
snprintf
(
buffer
,
PATH_MAX
,
"/proc/%d/mounts"
,
pid
);
vec_init
(
&
mount_list
);
file_to_vector
(
buffer
,
&
mount_list
);
// Unmount any loop mounts and dummy mounts
vec_for_each
(
&
mount_list
,
line
)
{
if
(
strstr
(
line
,
"/dev/block/loop"
)
||
strstr
(
line
,
DUMMDIR
))
{
sscanf
(
line
,
"%*s %4096s"
,
buffer
);
lazy_unmount
(
buffer
);
}
free
(
line
);
}
// Free uo memory
vec_destroy
(
&
mount_list
);
}
void
proc_monitor
()
{
void
proc_monitor
()
{
// Register the cancel signal
// Register the cancel signal
struct
sigaction
act
;
struct
sigaction
act
;
...
@@ -83,12 +148,16 @@ void proc_monitor() {
...
@@ -83,12 +148,16 @@ void proc_monitor() {
// The error handler should stop magiskhide services
// The error handler should stop magiskhide services
err_handler
=
proc_monitor_err
;
err_handler
=
proc_monitor_err
;
log_pid
=
target_pid
=
-
1
;
int
pid
;
buffer
=
xmalloc
(
PATH_MAX
);
buffer
=
xmalloc
(
PATH_MAX
);
cache_block
[
0
]
=
'\0'
;
// Get the mount namespace of init
// Get the mount namespace of init
read_namespace
(
1
,
init_ns
,
32
);
if
(
read_namespace
(
1
,
init_ns
,
32
))
{
LOGE
(
"proc_monitor: Your kernel doesn't support mount namespace :(
\n
"
);
proc_monitor_err
();
}
LOGI
(
"proc_monitor: init ns=%s
\n
"
,
init_ns
);
LOGI
(
"proc_monitor: init ns=%s
\n
"
,
init_ns
);
// Get the mount namespace of zygote
// Get the mount namespace of zygote
...
@@ -109,20 +178,8 @@ void proc_monitor() {
...
@@ -109,20 +178,8 @@ void proc_monitor() {
break
;
break
;
}
}
if
(
socketpair
(
AF_LOCAL
,
SOCK_STREAM
|
SOCK_CLOEXEC
,
0
,
sv
)
==
-
1
)
quit_pthread
(
SIGUSR1
);
/*
* The setns system call do not support multithread processes
* We have to fork a new process, and communicate with sockets
*/
if
(
hide_daemon
())
quit_pthread
(
SIGUSR1
);
close
(
sv
[
1
]);
while
(
1
)
{
while
(
1
)
{
// Clear previous buffer
// Clear previous
logcat
buffer
system
(
"logcat -b events -c"
);
system
(
"logcat -b events -c"
);
// Monitor am_proc_start
// Monitor am_proc_start
...
@@ -134,7 +191,7 @@ void proc_monitor() {
...
@@ -134,7 +191,7 @@ void proc_monitor() {
if
(
kill
(
log_pid
,
0
))
continue
;
if
(
kill
(
log_pid
,
0
))
continue
;
while
(
fdgets
(
buffer
,
PATH_MAX
,
log_fd
))
{
while
(
fdgets
(
buffer
,
PATH_MAX
,
log_fd
))
{
int
ret
,
comma
=
0
;
int
pid
,
ret
,
comma
=
0
;
char
*
pos
=
buffer
,
*
line
,
processName
[
256
];
char
*
pos
=
buffer
,
*
line
,
processName
[
256
];
while
(
1
)
{
while
(
1
)
{
...
@@ -159,10 +216,11 @@ void proc_monitor() {
...
@@ -159,10 +216,11 @@ void proc_monitor() {
pthread_mutex_lock
(
&
hide_lock
);
pthread_mutex_lock
(
&
hide_lock
);
vec_for_each
(
hide_list
,
line
)
{
vec_for_each
(
hide_list
,
line
)
{
if
(
strcmp
(
processName
,
line
)
==
0
)
{
if
(
strcmp
(
processName
,
line
)
==
0
)
{
target_pid
=
pid
;
while
(
1
)
{
while
(
1
)
{
ret
=
1
;
ret
=
1
;
for
(
int
i
=
0
;
i
<
zygote_num
;
++
i
)
{
for
(
int
i
=
0
;
i
<
zygote_num
;
++
i
)
{
read_namespace
(
pid
,
buffer
,
32
);
read_namespace
(
target_
pid
,
buffer
,
32
);
if
(
strcmp
(
buffer
,
zygote_ns
[
i
])
==
0
)
{
if
(
strcmp
(
buffer
,
zygote_ns
[
i
])
==
0
)
{
usleep
(
50
);
usleep
(
50
);
ret
=
0
;
ret
=
0
;
...
@@ -172,29 +230,39 @@ void proc_monitor() {
...
@@ -172,29 +230,39 @@ void proc_monitor() {
if
(
ret
)
break
;
if
(
ret
)
break
;
}
}
ret
=
0
;
// Send pause signal ASAP
// Send pause signal ASAP
if
(
kill
(
pid
,
SIGSTOP
)
==
-
1
)
continue
;
if
(
kill
(
target_pid
,
SIGSTOP
)
==
-
1
)
continue
;
LOGI
(
"proc_monitor: %s (PID=%d ns=%s)
\n
"
,
processName
,
pid
,
buffer
);
LOGI
(
"proc_monitor: %s (PID=%d ns=%s)
\n
"
,
processName
,
target_pid
,
buffer
);
/*
* The setns system call do not support multithread processes
* We have to fork a new process, setns, then do the unmounts
*/
int
hide_pid
=
fork
();
switch
(
hide_pid
)
{
case
-
1
:
PLOGE
(
"fork"
);
return
;
case
0
:
hide_daemon
(
target_pid
);
_exit
(
0
);
default:
break
;
}
// Unmount start
// Wait till the unmount process is done
xwrite
(
sv
[
0
],
&
pid
,
sizeof
(
pid
));
waitpid
(
hide_pid
,
&
ret
,
0
);
if
(
WEXITSTATUS
(
ret
))
quit_pthread
(
SIGUSR1
);
//
Get the hide daemon return code
//
All done, send resume signal
xxread
(
sv
[
0
],
&
ret
,
sizeof
(
ret
)
);
kill
(
target_pid
,
SIGCONT
);
LOGD
(
"proc_monitor: hide daemon response code: %d
\n
"
,
ret
)
;
target_pid
=
-
1
;
break
;
break
;
}
}
}
}
pthread_mutex_unlock
(
&
hide_lock
);
pthread_mutex_unlock
(
&
hide_lock
);
if
(
ret
)
{
// Wait hide process to kill itself
waitpid
(
hide_pid
,
NULL
,
0
);
quit_pthread
(
SIGUSR1
);
}
}
}
// For some reason it went here, restart logging
// For some reason it went here, restart logging
...
...
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