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
9ed110c9
Commit
9ed110c9
authored
Jan 08, 2021
by
topjohnwu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add JNI hooks to critical methods
parent
a30d510e
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
700 additions
and
5 deletions
+700
-5
Android.mk
native/jni/Android.mk
+2
-1
entry.cpp
native/jni/inject/entry.cpp
+1
-0
hook.cpp
native/jni/inject/hook.cpp
+75
-4
inject.hpp
native/jni/inject/inject.hpp
+26
-0
jni_hooks.cpp
native/jni/inject/jni_hooks.cpp
+596
-0
No files found.
native/jni/Android.mk
View file @
9ed110c9
...
@@ -33,7 +33,8 @@ LOCAL_SRC_FILES := \
...
@@ -33,7 +33,8 @@ LOCAL_SRC_FILES := \
su/su_daemon.cpp \
su/su_daemon.cpp \
inject/entry.cpp \
inject/entry.cpp \
inject/utils.cpp \
inject/utils.cpp \
inject/hook.cpp
inject/hook.cpp \
inject/jni_hooks.cpp
LOCAL_LDLIBS := -llog
LOCAL_LDLIBS := -llog
include $(BUILD_EXECUTABLE)
include $(BUILD_EXECUTABLE)
...
...
native/jni/inject/entry.cpp
View file @
9ed110c9
...
@@ -42,6 +42,7 @@ static void inject_cleanup() {
...
@@ -42,6 +42,7 @@ static void inject_cleanup() {
}
}
void
self_unload
()
{
void
self_unload
()
{
LOGD
(
"hook: Request to self unload
\n
"
);
// If unhook failed, do not unload or else it will cause SIGSEGV
// If unhook failed, do not unload or else it will cause SIGSEGV
if
(
!
unhook_functions
())
if
(
!
unhook_functions
())
return
;
return
;
...
...
native/jni/inject/hook.cpp
View file @
9ed110c9
...
@@ -8,20 +8,61 @@
...
@@ -8,20 +8,61 @@
using
namespace
std
;
using
namespace
std
;
// Static vector won't work, use a pointer instead
static
JavaVM
*
g_jvm
;
// For some reason static vector won't work, use a pointer instead
static
vector
<
tuple
<
const
char
*
,
const
char
*
,
void
**>>
*
hook_list
;
static
vector
<
tuple
<
const
char
*
,
const
char
*
,
void
**>>
*
hook_list
;
#define DEF_HOOK_FUNC(ret, func, ...) \
#define DEF_HOOK_FUNC(ret, func, ...) \
static ret (*old_##func)(__VA_ARGS__); \
static ret (*old_##func)(__VA_ARGS__); \
static ret new_##func(__VA_ARGS__)
static ret new_##func(__VA_ARGS__)
#define HOOK_JNI(clazz, method) \
if (newMethods[i].name == #method##sv) { \
JNI::clazz::method##_orig = new JNINativeMethod(); \
memcpy(JNI::clazz::method##_orig, &newMethods[i], sizeof(JNINativeMethod)); \
for (int j = 0; j < JNI::clazz::method##_methods_num; ++j) { \
if (strcmp(newMethods[i].signature, JNI::clazz::method##_methods[j].signature) == 0) { \
newMethods[i] = JNI::clazz::method##_methods[j]; \
LOGI("hook: replaced " #clazz "#" #method "\n"); \
++hooked; \
break; \
} \
} \
continue; \
}
#define clone_methods() \
newMethods = make_unique<JNINativeMethod[]>(numMethods); \
memcpy(newMethods.get(), methods, sizeof(JNINativeMethod) * numMethods)
DEF_HOOK_FUNC
(
int
,
jniRegisterNativeMethods
,
DEF_HOOK_FUNC
(
int
,
jniRegisterNativeMethods
,
JNIEnv
*
env
,
const
char
*
className
,
const
JNINativeMethod
*
methods
,
int
numMethods
)
{
JNIEnv
*
env
,
const
char
*
className
,
const
JNINativeMethod
*
methods
,
int
numMethods
)
{
LOGD
(
"hook: jniRegisterNativeMethods %s"
,
className
);
LOGD
(
"hook: jniRegisterNativeMethods %s"
,
className
);
// TODO: actually do things like replacing JNI native methods
unique_ptr
<
JNINativeMethod
[]
>
newMethods
;
int
hooked
=
0
;
if
(
g_jvm
==
nullptr
)
{
// Save for later unhooking
env
->
GetJavaVM
(
&
g_jvm
);
}
return
old_jniRegisterNativeMethods
(
env
,
className
,
methods
,
numMethods
);
if
(
className
==
"com/android/internal/os/Zygote"
sv
)
{
clone_methods
();
for
(
int
i
=
0
;
i
<
numMethods
&&
hooked
<
3
;
++
i
)
{
HOOK_JNI
(
Zygote
,
nativeForkAndSpecialize
);
HOOK_JNI
(
Zygote
,
nativeSpecializeAppProcess
);
HOOK_JNI
(
Zygote
,
nativeForkSystemServer
);
}
}
else
if
(
className
==
"android/os/SystemProperties"
sv
)
{
clone_methods
();
for
(
int
i
=
0
;
i
<
numMethods
&&
hooked
<
1
;
++
i
)
{
HOOK_JNI
(
SystemProperties
,
native_set
);
}
}
return
old_jniRegisterNativeMethods
(
env
,
className
,
newMethods
.
get
()
?:
methods
,
numMethods
);
}
}
static
bool
hook_refresh
()
{
static
bool
hook_refresh
()
{
...
@@ -58,10 +99,40 @@ void hook_functions() {
...
@@ -58,10 +99,40 @@ void hook_functions() {
hook_refresh
();
hook_refresh
();
}
}
#define push_method(clazz, method) \
if (JNI::clazz::method##_orig) methods.emplace_back(*JNI::clazz::method##_orig)
bool
unhook_functions
()
{
bool
unhook_functions
()
{
JNIEnv
*
env
;
if
(
g_jvm
->
GetEnv
(
reinterpret_cast
<
void
**>
(
&
env
),
JNI_VERSION_1_6
)
!=
JNI_OK
)
return
false
;
vector
<
JNINativeMethod
>
methods
;
push_method
(
Zygote
,
nativeForkAndSpecialize
);
push_method
(
Zygote
,
nativeSpecializeAppProcess
);
push_method
(
Zygote
,
nativeForkSystemServer
);
if
(
!
methods
.
empty
()
&&
old_jniRegisterNativeMethods
(
env
,
"com/android/internal/os/Zygote"
,
methods
.
data
(),
methods
.
size
())
!=
0
)
{
LOGE
(
"hook: Failed to register JNI hook for Zygote
\n
"
);
return
false
;
}
methods
.
clear
();
push_method
(
SystemProperties
,
native_set
);
if
(
!
methods
.
empty
()
&&
old_jniRegisterNativeMethods
(
env
,
"android/os/SystemProperties"
,
methods
.
data
(),
methods
.
size
())
!=
0
)
{
LOGE
(
"hook: Failed to register JNI hook for SystemProperties
\n
"
);
return
false
;
}
for
(
auto
&
[
path
,
sym
,
old_func
]
:
*
hook_list
)
{
for
(
auto
&
[
path
,
sym
,
old_func
]
:
*
hook_list
)
{
if
(
xhook_register
(
path
,
sym
,
*
old_func
,
nullptr
)
!=
0
)
{
if
(
xhook_register
(
path
,
sym
,
*
old_func
,
nullptr
)
!=
0
)
{
LOGE
(
"hook: Failed to register hook
\"
%s
\"\n
"
,
sym
);
\
LOGE
(
"hook: Failed to register hook
\"
%s
\"\n
"
,
sym
);
return
false
;
return
false
;
}
}
}
}
...
...
native/jni/inject/inject.hpp
View file @
9ed110c9
#pragma once
#pragma once
#include <stdint.h>
#include <stdint.h>
#include <jni.h>
#define INJECT_LIB_1 "/dev/tmp/magisk.1.so"
#define INJECT_LIB_1 "/dev/tmp/magisk.1.so"
#define INJECT_LIB_2 "/dev/tmp/magisk.2.so"
#define INJECT_LIB_2 "/dev/tmp/magisk.2.so"
...
@@ -19,3 +20,28 @@ uintptr_t get_remote_lib(int pid, const char *lib);
...
@@ -19,3 +20,28 @@ uintptr_t get_remote_lib(int pid, const char *lib);
void
self_unload
();
void
self_unload
();
void
hook_functions
();
void
hook_functions
();
bool
unhook_functions
();
bool
unhook_functions
();
// JNI method declarations
namespace
JNI
{
namespace
Zygote
{
extern
JNINativeMethod
*
nativeForkAndSpecialize_orig
;
extern
JNINativeMethod
*
nativeSpecializeAppProcess_orig
;
extern
JNINativeMethod
*
nativeForkSystemServer_orig
;
extern
const
JNINativeMethod
nativeForkAndSpecialize_methods
[];
extern
const
int
nativeForkAndSpecialize_methods_num
;
extern
const
JNINativeMethod
nativeSpecializeAppProcess_methods
[];
extern
const
int
nativeSpecializeAppProcess_methods_num
;
extern
const
JNINativeMethod
nativeForkSystemServer_methods
[];
extern
const
int
nativeForkSystemServer_methods_num
;
}
namespace
SystemProperties
{
extern
JNINativeMethod
*
native_set_orig
;
extern
const
JNINativeMethod
native_set_methods
[];
constexpr
int
native_set_methods_num
=
1
;
}
}
native/jni/inject/jni_hooks.cpp
0 → 100644
View file @
9ed110c9
/*
* Original code: https://github.com/RikkaApps/Riru/blob/master/riru/src/main/cpp/jni_native_method.cpp
* The code is modified and sublicensed to GPLv3 for incorporating into Magisk.
*
* Copyright (c) 2018-2021, RikkaW
* Copyright (c) 2021, John 'topjohnwu' Wu
*/
#include <jni.h>
#include <utils.hpp>
#include "inject.hpp"
#define ENABLE_LEGACY_DP 0 // Nobody should use outdated developer preview...
static
void
nativeForkAndSpecialize_pre
(
JNIEnv
*
env
,
jclass
clazz
,
jint
&
uid
,
jint
&
gid
,
jintArray
&
gids
,
jint
&
runtime_flags
,
jobjectArray
&
rlimits
,
jint
&
mount_external
,
jstring
&
se_info
,
jstring
&
se_name
,
jintArray
&
fdsToClose
,
jintArray
&
fdsToIgnore
,
jboolean
&
is_child_zygote
,
jstring
&
instructionSet
,
jstring
&
appDataDir
,
jboolean
&
isTopApp
,
jobjectArray
&
pkgDataInfoList
,
jobjectArray
&
whitelistedDataInfoList
,
jboolean
&
bindMountAppDataDirs
,
jboolean
&
bindMountAppStorageDirs
)
{
LOGD
(
"hook: %s
\n
"
,
__FUNCTION__
);
}
static
void
nativeForkAndSpecialize_post
(
JNIEnv
*
env
,
jclass
clazz
,
jint
uid
,
jint
pid
)
{
LOGD
(
"hook: %s
\n
"
,
__FUNCTION__
);
// Demonstrate self unload in child process
if
(
pid
==
0
)
self_unload
();
}
// -----------------------------------------------------------------
static
void
nativeSpecializeAppProcess_pre
(
JNIEnv
*
env
,
jclass
clazz
,
jint
uid
,
jint
gid
,
jintArray
gids
,
jint
runtimeFlags
,
jobjectArray
rlimits
,
jint
mountExternal
,
jstring
seInfo
,
jstring
niceName
,
jboolean
startChildZygote
,
jstring
instructionSet
,
jstring
appDataDir
,
jboolean
&
isTopApp
,
jobjectArray
&
pkgDataInfoList
,
jobjectArray
&
whitelistedDataInfoList
,
jboolean
&
bindMountAppDataDirs
,
jboolean
&
bindMountAppStorageDirs
)
{
LOGD
(
"hook: %s
\n
"
,
__FUNCTION__
);
}
static
void
nativeSpecializeAppProcess_post
(
JNIEnv
*
env
,
jclass
clazz
)
{
LOGD
(
"hook: %s
\n
"
,
__FUNCTION__
);
}
// -----------------------------------------------------------------
static
void
nativeForkSystemServer_pre
(
JNIEnv
*
env
,
jclass
clazz
,
uid_t
&
uid
,
gid_t
&
gid
,
jintArray
&
gids
,
jint
&
debug_flags
,
jobjectArray
&
rlimits
,
jlong
&
permittedCapabilities
,
jlong
&
effectiveCapabilities
)
{
LOGD
(
"hook: %s
\n
"
,
__FUNCTION__
);
}
static
void
nativeForkSystemServer_post
(
JNIEnv
*
env
,
jclass
clazz
,
jint
res
)
{
LOGD
(
"hook: %s
\n
"
,
__FUNCTION__
);
}
// -----------------------------------------------------------------
#define pre_fork() nativeForkAndSpecialize_pre( \
env, clazz, uid, gid, gids, runtime_flags, rlimits, mount_external, \
se_info, se_name, fdsToClose, fdsToIgnore, is_child_zygote, \
instructionSet, appDataDir, isTopApp, pkgDataInfoList, whitelistedDataInfoList, \
bindMountAppDataDirs, bindMountAppStorageDirs) \
template
<
typename
T
,
typename
...
Args
>
static
jint
orig_fork
(
Args
&&
...
args
)
{
return
reinterpret_cast
<
T
>
(
JNI
::
Zygote
::
nativeForkAndSpecialize_orig
->
fnPtr
)(
std
::
forward
<
Args
>
(
args
)...);
}
#define post_fork() nativeForkAndSpecialize_post(env, clazz, uid, pid)
const
static
char
nativeForkAndSpecialize_m_sig
[]
=
"(II[II[[IILjava/lang/String;Ljava/lang/String;[ILjava/lang/String;Ljava/lang/String;)I"
;
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
se_name
,
jintArray
fdsToClose
,
jstring
instructionSet
,
jstring
appDataDir
)
{
jintArray
fdsToIgnore
=
nullptr
;
jboolean
is_child_zygote
=
JNI_FALSE
;
jboolean
isTopApp
=
JNI_FALSE
;
jobjectArray
pkgDataInfoList
=
nullptr
;
jobjectArray
whitelistedDataInfoList
=
nullptr
;
jboolean
bindMountAppDataDirs
=
JNI_FALSE
;
jboolean
bindMountAppStorageDirs
=
JNI_FALSE
;
pre_fork
();
jint
pid
=
orig_fork
<
decltype
(
&
nativeForkAndSpecialize_m
)
>
(
env
,
clazz
,
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
se_info
,
se_name
,
fdsToClose
,
instructionSet
,
appDataDir
);
post_fork
();
return
pid
;
}
const
static
char
nativeForkAndSpecialize_o_sig
[]
=
"(II[II[[IILjava/lang/String;Ljava/lang/String;[I[ILjava/lang/String;Ljava/lang/String;)I"
;
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
se_name
,
jintArray
fdsToClose
,
jintArray
fdsToIgnore
,
jstring
instructionSet
,
jstring
appDataDir
)
{
jboolean
is_child_zygote
=
JNI_FALSE
;
jboolean
isTopApp
=
JNI_FALSE
;
jobjectArray
pkgDataInfoList
=
nullptr
;
jobjectArray
whitelistedDataInfoList
=
nullptr
;
jboolean
bindMountAppDataDirs
=
JNI_FALSE
;
jboolean
bindMountAppStorageDirs
=
JNI_FALSE
;
pre_fork
();
jint
pid
=
orig_fork
<
decltype
(
&
nativeForkAndSpecialize_o
)
>
(
env
,
clazz
,
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
se_info
,
se_name
,
fdsToClose
,
fdsToIgnore
,
instructionSet
,
appDataDir
);
post_fork
();
return
pid
;
}
const
static
char
nativeForkAndSpecialize_p_sig
[]
=
"(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;)I"
;
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
se_name
,
jintArray
fdsToClose
,
jintArray
fdsToIgnore
,
jboolean
is_child_zygote
,
jstring
instructionSet
,
jstring
appDataDir
)
{
jboolean
isTopApp
=
JNI_FALSE
;
jobjectArray
pkgDataInfoList
=
nullptr
;
jobjectArray
whitelistedDataInfoList
=
nullptr
;
jboolean
bindMountAppDataDirs
=
JNI_FALSE
;
jboolean
bindMountAppStorageDirs
=
JNI_FALSE
;
pre_fork
();
jint
pid
=
orig_fork
<
decltype
(
&
nativeForkAndSpecialize_p
)
>
(
env
,
clazz
,
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
se_info
,
se_name
,
fdsToClose
,
fdsToIgnore
,
is_child_zygote
,
instructionSet
,
appDataDir
);
post_fork
();
return
pid
;
}
const
static
char
nativeForkAndSpecialize_q_alt_sig
[]
=
"(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;Z)I"
;
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
se_name
,
jintArray
fdsToClose
,
jintArray
fdsToIgnore
,
jboolean
is_child_zygote
,
jstring
instructionSet
,
jstring
appDataDir
,
jboolean
isTopApp
)
{
jobjectArray
pkgDataInfoList
=
nullptr
;
jobjectArray
whitelistedDataInfoList
=
nullptr
;
jboolean
bindMountAppDataDirs
=
JNI_FALSE
;
jboolean
bindMountAppStorageDirs
=
JNI_FALSE
;
pre_fork
();
jint
pid
=
orig_fork
<
decltype
(
&
nativeForkAndSpecialize_q_alt
)
>
(
env
,
clazz
,
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
se_info
,
se_name
,
fdsToClose
,
fdsToIgnore
,
is_child_zygote
,
instructionSet
,
appDataDir
,
isTopApp
);
post_fork
();
return
pid
;
}
#if ENABLE_LEGACY_DP
const
static
char
nativeForkAndSpecialize_r_dp2_sig
[]
=
"(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;Z[Ljava/lang/String;)I"
;
static
jint
nativeForkAndSpecialize_r_dp2
(
JNIEnv
*
env
,
jclass
clazz
,
jint
uid
,
jint
gid
,
jintArray
gids
,
jint
runtime_flags
,
jobjectArray
rlimits
,
jint
mount_external
,
jstring
se_info
,
jstring
se_name
,
jintArray
fdsToClose
,
jintArray
fdsToIgnore
,
jboolean
is_child_zygote
,
jstring
instructionSet
,
jstring
appDataDir
,
jboolean
isTopApp
,
jobjectArray
pkgDataInfoList
)
{
jobjectArray
whitelistedDataInfoList
=
nullptr
;
jboolean
bindMountAppDataDirs
=
JNI_FALSE
;
jboolean
bindMountAppStorageDirs
=
JNI_FALSE
;
pre_fork
();
jint
pid
=
orig_fork
<
decltype
(
&
nativeForkAndSpecialize_r_dp2
)
>
(
env
,
clazz
,
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
se_info
,
se_name
,
fdsToClose
,
fdsToIgnore
,
is_child_zygote
,
instructionSet
,
appDataDir
,
isTopApp
,
pkgDataInfoList
);
post_fork
();
return
pid
;
}
const
static
char
nativeForkAndSpecialize_r_dp3_sig
[]
=
"(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;Z[Ljava/lang/String;Z)I"
;
static
jint
nativeForkAndSpecialize_r_dp3
(
JNIEnv
*
env
,
jclass
clazz
,
jint
uid
,
jint
gid
,
jintArray
gids
,
jint
runtime_flags
,
jobjectArray
rlimits
,
jint
mount_external
,
jstring
se_info
,
jstring
se_name
,
jintArray
fdsToClose
,
jintArray
fdsToIgnore
,
jboolean
is_child_zygote
,
jstring
instructionSet
,
jstring
appDataDir
,
jboolean
isTopApp
,
jobjectArray
pkgDataInfoList
,
jboolean
bindMountAppStorageDirs
)
{
jobjectArray
whitelistedDataInfoList
=
nullptr
;
jboolean
bindMountAppDataDirs
=
JNI_FALSE
;
pre_fork
();
jint
pid
=
orig_fork
<
decltype
(
&
nativeForkAndSpecialize_r_dp3
)
>
(
env
,
clazz
,
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
se_info
,
se_name
,
fdsToClose
,
fdsToIgnore
,
is_child_zygote
,
instructionSet
,
appDataDir
,
isTopApp
,
pkgDataInfoList
,
bindMountAppStorageDirs
);
post_fork
();
return
pid
;
}
#endif // ENABLE_LEGACY_DP
const
static
char
*
nativeForkAndSpecialize_r_sig
=
"(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;Z[Ljava/lang/String;[Ljava/lang/String;ZZ)I"
;
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
se_name
,
jintArray
fdsToClose
,
jintArray
fdsToIgnore
,
jboolean
is_child_zygote
,
jstring
instructionSet
,
jstring
appDataDir
,
jboolean
isTopApp
,
jobjectArray
pkgDataInfoList
,
jobjectArray
whitelistedDataInfoList
,
jboolean
bindMountAppDataDirs
,
jboolean
bindMountAppStorageDirs
)
{
pre_fork
();
jint
pid
=
orig_fork
<
decltype
(
&
nativeForkAndSpecialize_r
)
>
(
env
,
clazz
,
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
se_info
,
se_name
,
fdsToClose
,
fdsToIgnore
,
is_child_zygote
,
instructionSet
,
appDataDir
,
isTopApp
,
pkgDataInfoList
,
whitelistedDataInfoList
,
bindMountAppDataDirs
,
bindMountAppStorageDirs
);
post_fork
();
return
pid
;
}
const
static
char
nativeForkAndSpecialize_samsung_m_sig
[]
=
"(II[II[[IILjava/lang/String;IILjava/lang/String;[ILjava/lang/String;Ljava/lang/String;)I"
;
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
category
,
jint
accessInfo
,
jstring
se_name
,
jintArray
fdsToClose
,
jstring
instructionSet
,
jstring
appDataDir
)
{
jintArray
fdsToIgnore
=
nullptr
;
jboolean
is_child_zygote
=
JNI_FALSE
;
jboolean
isTopApp
=
JNI_FALSE
;
jobjectArray
pkgDataInfoList
=
nullptr
;
jobjectArray
whitelistedDataInfoList
=
nullptr
;
jboolean
bindMountAppDataDirs
=
JNI_FALSE
;
jboolean
bindMountAppStorageDirs
=
JNI_FALSE
;
pre_fork
();
jint
pid
=
orig_fork
<
decltype
(
&
nativeForkAndSpecialize_samsung_m
)
>
(
env
,
clazz
,
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
se_info
,
category
,
accessInfo
,
se_name
,
fdsToClose
,
instructionSet
,
appDataDir
);
post_fork
();
return
pid
;
}
const
static
char
nativeForkAndSpecialize_samsung_n_sig
[]
=
"(II[II[[IILjava/lang/String;IILjava/lang/String;[ILjava/lang/String;Ljava/lang/String;I)I"
;
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
category
,
jint
accessInfo
,
jstring
se_name
,
jintArray
fdsToClose
,
jstring
instructionSet
,
jstring
appDataDir
,
jint
a1
)
{
jintArray
fdsToIgnore
=
nullptr
;
jboolean
is_child_zygote
=
JNI_FALSE
;
jboolean
isTopApp
=
JNI_FALSE
;
jobjectArray
pkgDataInfoList
=
nullptr
;
jobjectArray
whitelistedDataInfoList
=
nullptr
;
jboolean
bindMountAppDataDirs
=
JNI_FALSE
;
jboolean
bindMountAppStorageDirs
=
JNI_FALSE
;
pre_fork
();
jint
pid
=
orig_fork
<
decltype
(
&
nativeForkAndSpecialize_samsung_n
)
>
(
env
,
clazz
,
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
se_info
,
category
,
accessInfo
,
se_name
,
fdsToClose
,
instructionSet
,
appDataDir
,
a1
);
post_fork
();
return
pid
;
}
const
static
char
nativeForkAndSpecialize_samsung_o_sig
[]
=
"(II[II[[IILjava/lang/String;IILjava/lang/String;[I[ILjava/lang/String;Ljava/lang/String;)I"
;
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
category
,
jint
accessInfo
,
jstring
se_name
,
jintArray
fdsToClose
,
jintArray
fdsToIgnore
,
jstring
instructionSet
,
jstring
appDataDir
)
{
jboolean
is_child_zygote
=
JNI_FALSE
;
jboolean
isTopApp
=
JNI_FALSE
;
jobjectArray
pkgDataInfoList
=
nullptr
;
jobjectArray
whitelistedDataInfoList
=
nullptr
;
jboolean
bindMountAppDataDirs
=
JNI_FALSE
;
jboolean
bindMountAppStorageDirs
=
JNI_FALSE
;
pre_fork
();
jint
pid
=
orig_fork
<
decltype
(
&
nativeForkAndSpecialize_samsung_o
)
>
(
env
,
clazz
,
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
se_info
,
category
,
accessInfo
,
se_name
,
fdsToClose
,
fdsToIgnore
,
instructionSet
,
appDataDir
);
post_fork
();
return
pid
;
}
const
static
char
nativeForkAndSpecialize_samsung_p_sig
[]
=
"(II[II[[IILjava/lang/String;IILjava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;)I"
;
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
category
,
jint
accessInfo
,
jstring
se_name
,
jintArray
fdsToClose
,
jintArray
fdsToIgnore
,
jboolean
is_child_zygote
,
jstring
instructionSet
,
jstring
appDataDir
)
{
jboolean
isTopApp
=
JNI_FALSE
;
jobjectArray
pkgDataInfoList
=
nullptr
;
jobjectArray
whitelistedDataInfoList
=
nullptr
;
jboolean
bindMountAppDataDirs
=
JNI_FALSE
;
jboolean
bindMountAppStorageDirs
=
JNI_FALSE
;
pre_fork
();
jint
pid
=
orig_fork
<
decltype
(
&
nativeForkAndSpecialize_samsung_p
)
>
(
env
,
clazz
,
uid
,
gid
,
gids
,
runtime_flags
,
rlimits
,
mount_external
,
se_info
,
category
,
accessInfo
,
se_name
,
fdsToClose
,
fdsToIgnore
,
is_child_zygote
,
instructionSet
,
appDataDir
);
post_fork
();
return
pid
;
}
#define DCL_FORK(ver) { \
"nativeForkAndSpecialize", \
nativeForkAndSpecialize_##ver##_sig, \
(void *) &nativeForkAndSpecialize_##ver \
}
// -----------------------------------------------------------------
#define pre_spec() nativeSpecializeAppProcess_pre( \
env, clazz, uid, gid, gids, runtimeFlags, rlimits, mountExternal, seInfo, niceName, \
startChildZygote, instructionSet, appDataDir, isTopApp, pkgDataInfoList, \
whitelistedDataInfoList, bindMountAppDataDirs, bindMountAppStorageDirs)
template
<
typename
T
,
typename
...
Args
>
static
void
orig_spec
(
Args
&&
...
args
)
{
reinterpret_cast
<
T
>
(
JNI
::
Zygote
::
nativeSpecializeAppProcess_orig
->
fnPtr
)(
std
::
forward
<
Args
>
(
args
)...);
}
#define post_spec() nativeSpecializeAppProcess_post(env, clazz)
const
static
char
nativeSpecializeAppProcess_q_sig
[]
=
"(II[II[[IILjava/lang/String;Ljava/lang/String;ZLjava/lang/String;Ljava/lang/String;)V"
;
static
void
nativeSpecializeAppProcess_q
(
JNIEnv
*
env
,
jclass
clazz
,
jint
uid
,
jint
gid
,
jintArray
gids
,
jint
runtimeFlags
,
jobjectArray
rlimits
,
jint
mountExternal
,
jstring
seInfo
,
jstring
niceName
,
jboolean
startChildZygote
,
jstring
instructionSet
,
jstring
appDataDir
)
{
jboolean
isTopApp
=
JNI_FALSE
;
jobjectArray
pkgDataInfoList
=
nullptr
;
jobjectArray
whitelistedDataInfoList
=
nullptr
;
jboolean
bindMountAppDataDirs
=
JNI_FALSE
;
jboolean
bindMountAppStorageDirs
=
JNI_FALSE
;
pre_spec
();
orig_spec
<
decltype
(
&
nativeSpecializeAppProcess_q
)
>
(
env
,
clazz
,
uid
,
gid
,
gids
,
runtimeFlags
,
rlimits
,
mountExternal
,
seInfo
,
niceName
,
startChildZygote
,
instructionSet
,
appDataDir
);
post_spec
();
}
const
static
char
nativeSpecializeAppProcess_q_alt_sig
[]
=
"(II[II[[IILjava/lang/String;Ljava/lang/String;ZLjava/lang/String;Ljava/lang/String;Z)V"
;
static
void
nativeSpecializeAppProcess_q_alt
(
JNIEnv
*
env
,
jclass
clazz
,
jint
uid
,
jint
gid
,
jintArray
gids
,
jint
runtimeFlags
,
jobjectArray
rlimits
,
jint
mountExternal
,
jstring
seInfo
,
jstring
niceName
,
jboolean
startChildZygote
,
jstring
instructionSet
,
jstring
appDataDir
,
jboolean
isTopApp
)
{
jobjectArray
pkgDataInfoList
=
nullptr
;
jobjectArray
whitelistedDataInfoList
=
nullptr
;
jboolean
bindMountAppDataDirs
=
JNI_FALSE
;
jboolean
bindMountAppStorageDirs
=
JNI_FALSE
;
pre_spec
();
orig_spec
<
decltype
(
&
nativeSpecializeAppProcess_q_alt
)
>
(
env
,
clazz
,
uid
,
gid
,
gids
,
runtimeFlags
,
rlimits
,
mountExternal
,
seInfo
,
niceName
,
startChildZygote
,
instructionSet
,
appDataDir
,
isTopApp
);
post_spec
();
}
#if ENABLE_LEGACY_DP
const
static
char
nativeSpecializeAppProcess_r_dp2_sig
[]
=
"(II[II[[IILjava/lang/String;Ljava/lang/String;ZLjava/lang/String;Ljava/lang/String;Z[Ljava/lang/String;)V"
;
static
void
nativeSpecializeAppProcess_r_dp2
(
JNIEnv
*
env
,
jclass
clazz
,
jint
uid
,
jint
gid
,
jintArray
gids
,
jint
runtimeFlags
,
jobjectArray
rlimits
,
jint
mountExternal
,
jstring
seInfo
,
jstring
niceName
,
jboolean
startChildZygote
,
jstring
instructionSet
,
jstring
appDataDir
,
jboolean
isTopApp
,
jobjectArray
pkgDataInfoList
)
{
jobjectArray
whitelistedDataInfoList
=
nullptr
;
jboolean
bindMountAppDataDirs
=
JNI_FALSE
;
jboolean
bindMountAppStorageDirs
=
JNI_FALSE
;
pre_spec
();
orig_spec
<
decltype
(
&
nativeSpecializeAppProcess_r_dp2
)
>
(
env
,
clazz
,
uid
,
gid
,
gids
,
runtimeFlags
,
rlimits
,
mountExternal
,
seInfo
,
niceName
,
startChildZygote
,
instructionSet
,
appDataDir
,
isTopApp
,
pkgDataInfoList
);
post_spec
();
}
const
static
char
nativeSpecializeAppProcess_r_dp3_sig
[]
=
"(II[II[[IILjava/lang/String;Ljava/lang/String;ZLjava/lang/String;Ljava/lang/String;Z[Ljava/lang/String;Z)V"
;
static
void
nativeSpecializeAppProcess_r_dp3
(
JNIEnv
*
env
,
jclass
clazz
,
jint
uid
,
jint
gid
,
jintArray
gids
,
jint
runtimeFlags
,
jobjectArray
rlimits
,
jint
mountExternal
,
jstring
seInfo
,
jstring
niceName
,
jboolean
startChildZygote
,
jstring
instructionSet
,
jstring
appDataDir
,
jboolean
isTopApp
,
jobjectArray
pkgDataInfoList
,
jboolean
bindMountAppStorageDirs
)
{
jobjectArray
whitelistedDataInfoList
=
nullptr
;
jboolean
bindMountAppDataDirs
=
JNI_FALSE
;
pre_spec
();
orig_spec
<
decltype
(
&
nativeSpecializeAppProcess_r_dp3
)
>
(
env
,
clazz
,
uid
,
gid
,
gids
,
runtimeFlags
,
rlimits
,
mountExternal
,
seInfo
,
niceName
,
startChildZygote
,
instructionSet
,
appDataDir
,
isTopApp
,
pkgDataInfoList
,
bindMountAppStorageDirs
);
post_spec
();
}
#endif // ENABLE_LEGACY_DP
const
static
char
nativeSpecializeAppProcess_r_sig
[]
=
"(II[II[[IILjava/lang/String;Ljava/lang/String;ZLjava/lang/String;Ljava/lang/String;Z[Ljava/lang/String;[Ljava/lang/String;ZZ)V"
;
static
void
nativeSpecializeAppProcess_r
(
JNIEnv
*
env
,
jclass
clazz
,
jint
uid
,
jint
gid
,
jintArray
gids
,
jint
runtimeFlags
,
jobjectArray
rlimits
,
jint
mountExternal
,
jstring
seInfo
,
jstring
niceName
,
jboolean
startChildZygote
,
jstring
instructionSet
,
jstring
appDataDir
,
jboolean
isTopApp
,
jobjectArray
pkgDataInfoList
,
jobjectArray
whitelistedDataInfoList
,
jboolean
bindMountAppDataDirs
,
jboolean
bindMountAppStorageDirs
)
{
pre_spec
();
orig_spec
<
decltype
(
&
nativeSpecializeAppProcess_r
)
>
(
env
,
clazz
,
uid
,
gid
,
gids
,
runtimeFlags
,
rlimits
,
mountExternal
,
seInfo
,
niceName
,
startChildZygote
,
instructionSet
,
appDataDir
,
isTopApp
,
pkgDataInfoList
,
whitelistedDataInfoList
,
bindMountAppDataDirs
,
bindMountAppStorageDirs
);
post_spec
();
}
const
static
char
nativeSpecializeAppProcess_samsung_q_sig
[]
=
"(II[II[[IILjava/lang/String;IILjava/lang/String;ZLjava/lang/String;Ljava/lang/String;)V"
;
static
void
nativeSpecializeAppProcess_samsung_q
(
JNIEnv
*
env
,
jclass
clazz
,
jint
uid
,
jint
gid
,
jintArray
gids
,
jint
runtimeFlags
,
jobjectArray
rlimits
,
jint
mountExternal
,
jstring
seInfo
,
jint
space
,
jint
accessInfo
,
jstring
niceName
,
jboolean
startChildZygote
,
jstring
instructionSet
,
jstring
appDataDir
)
{
jboolean
isTopApp
=
JNI_FALSE
;
jobjectArray
pkgDataInfoList
=
nullptr
;
jobjectArray
whitelistedDataInfoList
=
nullptr
;
jboolean
bindMountAppDataDirs
=
JNI_FALSE
;
jboolean
bindMountAppStorageDirs
=
JNI_FALSE
;
pre_spec
();
orig_spec
<
decltype
(
&
nativeSpecializeAppProcess_samsung_q
)
>
(
env
,
clazz
,
uid
,
gid
,
gids
,
runtimeFlags
,
rlimits
,
mountExternal
,
seInfo
,
space
,
accessInfo
,
niceName
,
startChildZygote
,
instructionSet
,
appDataDir
);
post_spec
();
}
#define DCL_SPEC(ver) { \
"nativeSpecializeAppProcess", \
nativeSpecializeAppProcess_##ver##_sig, \
(void *) &nativeSpecializeAppProcess_##ver \
}
// -----------------------------------------------------------------
#define pre_server() nativeForkSystemServer_pre( \
env, clazz, uid, gid, gids, runtimeFlags, rlimits, permittedCapabilities, \
effectiveCapabilities)
template
<
typename
T
,
typename
...
Args
>
static
jint
orig_server
(
Args
&&
...
args
)
{
return
reinterpret_cast
<
T
>
(
JNI
::
Zygote
::
nativeForkSystemServer_orig
->
fnPtr
)(
std
::
forward
<
Args
>
(
args
)...);
}
#define post_server() nativeForkSystemServer_post(env, clazz, pid)
const
static
char
nativeForkSystemServer_m_sig
[]
=
"(II[II[[IJJ)I"
;
static
jint
nativeForkSystemServer_m
(
JNIEnv
*
env
,
jclass
clazz
,
uid_t
uid
,
gid_t
gid
,
jintArray
gids
,
jint
runtimeFlags
,
jobjectArray
rlimits
,
jlong
permittedCapabilities
,
jlong
effectiveCapabilities
)
{
pre_server
();
jint
pid
=
orig_server
<
decltype
(
&
nativeForkSystemServer_m
)
>
(
env
,
clazz
,
uid
,
gid
,
gids
,
runtimeFlags
,
rlimits
,
permittedCapabilities
,
effectiveCapabilities
);
post_server
();
return
pid
;
}
const
static
char
nativeForkSystemServer_samsung_q_sig
[]
=
"(II[IIII[[IJJ)I"
;
static
jint
nativeForkSystemServer_samsung_q
(
JNIEnv
*
env
,
jclass
clazz
,
uid_t
uid
,
gid_t
gid
,
jintArray
gids
,
jint
runtimeFlags
,
jint
space
,
jint
accessInfo
,
jobjectArray
rlimits
,
jlong
permittedCapabilities
,
jlong
effectiveCapabilities
)
{
pre_server
();
jint
pid
=
orig_server
<
decltype
(
&
nativeForkSystemServer_samsung_q
)
>
(
env
,
clazz
,
uid
,
gid
,
gids
,
runtimeFlags
,
space
,
accessInfo
,
rlimits
,
permittedCapabilities
,
effectiveCapabilities
);
post_server
();
return
pid
;
}
#define DCL_SERVER(ver) { \
"nativeForkSystemServer", \
nativeForkSystemServer_##ver##_sig, \
(void *) &nativeForkSystemServer_##ver \
}
/*
* On Android 9+, in very rare cases, SystemProperties.set("sys.user." + userId + ".ce_available", "true")
* will throw an exception (no idea if this is caused by hooking) and user data will be wiped.
* Hook it and clear the exception to prevent this problem from happening.
*
* https://cs.android.com/android/platform/superproject/+/android-9.0.0_r34:frameworks/base/services/core/java/com/android/server/pm/UserDataPreparer.java;l=107;bpv=0;bpt=0
*/
static
void
SystemProperties_set
(
JNIEnv
*
env
,
jobject
clazz
,
jstring
keyJ
,
jstring
valJ
)
{
const
char
*
key
=
env
->
GetStringUTFChars
(
keyJ
,
JNI_FALSE
);
char
user
[
16
];
bool
no_throw
=
sscanf
(
key
,
"sys.user.%[^.].ce_available"
,
user
)
==
1
;
env
->
ReleaseStringUTFChars
(
keyJ
,
key
);
reinterpret_cast
<
decltype
(
&
SystemProperties_set
)
>
(
JNI
::
SystemProperties
::
native_set_orig
->
fnPtr
)(
env
,
clazz
,
keyJ
,
valJ
);
jthrowable
exception
=
env
->
ExceptionOccurred
();
if
(
exception
&&
no_throw
)
{
LOGW
(
"prevented data destroy"
);
env
->
ExceptionDescribe
();
env
->
ExceptionClear
();
}
}
namespace
JNI
{
namespace
Zygote
{
JNINativeMethod
*
nativeForkAndSpecialize_orig
=
nullptr
;
JNINativeMethod
*
nativeSpecializeAppProcess_orig
=
nullptr
;
JNINativeMethod
*
nativeForkSystemServer_orig
=
nullptr
;
const
JNINativeMethod
nativeForkAndSpecialize_methods
[]
=
{
DCL_FORK
(
m
),
DCL_FORK
(
o
),
DCL_FORK
(
p
),
DCL_FORK
(
q_alt
),
DCL_FORK
(
r
),
DCL_FORK
(
samsung_m
),
DCL_FORK
(
samsung_n
),
DCL_FORK
(
samsung_o
),
DCL_FORK
(
samsung_p
),
#if ENABLE_LEGACY_DP
DCL_FORK
(
r_dp2
),
DCL_FORK
(
r_dp3
)
#endif
};
const
int
nativeForkAndSpecialize_methods_num
=
std
::
size
(
nativeForkAndSpecialize_methods
);
const
JNINativeMethod
nativeSpecializeAppProcess_methods
[]
=
{
DCL_SPEC
(
q
),
DCL_SPEC
(
q_alt
),
DCL_SPEC
(
r
),
DCL_SPEC
(
samsung_q
),
#if ENABLE_LEGACY_DP
DCL_SPEC
(
r_dp2
),
DCL_SPEC
(
r_dp3
)
#endif
};
const
int
nativeSpecializeAppProcess_methods_num
=
std
::
size
(
nativeSpecializeAppProcess_methods
);
const
JNINativeMethod
nativeForkSystemServer_methods
[]
=
{
DCL_SERVER
(
m
),
DCL_SERVER
(
samsung_q
)
};
const
int
nativeForkSystemServer_methods_num
=
std
::
size
(
nativeForkSystemServer_methods
);
}
namespace
SystemProperties
{
JNINativeMethod
*
native_set_orig
=
nullptr
;
const
JNINativeMethod
native_set_methods
[]
=
{{
"native_set"
,
"(Ljava/lang/String;Ljava/lang/String;)V"
,
(
void
*
)
&
SystemProperties_set
}};
}
}
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