From 5121a21064498be614147a8cc2b213fe6ef3b5a4 Mon Sep 17 00:00:00 2001 From: LoveSy Date: Tue, 23 Jul 2024 11:40:35 +0800 Subject: [PATCH] Remove dangerous implicit cast --- .../src/main/jni/art/runtime/art_method.cxx | 4 ++-- .../src/main/jni/include/utils/jni_helper.hpp | 24 ++++++++++++------- .../src/main/jni/include/utils/jni_helper.ixx | 2 ++ lsplant/src/main/jni/lsplant.cc | 24 +++++++++---------- 4 files changed, 32 insertions(+), 22 deletions(-) diff --git a/lsplant/src/main/jni/art/runtime/art_method.cxx b/lsplant/src/main/jni/art/runtime/art_method.cxx index 1bfbbebe4..f325654d0 100644 --- a/lsplant/src/main/jni/art/runtime/art_method.cxx +++ b/lsplant/src/main/jni/art/runtime/art_method.cxx @@ -228,7 +228,7 @@ export class ArtMethod { env, JNI_GetObjectField( env, - env->ToReflectedField(executable, + JNI_ToReflectedField(env, executable, JNI_GetFieldID(env, executable, name, sig), false), art_field_field), field_offset); @@ -284,7 +284,7 @@ export class ArtMethod { RETRIEVE_MEM_FUNC_SYMBOL(ThrowInvocationTimeError, "_ZN3art9ArtMethod24ThrowInvocationTimeErrorEv"); auto abstract_method = FromReflectedMethod( - env, JNI_ToReflectedMethod(env, executable, executable_get_name, false)); + env, JNI_ToReflectedMethod(env, executable, executable_get_name, false).get()); uint32_t access_flags = abstract_method->GetAccessFlags(); abstract_method->SetAccessFlags(access_flags | kAccDefaultConflict); abstract_method->ThrowInvocationTimeError(); diff --git a/lsplant/src/main/jni/include/utils/jni_helper.hpp b/lsplant/src/main/jni/include/utils/jni_helper.hpp index 1bca68cc1..4d38e3519 100644 --- a/lsplant/src/main/jni/include/utils/jni_helper.hpp +++ b/lsplant/src/main/jni/include/utils/jni_helper.hpp @@ -58,8 +58,6 @@ class ScopedLocalRef { return ScopedLocalRef(env_, (T)env_->NewLocalRef(local_ref_)); } - operator T() const { return local_ref_; } - ScopedLocalRef &operator=(ScopedLocalRef &&s) noexcept { reset(s.release()); env_ = s.env_; @@ -126,10 +124,11 @@ concept ScopeOrObject = ScopeOrRaw; inline ScopedLocalRef ClearException(JNIEnv *env) { if (auto exception = env->ExceptionOccurred()) { env->ExceptionClear(); - static jclass log = (jclass)env->NewGlobalRef(env->FindClass("android/util/Log")); + jclass log = (jclass)env->FindClass("android/util/Log"); static jmethodID toString = env->GetStaticMethodID( log, "getStackTraceString", "(Ljava/lang/Throwable;)Ljava/lang/String;"); auto str = (jstring)env->CallStaticObjectMethod(log, toString, exception); + env->DeleteLocalRef(log); env->DeleteLocalRef(exception); return {env, str}; } @@ -506,6 +505,13 @@ template isStatic); } +template +[[maybe_unused]] inline auto JNI_ToReflectedField(JNIEnv *env, Class &&clazz, jfieldID field, + jboolean isStatic = JNI_FALSE) { + return JNI_SafeInvoke(env, &JNIEnv::ToReflectedField, std::forward(clazz), field, + isStatic); +} + // functions to method // virtual methods @@ -763,6 +769,12 @@ template std::forward(clazz)); } +template +[[maybe_unused]] inline auto JNI_IsSameObject(JNIEnv *env, Object1 &&a, Object2 &&b) { + return JNI_SafeInvoke(env, &JNIEnv::IsSameObject, std::forward(a), + std::forward(b)); +} + template [[maybe_unused]] inline auto JNI_NewGlobalRef(JNIEnv *env, Object &&x) { return (decltype(UnwrapScope(std::forward(x))))env->NewGlobalRef( @@ -941,8 +953,6 @@ class ScopedLocalRef { T get() const { return local_ref_; } - explicit operator T() const { return local_ref_; } - JArrayUnderlyingType &operator[](size_t index) { modified_ = true; return elements_[index]; @@ -1064,7 +1074,7 @@ class JObjectArrayElement { } template - JObjectArrayElement &operator=(ScopedLocalRef &s) { + JObjectArrayElement &operator=(const ScopedLocalRef &s) { reset(s.clone()); return *this; } @@ -1081,8 +1091,6 @@ class JObjectArrayElement { ScopedLocalRef clone() const { return item_.clone(); } - operator jobject() const { return item_; } - jobject get() const { return item_.get(); } jobject release() { return item_.release(); } diff --git a/lsplant/src/main/jni/include/utils/jni_helper.ixx b/lsplant/src/main/jni/include/utils/jni_helper.ixx index e0ed90eb4..efaf407b0 100644 --- a/lsplant/src/main/jni/include/utils/jni_helper.ixx +++ b/lsplant/src/main/jni/include/utils/jni_helper.ixx @@ -115,6 +115,7 @@ using lsplant::JNI_CallVoidMethod; using lsplant::JNI_GetMethodID; using lsplant::JNI_GetStaticMethodID; using lsplant::JNI_ToReflectedMethod; +using lsplant::JNI_ToReflectedField; using lsplant::JNI_NewBooleanArray; using lsplant::JNI_NewByteArray; @@ -134,6 +135,7 @@ using lsplant::JNI_GetArrayLength; using lsplant::JNI_GetObjectClass; using lsplant::JNI_GetObjectFieldOf; using lsplant::JNI_IsInstanceOf; +using lsplant::JNI_IsSameObject; using lsplant::JNI_NewGlobalRef; using lsplant::JNI_NewStringUTF; using lsplant::JNI_RegisterNatives; diff --git a/lsplant/src/main/jni/lsplant.cc b/lsplant/src/main/jni/lsplant.cc index d84c6a663..5f72dd19c 100644 --- a/lsplant/src/main/jni/lsplant.cc +++ b/lsplant/src/main/jni/lsplant.cc @@ -664,15 +664,15 @@ std::string GetProxyMethodShorty(JNIEnv *env, jobject proxy_method) { std::string out; auto type_to_shorty = [&](const ScopedLocalRef &type) { - if (env->IsSameObject(type, int_type)) return 'I'; - if (env->IsSameObject(type, long_type)) return 'J'; - if (env->IsSameObject(type, float_type)) return 'F'; - if (env->IsSameObject(type, double_type)) return 'D'; - if (env->IsSameObject(type, boolean_type)) return 'Z'; - if (env->IsSameObject(type, byte_type)) return 'B'; - if (env->IsSameObject(type, char_type)) return 'C'; - if (env->IsSameObject(type, short_type)) return 'S'; - if (env->IsSameObject(type, void_type)) return 'V'; + if (JNI_IsSameObject(env, type, int_type)) return 'I'; + if (JNI_IsSameObject(env, type, long_type)) return 'J'; + if (JNI_IsSameObject(env, type, float_type)) return 'F'; + if (JNI_IsSameObject(env, type, double_type)) return 'D'; + if (JNI_IsSameObject(env, type, boolean_type)) return 'Z'; + if (JNI_IsSameObject(env, type, byte_type)) return 'B'; + if (JNI_IsSameObject(env, type, char_type)) return 'C'; + if (JNI_IsSameObject(env, type, short_type)) return 'S'; + if (JNI_IsSameObject(env, type, void_type)) return 'V'; return 'L'; }; out += type_to_shorty(return_type); @@ -740,7 +740,7 @@ using ::lsplant::IsHooked; } std::tie(built_class, hooker_field, hook_method, backup_method) = WrapScope( env, - BuildDex(env, callback_class_loader, + BuildDex(env, callback_class_loader.get(), __builtin_expect(is_proxy, 0) ? GetProxyMethodShorty(env, target_method) : ArtMethod::GetMethodShorty(env, target_method), is_static, target->IsConstructor() ? "constructor" : target_method_name.get(), @@ -756,8 +756,8 @@ using ::lsplant::IsHooked; JNI_CallVoidMethod(env, reflected_backup, set_accessible, JNI_TRUE); - auto *hook = ArtMethod::FromReflectedMethod(env, reflected_hook); - auto *backup = ArtMethod::FromReflectedMethod(env, reflected_backup); + auto *hook = ArtMethod::FromReflectedMethod(env, reflected_hook.get()); + auto *backup = ArtMethod::FromReflectedMethod(env, reflected_backup.get()); JNI_SetStaticObjectField(env, built_class, hooker_field, hooker_object);