Skip to content

Commit 6a661b2

Browse files
authored
Merge pull request #59 from WaterlooBridge/master
Feature: add support for Android Q and R
2 parents 43debbb + 0c5058e commit 6a661b2

File tree

8 files changed

+68
-14
lines changed

8 files changed

+68
-14
lines changed

whale/src/android/android_build.h

+2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
#define ANDROID_O 26
2121
#define ANDROID_O_MR1 27
2222
#define ANDROID_P 28
23+
#define ANDROID_Q 29
24+
#define ANDROID_R 30
2325

2426
static inline int32_t GetAndroidApiLevel() {
2527
char prop_value[PROP_VALUE_MAX];

whale/src/android/art/art_runtime.cc

+42-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,13 @@ bool ArtRuntime::OnLoad(JavaVM *vm, JNIEnv *env, jclass java_class) {
5454
}
5555
api_level_ = GetAndroidApiLevel();
5656
PreLoadRequiredStuff(env);
57-
const char *art_path = kLibArtPath;
57+
const char *art_path;
58+
if (api_level_ >= ANDROID_R)
59+
art_path = kLibArtPath_R;
60+
else if (api_level_ >= ANDROID_Q)
61+
art_path = kLibArtPath_Q;
62+
else
63+
art_path = kLibArtPath;
5864
art_elf_image_ = WDynamicLibOpen(art_path);
5965
if (art_elf_image_ == nullptr) {
6066
LOG(ERROR) << "Unable to read data from libart.so.";
@@ -70,6 +76,9 @@ bool ArtRuntime::OnLoad(JavaVM *vm, JNIEnv *env, jclass java_class) {
7076
size_t entrypoint_filed_size = (api_level_ <= ANDROID_LOLLIPOP) ? 8
7177
: kPointerSize;
7278
u4 expected_access_flags = kAccPrivate | kAccStatic | kAccNative;
79+
if (api_level_ >= ANDROID_Q)
80+
expected_access_flags |= kAccPublicApi;
81+
hookEncodeArtMethod();
7382
jmethodID reserved0 = env->GetStaticMethodID(java_class, kMethodReserved0, "()V");
7483
jmethodID reserved1 = env->GetStaticMethodID(java_class, kMethodReserved1, "()V");
7584

@@ -235,6 +244,9 @@ ArtRuntime::HookMethod(JNIEnv *env, jclass decl_class, jobject hooked_java_metho
235244
if (api_level_ >= ANDROID_P) {
236245
access_flags &= ~kAccCriticalNative_P;
237246
}
247+
if (api_level_ >= ANDROID_Q) {
248+
access_flags &= ~kAccFastInterpreterToInterpreterInvoke;
249+
}
238250
hooked_method.SetAccessFlags(access_flags);
239251
hooked_method.SetEntryPointFromQuickCompiledCode(
240252
class_linker_objects_.quick_generic_jni_trampoline_
@@ -457,6 +469,21 @@ ALWAYS_INLINE bool ArtRuntime::EnforceDisableHiddenAPIPolicyImpl() {
457469
if (symbol) {
458470
WInlineHookFunction(symbol, reinterpret_cast<void *>(OnInvokeHiddenAPI), nullptr);
459471
}
472+
// Android Q : Release version
473+
symbol = WDynamicLibSymbol(
474+
art_elf_image_,
475+
"_ZN3art9hiddenapi6detail28ShouldDenyAccessToMemberImplINS_8ArtFieldEEEbPT_NS0_7ApiListENS0_12AccessMethodE"
476+
);
477+
if (symbol) {
478+
WInlineHookFunction(symbol, reinterpret_cast<void *>(OnInvokeHiddenAPI), nullptr);
479+
}
480+
symbol = WDynamicLibSymbol(
481+
art_elf_image_,
482+
"_ZN3art9hiddenapi6detail28ShouldDenyAccessToMemberImplINS_9ArtMethodEEEbPT_NS0_7ApiListENS0_12AccessMethodE"
483+
);
484+
if (symbol) {
485+
WInlineHookFunction(symbol, reinterpret_cast<void *>(OnInvokeHiddenAPI), nullptr);
486+
}
460487
return symbol != nullptr;
461488
}
462489

@@ -491,5 +518,19 @@ void ArtRuntime::FixBugN() {
491518
is_hooked = true;
492519
}
493520

521+
jmethodID OnInvokeEncodeMethodId(void *thiz, void *method) {
522+
return reinterpret_cast<jmethodID>(method);
523+
}
524+
525+
void ArtRuntime::hookEncodeArtMethod() {
526+
void *symbol = nullptr;
527+
symbol = WDynamicLibSymbol(art_elf_image_,
528+
"_ZN3art3jni12JniIdManager14EncodeMethodIdEPNS_9ArtMethodE");
529+
if (symbol) {
530+
WInlineHookFunction(symbol, reinterpret_cast<void *>(OnInvokeEncodeMethodId),
531+
nullptr);
532+
}
533+
}
534+
494535
} // namespace art
495536
} // namespace whale

whale/src/android/art/art_runtime.h

+6
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,15 @@
1717
static constexpr const char *kAndroidLibDir = "/system/lib64/";
1818
static constexpr const char *kLibNativeBridgePath = "/system/lib64/libnativebridge.so";
1919
static constexpr const char *kLibArtPath = "/system/lib64/libart.so";
20+
static constexpr const char *kLibArtPath_Q = "/apex/com.android.runtime/lib64/libart.so";
21+
static constexpr const char *kLibArtPath_R = "/apex/com.android.art/lib64/libart.so";
2022
static constexpr const char *kLibAocPath = "/system/lib64/libaoc.so";
2123
static constexpr const char *kLibHoudiniArtPath = "/system/lib64/arm64/libart.so";
2224
#else
2325
static constexpr const char *kAndroidLibDir = "/system/lib/";
2426
static constexpr const char *kLibArtPath = "/system/lib/libart.so";
27+
static constexpr const char *kLibArtPath_Q = "/apex/com.android.runtime/lib/libart.so";
28+
static constexpr const char *kLibArtPath_R = "/apex/com.android.art/lib/libart.so";
2529
static constexpr const char *kLibAocPath = "/system/lib/libaoc.so";
2630
static constexpr const char *kLibHoudiniArtPath = "/system/lib/arm/libart.so";
2731
#endif
@@ -127,6 +131,8 @@ class ArtRuntime final {
127131

128132
void FixBugN();
129133

134+
void hookEncodeArtMethod();
135+
130136
private:
131137
JavaVM *vm_;
132138
jclass java_class_;

whale/src/android/art/art_symbol_resolver.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ bool ArtSymbolResolver::Resolve(void *elf_image, s4 api_level) {
106106
FIND_SYMBOL(kArt_Object_CloneWithSize, symbols_.Object_CloneWithSize, false);
107107
}
108108
if (symbols_.Object_Clone == nullptr) {
109-
FIND_SYMBOL(kArt_Object_CloneWithClass, symbols_.Object_CloneWithClass, true);
109+
FIND_SYMBOL(kArt_Object_CloneWithClass, symbols_.Object_CloneWithClass, false);
110110
}
111111
FIND_SYMBOL(kArt_DecodeJObject, symbols_.Thread_DecodeJObject, true);
112112
FIND_SYMBOL(kArt_JniEnvExt_NewLocalRef, symbols_.JniEnvExt_NewLocalRef, true);

whale/src/android/art/modifiers.h

+1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ static constexpr uint32_t kAccFastNative = 0x00080000u; // method (dex only)
3838
static constexpr uint32_t kAccPreverified = kAccFastNative; // class (runtime)
3939
static constexpr uint32_t kAccSkipAccessChecks = kAccPreverified;
4040
static constexpr uint32_t kAccCriticalNative_P = 0x00200000; // method (runtime; native only)
41+
static constexpr uint32_t kAccFastInterpreterToInterpreterInvoke = 0x40000000;
4142
// Android M only
4243
static constexpr uint32_t kAccDontInline = 0x00400000u; // method (dex only)
4344
// Android N or later. Set by the verifier for a method we do not want the compiler to compile.

whale/src/dbi/hook_common.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ void InterceptSysCallHook::StartHook() {
3636
bool stop_foreach = false;
3737
#if defined(linux)
3838
ForeachMemoryRange(
39-
[&](uintptr_t begin, uintptr_t end, char *perm, char *mapname) -> bool {
39+
[&](uintptr_t begin, uintptr_t end, uintptr_t offset, char *perm, char *mapname) -> bool {
4040
if (strstr(perm, "x") && strstr(perm, "r")) {
4141
if (callback_(mapname, &stop_foreach)) {
4242
FindSysCalls(begin, end);

whale/src/platform/linux/process_map.cc

+14-10
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ std::unique_ptr<MemoryRange> FindFileMemoryRange(const char *name) {
1111
std::unique_ptr<MemoryRange> range(new MemoryRange);
1212
range->base_ = UINTPTR_MAX;
1313
ForeachMemoryRange(
14-
[&](uintptr_t begin, uintptr_t end, char *perm, char *mapname) -> bool {
14+
[&](uintptr_t begin, uintptr_t end, uintptr_t offset, char *perm, char *mapname) -> bool {
1515
if (strstr(mapname, name)) {
1616
if (range->path_ == nullptr) {
1717
range->path_ = strdup(mapname);
@@ -31,23 +31,27 @@ std::unique_ptr<MemoryRange> FindFileMemoryRange(const char *name) {
3131
std::unique_ptr<MemoryRange> FindExecuteMemoryRange(const char *name) {
3232
std::unique_ptr<MemoryRange> range(new MemoryRange);
3333
ForeachMemoryRange(
34-
[&](uintptr_t begin, uintptr_t end, char *perm, char *mapname) -> bool {
34+
[&](uintptr_t begin, uintptr_t end, uintptr_t offset, char *perm, char *mapname) -> bool {
3535
if (strncmp(mapname, "/system/fake-libs/", 18) == 0) {
3636
return true;
3737
}
38-
if (strstr(mapname, name) && strstr(perm, "x") && strstr(perm, "r")) {
39-
range->path_ = strdup(mapname);
40-
range->base_ = begin;
41-
range->end_ = end;
42-
return false;
38+
if (strstr(mapname, name)) {
39+
//find the correct base address
40+
if (offset == 0) {
41+
range->path_ = strdup(mapname);
42+
range->base_ = begin;
43+
range->end_ = end;
44+
}
45+
if (strstr(perm, "x"))
46+
return false;
4347
}
4448
return true;
4549
});
4650
return range;
4751
}
4852

4953
void
50-
ForeachMemoryRange(std::function<bool(uintptr_t, uintptr_t, char *, char *)> callback) {
54+
ForeachMemoryRange(std::function<bool(uintptr_t, uintptr_t, uintptr_t offset, char *, char *)> callback) {
5155
FILE *f;
5256
if ((f = fopen("/proc/self/maps", "r"))) {
5357
char buf[PATH_MAX], perm[12] = {'\0'}, dev[12] = {'\0'}, mapname[PATH_MAX] = {'\0'};
@@ -58,7 +62,7 @@ ForeachMemoryRange(std::function<bool(uintptr_t, uintptr_t, char *, char *)> cal
5862
break;
5963
sscanf(buf, "%lx-%lx %s %lx %s %ld %s", &begin, &end, perm,
6064
&foo, dev, &inode, mapname);
61-
if (!callback(begin, end, perm, mapname)) {
65+
if (!callback(begin, end, foo, perm, mapname)) {
6266
break;
6367
}
6468
}
@@ -69,7 +73,7 @@ ForeachMemoryRange(std::function<bool(uintptr_t, uintptr_t, char *, char *)> cal
6973
bool IsFileInMemory(const char *name) {
7074
bool found = false;
7175
ForeachMemoryRange(
72-
[&](uintptr_t begin, uintptr_t end, char *perm, char *mapname) -> bool {
76+
[&](uintptr_t begin, uintptr_t end, uintptr_t offset, char *perm, char *mapname) -> bool {
7377
if (strstr(mapname, name)) {
7478
found = true;
7579
return false;

whale/src/platform/linux/process_map.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ std::unique_ptr<MemoryRange> FindExecuteMemoryRange(const char *name);
3737

3838
std::unique_ptr<MemoryRange> FindFileMemoryRange(const char *name);
3939

40-
void ForeachMemoryRange(std::function<bool(uintptr_t, uintptr_t, char *, char *)> callback);
40+
void ForeachMemoryRange(std::function<bool(uintptr_t, uintptr_t, uintptr_t, char *, char *)> callback);
4141

4242
} // namespace whale
4343

0 commit comments

Comments
 (0)