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
25efdd3d
Commit
25efdd3d
authored
Aug 02, 2021
by
topjohnwu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Use code generator for jni_hooks
parent
00a1e189
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
542 additions
and
419 deletions
+542
-419
gen_jni_hooks.py
native/jni/inject/gen_jni_hooks.py
+201
-0
hook.cpp
native/jni/inject/hook.cpp
+89
-77
jni_hooks.hpp
native/jni/inject/jni_hooks.hpp
+252
-342
No files found.
native/jni/inject/gen_jni_hooks.py
0 → 100755
View file @
25efdd3d
#!/usr/bin/env python3
primitives
=
[
'jint'
,
'jboolean'
,
'jlong'
]
class
JType
:
def
__init__
(
self
,
name
,
sig
)
->
None
:
self
.
name
=
name
self
.
sig
=
sig
class
JArray
(
JType
):
def
__init__
(
self
,
type
)
->
None
:
if
type
.
name
in
primitives
:
name
=
type
.
name
+
'Array'
else
:
name
=
'jobjectArray'
super
()
.
__init__
(
name
,
'['
+
type
.
sig
)
class
Argument
:
def
__init__
(
self
,
name
,
type
,
set_arg
=
False
)
->
None
:
self
.
name
=
name
self
.
type
=
type
self
.
set_arg
=
set_arg
def
cpp
(
self
):
return
f
'{self.type.name} {self.name}'
class
Method
:
def
__init__
(
self
,
name
,
args
)
->
None
:
self
.
name
=
name
self
.
args
=
args
def
cpp
(
self
):
return
', '
.
join
(
map
(
lambda
a
:
a
.
cpp
(),
self
.
args
))
def
name_list
(
self
):
return
', '
.
join
(
map
(
lambda
a
:
a
.
name
,
self
.
args
))
def
jni
(
self
):
return
''
.
join
(
map
(
lambda
a
:
a
.
type
.
sig
,
self
.
args
))
# Common types
jint
=
JType
(
'jint'
,
'I'
)
jintArray
=
JArray
(
jint
)
jstring
=
JType
(
'jstring'
,
'Ljava/lang/String;'
)
jboolean
=
JType
(
'jboolean'
,
'Z'
)
jlong
=
JType
(
'jlong'
,
'J'
)
# Common args
uid
=
Argument
(
'uid'
,
jint
)
gid
=
Argument
(
'gid'
,
jint
)
gids
=
Argument
(
'gids'
,
jintArray
)
runtime_flags
=
Argument
(
'runtime_flags'
,
jint
)
rlimits
=
Argument
(
'rlimits'
,
JArray
(
jintArray
))
mount_external
=
Argument
(
'mount_external'
,
jint
)
se_info
=
Argument
(
'se_info'
,
jstring
)
nice_name
=
Argument
(
'nice_name'
,
jstring
)
fds_to_close
=
Argument
(
'fds_to_close'
,
jintArray
)
instruction_set
=
Argument
(
'instruction_set'
,
jstring
)
app_data_dir
=
Argument
(
'app_data_dir'
,
jstring
)
# o
fds_to_ignore
=
Argument
(
'fds_to_ignore'
,
jintArray
)
# p
is_child_zygote
=
Argument
(
'is_child_zygote'
,
jboolean
,
True
)
# q_alt
is_top_app
=
Argument
(
'is_top_app'
,
jboolean
,
True
)
# r
pkg_data_info_list
=
Argument
(
'pkg_data_info_list'
,
JArray
(
jstring
),
True
)
whitelisted_data_info_list
=
Argument
(
'whitelisted_data_info_list'
,
JArray
(
jstring
),
True
)
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
fork_m
=
Method
(
'm'
,
[
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
se_info
,
nice_name
,
fds_to_close
,
instruction_set
,
app_data_dir
])
fork_o
=
Method
(
'o'
,
[
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
se_info
,
nice_name
,
fds_to_close
,
fds_to_ignore
,
instruction_set
,
app_data_dir
])
fork_p
=
Method
(
'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
])
fork_q_alt
=
Method
(
'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
])
fork_r
=
Method
(
'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
])
fork_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
])
fork_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
])
fork_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
])
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
])
spec_q
=
Method
(
'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
,
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
,
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
])
server_m
=
Method
(
'm'
,
[
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
permitted_capabilities
,
effective_capabilities
])
server_samsung_q
=
Method
(
'samsung_q'
,
[
uid
,
gid
,
gids
,
runtime_flags
,
i1
,
i2
,
rlimits
,
permitted_capabilities
,
effective_capabilities
])
def
ind
(
i
):
return
'
\n
'
+
' '
*
i
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
'static {cpp_ret} {func_name}(JNIEnv *env, jclass clazz, {m.cpp()}) {{'
decl
+=
ind
(
1
)
+
'HookContext ctx{};'
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
)
+
'ctx.raw_args = &args;'
decl
+=
ind
(
1
)
+
f
'{base_name}_pre(&ctx, env, clazz);'
decl
+=
ind
(
1
)
+
f
'reinterpret_cast<decltype(&{func_name})>({base_name}_orig)('
decl
+=
ind
(
2
)
+
f
'env, clazz, {m.name_list()}'
decl
+=
ind
(
1
)
+
');'
decl
+=
ind
(
1
)
+
f
'{base_name}_post(&ctx, env, clazz);'
decl
+=
ret_stat
decl
+=
ind
(
0
)
+
'}'
decl
+=
ind
(
0
)
+
'namespace {'
decl
+=
ind
(
0
)
+
f
'const JNINativeMethod {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
(
1
)
+
'},'
decl
+=
ind
(
0
)
+
'};'
decl
+=
ind
(
0
)
+
f
'const int {base_name}_methods_num = std::size({base_name}_methods);'
decl
+=
ind
(
0
)
+
'} // namespace'
decl
+=
ind
(
0
)
return
decl
def
gen_fork
():
methods
=
[
fork_m
,
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'
)
def
gen_spec
():
methods
=
[
spec_q
,
spec_q_alt
,
spec_r
,
spec_samsung_q
]
return
gen_definitions
(
methods
,
'nativeSpecializeAppProcess'
)
def
gen_server
():
methods
=
[
server_m
,
server_samsung_q
]
return
gen_definitions
(
methods
,
'nativeForkSystemServer'
)
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
())
native/jni/inject/hook.cpp
View file @
25efdd3d
...
...
@@ -11,9 +11,58 @@ using jni_hook::hash_map;
using
jni_hook
::
tree_map
;
using
xstring
=
jni_hook
::
string
;
struct
SpecializeAppProcessArgs
{
jint
&
uid
;
jint
&
gid
;
jintArray
&
gids
;
jint
&
runtime_flags
;
jint
&
mount_external
;
jstring
&
se_info
;
jstring
&
nice_name
;
jstring
&
instruction_set
;
jstring
&
app_data_dir
;
/* Optional */
jboolean
*
is_child_zygote
=
nullptr
;
jboolean
*
is_top_app
=
nullptr
;
jobjectArray
*
pkg_data_info_list
=
nullptr
;
jobjectArray
*
whitelisted_data_info_list
=
nullptr
;
jboolean
*
mount_data_dirs
=
nullptr
;
jboolean
*
mount_storage_dirs
=
nullptr
;
SpecializeAppProcessArgs
(
jint
&
uid
,
jint
&
gid
,
jintArray
&
gids
,
jint
&
runtime_flags
,
jint
&
mount_external
,
jstring
&
se_info
,
jstring
&
nice_name
,
jstring
&
instruction_set
,
jstring
&
app_data_dir
)
:
uid
(
uid
),
gid
(
gid
),
gids
(
gids
),
runtime_flags
(
runtime_flags
),
mount_external
(
mount_external
),
se_info
(
se_info
),
nice_name
(
nice_name
),
instruction_set
(
instruction_set
),
app_data_dir
(
app_data_dir
)
{}
};
struct
ForkSystemServerArgs
{
jint
&
uid
;
jint
&
gid
;
jintArray
&
gids
;
jint
&
runtime_flags
;
jlong
&
permitted_capabilities
;
jlong
&
effective_capabilities
;
ForkSystemServerArgs
(
jint
&
uid
,
jint
&
gid
,
jintArray
&
gids
,
jint
&
runtime_flags
,
jlong
&
permitted_capabilities
,
jlong
&
effective_capabilities
)
:
uid
(
uid
),
gid
(
gid
),
gids
(
gids
),
runtime_flags
(
runtime_flags
),
permitted_capabilities
(
permitted_capabilities
),
effective_capabilities
(
effective_capabilities
)
{}
};
struct
HookContext
{
int
pid
;
bool
do_hide
;
union
{
SpecializeAppProcessArgs
*
args
;
ForkSystemServerArgs
*
server_args
;
void
*
raw_args
;
};
};
static
vector
<
tuple
<
const
char
*
,
const
char
*
,
void
**>>
*
xhook_list
;
...
...
@@ -21,7 +70,6 @@ static vector<JNINativeMethod> *jni_hook_list;
static
hash_map
<
xstring
,
tree_map
<
xstring
,
tree_map
<
xstring
,
void
*>>>
*
jni_method_map
;
static
JavaVM
*
g_jvm
;
static
int
prev_fork_pid
=
-
1
;
static
HookContext
*
current_ctx
;
#define DCL_HOOK_FUNC(ret, func, ...) \
...
...
@@ -29,10 +77,7 @@ static HookContext *current_ctx;
static ret new_##func(__VA_ARGS__)
#define DCL_JNI_FUNC(name) \
static int name##_orig_idx; \
static inline JNINativeMethod &name##_orig() { \
return (*jni_hook_list)[name##_orig_idx]; \
} \
static void *name##_orig; \
extern const JNINativeMethod name##_methods[]; \
extern const int name##_methods_num;
...
...
@@ -44,9 +89,9 @@ DCL_JNI_FUNC(nativeForkSystemServer)
}
#define HOOK_JNI(method) \
if (
hooked < 3 &&
methods[i].name == #method##sv) { \
if (methods[i].name == #method##sv) { \
jni_hook_list->push_back(methods[i]); \
method##_orig
_idx = jni_hook_list->size() - 1;
\
method##_orig
= methods[i].fnPtr;
\
for (int j = 0; j < method##_methods_num; ++j) { \
if (strcmp(methods[i].signature, method##_methods[j].signature) == 0) { \
newMethods[i] = method##_methods[j]; \
...
...
@@ -78,22 +123,18 @@ DCL_HOOK_FUNC(int, jniRegisterNativeMethods,
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
old_jniRegisterNativeMethods
(
env
,
className
,
newMethods
.
get
()
?:
methods
,
numMethods
);
}
DCL_HOOK_FUNC
(
int
,
fork
)
{
if
(
prev_fork_pid
<
0
)
return
old_fork
();
// Skip an actual fork and return the previous fork result
int
pid
=
prev_fork_pid
;
prev_fork_pid
=
-
1
;
return
pid
;
return
current_ctx
?
current_ctx
->
pid
:
old_fork
();
}
DCL_HOOK_FUNC
(
int
,
selinux_android_setcontext
,
...
...
@@ -114,103 +155,73 @@ static int sigmask(int how, int signum) {
return
sigprocmask
(
how
,
&
set
,
nullptr
);
}
static
int
pre_specialize_fork
()
{
// First block SIGCHLD, unblock after original fork is done
sigmask
(
SIG_BLOCK
,
SIGCHLD
);
prev_fork_pid
=
old_fork
();
return
prev_fork_pid
;
}
// -----------------------------------------------------------------
static
void
nativeSpecializeAppProcess_pre
(
HookContext
*
ctx
,
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
,
jboolean
&
is_top_app
,
jobjectArray
&
pkg_data_info_list
,
jobjectArray
&
whitelisted_data_info_list
,
jboolean
&
mount_data_dirs
,
jboolean
&
mount_storage_dirs
)
{
static
void
nativeSpecializeAppProcess_pre
(
HookContext
*
ctx
,
JNIEnv
*
env
,
jclass
clazz
)
{
current_ctx
=
ctx
;
const
char
*
process
=
env
->
GetStringUTFChars
(
nice_name
,
nullptr
);
const
char
*
process
=
env
->
GetStringUTFChars
(
ctx
->
args
->
nice_name
,
nullptr
);
LOGD
(
"hook: %s %s
\n
"
,
__FUNCTION__
,
process
);
if
(
mount_external
!=
0
/* TODO: Handle MOUNT_EXTERNAL_NONE cases */
&&
remote_check_hide
(
uid
,
process
))
{
if
(
ctx
->
args
->
mount_external
!=
0
/* TODO: Handle MOUNT_EXTERNAL_NONE cases */
&&
remote_check_hide
(
ctx
->
args
->
uid
,
process
))
{
ctx
->
do_hide
=
true
;
LOGI
(
"hook: [%s] should be hidden
\n
"
,
process
);
}
env
->
ReleaseStringUTFChars
(
nice_name
,
process
);
env
->
ReleaseStringUTFChars
(
ctx
->
args
->
nice_name
,
process
);
}
static
void
nativeSpecializeAppProcess_post
(
HookContext
*
ctx
,
JNIEnv
*
env
,
jclass
clazz
)
{
current_ctx
=
nullptr
;
LOGD
(
"hook: %s
\n
"
,
__FUNCTION__
);
if
(
ctx
->
do_hide
)
self_unload
();
current_ctx
=
nullptr
;
}
// -----------------------------------------------------------------
static
void
nativeForkAndSpecialize_pre
(
HookContext
*
ctx
,
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
,
jintArray
fds_to_ignore
,
/* These 2 arguments are unique to fork */
jboolean
&
is_child_zygote
,
jstring
&
instruction_set
,
jstring
&
app_data_dir
,
jboolean
&
is_top_app
,
jobjectArray
&
pkg_data_info_list
,
jobjectArray
&
whitelisted_data_info_list
,
jboolean
&
mount_data_dirs
,
jboolean
&
mount_storage_dirs
)
{
// Do our own fork before loading any 3rd party code
ctx
->
pid
=
pre_specialize_fork
();
if
(
ctx
->
pid
!=
0
)
// Do our own fork before loading any 3rd party code
// First block SIGCHLD, unblock after original fork is done
#define PRE_FORK() \
current_ctx = ctx; \
sigmask(SIG_BLOCK, SIGCHLD); \
ctx->pid = old_fork(); \
if (ctx->pid != 0) \
return;
nativeSpecializeAppProcess_pre
(
ctx
,
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
);
// Unblock SIGCHLD in case the original method didn't
#define POST_FORK() \
current_ctx = nullptr; \
sigmask(SIG_UNBLOCK, SIGCHLD); \
if (ctx->pid != 0)\
return;
static
void
nativeForkAndSpecialize_pre
(
HookContext
*
ctx
,
JNIEnv
*
env
,
jclass
clazz
)
{
PRE_FORK
();
nativeSpecializeAppProcess_pre
(
ctx
,
env
,
clazz
);
}
static
void
nativeForkAndSpecialize_post
(
HookContext
*
ctx
,
JNIEnv
*
env
,
jclass
clazz
)
{
// Unblock SIGCHLD in case the original method didn't
sigmask
(
SIG_UNBLOCK
,
SIGCHLD
);
if
(
ctx
->
pid
!=
0
)
return
;
POST_FORK
();
nativeSpecializeAppProcess_post
(
ctx
,
env
,
clazz
);
}
// -----------------------------------------------------------------
static
void
nativeForkSystemServer_pre
(
HookContext
*
ctx
,
JNIEnv
*
env
,
jclass
clazz
,
uid_t
&
uid
,
gid_t
&
gid
,
jintArray
&
gids
,
jint
&
runtime_flags
,
jobjectArray
&
rlimits
,
jlong
&
permitted_capabilities
,
jlong
&
effective_capabilities
)
{
// Do our own fork before loading any 3rd party code
ctx
->
pid
=
pre_specialize_fork
();
if
(
ctx
->
pid
!=
0
)
return
;
current_ctx
=
ctx
;
static
void
nativeForkSystemServer_pre
(
HookContext
*
ctx
,
JNIEnv
*
env
,
jclass
clazz
)
{
PRE_FORK
();
LOGD
(
"hook: %s
\n
"
,
__FUNCTION__
);
}
static
void
nativeForkSystemServer_post
(
HookContext
*
ctx
,
JNIEnv
*
env
,
jclass
clazz
)
{
// Unblock SIGCHLD in case the original method didn't
sigmask
(
SIG_UNBLOCK
,
SIGCHLD
);
if
(
ctx
->
pid
!=
0
)
return
;
POST_FORK
();
LOGD
(
"hook: %s
\n
"
,
__FUNCTION__
);
current_ctx
=
nullptr
;
}
#undef PRE_FORK
#undef POST_FORK
// -----------------------------------------------------------------
static
bool
hook_refresh
()
{
...
...
@@ -282,4 +293,5 @@ bool unhook_functions() {
return
hook_refresh
();
}
// JNI method definitions, include all method signatures of past Android versions
#include "jni_hooks.hpp"
native/jni/inject/jni_hooks.hpp
View file @
25efdd3d
/*
* Original code from: https://github.com/RikkaApps/Riru
* The code is modified and sublicensed to GPLv3 for incorporating into Magisk.
*
* Copyright (c) 2018-2021, RikkaW
* Copyright (c) 2021, John 'topjohnwu' Wu
*/
#define ENABLE_LEGACY_DP 0 // Nobody should use outdated developer preview...
// All possible missing arguments
static
union
{
struct
{
jintArray
fds_to_ignore
;
jboolean
is_child_zygote
;
jboolean
is_top_app
;
jobjectArray
pkg_data_info_list
;
jobjectArray
whitelisted_data_info_list
;
jboolean
mount_data_dirs
;
jboolean
mount_storage_dirs
;
};
size_t
args_buf
[
8
];
// Easy access to wipe all variables at once
};
#define DCL_JNI(ret, name, sig, ...) \
const static char name##_sig[] = sig; \
static ret name(__VA_ARGS__)
// -----------------------------------------------------------------
#define pre_fork() \
HookContext ctx{}; \
memset(args_buf, 0, sizeof(args_buf)); \
nativeForkAndSpecialize_pre(&ctx, 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)
#define orig_fork(ver, ...) \
reinterpret_cast<decltype(&nativeForkAndSpecialize_##ver)> \
(nativeForkAndSpecialize_orig().fnPtr)(__VA_ARGS__)
#define post_fork() \
nativeForkAndSpecialize_post(&ctx, env, clazz); \
return ctx.pid
#define DCL_FORK_AND_SPECIALIZE(ver, sig, ...) \
DCL_JNI(jint, nativeForkAndSpecialize_##ver, sig, __VA_ARGS__)
DCL_FORK_AND_SPECIALIZE
(
m
,
"(II[II[[IILjava/lang/String;Ljava/lang/String;[ILjava/lang/String;Ljava/lang/String;)I"
,
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
)
{
pre_fork
();
orig_fork
(
m
,
env
,
clazz
,
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
se_info
,
nice_name
,
fds_to_close
,
instruction_set
,
app_data_dir
);
post_fork
();
// Generated by gen_jni_hooks.py
static
jint
nativeForkAndSpecialize_m
(
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
)
{
HookContext
ctx
{};
SpecializeAppProcessArgs
args
(
uid
,
gid
,
gids
,
runtime_flags
,
mount_external
,
se_info
,
nice_name
,
instruction_set
,
app_data_dir
);
ctx
.
raw_args
=
&
args
;
nativeForkAndSpecialize_pre
(
&
ctx
,
env
,
clazz
);
reinterpret_cast
<
decltype
(
&
nativeForkAndSpecialize_m
)
>
(
nativeForkAndSpecialize_orig
)(
env
,
clazz
,
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
se_info
,
nice_name
,
fds_to_close
,
instruction_set
,
app_data_dir
);
nativeForkAndSpecialize_post
(
&
ctx
,
env
,
clazz
);
return
ctx
.
pid
;
}
DCL_FORK_AND_SPECIALIZE
(
o
,
"(II[II[[IILjava/lang/String;Ljava/lang/String;[I[ILjava/lang/String;Ljava/lang/String;)I"
,
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
,
jintArray
fds_to_ignore
,
jstring
instruction_set
,
jstring
app_data_dir
)
{
pre_fork
();
orig_fork
(
o
,
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
);
post_fork
()
;
static
jint
nativeForkAndSpecialize_o
(
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
,
jintArray
fds_to_ignore
,
jstring
instruction_set
,
jstring
app_data_dir
)
{
HookContext
ctx
{};
SpecializeAppProcessArgs
args
(
uid
,
gid
,
gids
,
runtime_flags
,
mount_external
,
se_info
,
nice_name
,
instruction_set
,
app_data_dir
);
ctx
.
raw_args
=
&
args
;
nativeForkAndSpecialize_pre
(
&
ctx
,
env
,
clazz
);
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
);
nativeForkAndSpecialize_post
(
&
ctx
,
env
,
clazz
);
return
ctx
.
pid
;
}
DCL_FORK_AND_SPECIALIZE
(
p
,
"(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;)I"
,
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
,
jintArray
fds_to_ignore
,
jboolean
is_child_zygote
,
jstring
instruction_set
,
jstring
app_data_dir
)
{
pre_fork
();
orig_fork
(
p
,
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
);
post_fork
()
;
static
jint
nativeForkAndSpecialize_p
(
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
,
jintArray
fds_to_ignore
,
jboolean
is_child_zygote
,
jstring
instruction_set
,
jstring
app_data_dir
)
{
HookContext
ctx
{};
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
;
ctx
.
raw_args
=
&
args
;
nativeForkAndSpecialize_pre
(
&
ctx
,
env
,
clazz
);
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
);
nativeForkAndSpecialize_post
(
&
ctx
,
env
,
clazz
);
return
ctx
.
pid
;
}
DCL_FORK_AND_SPECIALIZE
(
q_alt
,
"(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;Z)I"
,
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
,
jintArray
fds_to_ignore
,
jboolean
is_child_zygote
,
jstring
instruction_set
,
jstring
app_data_dir
,
jboolean
is_top_app
)
{
pre_fork
();
orig_fork
(
q_alt
,
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
);
post_fork
();
static
jint
nativeForkAndSpecialize_q_alt
(
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
,
jintArray
fds_to_ignore
,
jboolean
is_child_zygote
,
jstring
instruction_set
,
jstring
app_data_dir
,
jboolean
is_top_app
)
{
HookContext
ctx
{};
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
;
args
.
is_top_app
=
&
is_top_app
;
ctx
.
raw_args
=
&
args
;
nativeForkAndSpecialize_pre
(
&
ctx
,
env
,
clazz
);
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
);
nativeForkAndSpecialize_post
(
&
ctx
,
env
,
clazz
);
return
ctx
.
pid
;
}
#if ENABLE_LEGACY_DP
DCL_FORK_AND_SPECIALIZE
(
r_dp2
,
"(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;Z[Ljava/lang/String;)I"
,
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
,
jintArray
fds_to_ignore
,
jboolean
is_child_zygote
,
jstring
instruction_set
,
jstring
app_data_dir
,
jboolean
is_top_app
,
jobjectArray
pkg_data_info_list
)
{
pre_fork
();
orig_fork
(
r_dp2
,
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
);
post_fork
();
static
jint
nativeForkAndSpecialize_r
(
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
,
jintArray
fds_to_ignore
,
jboolean
is_child_zygote
,
jstring
instruction_set
,
jstring
app_data_dir
,
jboolean
is_top_app
,
jobjectArray
pkg_data_info_list
,
jobjectArray
whitelisted_data_info_list
,
jboolean
mount_data_dirs
,
jboolean
mount_storage_dirs
)
{
HookContext
ctx
{};
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
;
args
.
is_top_app
=
&
is_top_app
;
args
.
pkg_data_info_list
=
&
pkg_data_info_list
;
args
.
whitelisted_data_info_list
=
&
whitelisted_data_info_list
;
args
.
mount_data_dirs
=
&
mount_data_dirs
;
args
.
mount_storage_dirs
=
&
mount_storage_dirs
;
ctx
.
raw_args
=
&
args
;
nativeForkAndSpecialize_pre
(
&
ctx
,
env
,
clazz
);
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
);
nativeForkAndSpecialize_post
(
&
ctx
,
env
,
clazz
);
return
ctx
.
pid
;
}
DCL_FORK_AND_SPECIALIZE
(
r_dp3
,
"(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;Z[Ljava/lang/String;Z)I"
,
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
,
jintArray
fds_to_ignore
,
jboolean
is_child_zygote
,
jstring
instruction_set
,
jstring
app_data_dir
,
jboolean
is_top_app
,
jobjectArray
pkg_data_info_list
,
jboolean
mount_storage_dirs
)
{
pre_fork
();
orig_fork
(
r_dp3
,
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
,
mount_storage_dirs
);
post_fork
();
static
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
)
{
HookContext
ctx
{};
SpecializeAppProcessArgs
args
(
uid
,
gid
,
gids
,
runtime_flags
,
mount_external
,
se_info
,
nice_name
,
instruction_set
,
app_data_dir
);
ctx
.
raw_args
=
&
args
;
nativeForkAndSpecialize_pre
(
&
ctx
,
env
,
clazz
);
reinterpret_cast
<
decltype
(
&
nativeForkAndSpecialize_samsung_m
)
>
(
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
);
nativeForkAndSpecialize_post
(
&
ctx
,
env
,
clazz
);
return
ctx
.
pid
;
}
#endif // ENABLE_LEGACY_DP
DCL_FORK_AND_SPECIALIZE
(
r
,
"(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;Z[Ljava/lang/String;[Ljava/lang/String;ZZ)I"
,
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
,
jintArray
fds_to_ignore
,
jboolean
is_child_zygote
,
jstring
instruction_set
,
jstring
app_data_dir
,
jboolean
is_top_app
,
jobjectArray
pkg_data_info_list
,
jobjectArray
whitelisted_data_info_list
,
jboolean
mount_data_dirs
,
jboolean
mount_storage_dirs
)
{
pre_fork
();
orig_fork
(
r
,
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
);
post_fork
();
static
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
)
{
HookContext
ctx
{};
SpecializeAppProcessArgs
args
(
uid
,
gid
,
gids
,
runtime_flags
,
mount_external
,
se_info
,
nice_name
,
instruction_set
,
app_data_dir
);
ctx
.
raw_args
=
&
args
;
nativeForkAndSpecialize_pre
(
&
ctx
,
env
,
clazz
);
reinterpret_cast
<
decltype
(
&
nativeForkAndSpecialize_samsung_n
)
>
(
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
);
nativeForkAndSpecialize_post
(
&
ctx
,
env
,
clazz
);
return
ctx
.
pid
;
}
DCL_FORK_AND_SPECIALIZE
(
samsung_m
,
"(II[II[[IILjava/lang/String;IILjava/lang/String;[ILjava/lang/String;Ljava/lang/String;)I"
,
JNIEnv
*
env
,
jclass
clazz
,
jint
uid
,
jint
gid
,
jintArray
gids
,
jint
runtime_flags
,
jobjectArray
rlimits
,
jint
mount_external
,
jstring
se_info
,
jint
category
,
jint
accessInfo
,
jstring
nice_name
,
jintArray
fds_to_close
,
jstring
instruction_set
,
jstring
app_data_dir
)
{
pre_fork
();
orig_fork
(
samsung_m
,
env
,
clazz
,
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
se_info
,
category
,
accessInfo
,
nice_name
,
fds_to_close
,
instruction_set
,
app_data_dir
);
post_fork
()
;
static
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
)
{
HookContext
ctx
{};
SpecializeAppProcessArgs
args
(
uid
,
gid
,
gids
,
runtime_flags
,
mount_external
,
se_info
,
nice_name
,
instruction_set
,
app_data_dir
);
ctx
.
raw_args
=
&
args
;
nativeForkAndSpecialize_pre
(
&
ctx
,
env
,
clazz
);
reinterpret_cast
<
decltype
(
&
nativeForkAndSpecialize_samsung_o
)
>
(
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
);
nativeForkAndSpecialize_post
(
&
ctx
,
env
,
clazz
);
return
ctx
.
pid
;
}
DCL_FORK_AND_SPECIALIZE
(
samsung_n
,
"(II[II[[IILjava/lang/String;IILjava/lang/String;[ILjava/lang/String;Ljava/lang/String;I)I"
,
JNIEnv
*
env
,
jclass
clazz
,
jint
uid
,
jint
gid
,
jintArray
gids
,
jint
runtime_flags
,
jobjectArray
rlimits
,
jint
mount_external
,
jstring
se_info
,
jint
category
,
jint
accessInfo
,
jstring
nice_name
,
jintArray
fds_to_close
,
jstring
instruction_set
,
jstring
app_data_dir
,
jint
a1
)
{
pre_fork
();
orig_fork
(
samsung_n
,
env
,
clazz
,
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
se_info
,
category
,
accessInfo
,
nice_name
,
fds_to_close
,
instruction_set
,
app_data_dir
,
a1
);
post_fork
();
static
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
)
{
HookContext
ctx
{};
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
;
ctx
.
raw_args
=
&
args
;
nativeForkAndSpecialize_pre
(
&
ctx
,
env
,
clazz
);
reinterpret_cast
<
decltype
(
&
nativeForkAndSpecialize_samsung_p
)
>
(
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
);
nativeForkAndSpecialize_post
(
&
ctx
,
env
,
clazz
);
return
ctx
.
pid
;
}
DCL_FORK_AND_SPECIALIZE
(
samsung_o
,
namespace
{
const
JNINativeMethod
nativeForkAndSpecialize_methods
[]
=
{
{
"nativeForkAndSpecialize"
,
"(II[II[[IILjava/lang/String;Ljava/lang/String;[ILjava/lang/String;Ljava/lang/String;)I"
,
(
void
*
)
&
nativeForkAndSpecialize_m
},
{
"nativeForkAndSpecialize"
,
"(II[II[[IILjava/lang/String;Ljava/lang/String;[I[ILjava/lang/String;Ljava/lang/String;)I"
,
(
void
*
)
&
nativeForkAndSpecialize_o
},
{
"nativeForkAndSpecialize"
,
"(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;)I"
,
(
void
*
)
&
nativeForkAndSpecialize_p
},
{
"nativeForkAndSpecialize"
,
"(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;Z)I"
,
(
void
*
)
&
nativeForkAndSpecialize_q_alt
},
{
"nativeForkAndSpecialize"
,
"(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;Z[Ljava/lang/String;[Ljava/lang/String;ZZ)I"
,
(
void
*
)
&
nativeForkAndSpecialize_r
},
{
"nativeForkAndSpecialize"
,
"(II[II[[IILjava/lang/String;IILjava/lang/String;[ILjava/lang/String;Ljava/lang/String;)I"
,
(
void
*
)
&
nativeForkAndSpecialize_samsung_m
},
{
"nativeForkAndSpecialize"
,
"(II[II[[IILjava/lang/String;IILjava/lang/String;[ILjava/lang/String;Ljava/lang/String;I)I"
,
(
void
*
)
&
nativeForkAndSpecialize_samsung_n
},
{
"nativeForkAndSpecialize"
,
"(II[II[[IILjava/lang/String;IILjava/lang/String;[I[ILjava/lang/String;Ljava/lang/String;)I"
,
JNIEnv
*
env
,
jclass
clazz
,
jint
uid
,
jint
gid
,
jintArray
gids
,
jint
runtime_flags
,
jobjectArray
rlimits
,
jint
mount_external
,
jstring
se_info
,
jint
category
,
jint
accessInfo
,
jstring
nice_name
,
jintArray
fds_to_close
,
jintArray
fds_to_ignore
,
jstring
instruction_set
,
jstring
app_data_dir
)
{
pre_fork
();
orig_fork
(
samsung_o
,
env
,
clazz
,
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
se_info
,
category
,
accessInfo
,
nice_name
,
fds_to_close
,
fds_to_ignore
,
instruction_set
,
app_data_dir
);
post_fork
();
}
DCL_FORK_AND_SPECIALIZE
(
samsung_p
,
(
void
*
)
&
nativeForkAndSpecialize_samsung_o
},
{
"nativeForkAndSpecialize"
,
"(II[II[[IILjava/lang/String;IILjava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;)I"
,
JNIEnv
*
env
,
jclass
clazz
,
jint
uid
,
jint
gid
,
jintArray
gids
,
jint
runtime_flags
,
jobjectArray
rlimits
,
jint
mount_external
,
jstring
se_info
,
jint
category
,
jint
accessInfo
,
jstring
nice_name
,
jintArray
fds_to_close
,
jintArray
fds_to_ignore
,
jboolean
is_child_zygote
,
jstring
instruction_set
,
jstring
app_data_dir
)
{
pre_fork
();
orig_fork
(
samsung_p
,
env
,
clazz
,
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
se_info
,
category
,
accessInfo
,
nice_name
,
fds_to_close
,
fds_to_ignore
,
is_child_zygote
,
instruction_set
,
app_data_dir
);
post_fork
();
}
#define DEF_FORK(ver) { \
"nativeForkAndSpecialize", \
nativeForkAndSpecialize_##ver##_sig, \
(void *) &nativeForkAndSpecialize_##ver \
}
// -----------------------------------------------------------------
#define pre_spec() \
HookContext ctx{}; \
memset(args_buf, 0, sizeof(args_buf)); \
nativeSpecializeAppProcess_pre(&ctx, \
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)
#define orig_spec(ver, ...) \
reinterpret_cast<decltype(&nativeSpecializeAppProcess_##ver)> \
(nativeSpecializeAppProcess_orig().fnPtr)(__VA_ARGS__)
#define post_spec() \
nativeSpecializeAppProcess_post(&ctx, env, clazz)
#define DCL_SPECIALIZE_APP(ver, sig, ...) \
DCL_JNI(void, nativeSpecializeAppProcess_##ver, sig, __VA_ARGS__)
DCL_SPECIALIZE_APP
(
q
,
"(II[II[[IILjava/lang/String;Ljava/lang/String;ZLjava/lang/String;Ljava/lang/String;)V"
,
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
)
{
pre_spec
();
orig_spec
(
q
,
env
,
clazz
,
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
se_info
,
nice_name
,
is_child_zygote
,
instruction_set
,
app_data_dir
);
post_spec
();
(
void
*
)
&
nativeForkAndSpecialize_samsung_p
},
};
const
int
nativeForkAndSpecialize_methods_num
=
std
::
size
(
nativeForkAndSpecialize_methods
);
}
// namespace
static
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
)
{
HookContext
ctx
{};
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
;
ctx
.
raw_args
=
&
args
;
nativeSpecializeAppProcess_pre
(
&
ctx
,
env
,
clazz
);
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
);
nativeSpecializeAppProcess_post
(
&
ctx
,
env
,
clazz
);
}
DCL_SPECIALIZE_APP
(
q_alt
,
"(II[II[[IILjava/lang/String;Ljava/lang/String;ZLjava/lang/String;Ljava/lang/String;Z)V"
,
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
,
jboolean
is_top_app
)
{
pre_spec
();
orig_spec
(
q_alt
,
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
);
post_spec
(
);
static
void
nativeSpecializeAppProcess_q_alt
(
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
,
jboolean
is_top_app
)
{
HookContext
ctx
{};
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
;
args
.
is_top_app
=
&
is_top_app
;
ctx
.
raw_args
=
&
args
;
nativeSpecializeAppProcess_pre
(
&
ctx
,
env
,
clazz
);
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
);
nativeSpecializeAppProcess_post
(
&
ctx
,
env
,
clazz
);
}
#if ENABLE_LEGACY_DP
DCL_SPECIALIZE_APP
(
r_dp2
,
"(II[II[[IILjava/lang/String;Ljava/lang/String;ZLjava/lang/String;Ljava/lang/String;Z[Ljava/lang/String;)V"
,
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
,
jboolean
is_top_app
,
jobjectArray
pkg_data_info_list
)
{
pre_spec
();
orig_spec
(
r_dp2
,
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
);
post_spec
();
static
void
nativeSpecializeAppProcess_r
(
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
,
jboolean
is_top_app
,
jobjectArray
pkg_data_info_list
,
jobjectArray
whitelisted_data_info_list
,
jboolean
mount_data_dirs
,
jboolean
mount_storage_dirs
)
{
HookContext
ctx
{};
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
;
args
.
is_top_app
=
&
is_top_app
;
args
.
pkg_data_info_list
=
&
pkg_data_info_list
;
args
.
whitelisted_data_info_list
=
&
whitelisted_data_info_list
;
args
.
mount_data_dirs
=
&
mount_data_dirs
;
args
.
mount_storage_dirs
=
&
mount_storage_dirs
;
ctx
.
raw_args
=
&
args
;
nativeSpecializeAppProcess_pre
(
&
ctx
,
env
,
clazz
);
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
);
nativeSpecializeAppProcess_post
(
&
ctx
,
env
,
clazz
);
}
DCL_SPECIALIZE_APP
(
r_dp3
,
"(II[II[[IILjava/lang/String;Ljava/lang/String;ZLjava/lang/String;Ljava/lang/String;Z[Ljava/lang/String;Z)V"
,
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
,
jboolean
is_top_app
,
jobjectArray
pkg_data_info_list
,
jboolean
mount_storage_dirs
)
{
pre_spec
();
orig_spec
(
r_dp3
,
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
,
mount_storage_dirs
);
post_spec
();
static
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
)
{
HookContext
ctx
{};
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
;
ctx
.
raw_args
=
&
args
;
nativeSpecializeAppProcess_pre
(
&
ctx
,
env
,
clazz
);
reinterpret_cast
<
decltype
(
&
nativeSpecializeAppProcess_samsung_q
)
>
(
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
);
nativeSpecializeAppProcess_post
(
&
ctx
,
env
,
clazz
);
}
#endif // ENABLE_LEGACY_DP
DCL_SPECIALIZE_APP
(
r
,
namespace
{
const
JNINativeMethod
nativeSpecializeAppProcess_methods
[]
=
{
{
"nativeSpecializeAppProcess"
,
"(II[II[[IILjava/lang/String;Ljava/lang/String;ZLjava/lang/String;Ljava/lang/String;)V"
,
(
void
*
)
&
nativeSpecializeAppProcess_q
},
{
"nativeSpecializeAppProcess"
,
"(II[II[[IILjava/lang/String;Ljava/lang/String;ZLjava/lang/String;Ljava/lang/String;Z)V"
,
(
void
*
)
&
nativeSpecializeAppProcess_q_alt
},
{
"nativeSpecializeAppProcess"
,
"(II[II[[IILjava/lang/String;Ljava/lang/String;ZLjava/lang/String;Ljava/lang/String;Z[Ljava/lang/String;[Ljava/lang/String;ZZ)V"
,
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
,
jboolean
is_top_app
,
jobjectArray
pkg_data_info_list
,
jobjectArray
whitelisted_data_info_list
,
jboolean
mount_data_dirs
,
jboolean
mount_storage_dirs
)
{
pre_spec
();
orig_spec
(
r
,
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
);
post_spec
();
}
DCL_SPECIALIZE_APP
(
samsung_q
,
(
void
*
)
&
nativeSpecializeAppProcess_r
},
{
"nativeSpecializeAppProcess"
,
"(II[II[[IILjava/lang/String;IILjava/lang/String;ZLjava/lang/String;Ljava/lang/String;)V"
,
JNIEnv
*
env
,
jclass
clazz
,
jint
uid
,
jint
gid
,
jintArray
gids
,
jint
runtime_flags
,
jobjectArray
rlimits
,
jint
mount_external
,
jstring
se_info
,
jint
space
,
jint
accessInfo
,
jstring
nice_name
,
jboolean
is_child_zygote
,
jstring
instruction_set
,
jstring
app_data_dir
)
{
pre_spec
();
orig_spec
(
samsung_q
,
env
,
clazz
,
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
se_info
,
space
,
accessInfo
,
nice_name
,
is_child_zygote
,
instruction_set
,
app_data_dir
);
post_spec
();
}
#define DEF_SPEC(ver) { \
"nativeSpecializeAppProcess", \
nativeSpecializeAppProcess_##ver##_sig, \
(void *) &nativeSpecializeAppProcess_##ver \
}
// -----------------------------------------------------------------
#define pre_server() \
HookContext ctx{}; \
memset(args_buf, 0, sizeof(args_buf)); \
nativeForkSystemServer_pre(&ctx, env, clazz, uid, gid, gids, runtime_flags, \
rlimits, permitted_capabilities, effective_capabilities)
#define orig_server(ver, ...) \
reinterpret_cast<decltype(&nativeForkSystemServer_##ver)> \
(nativeForkSystemServer_orig().fnPtr)(__VA_ARGS__)
#define post_server() \
nativeForkSystemServer_post(&ctx, env, clazz); \
return ctx.pid
#define DCL_FORK_SERVER(ver, sig, ...) \
DCL_JNI(jint, nativeForkSystemServer_##ver, sig, __VA_ARGS__)
DCL_FORK_SERVER
(
m
,
"(II[II[[IJJ)I"
,
JNIEnv
*
env
,
jclass
clazz
,
uid_t
uid
,
gid_t
gid
,
jintArray
gids
,
jint
runtime_flags
,
jobjectArray
rlimits
,
jlong
permitted_capabilities
,
jlong
effective_capabilities
)
{
pre_server
();
orig_server
(
m
,
env
,
clazz
,
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
permitted_capabilities
,
effective_capabilities
);
post_server
();
}
DCL_FORK_SERVER
(
samsung_q
,
"(II[IIII[[IJJ)I"
,
JNIEnv
*
env
,
jclass
clazz
,
uid_t
uid
,
gid_t
gid
,
jintArray
gids
,
jint
runtime_flags
,
jint
space
,
jint
accessInfo
,
jobjectArray
rlimits
,
jlong
permitted_capabilities
,
jlong
effective_capabilities
)
{
pre_server
();
orig_server
(
samsung_q
,
env
,
clazz
,
uid
,
gid
,
gids
,
runtime_flags
,
space
,
accessInfo
,
rlimits
,
permitted_capabilities
,
effective_capabilities
);
post_server
();
(
void
*
)
&
nativeSpecializeAppProcess_samsung_q
},
};
const
int
nativeSpecializeAppProcess_methods_num
=
std
::
size
(
nativeSpecializeAppProcess_methods
);
}
// namespace
static
jint
nativeForkSystemServer_m
(
JNIEnv
*
env
,
jclass
clazz
,
jint
uid
,
jint
gid
,
jintArray
gids
,
jint
runtime_flags
,
jobjectArray
rlimits
,
jlong
permitted_capabilities
,
jlong
effective_capabilities
)
{
HookContext
ctx
{};
ForkSystemServerArgs
args
(
uid
,
gid
,
gids
,
runtime_flags
,
permitted_capabilities
,
effective_capabilities
);
ctx
.
raw_args
=
&
args
;
nativeForkSystemServer_pre
(
&
ctx
,
env
,
clazz
);
reinterpret_cast
<
decltype
(
&
nativeForkSystemServer_m
)
>
(
nativeForkSystemServer_orig
)(
env
,
clazz
,
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
permitted_capabilities
,
effective_capabilities
);
nativeForkSystemServer_post
(
&
ctx
,
env
,
clazz
);
return
ctx
.
pid
;
}
#define DEF_SERVER(ver) { \
"nativeForkSystemServer", \
nativeForkSystemServer_##ver##_sig, \
(void *) &nativeForkSystemServer_##ver \
static
jint
nativeForkSystemServer_samsung_q
(
JNIEnv
*
env
,
jclass
clazz
,
jint
uid
,
jint
gid
,
jintArray
gids
,
jint
runtime_flags
,
jint
i1
,
jint
i2
,
jobjectArray
rlimits
,
jlong
permitted_capabilities
,
jlong
effective_capabilities
)
{
HookContext
ctx
{};
ForkSystemServerArgs
args
(
uid
,
gid
,
gids
,
runtime_flags
,
permitted_capabilities
,
effective_capabilities
);
ctx
.
raw_args
=
&
args
;
nativeForkSystemServer_pre
(
&
ctx
,
env
,
clazz
);
reinterpret_cast
<
decltype
(
&
nativeForkSystemServer_samsung_q
)
>
(
nativeForkSystemServer_orig
)(
env
,
clazz
,
uid
,
gid
,
gids
,
runtime_flags
,
i1
,
i2
,
rlimits
,
permitted_capabilities
,
effective_capabilities
);
nativeForkSystemServer_post
(
&
ctx
,
env
,
clazz
);
return
ctx
.
pid
;
}
namespace
{
const
JNINativeMethod
nativeForkAndSpecialize_methods
[]
=
{
DEF_FORK
(
m
),
DEF_FORK
(
o
),
DEF_FORK
(
p
),
DEF_FORK
(
q_alt
),
DEF_FORK
(
r
),
DEF_FORK
(
samsung_m
),
DEF_FORK
(
samsung_n
),
DEF_FORK
(
samsung_o
),
DEF_FORK
(
samsung_p
),
#if ENABLE_LEGACY_DP
DEF_FORK
(
r_dp2
),
DEF_FORK
(
r_dp3
)
#endif
};
const
int
nativeForkAndSpecialize_methods_num
=
std
::
size
(
nativeForkAndSpecialize_methods
);
const
JNINativeMethod
nativeSpecializeAppProcess_methods
[]
=
{
DEF_SPEC
(
q
),
DEF_SPEC
(
q_alt
),
DEF_SPEC
(
r
),
DEF_SPEC
(
samsung_q
),
#if ENABLE_LEGACY_DP
DEF_SPEC
(
r_dp2
),
DEF_SPEC
(
r_dp3
)
#endif
};
const
int
nativeSpecializeAppProcess_methods_num
=
std
::
size
(
nativeSpecializeAppProcess_methods
);
const
JNINativeMethod
nativeForkSystemServer_methods
[]
=
{
DEF_SERVER
(
m
),
DEF_SERVER
(
samsung_q
)
{
"nativeForkSystemServer"
,
"(II[II[[IJJ)I"
,
(
void
*
)
&
nativeForkSystemServer_m
},
{
"nativeForkSystemServer"
,
"(II[IIII[[IJJ)I"
,
(
void
*
)
&
nativeForkSystemServer_samsung_q
},
};
const
int
nativeForkSystemServer_methods_num
=
std
::
size
(
nativeForkSystemServer_methods
);
}
}
// namespace
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