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
b8c15882
Commit
b8c15882
authored
Nov 07, 2021
by
topjohnwu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Always unload zygisk after specialize
parent
4dac9e40
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
51 additions
and
35 deletions
+51
-35
api.hpp
native/jni/zygisk/api.hpp
+8
-6
entry.cpp
native/jni/zygisk/entry.cpp
+1
-9
hook.cpp
native/jni/zygisk/hook.cpp
+39
-18
module.hpp
native/jni/zygisk/module.hpp
+1
-0
zygisk.hpp
native/jni/zygisk/zygisk.hpp
+2
-2
No files found.
native/jni/zygisk/api.hpp
View file @
b8c15882
...
@@ -152,6 +152,8 @@ enum Option : int {
...
@@ -152,6 +152,8 @@ enum Option : int {
DLCLOSE_MODULE_LIBRARY
=
1
,
DLCLOSE_MODULE_LIBRARY
=
1
,
};
};
// All API functions will stop working after post[XXX]Specialize as Zygisk will be unloaded
// from the specialized process afterwards.
struct
Api
{
struct
Api
{
// Connect to a root companion process and get a Unix domain socket for IPC.
// Connect to a root companion process and get a Unix domain socket for IPC.
...
@@ -274,22 +276,22 @@ void entry_impl(api_table *table, JNIEnv *env) {
...
@@ -274,22 +276,22 @@ void entry_impl(api_table *table, JNIEnv *env) {
}
// namespace internal
}
// namespace internal
inline
int
Api
::
connectCompanion
()
{
inline
int
Api
::
connectCompanion
()
{
return
impl
->
connectCompanion
(
impl
->
_this
)
;
return
impl
->
connectCompanion
?
impl
->
connectCompanion
(
impl
->
_this
)
:
-
1
;
}
}
inline
void
Api
::
setOption
(
Option
opt
)
{
inline
void
Api
::
setOption
(
Option
opt
)
{
impl
->
setOption
(
impl
->
_this
,
opt
);
i
f
(
impl
->
setOption
)
i
mpl
->
setOption
(
impl
->
_this
,
opt
);
}
}
inline
void
Api
::
hookJniNativeMethods
(
JNIEnv
*
env
,
const
char
*
className
,
JNINativeMethod
*
methods
,
int
numMethods
)
{
inline
void
Api
::
hookJniNativeMethods
(
JNIEnv
*
env
,
const
char
*
className
,
JNINativeMethod
*
methods
,
int
numMethods
)
{
impl
->
hookJniNativeMethods
(
env
,
className
,
methods
,
numMethods
);
i
f
(
impl
->
hookJniNativeMethods
)
i
mpl
->
hookJniNativeMethods
(
env
,
className
,
methods
,
numMethods
);
}
}
inline
void
Api
::
pltHookRegister
(
const
char
*
regex
,
const
char
*
symbol
,
void
*
newFunc
,
void
**
oldFunc
)
{
inline
void
Api
::
pltHookRegister
(
const
char
*
regex
,
const
char
*
symbol
,
void
*
newFunc
,
void
**
oldFunc
)
{
impl
->
pltHookRegister
(
regex
,
symbol
,
newFunc
,
oldFunc
);
i
f
(
impl
->
pltHookRegister
)
i
mpl
->
pltHookRegister
(
regex
,
symbol
,
newFunc
,
oldFunc
);
}
}
inline
void
Api
::
pltHookExclude
(
const
char
*
regex
,
const
char
*
symbol
)
{
inline
void
Api
::
pltHookExclude
(
const
char
*
regex
,
const
char
*
symbol
)
{
impl
->
pltHookExclude
(
regex
,
symbol
);
i
f
(
impl
->
pltHookExclude
)
i
mpl
->
pltHookExclude
(
regex
,
symbol
);
}
}
inline
bool
Api
::
pltHookCommit
()
{
inline
bool
Api
::
pltHookCommit
()
{
return
impl
->
pltHookCommit
();
return
impl
->
pltHookCommit
!=
nullptr
&&
impl
->
pltHookCommit
();
}
}
}
// namespace zygisk
}
// namespace zygisk
...
...
native/jni/zygisk/entry.cpp
View file @
b8c15882
...
@@ -13,7 +13,7 @@
...
@@ -13,7 +13,7 @@
using
namespace
std
;
using
namespace
std
;
static
void
*
self_handle
=
nullptr
;
void
*
self_handle
=
nullptr
;
static
int
zygisk_log
(
int
prio
,
const
char
*
fmt
,
va_list
ap
);
static
int
zygisk_log
(
int
prio
,
const
char
*
fmt
,
va_list
ap
);
...
@@ -26,14 +26,6 @@ static void zygisk_logging() {
...
@@ -26,14 +26,6 @@ static void zygisk_logging() {
log_cb
.
ex
=
nop_ex
;
log_cb
.
ex
=
nop_ex
;
}
}
void
self_unload
()
{
ZLOGD
(
"Request to self unload
\n
"
);
// If unhooking failed, do not unload or else it will cause SIGSEGV
if
(
!
unhook_functions
())
return
;
new_daemon_thread
(
reinterpret_cast
<
thread_entry
>
(
&
dlclose
),
self_handle
);
}
static
char
*
first_stage_path
=
nullptr
;
static
char
*
first_stage_path
=
nullptr
;
void
unload_first_stage
()
{
void
unload_first_stage
()
{
if
(
first_stage_path
)
{
if
(
first_stage_path
)
{
...
...
native/jni/zygisk/hook.cpp
View file @
b8c15882
...
@@ -21,6 +21,8 @@ using xstring = jni_hook::string;
...
@@ -21,6 +21,8 @@ using xstring = jni_hook::string;
//#define ZLOGV(...) ZLOGD(__VA_ARGS__)
//#define ZLOGV(...) ZLOGD(__VA_ARGS__)
#define ZLOGV(...)
#define ZLOGV(...)
static
bool
unhook_functions
();
namespace
{
namespace
{
enum
{
enum
{
...
@@ -28,6 +30,7 @@ enum {
...
@@ -28,6 +30,7 @@ enum {
FORK_AND_SPECIALIZE
,
FORK_AND_SPECIALIZE
,
APP_SPECIALIZE
,
APP_SPECIALIZE
,
SERVER_SPECIALIZE
,
SERVER_SPECIALIZE
,
CAN_DLCLOSE
,
FLAG_MAX
FLAG_MAX
};
};
...
@@ -51,6 +54,7 @@ struct HookContext {
...
@@ -51,6 +54,7 @@ struct HookContext {
HookContext
()
:
pid
(
-
1
),
info
{}
{}
HookContext
()
:
pid
(
-
1
),
info
{}
{}
static
void
close_fds
();
static
void
close_fds
();
void
unload_zygisk
();
DCL_PRE_POST
(
fork
)
DCL_PRE_POST
(
fork
)
void
run_modules_pre
(
const
vector
<
int
>
&
fds
);
void
run_modules_pre
(
const
vector
<
int
>
&
fds
);
...
@@ -170,6 +174,15 @@ DCL_HOOK_FUNC(void, android_log_close) {
...
@@ -170,6 +174,15 @@ DCL_HOOK_FUNC(void, android_log_close) {
old_android_log_close
();
old_android_log_close
();
}
}
// Last point before process secontext changes
DCL_HOOK_FUNC
(
int
,
selinux_android_setcontext
,
uid_t
uid
,
int
isSystemServer
,
const
char
*
seinfo
,
const
char
*
pkgname
)
{
if
(
g_ctx
)
{
g_ctx
->
flags
[
CAN_DLCLOSE
]
=
unhook_functions
();
}
return
old_selinux_android_setcontext
(
uid
,
isSystemServer
,
seinfo
,
pkgname
);
}
// -----------------------------------------------------------------
// -----------------------------------------------------------------
// The original android::AppRuntime virtual table
// The original android::AppRuntime virtual table
...
@@ -327,6 +340,7 @@ void HookContext::run_modules_pre(const vector<int> &fds) {
...
@@ -327,6 +340,7 @@ void HookContext::run_modules_pre(const vector<int> &fds) {
modules
.
emplace_back
(
i
,
h
);
modules
.
emplace_back
(
i
,
h
);
auto
api
=
new
ApiTable
(
&
modules
.
back
());
auto
api
=
new
ApiTable
(
&
modules
.
back
());
module_entry
(
api
,
env
);
module_entry
(
api
,
env
);
modules
.
back
().
table
=
api
;
}
}
}
}
close
(
fds
[
i
]);
close
(
fds
[
i
]);
...
@@ -357,6 +371,22 @@ void HookContext::close_fds() {
...
@@ -357,6 +371,22 @@ void HookContext::close_fds() {
close
(
logd_fd
.
exchange
(
-
1
));
close
(
logd_fd
.
exchange
(
-
1
));
}
}
void
HookContext
::
unload_zygisk
()
{
if
(
flags
[
CAN_DLCLOSE
])
{
// Do NOT call the destructor
operator
delete
(
jni_method_map
);
// Directly unmap the whole memory block
jni_hook
::
memory_block
::
release
();
// Strip out all API function pointers
for
(
auto
&
m
:
modules
)
{
memset
(
m
.
table
,
0
,
sizeof
(
*
m
.
table
));
}
new_daemon_thread
(
reinterpret_cast
<
thread_entry
>
(
&
dlclose
),
self_handle
);
}
}
// -----------------------------------------------------------------
// -----------------------------------------------------------------
void
HookContext
::
nativeSpecializeAppProcess_pre
()
{
void
HookContext
::
nativeSpecializeAppProcess_pre
()
{
...
@@ -387,19 +417,14 @@ void HookContext::nativeSpecializeAppProcess_post() {
...
@@ -387,19 +417,14 @@ void HookContext::nativeSpecializeAppProcess_post() {
}
}
env
->
ReleaseStringUTFChars
(
args
->
nice_name
,
process
);
env
->
ReleaseStringUTFChars
(
args
->
nice_name
,
process
);
if
(
info
.
on_denylist
)
{
self_unload
();
}
else
{
run_modules_post
();
run_modules_post
();
if
(
info
.
is_magisk_app
)
{
if
(
info
.
is_magisk_app
)
{
setenv
(
"ZYGISK_ENABLED"
,
"1"
,
1
);
setenv
(
"ZYGISK_ENABLED"
,
"1"
,
1
);
}
else
if
(
args
->
is_child_zygote
&&
*
args
->
is_child_zygote
)
{
// If we are in child zygote, unhook all zygisk hooks
// Modules still have their code loaded and can do whatever they want
unhook_functions
();
}
}
}
g_ctx
=
nullptr
;
g_ctx
=
nullptr
;
if
(
!
flags
[
FORK_AND_SPECIALIZE
])
{
unload_zygisk
();
}
}
}
void
HookContext
::
nativeForkSystemServer_pre
()
{
void
HookContext
::
nativeForkSystemServer_pre
()
{
...
@@ -457,6 +482,7 @@ void HookContext::fork_pre() {
...
@@ -457,6 +482,7 @@ void HookContext::fork_pre() {
void
HookContext
::
fork_post
()
{
void
HookContext
::
fork_post
()
{
sigmask
(
SIG_UNBLOCK
,
SIGCHLD
);
sigmask
(
SIG_UNBLOCK
,
SIGCHLD
);
g_ctx
=
nullptr
;
g_ctx
=
nullptr
;
unload_zygisk
();
}
}
}
// namespace
}
// namespace
...
@@ -464,7 +490,6 @@ void HookContext::fork_post() {
...
@@ -464,7 +490,6 @@ void HookContext::fork_post() {
static
bool
hook_refresh
()
{
static
bool
hook_refresh
()
{
if
(
xhook_refresh
(
0
)
==
0
)
{
if
(
xhook_refresh
(
0
)
==
0
)
{
xhook_clear
();
xhook_clear
();
ZLOGI
(
"xhook success
\n
"
);
return
true
;
return
true
;
}
else
{
}
else
{
ZLOGE
(
"xhook failed
\n
"
);
ZLOGE
(
"xhook failed
\n
"
);
...
@@ -503,6 +528,7 @@ void hook_functions() {
...
@@ -503,6 +528,7 @@ void hook_functions() {
XHOOK_REGISTER
(
ANDROID_RUNTIME
,
fork
);
XHOOK_REGISTER
(
ANDROID_RUNTIME
,
fork
);
XHOOK_REGISTER
(
ANDROID_RUNTIME
,
unshare
);
XHOOK_REGISTER
(
ANDROID_RUNTIME
,
unshare
);
XHOOK_REGISTER
(
ANDROID_RUNTIME
,
jniRegisterNativeMethods
);
XHOOK_REGISTER
(
ANDROID_RUNTIME
,
jniRegisterNativeMethods
);
XHOOK_REGISTER
(
ANDROID_RUNTIME
,
selinux_android_setcontext
);
XHOOK_REGISTER_SYM
(
ANDROID_RUNTIME
,
"__android_log_close"
,
android_log_close
);
XHOOK_REGISTER_SYM
(
ANDROID_RUNTIME
,
"__android_log_close"
,
android_log_close
);
hook_refresh
();
hook_refresh
();
...
@@ -526,7 +552,7 @@ void hook_functions() {
...
@@ -526,7 +552,7 @@ void hook_functions() {
}
}
}
}
bool
unhook_functions
()
{
static
bool
unhook_functions
()
{
bool
success
=
true
;
bool
success
=
true
;
// Restore JNIEnv
// Restore JNIEnv
...
@@ -539,11 +565,6 @@ bool unhook_functions() {
...
@@ -539,11 +565,6 @@ bool unhook_functions() {
}
}
}
}
// Do NOT call the destructor
operator
delete
(
jni_method_map
);
// Directly unmap the whole memory block
jni_hook
::
memory_block
::
release
();
// Unhook JNI methods
// Unhook JNI methods
for
(
const
auto
&
[
clz
,
methods
]
:
*
jni_hook_list
)
{
for
(
const
auto
&
[
clz
,
methods
]
:
*
jni_hook_list
)
{
if
(
!
methods
.
empty
()
&&
old_jniRegisterNativeMethods
(
if
(
!
methods
.
empty
()
&&
old_jniRegisterNativeMethods
(
...
...
native/jni/zygisk/module.hpp
View file @
b8c15882
...
@@ -88,6 +88,7 @@ struct ZygiskModule {
...
@@ -88,6 +88,7 @@ struct ZygiskModule {
ZygiskModule
(
int
id
,
void
*
handle
)
:
handle
(
handle
),
id
(
id
)
{}
ZygiskModule
(
int
id
,
void
*
handle
)
:
handle
(
handle
),
id
(
id
)
{}
void
*
const
handle
;
void
*
const
handle
;
ApiTable
*
table
=
nullptr
;
bool
unload
=
false
;
bool
unload
=
false
;
private
:
private
:
...
...
native/jni/zygisk/zygisk.hpp
View file @
b8c15882
...
@@ -41,9 +41,9 @@ struct AppInfo {
...
@@ -41,9 +41,9 @@ struct AppInfo {
bool
on_denylist
;
bool
on_denylist
;
};
};
extern
void
*
self_handle
;
void
unload_first_stage
();
void
unload_first_stage
();
void
self_unload
();
void
hook_functions
();
void
hook_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
();
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