mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-11-24 18:45:28 +00:00
Refine hookJniNativeMethods
This commit is contained in:
parent
93bcf2cd25
commit
f2d057baba
@ -572,29 +572,38 @@ void hookJniNativeMethods(JNIEnv *env, const char *clz, JNINativeMethod *methods
|
|||||||
|
|
||||||
// Backup existing methods
|
// Backup existing methods
|
||||||
auto total = g_hook->runtime_callbacks->getNativeMethodCount(env, clazz);
|
auto total = g_hook->runtime_callbacks->getNativeMethodCount(env, clazz);
|
||||||
vector<JNINativeMethod> old_methods(total);
|
auto old_methods = std::make_unique_for_overwrite<JNINativeMethod[]>(total);
|
||||||
g_hook->runtime_callbacks->getNativeMethods(env, clazz, old_methods.data(), total);
|
g_hook->runtime_callbacks->getNativeMethods(env, clazz, old_methods.get(), total);
|
||||||
|
auto new_methods = std::make_unique_for_overwrite<JNINativeMethod[]>(total);
|
||||||
|
|
||||||
// Replace the method
|
// Replace the method
|
||||||
for (auto i = 0; i < numMethods; ++i) {
|
for (auto i = 0; i < numMethods; ++i) {
|
||||||
auto &method = methods[i];
|
auto &method = methods[i];
|
||||||
auto res = env->RegisterNatives(clazz, &method, 1);
|
// It's useful to allow nullptr function pointer for restoring hook
|
||||||
|
if (!method.fnPtr) continue;
|
||||||
// It's normal that the method is not found
|
// It's normal that the method is not found
|
||||||
if (res == JNI_ERR || env->ExceptionCheck()) {
|
if (env->RegisterNatives(clazz, &method, 1) == JNI_ERR ||
|
||||||
auto exception = env->ExceptionOccurred();
|
env->ExceptionCheck() == JNI_TRUE) {
|
||||||
if (exception) env->DeleteLocalRef(exception);
|
if (auto *exception = env->ExceptionOccurred(); exception) {
|
||||||
|
env->DeleteLocalRef(exception);
|
||||||
|
}
|
||||||
env->ExceptionClear();
|
env->ExceptionClear();
|
||||||
method.fnPtr = nullptr;
|
method.fnPtr = nullptr;
|
||||||
} else {
|
continue;
|
||||||
|
}
|
||||||
// Find the old function pointer and return to caller
|
// Find the old function pointer and return to caller
|
||||||
for (const auto &old_method : old_methods) {
|
g_hook->runtime_callbacks->getNativeMethods(env, clazz, new_methods.get(), total);
|
||||||
if (strcmp(method.name, old_method.name) == 0 &&
|
for (auto j = 0; j < total; ++j) {
|
||||||
strcmp(method.signature, old_method.signature) == 0) {
|
auto &new_method = new_methods[j];
|
||||||
|
auto &old_method = old_methods[j];
|
||||||
|
if (new_method.fnPtr == method.fnPtr && old_method.fnPtr != new_method.fnPtr &&
|
||||||
|
strcmp(new_method.name, method.name) == 0) {
|
||||||
ZLOGD("replace %s#%s%s %p -> %p\n", clz,
|
ZLOGD("replace %s#%s%s %p -> %p\n", clz,
|
||||||
method.name, method.signature, old_method.fnPtr, method.fnPtr);
|
method.name, method.signature, old_method.fnPtr, method.fnPtr);
|
||||||
method.fnPtr = old_method.fnPtr;
|
method.fnPtr = old_method.fnPtr;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
old_methods.swap(new_methods);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user