From d8943e0937ac1ac43d531e704825c88a622a2a07 Mon Sep 17 00:00:00 2001 From: LoveSy Date: Sun, 26 Sep 2021 13:39:33 +0800 Subject: [PATCH] [core] Try to fix #1144 by hook (#1166) --- .../main/include/art/runtime/class_linker.h | 1 + .../include/art/runtime/jit/profiling_info.h | 65 +++++++++++++++++++ .../main/cpp/main/src/jni/pending_hooks.cpp | 16 +---- .../src/main/cpp/main/src/jni/pending_hooks.h | 4 -- core/src/main/cpp/main/src/jni/yahfa.cpp | 17 +++++ core/src/main/cpp/main/src/jni/yahfa.h | 4 ++ core/src/main/cpp/main/src/native_hook.cpp | 4 +- 7 files changed, 91 insertions(+), 20 deletions(-) create mode 100644 core/src/main/cpp/main/include/art/runtime/jit/profiling_info.h diff --git a/core/src/main/cpp/main/include/art/runtime/class_linker.h b/core/src/main/cpp/main/include/art/runtime/class_linker.h index 405ceb77..2dd7b4b1 100644 --- a/core/src/main/cpp/main/include/art/runtime/class_linker.h +++ b/core/src/main/cpp/main/include/art/runtime/class_linker.h @@ -28,6 +28,7 @@ #include "jni_env_ext.h" #include "context.h" #include "jni/pending_hooks.h" +#include "jni/yahfa.h" #include "utils.h" #include "HookMain.h" diff --git a/core/src/main/cpp/main/include/art/runtime/jit/profiling_info.h b/core/src/main/cpp/main/include/art/runtime/jit/profiling_info.h new file mode 100644 index 00000000..5c0c2a25 --- /dev/null +++ b/core/src/main/cpp/main/include/art/runtime/jit/profiling_info.h @@ -0,0 +1,65 @@ +/* + * This file is part of LSPosed. + * + * LSPosed is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * LSPosed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with LSPosed. If not, see . + * + * Copyright (C) 2021 LSPosed Contributors + */ + +#pragma once + +#include +#include +#include +#include "utils.h" +#include "jni/pending_hooks.h" + +namespace art { + namespace profiling_info { + inline static size_t OFFSET_art_method = -1; + + CREATE_MEM_HOOK_STUB_ENTRIES( + "_ZN3art13ProfilingInfo13AddInvokeInfoEjPNS_6mirror5ClassE", + void, AddInvokeInfo, (void * thiz, uint32_t dex_pc, void * clazz_ptr), { + void *method = *reinterpret_cast( + reinterpret_cast(thiz) + OFFSET_art_method); + if (lspd::isHooked(method)) [[unlikely]] return; + backup(thiz, dex_pc, clazz_ptr); + }); + + static void Setup(const SandHook::ElfImg &handle) { + int api_level = lspd::GetAndroidApiLevel(); + switch (api_level) { + case __ANDROID_API_Q__: + OFFSET_art_method = 0; + break; + case __ANDROID_API_O_MR1__: + [[fallthrough]]; + case __ANDROID_API_P__: + [[fallthrough]]; + case __ANDROID_API_R__: + [[fallthrough]]; + case __ANDROID_API_S__: + if constexpr(lspd::is64) { + OFFSET_art_method = 8; + } else { + OFFSET_art_method = 4; + } + break; + } + if (OFFSET_art_method != size_t(-1)) + lspd::HookSyms(handle, AddInvokeInfo); + } + } +} diff --git a/core/src/main/cpp/main/src/jni/pending_hooks.cpp b/core/src/main/cpp/main/src/jni/pending_hooks.cpp index 8f1a4a47..025a5649 100644 --- a/core/src/main/cpp/main/src/jni/pending_hooks.cpp +++ b/core/src/main/cpp/main/src/jni/pending_hooks.cpp @@ -35,9 +35,6 @@ namespace lspd { std::unordered_set pending_methods_; std::shared_mutex pending_methods_lock_; - - std::unordered_set hooked_methods_; - std::shared_mutex hooked_methods_lock_; } bool IsClassPending(void *clazz) { @@ -93,15 +90,4 @@ namespace lspd { void RegisterPendingHooks(JNIEnv *env) { REGISTER_LSP_NATIVE_METHODS(PendingHooks); } - - bool isHooked(void *art_method) { - std::shared_lock lk(hooked_methods_lock_); - return hooked_methods_.contains(art_method); - } - - void recordHooked(void *art_method) { - std::unique_lock lk(hooked_methods_lock_); - hooked_methods_.insert(art_method); - } - -} +} // namespace lspd diff --git a/core/src/main/cpp/main/src/jni/pending_hooks.h b/core/src/main/cpp/main/src/jni/pending_hooks.h index 49dc141d..b991c0e0 100644 --- a/core/src/main/cpp/main/src/jni/pending_hooks.h +++ b/core/src/main/cpp/main/src/jni/pending_hooks.h @@ -28,10 +28,6 @@ namespace lspd { void RegisterPendingHooks(JNIEnv *); - bool isHooked(void* art_method); - - void recordHooked(void* art_method); - void DonePendingHook(void *clazz); bool IsMethodPending(void* art_method); diff --git a/core/src/main/cpp/main/src/jni/yahfa.cpp b/core/src/main/cpp/main/src/jni/yahfa.cpp index 72fd92fe..49179ee7 100644 --- a/core/src/main/cpp/main/src/jni/yahfa.cpp +++ b/core/src/main/cpp/main/src/jni/yahfa.cpp @@ -27,9 +27,26 @@ #include "art/runtime/thread.h" #include "art/runtime/gc/scoped_gc_critical_section.h" #include +#include +#include namespace lspd { + namespace { + std::unordered_set hooked_methods_; + std::shared_mutex hooked_methods_lock_; + } + + bool isHooked(void *art_method) { + std::shared_lock lk(hooked_methods_lock_); + return hooked_methods_.contains(art_method); + } + + void recordHooked(void *art_method) { + std::unique_lock lk(hooked_methods_lock_); + hooked_methods_.insert(art_method); + } + using namespace startop::dex; LSP_DEF_NATIVE_METHOD(void, Yahfa, init, jint sdkVersion) { yahfa::init(env, clazz, sdkVersion); diff --git a/core/src/main/cpp/main/src/jni/yahfa.h b/core/src/main/cpp/main/src/jni/yahfa.h index 8f1e1c86..b3c04203 100644 --- a/core/src/main/cpp/main/src/jni/yahfa.h +++ b/core/src/main/cpp/main/src/jni/yahfa.h @@ -24,6 +24,10 @@ namespace lspd { + bool isHooked(void* art_method); + + void recordHooked(void* art_method); + void RegisterYahfa(JNIEnv *); } // namespace lspd diff --git a/core/src/main/cpp/main/src/native_hook.cpp b/core/src/main/cpp/main/src/native_hook.cpp index 8b46ec29..f6cf1a13 100644 --- a/core/src/main/cpp/main/src/native_hook.cpp +++ b/core/src/main/cpp/main/src/native_hook.cpp @@ -36,6 +36,7 @@ #include "art/runtime/instrumentation.h" #include "art/runtime/thread_list.h" #include "art/runtime/gc/scoped_gc_critical_section.h" +#include "art/runtime/jit/profiling_info.h" namespace lspd { static std::atomic_bool installed = false; @@ -60,8 +61,9 @@ namespace lspd { art::instrumentation::DisableUpdateHookedMethodsCode(handle_libart); art::thread_list::ScopedSuspendAll::Setup(handle_libart); art::gc::ScopedGCCriticalSection::Setup(handle_libart); + art::profiling_info::Setup(handle_libart); art_img.reset(); LOGD("Inline hooks installed"); } -} +} // namespace lspd