Guard backup during hook (#2263)

This commit is contained in:
LoveSy 2022-12-03 02:37:23 +08:00 committed by GitHub
parent 0d5b6af524
commit 2327e7b398
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 16 additions and 4 deletions

View File

@ -23,6 +23,7 @@
#include <absl/container/flat_hash_map.h>
#include <memory>
#include <shared_mutex>
#include <mutex>
#include <set>
using namespace lsplant;
@ -35,6 +36,7 @@ struct HookItem {
};
std::shared_mutex hooked_lock;
std::recursive_mutex backup_lock;
absl::flat_hash_map<jmethodID, std::unique_ptr<HookItem>> hooked_methods;
jmethodID invoke = nullptr;
@ -83,6 +85,7 @@ LSP_DEF_NATIVE_METHOD(jboolean, HookBridge, hookMethod, jobject hookMethod,
"([Ljava/lang/Object;)Ljava/lang/Object;"),
false);
auto hooker_object = env->NewObject(hooker, init, hookMethod);
std::unique_lock lk(backup_lock);
hook_item->backup = lsplant::Hook(env, hookMethod, hooker_object, callback_method);
env->DeleteLocalRef(hooker_object);
}
@ -101,7 +104,11 @@ LSP_DEF_NATIVE_METHOD(jboolean, HookBridge, unhookMethod, jobject hookMethod, jo
}
}
if (!hook_item) return JNI_FALSE;
auto backup = hook_item->backup;
jobject backup = nullptr;
{
std::unique_lock lk(backup_lock);
backup = hook_item->backup;
}
if (!backup) return JNI_FALSE;
JNIMonitor monitor(env, backup);
for (auto i = hook_item->callbacks.begin(); i != hook_item->callbacks.end(); ++i) {
@ -129,8 +136,9 @@ LSP_DEF_NATIVE_METHOD(jobject, HookBridge, invokeOriginalMethod, jobject hookMet
}
}
jobject to_call = hookMethod;
if (hook_item && hook_item->backup) {
to_call = hook_item->backup;
if (hook_item) {
std::unique_lock lk(backup_lock);
if (hook_item->backup) to_call = hook_item->backup;
}
return env->CallObjectMethod(to_call, invoke, thiz, args);
}
@ -153,7 +161,11 @@ LSP_DEF_NATIVE_METHOD(jobjectArray, HookBridge, callbackSnapshot, jobject method
}
}
if (!hook_item) return nullptr;
auto backup = hook_item->backup;
jobject backup = nullptr;
{
std::unique_lock lk(backup_lock);
backup = hook_item->backup;
}
if (!backup) return nullptr;
JNIMonitor monitor(env, backup);
auto res = env->NewObjectArray((jsize) hook_item->callbacks.size(), env->FindClass("java/lang/Object"), nullptr);