mirror of
https://github.com/LSPosed/LSPlant.git
synced 2025-05-04 20:42:02 +08:00
Refine codes
This commit is contained in:
parent
6d40254a3f
commit
b95af07672
@ -1,101 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "art/thread.hpp"
|
||||
#include "common.hpp"
|
||||
|
||||
namespace lsplant::art {
|
||||
|
||||
namespace dex {
|
||||
class ClassDef {};
|
||||
} // namespace dex
|
||||
|
||||
namespace mirror {
|
||||
|
||||
class Class {
|
||||
private:
|
||||
CREATE_MEM_FUNC_SYMBOL_ENTRY(const char *, GetDescriptor, Class *thiz, std::string *storage) {
|
||||
if (GetDescriptorSym) [[likely]]
|
||||
return GetDescriptor(thiz, storage);
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
CREATE_MEM_FUNC_SYMBOL_ENTRY(const dex::ClassDef *, GetClassDef, Class *thiz) {
|
||||
if (GetClassDefSym) [[likely]]
|
||||
return GetClassDefSym(thiz);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
public:
|
||||
static bool Init(JNIEnv *env, const HookHandler &handler) {
|
||||
if (!RETRIEVE_MEM_FUNC_SYMBOL(GetDescriptor,
|
||||
"_ZN3art6mirror5Class13GetDescriptorEPNSt3__112"
|
||||
"basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE")) {
|
||||
return false;
|
||||
}
|
||||
if (!RETRIEVE_MEM_FUNC_SYMBOL(GetClassDef, "_ZN3art6mirror5Class11GetClassDefEv")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto clazz = JNI_FindClass(env, "java/lang/Class");
|
||||
if (!clazz) {
|
||||
LOGE("Failed to find Class");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (class_status = JNI_GetFieldID(env, clazz, "status", "I"); !class_status) {
|
||||
LOGE("Failed to find status");
|
||||
return false;
|
||||
}
|
||||
|
||||
int sdk_int = GetAndroidApiLevel();
|
||||
|
||||
if (sdk_int >= __ANDROID_API_P__) {
|
||||
initialized_status = -14;
|
||||
} else if (sdk_int == __ANDROID_API_O_MR1__) {
|
||||
initialized_status = 11;
|
||||
} else {
|
||||
initialized_status = 10;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const char *GetDescriptor(std::string *storage) {
|
||||
if (GetDescriptorSym) {
|
||||
return GetDescriptor(storage);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string GetDescriptor() {
|
||||
std::string storage;
|
||||
return GetDescriptor(&storage);
|
||||
}
|
||||
|
||||
const dex::ClassDef *GetClassDef() {
|
||||
if (GetClassDefSym) return GetClassDef(this);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static int GetStatus(JNIEnv *env, jclass clazz) {
|
||||
int status = JNI_GetIntField(env, clazz, class_status);
|
||||
return initialized_status < 0 ? static_cast<uint32_t>(status) >> (32 - 4) : status;
|
||||
}
|
||||
|
||||
static bool IsInitialized(JNIEnv *env, jclass clazz) {
|
||||
return initialized_status < 0 ? GetStatus(env, clazz) >= -initialized_status
|
||||
: GetStatus(env, clazz) == initialized_status;
|
||||
}
|
||||
|
||||
static Class *FromReflectedClass(JNIEnv *, jclass clazz) {
|
||||
return reinterpret_cast<Class *>(art::Thread::Current()->DecodeJObject(clazz));
|
||||
}
|
||||
|
||||
private:
|
||||
inline static jfieldID class_status = nullptr;
|
||||
inline static int initialized_status = 0;
|
||||
};
|
||||
|
||||
} // namespace mirror
|
||||
} // namespace lsplant::art
|
@ -1,6 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "art/mirror/class.hpp"
|
||||
#include "common.hpp"
|
||||
|
||||
namespace lsplant::art {
|
||||
|
@ -1,6 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "art/mirror/class.hpp"
|
||||
#include "art/runtime/art_method.hpp"
|
||||
#include "art/thread.hpp"
|
||||
#include "common.hpp"
|
||||
@ -40,7 +39,7 @@ public:
|
||||
static bool Init(const HookHandler &handler) {
|
||||
int sdk_int = GetAndroidApiLevel();
|
||||
|
||||
if (sdk_int >= __ANDROID_API_N__) {
|
||||
if (sdk_int >= __ANDROID_API_N__) [[likely]] {
|
||||
if (!HookSyms(handler, ShouldUseInterpreterEntrypoint, ShouldStayInSwitchInterpreter))
|
||||
[[unlikely]] {
|
||||
return false;
|
||||
@ -49,13 +48,14 @@ public:
|
||||
|
||||
if (!RETRIEVE_MEM_FUNC_SYMBOL(
|
||||
SetEntryPointsToInterpreter,
|
||||
"_ZNK3art11ClassLinker27SetEntryPointsToInterpreterEPNS_9ArtMethodE")) {
|
||||
"_ZNK3art11ClassLinker27SetEntryPointsToInterpreterEPNS_9ArtMethodE"))
|
||||
[[unlikely]] {
|
||||
if (!RETRIEVE_FUNC_SYMBOL(art_quick_to_interpreter_bridge,
|
||||
"art_quick_to_interpreter_bridge")) {
|
||||
"art_quick_to_interpreter_bridge")) [[unlikely]] {
|
||||
return false;
|
||||
}
|
||||
if (!RETRIEVE_FUNC_SYMBOL(art_quick_generic_jni_trampoline,
|
||||
"art_quick_generic_jni_trampoline")) {
|
||||
"art_quick_generic_jni_trampoline")) [[unlikely]] {
|
||||
return false;
|
||||
}
|
||||
LOGD("art_quick_to_interpreter_bridge = %p", art_quick_to_interpreter_bridgeSym);
|
||||
|
@ -45,11 +45,6 @@ class DexFile {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CREATE_MEM_FUNC_SYMBOL_ENTRY(void, push_back, std::vector<const DexFile*>* thiz,
|
||||
const DexFile** dex_file) {
|
||||
push_backSym(thiz, dex_file);
|
||||
}
|
||||
|
||||
public:
|
||||
static const DexFile* OpenMemory(const void* dex_file, size_t size, std::string location,
|
||||
std::string* error_msg) {
|
||||
@ -58,11 +53,11 @@ public:
|
||||
reinterpret_cast<const Header*>(dex_file)->checksum_, nullptr,
|
||||
nullptr, error_msg)
|
||||
.release();
|
||||
} else if (OpenMemoryRawSym) {
|
||||
} else if (OpenMemoryRawSym) [[likely]] {
|
||||
return OpenMemoryRaw(reinterpret_cast<const uint8_t*>(dex_file), size, location,
|
||||
reinterpret_cast<const Header*>(dex_file)->checksum_, nullptr,
|
||||
nullptr, error_msg);
|
||||
} else if (OpenMemoryWithoutOdexSym) {
|
||||
} else if (OpenMemoryWithoutOdexSym) [[likely]] {
|
||||
return OpenMemoryWithoutOdex(reinterpret_cast<const uint8_t*>(dex_file), size, location,
|
||||
reinterpret_cast<const Header*>(dex_file)->checksum_,
|
||||
nullptr, error_msg);
|
||||
@ -119,26 +114,26 @@ public:
|
||||
return false;
|
||||
}
|
||||
dex_file_class = JNI_NewGlobalRef(env, JNI_FindClass(env, "dalvik/system/DexFile"));
|
||||
if (!dex_file_class) {
|
||||
if (!dex_file_class) [[unlikely]] {
|
||||
return false;
|
||||
}
|
||||
if (sdk_int >= __ANDROID_API_M__) {
|
||||
if (sdk_int >= __ANDROID_API_M__) [[unlikely]] {
|
||||
cookie_field = JNI_GetFieldID(env, dex_file_class, "mCookie", "Ljava/lang/Object;");
|
||||
} else {
|
||||
cookie_field = JNI_GetFieldID(env, dex_file_class, "mCookie", "J");
|
||||
dex_file_start_index = -1;
|
||||
}
|
||||
if (!cookie_field) {
|
||||
if (!cookie_field) [[unlikely]] {
|
||||
return false;
|
||||
}
|
||||
file_name_field = JNI_GetFieldID(env, dex_file_class, "mFileName", "Ljava/lang/String;");
|
||||
if (!file_name_field) {
|
||||
if (!file_name_field) [[unlikely]] {
|
||||
return false;
|
||||
}
|
||||
if (sdk_int >= __ANDROID_API_N__) {
|
||||
if (sdk_int >= __ANDROID_API_N__) [[likely]] {
|
||||
internal_cookie_field =
|
||||
JNI_GetFieldID(env, dex_file_class, "mInternalCookie", "Ljava/lang/Object;");
|
||||
if (!internal_cookie_field) {
|
||||
if (!internal_cookie_field) [[unlikely]] {
|
||||
return false;
|
||||
}
|
||||
dex_file_start_index = 1u;
|
||||
|
@ -16,17 +16,13 @@ private:
|
||||
class ScopedGCCriticalSection {
|
||||
CREATE_MEM_FUNC_SYMBOL_ENTRY(void, constructor, ScopedGCCriticalSection *thiz, Thread *self,
|
||||
GcCause cause, CollectorType collector_type) {
|
||||
if (thiz == nullptr) [[unlikely]]
|
||||
return;
|
||||
if (constructorSym) [[likely]]
|
||||
if (thiz && constructorSym) [[likely]]
|
||||
return constructorSym(thiz, self, cause, collector_type);
|
||||
}
|
||||
|
||||
CREATE_MEM_FUNC_SYMBOL_ENTRY(void, destructor, ScopedGCCriticalSection *thiz) {
|
||||
if (thiz == nullptr) [[unlikely]]
|
||||
return;
|
||||
if (destructorSym) [[likely]]
|
||||
return destructorSym(thiz);
|
||||
if (thiz && destructorSym) [[likely]]
|
||||
destructorSym(thiz);
|
||||
}
|
||||
|
||||
public:
|
||||
@ -39,7 +35,7 @@ public:
|
||||
static bool Init(const HookHandler &handler) {
|
||||
// for Android M, it's safe to not found since we have suspendVM & resumeVM
|
||||
auto sdk_int = GetAndroidApiLevel();
|
||||
if (sdk_int >= __ANDROID_API_N__) {
|
||||
if (sdk_int >= __ANDROID_API_N__) [[likely]] {
|
||||
if (!RETRIEVE_MEM_FUNC_SYMBOL(constructor,
|
||||
"_ZN3art2gc23ScopedGCCriticalSectionC2EPNS_6ThreadENS0_"
|
||||
"7GcCauseENS0_13CollectorTypeE")) [[unlikely]] {
|
||||
|
@ -36,7 +36,7 @@ public:
|
||||
}
|
||||
}
|
||||
if (sdk_int >= __ANDROID_API_N__) [[likely]] {
|
||||
if (!HookSyms(handler, GarbageCollectCache)) {
|
||||
if (!HookSyms(handler, GarbageCollectCache)) [[unlikely]] {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ class Thread {
|
||||
};
|
||||
|
||||
CREATE_MEM_FUNC_SYMBOL_ENTRY(ObjPtr, DecodeJObject, Thread *thiz, jobject obj) {
|
||||
if (DecodeJObjectSym)
|
||||
if (DecodeJObjectSym) [[likely]]
|
||||
return DecodeJObjectSym(thiz, obj);
|
||||
else
|
||||
return {.data = nullptr};
|
||||
@ -27,10 +27,12 @@ public:
|
||||
static Thread *Current() { return CurrentFromGdb(); }
|
||||
|
||||
static bool Init(const HookHandler &handler) {
|
||||
if (!RETRIEVE_MEM_FUNC_SYMBOL(DecodeJObject, "_ZNK3art6Thread13DecodeJObjectEP8_jobject")) {
|
||||
if (!RETRIEVE_MEM_FUNC_SYMBOL(DecodeJObject, "_ZNK3art6Thread13DecodeJObjectEP8_jobject"))
|
||||
[[unlikely]] {
|
||||
return false;
|
||||
}
|
||||
if (!RETRIEVE_FUNC_SYMBOL(CurrentFromGdb, "_ZN3art6Thread14CurrentFromGdbEv")) {
|
||||
if (!RETRIEVE_FUNC_SYMBOL(CurrentFromGdb, "_ZN3art6Thread14CurrentFromGdbEv"))
|
||||
[[unlikely]] {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -7,9 +7,7 @@ namespace lsplant::art::thread_list {
|
||||
class ScopedSuspendAll {
|
||||
CREATE_MEM_FUNC_SYMBOL_ENTRY(void, constructor, ScopedSuspendAll *thiz, const char *cause,
|
||||
bool long_suspend) {
|
||||
if (thiz == nullptr) [[unlikely]]
|
||||
return;
|
||||
if (constructorSym) [[likely]] {
|
||||
if (thiz && constructorSym) [[likely]] {
|
||||
return constructorSym(thiz, cause, long_suspend);
|
||||
} else {
|
||||
SuspendVM();
|
||||
@ -17,10 +15,7 @@ class ScopedSuspendAll {
|
||||
}
|
||||
|
||||
CREATE_MEM_FUNC_SYMBOL_ENTRY(void, destructor, ScopedSuspendAll *thiz) {
|
||||
if (thiz == nullptr) [[unlikely]] {
|
||||
return;
|
||||
}
|
||||
if (destructorSym) [[likely]] {
|
||||
if (thiz && destructorSym) [[likely]] {
|
||||
return destructorSym(thiz);
|
||||
} else {
|
||||
ResumeVM();
|
||||
@ -47,15 +42,13 @@ public:
|
||||
~ScopedSuspendAll() { destructor(this); }
|
||||
|
||||
static bool Init(const HookHandler &handler) {
|
||||
if (!RETRIEVE_MEM_FUNC_SYMBOL(constructor, "_ZN3art16ScopedSuspendAllC2EPKcb")) {
|
||||
if (!RETRIEVE_FUNC_SYMBOL(SuspendVM, "_ZN3art3Dbg9SuspendVMEv")) {
|
||||
return false;
|
||||
}
|
||||
if (!RETRIEVE_MEM_FUNC_SYMBOL(constructor, "_ZN3art16ScopedSuspendAllC2EPKcb") &&
|
||||
!RETRIEVE_FUNC_SYMBOL(SuspendVM, "_ZN3art3Dbg9SuspendVMEv")) [[unlikely]] {
|
||||
return false;
|
||||
}
|
||||
if (!RETRIEVE_MEM_FUNC_SYMBOL(destructor, "_ZN3art16ScopedSuspendAllD2Ev")) {
|
||||
if (!RETRIEVE_FUNC_SYMBOL(ResumeVM, "_ZN3art3Dbg8ResumeVMEv")) {
|
||||
return false;
|
||||
}
|
||||
if (!RETRIEVE_MEM_FUNC_SYMBOL(destructor, "_ZN3art16ScopedSuspendAllD2Ev") &&
|
||||
!RETRIEVE_FUNC_SYMBOL(ResumeVM, "_ZN3art3Dbg8ResumeVMEv")) [[unlikely]] {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -6,7 +6,6 @@
|
||||
#include <shared_mutex>
|
||||
#include <string_view>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
|
||||
#include "logging.hpp"
|
||||
#include "lsplant.hpp"
|
||||
@ -55,22 +54,8 @@ inline auto GetAndroidApiLevel() {
|
||||
|
||||
inline static constexpr auto kPointerSize = sizeof(void *);
|
||||
|
||||
template <typename T>
|
||||
inline T GetArtSymbol(const std::function<void *(std::string_view)> &resolver,
|
||||
std::string_view symbol) requires(std::is_pointer_v<T>) {
|
||||
if (auto *result = resolver(symbol); result) {
|
||||
return reinterpret_cast<T>(result);
|
||||
} else {
|
||||
LOGW("Failed to find symbol %*s", static_cast<int>(symbol.length()), symbol.data());
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
namespace art {
|
||||
class ArtMethod;
|
||||
namespace dex {
|
||||
class ClassDef;
|
||||
}
|
||||
class ArtMethod;
|
||||
} // namespace art
|
||||
|
||||
namespace {
|
||||
@ -92,7 +77,7 @@ inline std::list<std::pair<art::ArtMethod *, art::ArtMethod *>> GetJitMovements(
|
||||
return std::move(jit_movements_);
|
||||
}
|
||||
|
||||
inline void RecordHooked(art::ArtMethod *target, jobject reflected_backup, art::ArtMethod* backup) {
|
||||
inline void RecordHooked(art::ArtMethod *target, jobject reflected_backup, art::ArtMethod *backup) {
|
||||
std::unique_lock lk(hooked_methods_lock_);
|
||||
hooked_methods_.emplace(target, std::make_pair(reflected_backup, backup));
|
||||
}
|
||||
|
@ -59,8 +59,8 @@ struct InitInfo {
|
||||
/// \return Indicate whether initialization succeed. Behavior is undefined if calling other
|
||||
/// LSPlant interfaces before initialization or after a fail initialization.
|
||||
/// \see InitInfo.
|
||||
[[nodiscard]] [[maybe_unused]] [[gnu::visibility("default")]] bool Init(JNIEnv *env,
|
||||
const InitInfo &info);
|
||||
[[nodiscard, maybe_unused, gnu::visibility("default")]] bool Init(JNIEnv *env,
|
||||
const InitInfo &info);
|
||||
|
||||
/// \brief Hook a Java method by providing the \p target_method together with the context object
|
||||
/// \p hooker_object and its callback \p callback_method.
|
||||
@ -75,29 +75,32 @@ struct InitInfo {
|
||||
/// \param[in] callback_method The callback method to the \p hooker_object is used to replace the
|
||||
/// \p target_method. Whenever the \p target_method is invoked, the \p callback_method will be
|
||||
/// invoked instead of the original \p target_method. The signature of the \p callback_method must
|
||||
/// be:<br>
|
||||
/// be:
|
||||
/// \code{.java}
|
||||
/// public Object callback_method(Object []args)
|
||||
/// \endcode<br>
|
||||
/// \endcode
|
||||
/// That is, the return type must be \p Object and the parameter type must be \b Object[]. Behavior
|
||||
/// is undefined if the signature does not match the requirement.
|
||||
/// args[0] is the this object for non-static methods and there is NOT null this object placeholder
|
||||
/// for static methods.
|
||||
/// Extra info can be provided by defining member variables of \p hooker_object.
|
||||
/// This method must be a method to \p hooker_object.
|
||||
/// \return The backup method. You can invoke it by reflection to invoke the original method. null
|
||||
/// if fails.
|
||||
/// \note This function will automatically generate a stub class for hook. To help debug, you
|
||||
/// can set the generated class name, its field name, its source name and its method name
|
||||
/// by setting generated_* in \p InitInfo.
|
||||
/// \return The backup method. You can invoke it
|
||||
/// by reflection to invoke the original method. null if fails.
|
||||
/// \note This function will
|
||||
/// automatically generate a stub class for hook. To help debug, you can set the generated class
|
||||
/// name, its field name, its source name and its method name by setting generated_* in \ref
|
||||
/// InitInfo.
|
||||
/// \note This function thread safe (you can call it simultaneously from multiple thread)
|
||||
/// but it's not atomic to the same \b target_method. That means \p UnHook or \p IsUnhook does
|
||||
/// not guarantee to work properly on the same \p target_method before it returns. Also,
|
||||
/// simultaneously call on this function with the same \p target_method does not guarantee only one
|
||||
/// will success. If you call this with different \p hooker_object on the same target_method
|
||||
/// simultaneously, the behavior is undefined.
|
||||
[[nodiscard]] [[maybe_unused]] [[gnu::visibility("default")]] jobject Hook(JNIEnv *env,
|
||||
jobject target_method,
|
||||
jobject hooker_object,
|
||||
jobject callback_method);
|
||||
/// but it's not atomic to the same \b target_method. That means #UnHook() or #IsUnhook() does not
|
||||
/// guarantee to work properly on the same \p target_method before it returns. Also, simultaneously
|
||||
/// call on this function with the same \p target_method does not guarantee only one will success.
|
||||
/// If you call this with different \p hooker_object on the same target_method simultaneously, the
|
||||
/// behavior is undefined.
|
||||
[[nodiscard, maybe_unused, gnu::visibility("default")]] jobject Hook(JNIEnv *env,
|
||||
jobject target_method,
|
||||
jobject hooker_object,
|
||||
jobject callback_method);
|
||||
|
||||
/// \brief Unhook a Java function that is previously hooked.
|
||||
/// \param[in] env The Java environment.
|
||||
@ -106,8 +109,8 @@ struct InitInfo {
|
||||
/// \note Calling \p backup (the return method of #Hook()) after unhooking is undefined behavior.
|
||||
/// Please read #Hook()'s note for more details.
|
||||
/// \see Hook()
|
||||
[[nodiscard]] [[maybe_unused]] [[gnu::visibility("default")]] bool UnHook(JNIEnv *env,
|
||||
jobject target_method);
|
||||
[[nodiscard, maybe_unused, gnu::visibility("default")]] bool UnHook(JNIEnv *env,
|
||||
jobject target_method);
|
||||
|
||||
/// \brief Check if a Java function is hooked by LSPlant or not
|
||||
/// \param[in] env The Java environment.
|
||||
@ -115,8 +118,7 @@ struct InitInfo {
|
||||
/// \return If \p method hooked, ture; otherwise, false.
|
||||
/// Please read #Hook()'s note for more details.
|
||||
/// \see Hook()
|
||||
[[nodiscard]] [[maybe_unused]] [[gnu::visibility("default")]] bool IsHooked(JNIEnv *env,
|
||||
jobject method);
|
||||
[[nodiscard, maybe_unused, gnu::visibility("default")]] bool IsHooked(JNIEnv *env, jobject method);
|
||||
|
||||
/// \brief Deoptimize a method to avoid hooked callee not being called because of inline
|
||||
/// \param[in] env The Java environment.
|
||||
@ -125,14 +127,15 @@ struct InitInfo {
|
||||
/// A, and you find that your callback to B is not invoked after hooking, then it may mean A has
|
||||
/// inlined B inside its method body. To force A to call your hooked B, you can deoptimize A and
|
||||
/// then your hook can take effect. Generally, you need to find all the callers of your hooked
|
||||
/// callee and that can be hardly achieve. Use this function if you are sure the deoptimized callers
|
||||
/// callee and that can be hardly achieve (but you can still search all callers by using DexHelper).
|
||||
/// Use this function if you are sure the deoptimized callers
|
||||
/// are all you need. Otherwise, it would be better to change the hook point or to deoptimize the
|
||||
/// whole app manually (by simple reinstall the app without uninstalled).
|
||||
/// \return Indicate whether the deoptimizing succeed or not.
|
||||
/// \note It is safe to call deoptimizing on a hooked method because the deoptimization will
|
||||
/// perform on the backup method instead.
|
||||
[[nodiscard]] [[maybe_unused]] [[gnu::visibility("default")]] bool Deoptimize(JNIEnv *env,
|
||||
jobject method);
|
||||
[[nodiscard, maybe_unused, gnu::visibility("default")]] bool Deoptimize(JNIEnv *env,
|
||||
jobject method);
|
||||
|
||||
/// \brief Get the registered native function pointer of a native function. It helps user to hook
|
||||
/// native methods directly by backing up the native function pointer this function returns and
|
||||
@ -141,15 +144,15 @@ struct InitInfo {
|
||||
/// \param[in] method The native method to get the native function pointer.
|
||||
/// \return The native function pointer the \p method previously registered. If it has not been
|
||||
/// registered or it is not a native method, null is returned instead.
|
||||
[[nodiscard]] [[maybe_unused]] [[gnu::visibility("default")]] void *GetNativeFunction(
|
||||
JNIEnv *env, jobject method);
|
||||
[[nodiscard, maybe_unused, gnu::visibility("default")]] void *GetNativeFunction(JNIEnv *env,
|
||||
jobject method);
|
||||
|
||||
/// \brief Make a class inheritable. It will make the class non-final and make all its private
|
||||
/// constructors protected.
|
||||
/// \param[in] env The Java environment.
|
||||
/// \param[in] target The target class that is to make inheritable.
|
||||
/// \return Indicate whether the operation has succeed.
|
||||
[[nodiscard]] [[maybe_unused]] [[gnu::visibility("default")]] bool MakeClassInheritable(
|
||||
JNIEnv *env, jclass target);
|
||||
[[nodiscard, maybe_unused, gnu::visibility("default")]] bool MakeClassInheritable(JNIEnv *env,
|
||||
jclass target);
|
||||
} // namespace v1
|
||||
} // namespace lsplant
|
||||
|
@ -33,7 +33,6 @@ using art::Instrumentation;
|
||||
using art::Thread;
|
||||
using art::gc::ScopedGCCriticalSection;
|
||||
using art::jit::JitCodeCache;
|
||||
using art::mirror::Class;
|
||||
using art::thread_list::ScopedSuspendAll;
|
||||
|
||||
namespace {
|
||||
@ -227,10 +226,6 @@ bool InitNative(JNIEnv *env, const HookHandler &handler) {
|
||||
LOGE("Failed to init class linker");
|
||||
return false;
|
||||
}
|
||||
if (!Class::Init(env, handler)) {
|
||||
LOGE("Failed to init mirror class");
|
||||
return false;
|
||||
}
|
||||
if (!Instrumentation::Init(handler)) {
|
||||
LOGE("Failed to init instrumentation");
|
||||
return false;
|
||||
|
Loading…
x
Reference in New Issue
Block a user