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
5754782a
Commit
5754782a
authored
Aug 21, 2021
by
topjohnwu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Generalize gen_jni_hooks.py
parent
decdd54c
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
325 additions
and
237 deletions
+325
-237
build.gradle.kts
build.gradle.kts
+1
-1
gen_jni_hooks.py
native/jni/zygisk/gen_jni_hooks.py
+175
-86
hook.cpp
native/jni/zygisk/hook.cpp
+90
-108
jni_hooks.hpp
native/jni/zygisk/jni_hooks.hpp
+59
-42
No files found.
build.gradle.kts
View file @
5754782a
...
...
@@ -16,7 +16,7 @@ buildscript {
extra
[
"vNav"
]
=
vNav
dependencies
{
classpath
(
"com.android.tools.build:gradle:7.0.
0
"
)
classpath
(
"com.android.tools.build:gradle:7.0.
1
"
)
classpath
(
kotlin
(
"gradle-plugin"
,
version
=
"1.5.21"
))
classpath
(
"androidx.navigation:navigation-safe-args-gradle-plugin:${vNav}"
)
...
...
native/jni/zygisk/gen_jni_hooks.py
View file @
5754782a
...
...
@@ -3,44 +3,73 @@
primitives
=
[
'jint'
,
'jboolean'
,
'jlong'
]
class
JType
:
def
__init__
(
self
,
name
,
sig
)
->
None
:
self
.
name
=
name
self
.
sig
=
sig
def
__init__
(
self
,
cpp
,
jni
)
:
self
.
cpp
=
cpp
self
.
jni
=
jni
class
JArray
(
JType
):
def
__init__
(
self
,
type
)
->
None
:
if
type
.
name
in
primitives
:
name
=
type
.
name
+
'Array'
def
__init__
(
self
,
type
):
if
type
.
cpp
in
primitives
:
name
=
type
.
cpp
+
'Array'
else
:
name
=
'jobjectArray'
super
()
.
__init__
(
name
,
'['
+
type
.
sig
)
super
()
.
__init__
(
name
,
'['
+
type
.
jni
)
class
Argument
:
def
__init__
(
self
,
name
,
type
,
set_arg
=
False
)
->
None
:
def
__init__
(
self
,
name
,
type
,
set_arg
=
False
):
self
.
name
=
name
self
.
type
=
type
self
.
set_arg
=
set_arg
def
cpp
(
self
):
return
f
'{self.type.name} {self.name}'
return
f
'{self.type.cpp} {self.name}'
# Args we don't care, give it an auto generated name
class
Anon
(
Argument
):
cnt
=
0
def
__init__
(
self
,
type
):
super
()
.
__init__
(
f
'_{Anon.cnt}'
,
type
)
Anon
.
cnt
+=
1
class
Return
:
def
__init__
(
self
,
value
,
type
):
self
.
value
=
value
self
.
type
=
type
class
Method
:
def
__init__
(
self
,
name
,
args
)
->
None
:
def
__init__
(
self
,
name
,
ret
,
args
)
:
self
.
name
=
name
self
.
ret
=
ret
self
.
args
=
args
def
cpp
(
self
):
return
', '
.
join
(
map
(
lambda
a
:
a
.
cpp
(),
self
.
args
))
return
', '
.
join
(
map
(
lambda
x
:
x
.
cpp
(),
self
.
args
))
def
name_list
(
self
):
return
', '
.
join
(
map
(
lambda
a
:
a
.
name
,
self
.
args
))
return
', '
.
join
(
map
(
lambda
x
:
x
.
name
,
self
.
args
))
def
jni
(
self
):
return
''
.
join
(
map
(
lambda
a
:
a
.
type
.
sig
,
self
.
args
))
args
=
''
.
join
(
map
(
lambda
x
:
x
.
type
.
jni
,
self
.
args
))
return
f
'({args}){self.ret.type.jni}'
def
body
(
self
):
return
''
class
JNIHook
(
Method
):
def
__init__
(
self
,
ver
,
ret
,
args
):
name
=
f
'{self.base_name()}_{ver}'
super
()
.
__init__
(
name
,
ret
,
args
)
def
base_name
(
self
):
return
''
def
orig_method
(
self
):
return
f
'reinterpret_cast<decltype(&{self.name})>({self.base_name()}_orig)'
def
ind
(
i
):
return
'
\n
'
+
' '
*
i
# Common types
jint
=
JType
(
'jint'
,
'I'
)
...
...
@@ -48,6 +77,48 @@ jintArray = JArray(jint)
jstring
=
JType
(
'jstring'
,
'Ljava/lang/String;'
)
jboolean
=
JType
(
'jboolean'
,
'Z'
)
jlong
=
JType
(
'jlong'
,
'J'
)
void
=
JType
(
'void'
,
'V'
)
class
ForkAndSpec
(
JNIHook
):
def
__init__
(
self
,
ver
,
args
):
super
()
.
__init__
(
ver
,
Return
(
'ctx.pid'
,
jint
),
args
)
def
base_name
(
self
):
return
'nativeForkAndSpecialize'
def
init_args
(
self
):
return
'SpecializeAppProcessArgs args(uid, gid, gids, runtime_flags, mount_external, se_info, nice_name, instruction_set, app_data_dir);'
def
body
(
self
):
decl
=
''
decl
+=
ind
(
1
)
+
self
.
init_args
()
for
a
in
self
.
args
:
if
a
.
set_arg
:
decl
+=
ind
(
1
)
+
f
'args.{a.name} = &{a.name};'
decl
+=
ind
(
1
)
+
'HookContext ctx;'
decl
+=
ind
(
1
)
+
'ctx.env = env;'
decl
+=
ind
(
1
)
+
'ctx.raw_args = &args;'
decl
+=
ind
(
1
)
+
f
'ctx.{self.base_name()}_pre();'
decl
+=
ind
(
1
)
+
self
.
orig_method
()
+
'('
decl
+=
ind
(
2
)
+
f
'env, clazz, {self.name_list()}'
decl
+=
ind
(
1
)
+
');'
decl
+=
ind
(
1
)
+
f
'ctx.{self.base_name()}_post();'
return
decl
class
SpecApp
(
ForkAndSpec
):
def
__init__
(
self
,
ver
,
args
):
super
()
.
__init__
(
ver
,
args
)
self
.
ret
=
Return
(
''
,
void
)
def
base_name
(
self
):
return
'nativeSpecializeAppProcess'
class
ForkServer
(
ForkAndSpec
):
def
base_name
(
self
):
return
'nativeForkSystemServer'
def
init_args
(
self
):
return
'ForkSystemServerArgs args(uid, gid, gids, runtime_flags, permitted_capabilities, effective_capabilities);'
# Common args
uid
=
Argument
(
'uid'
,
jint
)
...
...
@@ -77,125 +148,143 @@ whitelisted_data_info_list = Argument('whitelisted_data_info_list', JArray(jstri
mount_data_dirs
=
Argument
(
'mount_data_dirs'
,
jboolean
,
True
)
mount_storage_dirs
=
Argument
(
'mount_storage_dirs'
,
jboolean
,
True
)
# samsung (non-standard arguments)
i1
=
Argument
(
'i1'
,
jint
)
i2
=
Argument
(
'i2'
,
jint
)
i3
=
Argument
(
'i3'
,
jint
)
# server
permitted_capabilities
=
Argument
(
'permitted_capabilities'
,
jlong
)
effective_capabilities
=
Argument
(
'effective_capabilities'
,
jlong
)
# Method definitions
f
ork_l
=
Method
(
'l'
,
[
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
f
as_l
=
ForkAndSpec
(
'l'
,
[
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
se_info
,
nice_name
,
fds_to_close
,
instruction_set
,
app_data_dir
])
f
ork_o
=
Method
(
'o'
,
[
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
f
as_o
=
ForkAndSpec
(
'o'
,
[
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
se_info
,
nice_name
,
fds_to_close
,
fds_to_ignore
,
instruction_set
,
app_data_dir
])
f
ork_p
=
Method
(
'p'
,
[
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
se_info
,
f
as_p
=
ForkAndSpec
(
'p'
,
[
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
se_info
,
nice_name
,
fds_to_close
,
fds_to_ignore
,
is_child_zygote
,
instruction_set
,
app_data_dir
])
f
ork_q_alt
=
Method
(
'q_alt'
,
[
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
se_info
,
f
as_q_alt
=
ForkAndSpec
(
'q_alt'
,
[
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
se_info
,
nice_name
,
fds_to_close
,
fds_to_ignore
,
is_child_zygote
,
instruction_set
,
app_data_dir
,
is_top_app
])
f
ork_r
=
Method
(
'r'
,
[
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
se_info
,
f
as_r
=
ForkAndSpec
(
'r'
,
[
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
se_info
,
nice_name
,
fds_to_close
,
fds_to_ignore
,
is_child_zygote
,
instruction_set
,
app_data_dir
,
is_top_app
,
pkg_data_info_list
,
whitelisted_data_info_list
,
mount_data_dirs
,
mount_storage_dirs
])
f
ork_samsung_m
=
Method
(
'samsung_m'
,
[
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
se_info
,
i1
,
i2
,
nice_name
,
fds_to_close
,
instruction_set
,
app_data_dir
])
f
as_samsung_m
=
ForkAndSpec
(
'samsung_m'
,
[
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
se_info
,
Anon
(
jint
),
Anon
(
jint
)
,
nice_name
,
fds_to_close
,
instruction_set
,
app_data_dir
])
f
ork_samsung_n
=
Method
(
'samsung_n'
,
[
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
se_info
,
i1
,
i2
,
nice_name
,
fds_to_close
,
instruction_set
,
app_data_dir
,
i3
])
f
as_samsung_n
=
ForkAndSpec
(
'samsung_n'
,
[
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
se_info
,
Anon
(
jint
),
Anon
(
jint
),
nice_name
,
fds_to_close
,
instruction_set
,
app_data_dir
,
Anon
(
jint
)
])
f
ork_samsung_o
=
Method
(
'samsung_o'
,
[
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
se_info
,
i1
,
i2
,
nice_name
,
fds_to_close
,
fds_to_ignore
,
instruction_set
,
app_data_dir
])
f
as_samsung_o
=
ForkAndSpec
(
'samsung_o'
,
[
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
se_info
,
Anon
(
jint
),
Anon
(
jint
)
,
nice_name
,
fds_to_close
,
fds_to_ignore
,
instruction_set
,
app_data_dir
])
fork_samsung_p
=
Method
(
'samsung_p'
,
[
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
se_info
,
i1
,
i2
,
nice_name
,
fds_to_close
,
fds_to_ignore
,
is_child_zygote
,
instruction_set
,
app_data_dir
])
fas_samsung_p
=
ForkAndSpec
(
'samsung_p'
,
[
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
se_info
,
Anon
(
jint
),
Anon
(
jint
),
nice_name
,
fds_to_close
,
fds_to_ignore
,
is_child_zygote
,
instruction_set
,
app_data_dir
])
spec_q
=
Method
(
'q'
,
[
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
se_info
,
spec_q
=
SpecApp
(
'q'
,
[
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
se_info
,
nice_name
,
is_child_zygote
,
instruction_set
,
app_data_dir
])
spec_q_alt
=
Method
(
'q_alt'
,
[
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
se_info
,
spec_q_alt
=
SpecApp
(
'q_alt'
,
[
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
se_info
,
nice_name
,
is_child_zygote
,
instruction_set
,
app_data_dir
,
is_top_app
])
spec_r
=
Method
(
'r'
,
[
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
se_info
,
nice_name
,
spec_r
=
SpecApp
(
'r'
,
[
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
se_info
,
nice_name
,
is_child_zygote
,
instruction_set
,
app_data_dir
,
is_top_app
,
pkg_data_info_list
,
whitelisted_data_info_list
,
mount_data_dirs
,
mount_storage_dirs
])
spec_samsung_q
=
Method
(
'samsung_q'
,
[
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
se_info
,
i1
,
i2
,
nice_name
,
is_child_zygote
,
instruction_set
,
app_data_dir
])
spec_samsung_q
=
SpecApp
(
'samsung_q'
,
[
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
se_info
,
Anon
(
jint
),
Anon
(
jint
)
,
nice_name
,
is_child_zygote
,
instruction_set
,
app_data_dir
])
server_l
=
Method
(
'l'
,
[
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
server_l
=
ForkServer
(
'l'
,
[
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
permitted_capabilities
,
effective_capabilities
])
server_samsung_q
=
Method
(
'samsung_q'
,
[
uid
,
gid
,
gids
,
runtime_flags
,
i1
,
i2
,
rlimits
,
server_samsung_q
=
ForkServer
(
'samsung_q'
,
[
uid
,
gid
,
gids
,
runtime_flags
,
Anon
(
jint
),
Anon
(
jint
)
,
rlimits
,
permitted_capabilities
,
effective_capabilities
])
hook_map
=
{}
def
ind
(
i
):
return
'
\n
'
+
' '
*
i
def
gen_jni_def
(
clz
,
methods
):
if
clz
not
in
hook_map
:
hook_map
[
clz
]
=
[]
def
gen_definitions
(
methods
,
base_name
):
decl
=
''
if
base_name
!=
'nativeSpecializeAppProcess'
:
ret_stat
=
ind
(
1
)
+
'return ctx.pid;'
cpp_ret
=
'jint'
jni_ret
=
'I'
else
:
ret_stat
=
''
cpp_ret
=
'void'
jni_ret
=
'V'
for
m
in
methods
:
func_name
=
f
'{base_name}_{m.name}'
decl
+=
ind
(
0
)
+
f
'{cpp_ret} {func_name}(JNIEnv *env, jclass clazz, {m.cpp()}) {{'
if
base_name
==
'nativeForkSystemServer'
:
decl
+=
ind
(
1
)
+
'ForkSystemServerArgs args(uid, gid, gids, runtime_flags, permitted_capabilities, effective_capabilities);'
else
:
decl
+=
ind
(
1
)
+
'SpecializeAppProcessArgs args(uid, gid, gids, runtime_flags, mount_external, se_info, nice_name, instruction_set, app_data_dir);'
for
a
in
m
.
args
:
if
a
.
set_arg
:
decl
+=
ind
(
1
)
+
f
'args.{a.name} = &{a.name};'
decl
+=
ind
(
1
)
+
'HookContext ctx;'
decl
+=
ind
(
1
)
+
'ctx.env = env;'
decl
+=
ind
(
1
)
+
'ctx.clazz = clazz;'
decl
+=
ind
(
1
)
+
'ctx.raw_args = &args;'
decl
+=
ind
(
1
)
+
f
'ctx.{base_name}_pre();'
decl
+=
ind
(
1
)
+
f
'reinterpret_cast<decltype(&{func_name})>(HookContext::{base_name}_orig)('
decl
+=
ind
(
2
)
+
f
'env, clazz, {m.name_list()}'
decl
+=
ind
(
1
)
+
');'
decl
+=
ind
(
1
)
+
f
'ctx.{base_name}_post();'
decl
+=
ret_stat
decl
+=
ind
(
0
)
+
f
'{m.ret.type.cpp} {m.name}(JNIEnv *env, jclass clazz, {m.cpp()}) {{'
decl
+=
m
.
body
()
if
m
.
ret
.
value
:
decl
+=
ind
(
1
)
+
f
'return {m.ret.value};'
decl
+=
ind
(
0
)
+
'}'
decl
+=
ind
(
0
)
+
f
'const JNINativeMethod {
base_name
}_methods[] = {{'
decl
+=
ind
(
0
)
+
f
'const JNINativeMethod {
m.base_name()
}_methods[] = {{'
for
m
in
methods
:
decl
+=
ind
(
1
)
+
'{'
decl
+=
ind
(
2
)
+
f
'"{
base_name
}",'
decl
+=
ind
(
2
)
+
f
'"
({m.jni()}){jni_ret
}",'
decl
+=
ind
(
2
)
+
f
'(void *) &{
base_name}_{
m.name}'
decl
+=
ind
(
2
)
+
f
'"{
m.base_name()
}",'
decl
+=
ind
(
2
)
+
f
'"
{m.jni()
}",'
decl
+=
ind
(
2
)
+
f
'(void *) &{m.name}'
decl
+=
ind
(
1
)
+
'},'
decl
+=
ind
(
0
)
+
'};'
decl
+=
ind
(
0
)
+
f
'constexpr int {base_name}_methods_num = std::size({base_name}_methods);'
decl
=
ind
(
0
)
+
f
'void *{m.base_name()}_orig = nullptr;'
+
decl
decl
+=
ind
(
0
)
+
f
'constexpr int {m.base_name()}_methods_num = std::size({m.base_name()}_methods);'
decl
+=
ind
(
0
)
hook_map
[
clz
]
.
append
(
m
.
base_name
())
return
decl
def
gen_jni_hook
():
decl
=
''
decl
+=
ind
(
0
)
+
'unique_ptr<JNINativeMethod[]> hookAndSaveJNIMethods(const char *className, const JNINativeMethod *methods, int numMethods) {'
decl
+=
ind
(
1
)
+
'unique_ptr<JNINativeMethod[]> newMethods;'
decl
+=
ind
(
1
)
+
'int clz_id = -1;'
decl
+=
ind
(
1
)
+
'int hook_cnt = 0;'
decl
+=
ind
(
1
)
+
'do {'
for
index
,
(
clz
,
methods
)
in
enumerate
(
hook_map
.
items
()):
decl
+=
ind
(
2
)
+
f
'if (className == "{clz}"sv) {{'
decl
+=
ind
(
3
)
+
f
'clz_id = {index};'
decl
+=
ind
(
3
)
+
f
'hook_cnt = {len(methods)};'
decl
+=
ind
(
3
)
+
'break;'
decl
+=
ind
(
2
)
+
'}'
decl
+=
ind
(
1
)
+
'} while (false);'
decl
+=
ind
(
1
)
+
'if (hook_cnt) {'
decl
+=
ind
(
2
)
+
'newMethods = make_unique<JNINativeMethod[]>(numMethods);'
decl
+=
ind
(
2
)
+
'memcpy(newMethods.get(), methods, sizeof(JNINativeMethod) * numMethods);'
decl
+=
ind
(
1
)
+
'}'
decl
+=
ind
(
1
)
+
'auto &class_map = (*jni_method_map)[className];'
decl
+=
ind
(
1
)
+
'for (int i = 0; i < numMethods; ++i) {'
decl
+=
ind
(
2
)
+
'class_map[methods[i].name][methods[i].signature] = methods[i].fnPtr;'
decl
+=
ind
(
2
)
+
'if (hook_cnt == 0) continue;'
for
index
,
methods
in
enumerate
(
hook_map
.
values
()):
decl
+=
ind
(
2
)
+
f
'if (clz_id == {index}) {{'
for
m
in
methods
:
decl
+=
ind
(
3
)
+
f
'HOOK_JNI({m})'
decl
+=
ind
(
3
)
+
'continue;'
decl
+=
ind
(
2
)
+
'}'
decl
+=
ind
(
1
)
+
'}'
decl
+=
ind
(
1
)
+
'return newMethods;'
decl
+=
ind
(
0
)
+
'}'
return
decl
def
gen_fork
():
methods
=
[
fork_l
,
fork_o
,
fork_p
,
fork_q_alt
,
fork_r
,
fork_samsung_m
,
fork_samsung_n
,
fork_samsung_o
,
fork_samsung_p
]
return
gen_definitions
(
methods
,
'nativeForkAndSpecialize'
)
with
open
(
'jni_hooks.hpp'
,
'w'
)
as
f
:
f
.
write
(
'// Generated by gen_jni_hooks.py
\n
'
)
zygote
=
'com/android/internal/os/Zygote'
methods
=
[
fas_l
,
fas_o
,
fas_p
,
fas_q_alt
,
fas_r
,
fas_samsung_m
,
fas_samsung_n
,
fas_samsung_o
,
fas_samsung_p
]
f
.
write
(
gen_jni_def
(
zygote
,
methods
))
def
gen_spec
():
methods
=
[
spec_q
,
spec_q_alt
,
spec_r
,
spec_samsung_q
]
return
gen_definitions
(
methods
,
'nativeSpecializeAppProcess'
)
f
.
write
(
gen_jni_def
(
zygote
,
methods
)
)
def
gen_server
():
methods
=
[
server_l
,
server_samsung_q
]
return
gen_definitions
(
methods
,
'nativeForkSystemServer'
)
f
.
write
(
gen_jni_def
(
zygote
,
methods
)
)
with
open
(
'jni_hooks.hpp'
,
'w'
)
as
f
:
f
.
write
(
'// Generated by gen_jni_hooks.py
\n
'
)
f
.
write
(
gen_fork
())
f
.
write
(
gen_spec
())
f
.
write
(
gen_server
())
f
.
write
(
gen_jni_hook
())
f
.
write
(
'
\n
'
)
native/jni/zygisk/hook.cpp
View file @
5754782a
...
...
@@ -15,25 +15,24 @@ using jni_hook::hash_map;
using
jni_hook
::
tree_map
;
using
xstring
=
jni_hook
::
string
;
namespace
{
// Extreme verbose logging
#define VLOG(...) LOGD(__VA_ARGS__)
//#define VLOG(...)
#define DCL_JNI_FUNC(name) \
static void *name##_orig; \
void name##_pre(); \
void name##_post();
#define DEF_STATIC(name) \
void *HookContext::name##_orig = nullptr;
namespace
{
enum
{
DENY_FLAG
,
APP_FORK
,
FORK_AND_SPECIALIZE
,
FLAG_MAX
};
#define DCL_JNI_FUNC(name) \
void name##_pre(); \
void name##_post();
struct
HookContext
{
JNIEnv
*
env
;
jclass
clazz
;
union
{
SpecializeAppProcessArgs
*
args
;
ForkSystemServerArgs
*
server_args
;
...
...
@@ -43,23 +42,26 @@ struct HookContext {
int
pid
;
bitset
<
FLAG_MAX
>
flags
;
HookContext
()
:
process
(
nullptr
),
pid
(
0
)
{}
HookContext
()
:
pid
(
-
1
)
{}
void
pre_fork
();
static
void
post_fork
();
// JNI method declarations
DCL_JNI_FUNC
(
nativeForkAndSpecialize
)
DCL_JNI_FUNC
(
nativeSpecializeAppProcess
)
DCL_JNI_FUNC
(
nativeForkSystemServer
)
};
DEF_STATIC
(
nativeForkAndSpecialize
)
DEF_STATIC
(
nativeSpecializeAppProcess
)
DEF_STATIC
(
nativeForkSystemServer
)
#undef DCL_JNI_FUNC
#undef DEF_STATIC
struct
StringCmp
{
using
is_transparent
=
void
;
bool
operator
()(
string_view
a
,
string_view
b
)
const
{
return
a
<
b
;
}
};
// Global variables
vector
<
tuple
<
const
char
*
,
const
char
*
,
void
**>>
*
xhook_list
;
vector
<
JNINativeMethod
>
*
jni_hook_list
;
map
<
string
,
vector
<
JNINativeMethod
>
,
StringCmp
>
*
jni_hook_list
;
hash_map
<
xstring
,
tree_map
<
xstring
,
tree_map
<
xstring
,
void
*>>>
*
jni_method_map
;
// Current context
...
...
@@ -67,46 +69,23 @@ HookContext *g_ctx;
const
JNINativeInterface
*
old_functions
;
JNINativeInterface
*
new_functions
;
// JNI method definitions
// Includes method signatures of all supported Android versions
#include "jni_hooks.hpp"
#define HOOK_JNI(method) \
if (methods[i].name == #method##sv) { \
jni_hook_list->push_back(methods[i]); \
HookContext::method##_orig = methods[i].fnPtr; \
for (int j = 0; j < method##_methods_num; ++j) { \
for (int j = 0; j < method##_methods_num; ++j) { \
if (strcmp(methods[i].signature, method##_methods[j].signature) == 0) { \
newMethods[i] = method##_methods[j]; \
LOGI("zygisk: replaced #" #method "\n"); \
++hooked; \
jni_hook_list->try_emplace(className).first->second.push_back(methods[i]); \
method##_orig = methods[i].fnPtr; \
newMethods[i] = method##_methods[j]; \
LOGI("zygisk: replaced %s#" #method "\n", className); \
--hook_cnt; \
break; \
} \
} \
continue; \
}
unique_ptr
<
JNINativeMethod
[]
>
hookAndSaveJNIMethods
(
const
char
*
className
,
const
JNINativeMethod
*
methods
,
int
numMethods
)
{
unique_ptr
<
JNINativeMethod
[]
>
newMethods
;
int
hooked
=
numeric_limits
<
int
>::
max
();
if
(
className
==
"com/android/internal/os/Zygote"
sv
)
{
hooked
=
0
;
newMethods
=
make_unique
<
JNINativeMethod
[]
>
(
numMethods
);
memcpy
(
newMethods
.
get
(),
methods
,
sizeof
(
JNINativeMethod
)
*
numMethods
);
}
auto
&
class_map
=
(
*
jni_method_map
)[
className
];
for
(
int
i
=
0
;
i
<
numMethods
;
++
i
)
{
class_map
[
methods
[
i
].
name
][
methods
[
i
].
signature
]
=
methods
[
i
].
fnPtr
;
if
(
hooked
<
3
)
{
HOOK_JNI
(
nativeForkAndSpecialize
)
HOOK_JNI
(
nativeSpecializeAppProcess
)
HOOK_JNI
(
nativeForkSystemServer
)
}
}
return
newMethods
;
}
// JNI method hook definitions, auto generated
#include "jni_hooks.hpp"
#undef HOOK_JNI
...
...
@@ -133,29 +112,29 @@ string get_class_name(JNIEnv *env, jclass clazz) {
ret (*old_##func)(__VA_ARGS__); \
ret new_##func(__VA_ARGS__)
jint
jni
RegisterNatives
(
jint
env_
RegisterNatives
(
JNIEnv
*
env
,
jclass
clazz
,
const
JNINativeMethod
*
methods
,
jint
numMethods
)
{
auto
className
=
get_class_name
(
env
,
clazz
);
LOGD
(
"zygisk: JNIEnv->RegisterNatives [%s]
\n
"
,
className
.
data
());
VLOG
(
"zygisk: JNIEnv->RegisterNatives [%s]
\n
"
,
className
.
data
());
auto
newMethods
=
hookAndSaveJNIMethods
(
className
.
data
(),
methods
,
numMethods
);
return
old_functions
->
RegisterNatives
(
env
,
clazz
,
newMethods
.
get
()
?:
methods
,
numMethods
);
}
DCL_HOOK_FUNC
(
int
,
jniRegisterNativeMethods
,
JNIEnv
*
env
,
const
char
*
className
,
const
JNINativeMethod
*
methods
,
int
numMethods
)
{
LOGD
(
"zygisk: jniRegisterNativeMethods [%s]
\n
"
,
className
);
VLOG
(
"zygisk: jniRegisterNativeMethods [%s]
\n
"
,
className
);
auto
newMethods
=
hookAndSaveJNIMethods
(
className
,
methods
,
numMethods
);
return
old_jniRegisterNativeMethods
(
env
,
className
,
newMethods
.
get
()
?:
methods
,
numMethods
);
}
DCL_HOOK_FUNC
(
int
,
fork
)
{
return
g_ctx
?
g_ctx
->
pid
:
old_fork
();
return
(
g_ctx
&&
g_ctx
->
pid
>=
0
)
?
g_ctx
->
pid
:
old_fork
();
}
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
])
{
//
Ask magiskd to cleanup our mount namespace before switching
context
//
Request magiskd to cleanup our mount namespace before switching se
context
// 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
"
);
...
...
@@ -180,7 +159,7 @@ void onVmCreated(void *self, JNIEnv* env) {
new_functions
=
new
JNINativeInterface
();
memcpy
(
new_functions
,
env
->
functions
,
sizeof
(
*
new_functions
));
new_functions
->
RegisterNatives
=
&
jni
RegisterNatives
;
new_functions
->
RegisterNatives
=
&
env_
RegisterNatives
;
// Replace the function table in JNIEnv to hook RegisterNatives
old_functions
=
env
->
functions
;
...
...
@@ -189,7 +168,7 @@ void onVmCreated(void *self, JNIEnv* env) {
template
<
int
N
>
void
vtable_entry
(
void
*
self
,
JNIEnv
*
env
)
{
// The first invocation will be onVmCreated
// The first invocation will be onVmCreated
. It will also restore the vtable.
onVmCreated
(
self
,
env
);
// Call original function
reinterpret_cast
<
decltype
(
&
onVmCreated
)
>
(
gAppRuntimeVTable
[
N
])(
self
,
env
);
...
...
@@ -232,10 +211,10 @@ DCL_HOOK_FUNC(void, setArgv0, void *self, const char *argv0, bool setProcName) {
void
HookContext
::
nativeSpecializeAppProcess_pre
()
{
g_ctx
=
this
;
process
=
env
->
GetStringUTFChars
(
args
->
nice_name
,
nullptr
);
if
(
flags
[
APP_FORK
])
{
LOGD
(
"zygisk: pre app fork
[%s]
\n
"
,
process
);
if
(
flags
[
FORK_AND_SPECIALIZE
])
{
VLOG
(
"zygisk: pre forkAndSpecialize
[%s]
\n
"
,
process
);
}
else
{
LOGD
(
"zygisk: pre
specialize [%s]
\n
"
,
process
);
VLOG
(
"zygisk: pre
specialize [%s]
\n
"
,
process
);
}
/* TODO: Handle MOUNT_EXTERNAL_NONE */
...
...
@@ -246,10 +225,10 @@ void HookContext::nativeSpecializeAppProcess_pre() {
}
void
HookContext
::
nativeSpecializeAppProcess_post
()
{
if
(
flags
[
APP_FORK
])
{
LOGD
(
"zygisk: post app fork
[%s]
\n
"
,
process
);
if
(
flags
[
FORK_AND_SPECIALIZE
])
{
VLOG
(
"zygisk: post forkAndSpecialize
[%s]
\n
"
,
process
);
}
else
{
LOGD
(
"zygisk: post specialize [%s]
\n
"
,
process
);
VLOG
(
"zygisk: post specialize [%s]
\n
"
,
process
);
}
env
->
ReleaseStringUTFChars
(
args
->
nice_name
,
process
);
...
...
@@ -258,6 +237,18 @@ void HookContext::nativeSpecializeAppProcess_post() {
g_ctx
=
nullptr
;
}
void
HookContext
::
nativeForkSystemServer_pre
()
{
pre_fork
();
if
(
pid
)
return
;
VLOG
(
"zygisk: pre forkSystemServer
\n
"
);
}
void
HookContext
::
nativeForkSystemServer_post
()
{
run_finally
f
([]{
post_fork
();
});
if
(
pid
)
return
;
VLOG
(
"zygisk: post forkSystemServer
\n
"
);
}
// -----------------------------------------------------------------
int
sigmask
(
int
how
,
int
signum
)
{
...
...
@@ -269,49 +260,34 @@ 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
#define PRE_FORK() \
g_ctx = this; \
sigmask(SIG_BLOCK, SIGCHLD); \
pid = old_fork(); \
if (pid != 0) \
return;
void
HookContext
::
pre_fork
()
{
g_ctx
=
this
;
sigmask
(
SIG_BLOCK
,
SIGCHLD
);
pid
=
old_fork
();
}
// Unblock SIGCHLD in case the original method didn't
#define POST_FORK() \
run_finally f([]{g_ctx = nullptr;}); \
sigmask(SIG_UNBLOCK, SIGCHLD); \
if (pid != 0) \
return;
void
HookContext
::
post_fork
()
{
sigmask
(
SIG_UNBLOCK
,
SIGCHLD
);
g_ctx
=
nullptr
;
}
void
HookContext
::
nativeForkAndSpecialize_pre
()
{
PRE_FORK
()
flags
[
APP_FORK
]
=
true
;
nativeSpecializeAppProcess_pre
();
pre_fork
();
flags
[
FORK_AND_SPECIALIZE
]
=
true
;
if
(
pid
==
0
)
nativeSpecializeAppProcess_pre
();
}
void
HookContext
::
nativeForkAndSpecialize_post
()
{
POST_FORK
()
nativeSpecializeAppProcess_post
();
if
(
pid
==
0
)
nativeSpecializeAppProcess_post
();
post_fork
();
}
// -----------------------------------------------------------------
void
HookContext
::
nativeForkSystemServer_pre
()
{
PRE_FORK
()
LOGD
(
"zygisk: pre server fork
\n
"
);
}
void
HookContext
::
nativeForkSystemServer_post
()
{
POST_FORK
()
LOGD
(
"zygisk: post server fork
\n
"
);
}
#undef PRE_FORK
#undef POST_FORK
// -----------------------------------------------------------------
}
// namespace
bool
hook_refresh
()
{
static
bool
hook_refresh
()
{
if
(
xhook_refresh
(
0
)
==
0
)
{
xhook_clear
();
LOGI
(
"zygisk: xhook success
\n
"
);
...
...
@@ -322,7 +298,7 @@ bool hook_refresh() {
}
}
int
hook_register
(
const
char
*
path
,
const
char
*
symbol
,
void
*
new_func
,
void
**
old_func
)
{
static
int
hook_register
(
const
char
*
path
,
const
char
*
symbol
,
void
*
new_func
,
void
**
old_func
)
{
int
ret
=
xhook_register
(
path
,
symbol
,
new_func
,
old_func
);
if
(
ret
!=
0
)
{
LOGE
(
"hook: Failed to register hook
\"
%s
\"\n
"
,
symbol
);
...
...
@@ -332,8 +308,6 @@ int hook_register(const char *path, const char *symbol, void *new_func, void **o
return
0
;
}
}
// namespace
#define XHOOK_REGISTER_SYM(PATH_REGEX, SYM, NAME) \
hook_register(PATH_REGEX, SYM, (void*) new_##NAME, (void **) &old_##NAME)
...
...
@@ -366,18 +340,20 @@ void hook_functions() {
if
(
old_jniRegisterNativeMethods
==
nullptr
)
{
LOGD
(
"zygisk: jniRegisterNativeMethods not hooked, using fallback
\n
"
);
// android::AndroidRuntime::setArgv0(const char
*, bool)
// android::AndroidRuntime::setArgv0(const char*, bool)
XHOOK_REGISTER_SYM
(
APP_PROCESS
,
"_ZN7android14AndroidRuntime8setArgv0EPKcb"
,
setArgv0
);
hook_refresh
();
// We still need old_jniRegisterNativeMethods as other code uses it
// android::AndroidRuntime::registerNativeMethods(_JNIEnv*, const char
*, const JNINativeMethod
*, int)
// android::AndroidRuntime::registerNativeMethods(_JNIEnv*, const char
*, const JNINativeMethod
*, int)
constexpr
char
sig
[]
=
"_ZN7android14AndroidRuntime21registerNativeMethodsEP7_JNIEnvPKcPK15JNINativeMethodi"
;
*
(
void
**
)
&
old_jniRegisterNativeMethods
=
dlsym
(
RTLD_DEFAULT
,
sig
);
}
}
bool
unhook_functions
()
{
bool
success
=
true
;
// Restore JNIEnv
if
(
g_ctx
->
env
->
functions
==
new_functions
)
{
g_ctx
->
env
->
functions
=
old_functions
;
...
...
@@ -394,21 +370,27 @@ bool unhook_functions() {
jni_hook
::
memory_block
::
release
();
// Unhook JNI methods
if
(
!
jni_hook_list
->
empty
()
&&
old_jniRegisterNativeMethods
(
g_ctx
->
env
,
"com/android/internal/os/Zygote"
,
jni_hook_list
->
data
(),
jni_hook_list
->
size
())
!=
0
)
{
LOGE
(
"hook: Failed to register JNI hook
\n
"
);
return
false
;
for
(
const
auto
&
[
clz
,
methods
]
:
*
jni_hook_list
)
{
if
(
!
methods
.
empty
()
&&
old_jniRegisterNativeMethods
(
g_ctx
->
env
,
clz
.
data
(),
methods
.
data
(),
methods
.
size
())
!=
0
)
{
LOGE
(
"zygisk: Failed to restore JNI hook of class [%s]
\n
"
,
clz
.
data
());
success
=
false
;
}
}
delete
jni_hook_list
;
// Unhook xhook
for
(
auto
&
[
path
,
sym
,
old_func
]
:
*
xhook_list
)
{
for
(
const
auto
&
[
path
,
sym
,
old_func
]
:
*
xhook_list
)
{
if
(
xhook_register
(
path
,
sym
,
*
old_func
,
nullptr
)
!=
0
)
{
LOGE
(
"
hook: Failed to register hook
\"
%s
\"
\n
"
,
sym
);
return
false
;
LOGE
(
"
zygisk: Failed to register xhook [%s]
\n
"
,
sym
);
success
=
false
;
}
}
delete
xhook_list
;
return
hook_refresh
();
if
(
!
hook_refresh
())
{
LOGE
(
"zygisk: Failed to restore xhook
\n
"
);
success
=
false
;
}
return
success
;
}
native/jni/zygisk/jni_hooks.hpp
View file @
5754782a
// Generated by gen_jni_hooks.py
void
*
nativeForkAndSpecialize_orig
=
nullptr
;
jint
nativeForkAndSpecialize_l
(
JNIEnv
*
env
,
jclass
clazz
,
jint
uid
,
jint
gid
,
jintArray
gids
,
jint
runtime_flags
,
jobjectArray
rlimits
,
jint
mount_external
,
jstring
se_info
,
jstring
nice_name
,
jintArray
fds_to_close
,
jstring
instruction_set
,
jstring
app_data_dir
)
{
SpecializeAppProcessArgs
args
(
uid
,
gid
,
gids
,
runtime_flags
,
mount_external
,
se_info
,
nice_name
,
instruction_set
,
app_data_dir
);
HookContext
ctx
;
ctx
.
env
=
env
;
ctx
.
clazz
=
clazz
;
ctx
.
raw_args
=
&
args
;
ctx
.
nativeForkAndSpecialize_pre
();
reinterpret_cast
<
decltype
(
&
nativeForkAndSpecialize_l
)
>
(
HookContext
::
nativeForkAndSpecialize_orig
)(
reinterpret_cast
<
decltype
(
&
nativeForkAndSpecialize_l
)
>
(
nativeForkAndSpecialize_orig
)(
env
,
clazz
,
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
se_info
,
nice_name
,
fds_to_close
,
instruction_set
,
app_data_dir
);
ctx
.
nativeForkAndSpecialize_post
();
...
...
@@ -17,10 +17,9 @@ jint nativeForkAndSpecialize_o(JNIEnv *env, jclass clazz, jint uid, jint gid, ji
SpecializeAppProcessArgs
args
(
uid
,
gid
,
gids
,
runtime_flags
,
mount_external
,
se_info
,
nice_name
,
instruction_set
,
app_data_dir
);
HookContext
ctx
;
ctx
.
env
=
env
;
ctx
.
clazz
=
clazz
;
ctx
.
raw_args
=
&
args
;
ctx
.
nativeForkAndSpecialize_pre
();
reinterpret_cast
<
decltype
(
&
nativeForkAndSpecialize_o
)
>
(
HookContext
::
nativeForkAndSpecialize_orig
)(
reinterpret_cast
<
decltype
(
&
nativeForkAndSpecialize_o
)
>
(
nativeForkAndSpecialize_orig
)(
env
,
clazz
,
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
se_info
,
nice_name
,
fds_to_close
,
fds_to_ignore
,
instruction_set
,
app_data_dir
);
ctx
.
nativeForkAndSpecialize_post
();
...
...
@@ -31,10 +30,9 @@ jint nativeForkAndSpecialize_p(JNIEnv *env, jclass clazz, jint uid, jint gid, ji
args
.
is_child_zygote
=
&
is_child_zygote
;
HookContext
ctx
;
ctx
.
env
=
env
;
ctx
.
clazz
=
clazz
;
ctx
.
raw_args
=
&
args
;
ctx
.
nativeForkAndSpecialize_pre
();
reinterpret_cast
<
decltype
(
&
nativeForkAndSpecialize_p
)
>
(
HookContext
::
nativeForkAndSpecialize_orig
)(
reinterpret_cast
<
decltype
(
&
nativeForkAndSpecialize_p
)
>
(
nativeForkAndSpecialize_orig
)(
env
,
clazz
,
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
se_info
,
nice_name
,
fds_to_close
,
fds_to_ignore
,
is_child_zygote
,
instruction_set
,
app_data_dir
);
ctx
.
nativeForkAndSpecialize_post
();
...
...
@@ -46,10 +44,9 @@ jint nativeForkAndSpecialize_q_alt(JNIEnv *env, jclass clazz, jint uid, jint gid
args
.
is_top_app
=
&
is_top_app
;
HookContext
ctx
;
ctx
.
env
=
env
;
ctx
.
clazz
=
clazz
;
ctx
.
raw_args
=
&
args
;
ctx
.
nativeForkAndSpecialize_pre
();
reinterpret_cast
<
decltype
(
&
nativeForkAndSpecialize_q_alt
)
>
(
HookContext
::
nativeForkAndSpecialize_orig
)(
reinterpret_cast
<
decltype
(
&
nativeForkAndSpecialize_q_alt
)
>
(
nativeForkAndSpecialize_orig
)(
env
,
clazz
,
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
se_info
,
nice_name
,
fds_to_close
,
fds_to_ignore
,
is_child_zygote
,
instruction_set
,
app_data_dir
,
is_top_app
);
ctx
.
nativeForkAndSpecialize_post
();
...
...
@@ -65,64 +62,59 @@ jint nativeForkAndSpecialize_r(JNIEnv *env, jclass clazz, jint uid, jint gid, ji
args
.
mount_storage_dirs
=
&
mount_storage_dirs
;
HookContext
ctx
;
ctx
.
env
=
env
;
ctx
.
clazz
=
clazz
;
ctx
.
raw_args
=
&
args
;
ctx
.
nativeForkAndSpecialize_pre
();
reinterpret_cast
<
decltype
(
&
nativeForkAndSpecialize_r
)
>
(
HookContext
::
nativeForkAndSpecialize_orig
)(
reinterpret_cast
<
decltype
(
&
nativeForkAndSpecialize_r
)
>
(
nativeForkAndSpecialize_orig
)(
env
,
clazz
,
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
se_info
,
nice_name
,
fds_to_close
,
fds_to_ignore
,
is_child_zygote
,
instruction_set
,
app_data_dir
,
is_top_app
,
pkg_data_info_list
,
whitelisted_data_info_list
,
mount_data_dirs
,
mount_storage_dirs
);
ctx
.
nativeForkAndSpecialize_post
();
return
ctx
.
pid
;
}
jint
nativeForkAndSpecialize_samsung_m
(
JNIEnv
*
env
,
jclass
clazz
,
jint
uid
,
jint
gid
,
jintArray
gids
,
jint
runtime_flags
,
jobjectArray
rlimits
,
jint
mount_external
,
jstring
se_info
,
jint
i1
,
jint
i2
,
jstring
nice_name
,
jintArray
fds_to_close
,
jstring
instruction_set
,
jstring
app_data_dir
)
{
jint
nativeForkAndSpecialize_samsung_m
(
JNIEnv
*
env
,
jclass
clazz
,
jint
uid
,
jint
gid
,
jintArray
gids
,
jint
runtime_flags
,
jobjectArray
rlimits
,
jint
mount_external
,
jstring
se_info
,
jint
_0
,
jint
_1
,
jstring
nice_name
,
jintArray
fds_to_close
,
jstring
instruction_set
,
jstring
app_data_dir
)
{
SpecializeAppProcessArgs
args
(
uid
,
gid
,
gids
,
runtime_flags
,
mount_external
,
se_info
,
nice_name
,
instruction_set
,
app_data_dir
);
HookContext
ctx
;
ctx
.
env
=
env
;
ctx
.
clazz
=
clazz
;
ctx
.
raw_args
=
&
args
;
ctx
.
nativeForkAndSpecialize_pre
();
reinterpret_cast
<
decltype
(
&
nativeForkAndSpecialize_samsung_m
)
>
(
HookContext
::
nativeForkAndSpecialize_orig
)(
env
,
clazz
,
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
se_info
,
i1
,
i2
,
nice_name
,
fds_to_close
,
instruction_set
,
app_data_dir
reinterpret_cast
<
decltype
(
&
nativeForkAndSpecialize_samsung_m
)
>
(
nativeForkAndSpecialize_orig
)(
env
,
clazz
,
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
se_info
,
_0
,
_1
,
nice_name
,
fds_to_close
,
instruction_set
,
app_data_dir
);
ctx
.
nativeForkAndSpecialize_post
();
return
ctx
.
pid
;
}
jint
nativeForkAndSpecialize_samsung_n
(
JNIEnv
*
env
,
jclass
clazz
,
jint
uid
,
jint
gid
,
jintArray
gids
,
jint
runtime_flags
,
jobjectArray
rlimits
,
jint
mount_external
,
jstring
se_info
,
jint
i1
,
jint
i2
,
jstring
nice_name
,
jintArray
fds_to_close
,
jstring
instruction_set
,
jstring
app_data_dir
,
jint
i3
)
{
jint
nativeForkAndSpecialize_samsung_n
(
JNIEnv
*
env
,
jclass
clazz
,
jint
uid
,
jint
gid
,
jintArray
gids
,
jint
runtime_flags
,
jobjectArray
rlimits
,
jint
mount_external
,
jstring
se_info
,
jint
_2
,
jint
_3
,
jstring
nice_name
,
jintArray
fds_to_close
,
jstring
instruction_set
,
jstring
app_data_dir
,
jint
_4
)
{
SpecializeAppProcessArgs
args
(
uid
,
gid
,
gids
,
runtime_flags
,
mount_external
,
se_info
,
nice_name
,
instruction_set
,
app_data_dir
);
HookContext
ctx
;
ctx
.
env
=
env
;
ctx
.
clazz
=
clazz
;
ctx
.
raw_args
=
&
args
;
ctx
.
nativeForkAndSpecialize_pre
();
reinterpret_cast
<
decltype
(
&
nativeForkAndSpecialize_samsung_n
)
>
(
HookContext
::
nativeForkAndSpecialize_orig
)(
env
,
clazz
,
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
se_info
,
i1
,
i2
,
nice_name
,
fds_to_close
,
instruction_set
,
app_data_dir
,
i3
reinterpret_cast
<
decltype
(
&
nativeForkAndSpecialize_samsung_n
)
>
(
nativeForkAndSpecialize_orig
)(
env
,
clazz
,
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
se_info
,
_2
,
_3
,
nice_name
,
fds_to_close
,
instruction_set
,
app_data_dir
,
_4
);
ctx
.
nativeForkAndSpecialize_post
();
return
ctx
.
pid
;
}
jint
nativeForkAndSpecialize_samsung_o
(
JNIEnv
*
env
,
jclass
clazz
,
jint
uid
,
jint
gid
,
jintArray
gids
,
jint
runtime_flags
,
jobjectArray
rlimits
,
jint
mount_external
,
jstring
se_info
,
jint
i1
,
jint
i2
,
jstring
nice_name
,
jintArray
fds_to_close
,
jintArray
fds_to_ignore
,
jstring
instruction_set
,
jstring
app_data_dir
)
{
jint
nativeForkAndSpecialize_samsung_o
(
JNIEnv
*
env
,
jclass
clazz
,
jint
uid
,
jint
gid
,
jintArray
gids
,
jint
runtime_flags
,
jobjectArray
rlimits
,
jint
mount_external
,
jstring
se_info
,
jint
_5
,
jint
_6
,
jstring
nice_name
,
jintArray
fds_to_close
,
jintArray
fds_to_ignore
,
jstring
instruction_set
,
jstring
app_data_dir
)
{
SpecializeAppProcessArgs
args
(
uid
,
gid
,
gids
,
runtime_flags
,
mount_external
,
se_info
,
nice_name
,
instruction_set
,
app_data_dir
);
HookContext
ctx
;
ctx
.
env
=
env
;
ctx
.
clazz
=
clazz
;
ctx
.
raw_args
=
&
args
;
ctx
.
nativeForkAndSpecialize_pre
();
reinterpret_cast
<
decltype
(
&
nativeForkAndSpecialize_samsung_o
)
>
(
HookContext
::
nativeForkAndSpecialize_orig
)(
env
,
clazz
,
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
se_info
,
i1
,
i2
,
nice_name
,
fds_to_close
,
fds_to_ignore
,
instruction_set
,
app_data_dir
reinterpret_cast
<
decltype
(
&
nativeForkAndSpecialize_samsung_o
)
>
(
nativeForkAndSpecialize_orig
)(
env
,
clazz
,
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
se_info
,
_5
,
_6
,
nice_name
,
fds_to_close
,
fds_to_ignore
,
instruction_set
,
app_data_dir
);
ctx
.
nativeForkAndSpecialize_post
();
return
ctx
.
pid
;
}
jint
nativeForkAndSpecialize_samsung_p
(
JNIEnv
*
env
,
jclass
clazz
,
jint
uid
,
jint
gid
,
jintArray
gids
,
jint
runtime_flags
,
jobjectArray
rlimits
,
jint
mount_external
,
jstring
se_info
,
jint
i1
,
jint
i2
,
jstring
nice_name
,
jintArray
fds_to_close
,
jintArray
fds_to_ignore
,
jboolean
is_child_zygote
,
jstring
instruction_set
,
jstring
app_data_dir
)
{
jint
nativeForkAndSpecialize_samsung_p
(
JNIEnv
*
env
,
jclass
clazz
,
jint
uid
,
jint
gid
,
jintArray
gids
,
jint
runtime_flags
,
jobjectArray
rlimits
,
jint
mount_external
,
jstring
se_info
,
jint
_7
,
jint
_8
,
jstring
nice_name
,
jintArray
fds_to_close
,
jintArray
fds_to_ignore
,
jboolean
is_child_zygote
,
jstring
instruction_set
,
jstring
app_data_dir
)
{
SpecializeAppProcessArgs
args
(
uid
,
gid
,
gids
,
runtime_flags
,
mount_external
,
se_info
,
nice_name
,
instruction_set
,
app_data_dir
);
args
.
is_child_zygote
=
&
is_child_zygote
;
HookContext
ctx
;
ctx
.
env
=
env
;
ctx
.
clazz
=
clazz
;
ctx
.
raw_args
=
&
args
;
ctx
.
nativeForkAndSpecialize_pre
();
reinterpret_cast
<
decltype
(
&
nativeForkAndSpecialize_samsung_p
)
>
(
HookContext
::
nativeForkAndSpecialize_orig
)(
env
,
clazz
,
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
se_info
,
i1
,
i2
,
nice_name
,
fds_to_close
,
fds_to_ignore
,
is_child_zygote
,
instruction_set
,
app_data_dir
reinterpret_cast
<
decltype
(
&
nativeForkAndSpecialize_samsung_p
)
>
(
nativeForkAndSpecialize_orig
)(
env
,
clazz
,
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
se_info
,
_7
,
_8
,
nice_name
,
fds_to_close
,
fds_to_ignore
,
is_child_zygote
,
instruction_set
,
app_data_dir
);
ctx
.
nativeForkAndSpecialize_post
();
return
ctx
.
pid
;
...
...
@@ -176,15 +168,15 @@ const JNINativeMethod nativeForkAndSpecialize_methods[] = {
};
constexpr
int
nativeForkAndSpecialize_methods_num
=
std
::
size
(
nativeForkAndSpecialize_methods
);
void
*
nativeSpecializeAppProcess_orig
=
nullptr
;
void
nativeSpecializeAppProcess_q
(
JNIEnv
*
env
,
jclass
clazz
,
jint
uid
,
jint
gid
,
jintArray
gids
,
jint
runtime_flags
,
jobjectArray
rlimits
,
jint
mount_external
,
jstring
se_info
,
jstring
nice_name
,
jboolean
is_child_zygote
,
jstring
instruction_set
,
jstring
app_data_dir
)
{
SpecializeAppProcessArgs
args
(
uid
,
gid
,
gids
,
runtime_flags
,
mount_external
,
se_info
,
nice_name
,
instruction_set
,
app_data_dir
);
args
.
is_child_zygote
=
&
is_child_zygote
;
HookContext
ctx
;
ctx
.
env
=
env
;
ctx
.
clazz
=
clazz
;
ctx
.
raw_args
=
&
args
;
ctx
.
nativeSpecializeAppProcess_pre
();
reinterpret_cast
<
decltype
(
&
nativeSpecializeAppProcess_q
)
>
(
HookContext
::
nativeSpecializeAppProcess_orig
)(
reinterpret_cast
<
decltype
(
&
nativeSpecializeAppProcess_q
)
>
(
nativeSpecializeAppProcess_orig
)(
env
,
clazz
,
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
se_info
,
nice_name
,
is_child_zygote
,
instruction_set
,
app_data_dir
);
ctx
.
nativeSpecializeAppProcess_post
();
...
...
@@ -195,10 +187,9 @@ void nativeSpecializeAppProcess_q_alt(JNIEnv *env, jclass clazz, jint uid, jint
args
.
is_top_app
=
&
is_top_app
;
HookContext
ctx
;
ctx
.
env
=
env
;
ctx
.
clazz
=
clazz
;
ctx
.
raw_args
=
&
args
;
ctx
.
nativeSpecializeAppProcess_pre
();
reinterpret_cast
<
decltype
(
&
nativeSpecializeAppProcess_q_alt
)
>
(
HookContext
::
nativeSpecializeAppProcess_orig
)(
reinterpret_cast
<
decltype
(
&
nativeSpecializeAppProcess_q_alt
)
>
(
nativeSpecializeAppProcess_orig
)(
env
,
clazz
,
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
se_info
,
nice_name
,
is_child_zygote
,
instruction_set
,
app_data_dir
,
is_top_app
);
ctx
.
nativeSpecializeAppProcess_post
();
...
...
@@ -213,24 +204,22 @@ void nativeSpecializeAppProcess_r(JNIEnv *env, jclass clazz, jint uid, jint gid,
args
.
mount_storage_dirs
=
&
mount_storage_dirs
;
HookContext
ctx
;
ctx
.
env
=
env
;
ctx
.
clazz
=
clazz
;
ctx
.
raw_args
=
&
args
;
ctx
.
nativeSpecializeAppProcess_pre
();
reinterpret_cast
<
decltype
(
&
nativeSpecializeAppProcess_r
)
>
(
HookContext
::
nativeSpecializeAppProcess_orig
)(
reinterpret_cast
<
decltype
(
&
nativeSpecializeAppProcess_r
)
>
(
nativeSpecializeAppProcess_orig
)(
env
,
clazz
,
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
se_info
,
nice_name
,
is_child_zygote
,
instruction_set
,
app_data_dir
,
is_top_app
,
pkg_data_info_list
,
whitelisted_data_info_list
,
mount_data_dirs
,
mount_storage_dirs
);
ctx
.
nativeSpecializeAppProcess_post
();
}
void
nativeSpecializeAppProcess_samsung_q
(
JNIEnv
*
env
,
jclass
clazz
,
jint
uid
,
jint
gid
,
jintArray
gids
,
jint
runtime_flags
,
jobjectArray
rlimits
,
jint
mount_external
,
jstring
se_info
,
jint
i1
,
jint
i2
,
jstring
nice_name
,
jboolean
is_child_zygote
,
jstring
instruction_set
,
jstring
app_data_dir
)
{
void
nativeSpecializeAppProcess_samsung_q
(
JNIEnv
*
env
,
jclass
clazz
,
jint
uid
,
jint
gid
,
jintArray
gids
,
jint
runtime_flags
,
jobjectArray
rlimits
,
jint
mount_external
,
jstring
se_info
,
jint
_9
,
jint
_10
,
jstring
nice_name
,
jboolean
is_child_zygote
,
jstring
instruction_set
,
jstring
app_data_dir
)
{
SpecializeAppProcessArgs
args
(
uid
,
gid
,
gids
,
runtime_flags
,
mount_external
,
se_info
,
nice_name
,
instruction_set
,
app_data_dir
);
args
.
is_child_zygote
=
&
is_child_zygote
;
HookContext
ctx
;
ctx
.
env
=
env
;
ctx
.
clazz
=
clazz
;
ctx
.
raw_args
=
&
args
;
ctx
.
nativeSpecializeAppProcess_pre
();
reinterpret_cast
<
decltype
(
&
nativeSpecializeAppProcess_samsung_q
)
>
(
HookContext
::
nativeSpecializeAppProcess_orig
)(
env
,
clazz
,
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
se_info
,
i1
,
i2
,
nice_name
,
is_child_zygote
,
instruction_set
,
app_data_dir
reinterpret_cast
<
decltype
(
&
nativeSpecializeAppProcess_samsung_q
)
>
(
nativeSpecializeAppProcess_orig
)(
env
,
clazz
,
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
se_info
,
_9
,
_10
,
nice_name
,
is_child_zygote
,
instruction_set
,
app_data_dir
);
ctx
.
nativeSpecializeAppProcess_post
();
}
...
...
@@ -258,28 +247,27 @@ const JNINativeMethod nativeSpecializeAppProcess_methods[] = {
};
constexpr
int
nativeSpecializeAppProcess_methods_num
=
std
::
size
(
nativeSpecializeAppProcess_methods
);
void
*
nativeForkSystemServer_orig
=
nullptr
;
jint
nativeForkSystemServer_l
(
JNIEnv
*
env
,
jclass
clazz
,
jint
uid
,
jint
gid
,
jintArray
gids
,
jint
runtime_flags
,
jobjectArray
rlimits
,
jlong
permitted_capabilities
,
jlong
effective_capabilities
)
{
ForkSystemServerArgs
args
(
uid
,
gid
,
gids
,
runtime_flags
,
permitted_capabilities
,
effective_capabilities
);
HookContext
ctx
;
ctx
.
env
=
env
;
ctx
.
clazz
=
clazz
;
ctx
.
raw_args
=
&
args
;
ctx
.
nativeForkSystemServer_pre
();
reinterpret_cast
<
decltype
(
&
nativeForkSystemServer_l
)
>
(
HookContext
::
nativeForkSystemServer_orig
)(
reinterpret_cast
<
decltype
(
&
nativeForkSystemServer_l
)
>
(
nativeForkSystemServer_orig
)(
env
,
clazz
,
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
permitted_capabilities
,
effective_capabilities
);
ctx
.
nativeForkSystemServer_post
();
return
ctx
.
pid
;
}
jint
nativeForkSystemServer_samsung_q
(
JNIEnv
*
env
,
jclass
clazz
,
jint
uid
,
jint
gid
,
jintArray
gids
,
jint
runtime_flags
,
jint
i1
,
jint
i
2
,
jobjectArray
rlimits
,
jlong
permitted_capabilities
,
jlong
effective_capabilities
)
{
jint
nativeForkSystemServer_samsung_q
(
JNIEnv
*
env
,
jclass
clazz
,
jint
uid
,
jint
gid
,
jintArray
gids
,
jint
runtime_flags
,
jint
_11
,
jint
_1
2
,
jobjectArray
rlimits
,
jlong
permitted_capabilities
,
jlong
effective_capabilities
)
{
ForkSystemServerArgs
args
(
uid
,
gid
,
gids
,
runtime_flags
,
permitted_capabilities
,
effective_capabilities
);
HookContext
ctx
;
ctx
.
env
=
env
;
ctx
.
clazz
=
clazz
;
ctx
.
raw_args
=
&
args
;
ctx
.
nativeForkSystemServer_pre
();
reinterpret_cast
<
decltype
(
&
nativeForkSystemServer_samsung_q
)
>
(
HookContext
::
nativeForkSystemServer_orig
)(
env
,
clazz
,
uid
,
gid
,
gids
,
runtime_flags
,
i1
,
i
2
,
rlimits
,
permitted_capabilities
,
effective_capabilities
reinterpret_cast
<
decltype
(
&
nativeForkSystemServer_samsung_q
)
>
(
nativeForkSystemServer_orig
)(
env
,
clazz
,
uid
,
gid
,
gids
,
runtime_flags
,
_11
,
_1
2
,
rlimits
,
permitted_capabilities
,
effective_capabilities
);
ctx
.
nativeForkSystemServer_post
();
return
ctx
.
pid
;
...
...
@@ -297,3 +285,32 @@ const JNINativeMethod nativeForkSystemServer_methods[] = {
},
};
constexpr
int
nativeForkSystemServer_methods_num
=
std
::
size
(
nativeForkSystemServer_methods
);
unique_ptr
<
JNINativeMethod
[]
>
hookAndSaveJNIMethods
(
const
char
*
className
,
const
JNINativeMethod
*
methods
,
int
numMethods
)
{
unique_ptr
<
JNINativeMethod
[]
>
newMethods
;
int
clz_id
=
-
1
;
int
hook_cnt
=
0
;
do
{
if
(
className
==
"com/android/internal/os/Zygote"
sv
)
{
clz_id
=
0
;
hook_cnt
=
3
;
break
;
}
}
while
(
false
);
if
(
hook_cnt
)
{
newMethods
=
make_unique
<
JNINativeMethod
[]
>
(
numMethods
);
memcpy
(
newMethods
.
get
(),
methods
,
sizeof
(
JNINativeMethod
)
*
numMethods
);
}
auto
&
class_map
=
(
*
jni_method_map
)[
className
];
for
(
int
i
=
0
;
i
<
numMethods
;
++
i
)
{
class_map
[
methods
[
i
].
name
][
methods
[
i
].
signature
]
=
methods
[
i
].
fnPtr
;
if
(
hook_cnt
==
0
)
continue
;
if
(
clz_id
==
0
)
{
HOOK_JNI
(
nativeForkAndSpecialize
)
HOOK_JNI
(
nativeSpecializeAppProcess
)
HOOK_JNI
(
nativeForkSystemServer
)
continue
;
}
}
return
newMethods
;
}
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