Fix corruption when hooking internal used methods

This commit is contained in:
LoveSy 2022-04-28 11:02:53 +08:00
parent 050348fd08
commit d3cd931364
3 changed files with 38 additions and 15 deletions

View File

@ -7,11 +7,11 @@
#endif #endif
#ifdef LOG_DISABLED #ifdef LOG_DISABLED
#define LOGD(...) #define LOGD(...) 0
#define LOGV(...) #define LOGV(...) 0
#define LOGI(...) #define LOGI(...) 0
#define LOGW(...) #define LOGW(...) 0
#define LOGE(...) #define LOGE(...) 0
#else #else
#ifndef NDEBUG #ifndef NDEBUG
#define LOGD(fmt, ...) \ #define LOGD(fmt, ...) \
@ -25,8 +25,8 @@
": " fmt, \ ": " fmt, \
__FILE_NAME__, __LINE__, __PRETTY_FUNCTION__ __VA_OPT__(, ) __VA_ARGS__) __FILE_NAME__, __LINE__, __PRETTY_FUNCTION__ __VA_OPT__(, ) __VA_ARGS__)
#else #else
#define LOGD(...) #define LOGD(...) 0
#define LOGV(...) #define LOGV(...) 0
#endif #endif
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__) #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__) #define LOGW(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)

View File

@ -89,6 +89,11 @@ jclass executable = nullptr;
jclass path_class_loader = nullptr; jclass path_class_loader = nullptr;
jmethodID path_class_loader_init = nullptr; jmethodID path_class_loader_init = nullptr;
constexpr auto kInternalMethods = std::make_tuple(
&method_get_name, &method_get_declaring_class, &class_get_name, &class_get_class_loader,
&class_get_declared_constructors, &in_memory_class_loader_init, &load_class, &set_accessible,
&path_class_loader_init);
std::string generated_class_name; std::string generated_class_name;
std::string generated_source_name; std::string generated_source_name;
std::string generated_field_name; std::string generated_field_name;
@ -604,6 +609,13 @@ using ::lsplant::IsHooked;
JNI_SetStaticObjectField(env, built_class, hooker_field, hooker_object); JNI_SetStaticObjectField(env, built_class, hooker_field, hooker_object);
if (DoHook(target, hook, backup)) { if (DoHook(target, hook, backup)) {
std::apply(
[backup_method, target_method_id = env->FromReflectedMethod(target_method)](auto... v) {
((*v == target_method_id &&
(LOGD("Propagate internal used method because of hook"), *v = backup_method)) ||
...);
},
kInternalMethods);
jobject global_backup = JNI_NewGlobalRef(env, reflected_backup); jobject global_backup = JNI_NewGlobalRef(env, reflected_backup);
RecordHooked(target, target->GetDeclaringClass()->GetClassDef(), global_backup, backup); RecordHooked(target, target->GetDeclaringClass()->GetClassDef(), global_backup, backup);
if (!is_proxy) [[likely]] { if (!is_proxy) [[likely]] {
@ -645,8 +657,19 @@ using ::lsplant::IsHooked;
} }
} }
} }
auto *backup_method = env->FromReflectedMethod(reflected_backup);
env->DeleteGlobalRef(reflected_backup); env->DeleteGlobalRef(reflected_backup);
return DoUnHook(target, backup); if (DoUnHook(target, backup)) {
std::apply(
[backup_method, target_method_id = env->FromReflectedMethod(target_method)](auto... v) {
((*v == backup_method && (LOGD("Propagate internal used method because of unhook"),
*v = target_method_id)) ||
...);
},
kInternalMethods);
return true;
}
return false;
} }
[[maybe_unused]] bool IsHooked(JNIEnv *env, jobject method) { [[maybe_unused]] bool IsHooked(JNIEnv *env, jobject method) {

View File

@ -28,18 +28,18 @@
#endif #endif
#ifdef LOG_DISABLED #ifdef LOG_DISABLED
#define LOGD(...) #define LOGD(...) 0
#define LOGV(...) #define LOGV(...) 0
#define LOGI(...) #define LOGI(...) 0
#define LOGW(...) #define LOGW(...) 0
#define LOGE(...) #define LOGE(...) 0
#else #else
#ifndef NDEBUG #ifndef NDEBUG
#define LOGD(fmt, ...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, "%s:%d#%s" ": " fmt, __FILE_NAME__, __LINE__, __PRETTY_FUNCTION__ __VA_OPT__(,) __VA_ARGS__) #define LOGD(fmt, ...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, "%s:%d#%s" ": " fmt, __FILE_NAME__, __LINE__, __PRETTY_FUNCTION__ __VA_OPT__(,) __VA_ARGS__)
#define LOGV(fmt, ...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, "%s:%d#%s" ": " fmt, __FILE_NAME__, __LINE__, __PRETTY_FUNCTION__ __VA_OPT__(,) __VA_ARGS__) #define LOGV(fmt, ...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, "%s:%d#%s" ": " fmt, __FILE_NAME__, __LINE__, __PRETTY_FUNCTION__ __VA_OPT__(,) __VA_ARGS__)
#else #else
#define LOGD(...) #define LOGD(...) 0
#define LOGV(...) #define LOGV(...) 0
#endif #endif
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__) #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__) #define LOGW(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)