diff --git a/core/src/main/cpp/external/yahfa/include/HookMain.h b/core/src/main/cpp/external/yahfa/include/HookMain.h index cdd2ad79..fd7e5db7 100644 --- a/core/src/main/cpp/external/yahfa/include/HookMain.h +++ b/core/src/main/cpp/external/yahfa/include/HookMain.h @@ -3,26 +3,18 @@ #include -#ifdef __cplusplus -extern "C" { -#endif +namespace yahfa { + void init(JNIEnv *env, jclass clazz, jint sdkVersion); -void Java_lab_galaxy_yahfa_HookMain_init(JNIEnv *env, jclass clazz, jint sdkVersion); + jobject findMethodNative(JNIEnv *env, jclass clazz, + jclass targetClass, jstring methodName, + jstring methodSig); -jobject Java_lab_galaxy_yahfa_HookMain_findMethodNative(JNIEnv *env, jclass clazz, - jclass targetClass, jstring methodName, - jstring methodSig); + jboolean backupAndHookNative(JNIEnv *env, jclass clazz, + jobject target, jobject hook, + jobject backup); -jboolean Java_lab_galaxy_yahfa_HookMain_backupAndHookNative(JNIEnv *env, jclass clazz, - jobject target, jobject hook, - jobject backup); - -void setNonCompilable(void *method); - -void *getArtMethodYahfa(JNIEnv *env, jobject jmethod); - -#ifdef __cplusplus + void *getArtMethod(JNIEnv *env, jobject jmethod); } -#endif #endif // HOOK_MAIN_H diff --git a/core/src/main/cpp/external/yahfa/src/HookMain.cpp b/core/src/main/cpp/external/yahfa/src/HookMain.cpp index 65aeec29..20add2bd 100644 --- a/core/src/main/cpp/external/yahfa/src/HookMain.cpp +++ b/core/src/main/cpp/external/yahfa/src/HookMain.cpp @@ -8,255 +8,201 @@ #include "HookMain.h" int SDKVersion; -static size_t OFFSET_entry_point_from_interpreter_in_ArtMethod; size_t OFFSET_entry_point_from_quick_compiled_code_in_ArtMethod; -static size_t OFFSET_ArtMehod_in_Object; -static size_t OFFSET_access_flags_in_ArtMethod; -static size_t ArtMethodSize; -static uint32_t kAccCompileDontBother = 0x01000000; -static uint32_t kAccPublic = 0x0001; // class, field, method, ic -static uint32_t kAccPrivate = 0x0002; // field, method, ic -static uint32_t kAccProtected = 0x0004; // field, method, ic -static uint32_t kAccStatic = 0x0008; // field, method, ic -static uint32_t kAccFastInterpreterToInterpreterInvoke = 0x40000000; +namespace { + size_t ArtMethodSize; + constexpr size_t OFFSET_access_flags_in_ArtMethod = 4; + constexpr uint32_t kAccCompileDontBother = 0x02000000; + constexpr uint32_t kAccPreCompiled = 0x00100000 | 0x00200000; + constexpr uint32_t kAccPublic = 0x0001; // class, field, method, ic + constexpr uint32_t kAccPrivate = 0x0002; // field, method, ic + constexpr uint32_t kAccProtected = 0x0004; // field, method, ic + constexpr uint32_t kAccStatic = 0x0008; // field, method, ic + constexpr uint32_t kAccFastInterpreterToInterpreterInvoke = 0x40000000; + jfieldID fieldArtMethod = nullptr; -static jfieldID fieldArtMethod = nullptr; - -static inline uint32_t read32(void *addr) { - return *((uint32_t *) addr); -} - -static inline void write32(void *addr, uint32_t value) { - *((uint32_t *) addr) = value; -} - -static inline void *readAddr(void *addr) { - return *((void **) addr); -} - -static inline void writeAddr(void *addr, void *value) { - *((void **) addr) = value; -} - -extern "C" void Java_lab_galaxy_yahfa_HookMain_init(JNIEnv *env, jclass clazz, jint sdkVersion) { - SDKVersion = sdkVersion; - jclass classExecutable; - LOGI("init to SDK %d", sdkVersion); - switch (sdkVersion) { - case __ANDROID_API_S__: - classExecutable = env->FindClass("java/lang/reflect/Executable"); - fieldArtMethod = env->GetFieldID(classExecutable, "artMethod", "J"); - kAccCompileDontBother = 0x02000000; - OFFSET_ArtMehod_in_Object = 0; - OFFSET_access_flags_in_ArtMethod = 4; - OFFSET_entry_point_from_quick_compiled_code_in_ArtMethod = - roundUpToPtrSize(4 * 3 + 2 * 2) + pointer_size; - ArtMethodSize = roundUpToPtrSize(4 * 3 + 2 * 2) + pointer_size * 2; - break; - case __ANDROID_API_R__: - classExecutable = env->FindClass("java/lang/reflect/Executable"); - fieldArtMethod = env->GetFieldID(classExecutable, "artMethod", "J"); - case __ANDROID_API_Q__: - case __ANDROID_API_P__: - kAccCompileDontBother = 0x02000000; - OFFSET_ArtMehod_in_Object = 0; - OFFSET_access_flags_in_ArtMethod = 4; - OFFSET_entry_point_from_quick_compiled_code_in_ArtMethod = - roundUpToPtrSize(4 * 4 + 2 * 2) + pointer_size; - ArtMethodSize = roundUpToPtrSize(4 * 4 + 2 * 2) + pointer_size * 2; - break; - case __ANDROID_API_O_MR1__: - kAccCompileDontBother = 0x02000000; - case __ANDROID_API_O__: - OFFSET_ArtMehod_in_Object = 0; - OFFSET_access_flags_in_ArtMethod = 4; - OFFSET_entry_point_from_quick_compiled_code_in_ArtMethod = - roundUpToPtrSize(4 * 4 + 2 * 2) + pointer_size * 2; - ArtMethodSize = roundUpToPtrSize(4 * 4 + 2 * 2) + pointer_size * 3; - break; - case __ANDROID_API_N_MR1__: - case __ANDROID_API_N__: - OFFSET_ArtMehod_in_Object = 0; - OFFSET_access_flags_in_ArtMethod = 4; // sizeof(GcRoot) = 4 - // ptr_sized_fields_ is rounded up to pointer_size in ArtMethod - OFFSET_entry_point_from_quick_compiled_code_in_ArtMethod = - roundUpToPtrSize(4 * 4 + 2 * 2) + pointer_size * 3; - - ArtMethodSize = roundUpToPtrSize(4 * 4 + 2 * 2) + pointer_size * 4; - break; - case __ANDROID_API_M__: - OFFSET_ArtMehod_in_Object = 0; - OFFSET_entry_point_from_interpreter_in_ArtMethod = roundUpToPtrSize(4 * 7); - OFFSET_entry_point_from_quick_compiled_code_in_ArtMethod = - OFFSET_entry_point_from_interpreter_in_ArtMethod + pointer_size * 2; - ArtMethodSize = roundUpToPtrSize(4 * 7) + pointer_size * 3; - break; - case __ANDROID_API_L_MR1__: - OFFSET_ArtMehod_in_Object = 4 * 2; - OFFSET_entry_point_from_interpreter_in_ArtMethod = roundUpToPtrSize( - OFFSET_ArtMehod_in_Object + 4 * 7); - OFFSET_entry_point_from_quick_compiled_code_in_ArtMethod = - OFFSET_entry_point_from_interpreter_in_ArtMethod + pointer_size * 2; - ArtMethodSize = OFFSET_entry_point_from_interpreter_in_ArtMethod + pointer_size * 3; - break; - case __ANDROID_API_L__: - OFFSET_ArtMehod_in_Object = 4 * 2; - OFFSET_entry_point_from_interpreter_in_ArtMethod = OFFSET_ArtMehod_in_Object + 4 * 4; - OFFSET_entry_point_from_quick_compiled_code_in_ArtMethod = - OFFSET_entry_point_from_interpreter_in_ArtMethod + 8 * 2; - ArtMethodSize = OFFSET_ArtMehod_in_Object + 4 * 4 + 8 * 4 + 4 * 4; - break; - default: - LOGE("not compatible with SDK %d", sdkVersion); - break; + constexpr inline uint32_t read32(void *addr) { + return *((uint32_t *) addr); } - setupTrampoline(); -} - -void setNonCompilable(void *method) { - if (SDKVersion < __ANDROID_API_N__) { - return; + constexpr inline void write32(void *addr, uint32_t value) { + *((uint32_t *) addr) = value; } - uint32_t access_flags = read32((char *) method + OFFSET_access_flags_in_ArtMethod); - LOGI("setNonCompilable: access flags is 0x%x", access_flags); - access_flags |= kAccCompileDontBother; - write32((char *) method + OFFSET_access_flags_in_ArtMethod, access_flags); -} -void setPrivate(void *method) { - uint32_t access_flags = read32((char *) method + OFFSET_access_flags_in_ArtMethod); - if (!(access_flags & kAccStatic)) { - LOGI("setPrivate: access flags is 0x%x", access_flags); - access_flags |= kAccPrivate; - access_flags &= ~kAccProtected; - access_flags &= ~kAccPublic; + constexpr inline void *readAddr(void *addr) { + return *((void **) addr); + } + + constexpr inline void writeAddr(void *addr, void *value) { + *((void **) addr) = value; + } + + void setNonCompilable(void *method) { + if (SDKVersion < __ANDROID_API_N__) { + return; + } + uint32_t access_flags = read32((char *) method + OFFSET_access_flags_in_ArtMethod); + LOGI("setNonCompilable: access flags is 0x%x", access_flags); + access_flags |= kAccCompileDontBother; + access_flags &= ~kAccPreCompiled; write32((char *) method + OFFSET_access_flags_in_ArtMethod, access_flags); } -} -static int doBackupAndHook(JNIEnv *env, void *targetMethod, void *hookMethod, void *backupMethod) { - if (hookCount >= hookCap) { - LOGI("not enough capacity. Allocating..."); - if (doInitHookCap(DEFAULT_CAP)) { - LOGE("cannot hook method"); + void setPrivate(void *method) { + uint32_t access_flags = read32((char *) method + OFFSET_access_flags_in_ArtMethod); + if (!(access_flags & kAccStatic)) { + LOGI("setPrivate: access flags is 0x%x", access_flags); + access_flags |= kAccPrivate; + access_flags &= ~kAccProtected; + access_flags &= ~kAccPublic; + write32((char *) method + OFFSET_access_flags_in_ArtMethod, access_flags); + } + } + + int doBackupAndHook(void *targetMethod, void *hookMethod, void *backupMethod) { + if (hookCount >= hookCap) { + LOGI("not enough capacity. Allocating..."); + if (doInitHookCap(DEFAULT_CAP)) { + LOGE("cannot hook method"); + return 1; + } + LOGI("Allocating done"); + } + + LOGI("target method is at %p, hook method is at %p, backup method is at %p", + targetMethod, hookMethod, backupMethod); + + + // set kAccCompileDontBother for a method we do not want the compiler to compile + // so that we don't need to worry about hotness_count_ + if (SDKVersion >= __ANDROID_API_N__) { + setNonCompilable(targetMethod); + setNonCompilable(hookMethod); + } + + if (backupMethod) {// do method backup + // have to copy the whole target ArtMethod here + // if the target method calls other methods which are to be resolved + // then ToDexPC would be invoked for the caller(origin method) + // in which case ToDexPC would use the entrypoint as a base for mapping pc to dex offset + // so any changes to the target method's entrypoint would result in a wrong dex offset + // and artQuickResolutionTrampoline would fail for methods called by the origin method + memcpy(backupMethod, targetMethod, ArtMethodSize); + setPrivate(backupMethod); + } + + // replace entry point + void *newEntrypoint = genTrampoline(hookMethod); + LOGI("origin ep is %p, new ep is %p", + readAddr((char *) targetMethod + OFFSET_entry_point_from_quick_compiled_code_in_ArtMethod), + newEntrypoint + ); + if (newEntrypoint) { + writeAddr((char *) targetMethod + OFFSET_entry_point_from_quick_compiled_code_in_ArtMethod, + newEntrypoint); + } else { + LOGE("failed to allocate space for trampoline of target method"); return 1; } - LOGI("Allocating done"); + + if (SDKVersion >= __ANDROID_API_Q__) { + uint32_t access_flags = read32((char *) targetMethod + OFFSET_access_flags_in_ArtMethod); + // On API 29 whether to use the fast path or not is cached in the ART method structure + access_flags &= ~kAccFastInterpreterToInterpreterInvoke; + write32((char *) targetMethod + OFFSET_access_flags_in_ArtMethod, access_flags); + } + + LOGI("hook and backup done"); + hookCount += 1; + return 0; } - LOGI("target method is at %p, hook method is at %p, backup method is at %p", - targetMethod, hookMethod, backupMethod); - - - // set kAccCompileDontBother for a method we do not want the compiler to compile - // so that we don't need to worry about hotness_count_ - if (SDKVersion >= __ANDROID_API_N__) { - setNonCompilable(targetMethod); - setNonCompilable(hookMethod); - } - - if (backupMethod) {// do method backup - // have to copy the whole target ArtMethod here - // if the target method calls other methods which are to be resolved - // then ToDexPC would be invoked for the caller(origin method) - // in which case ToDexPC would use the entrypoint as a base for mapping pc to dex offset - // so any changes to the target method's entrypoint would result in a wrong dex offset - // and artQuickResolutionTrampoline would fail for methods called by the origin method - memcpy(backupMethod, targetMethod, ArtMethodSize); - setPrivate(backupMethod); - } - - // replace entry point - void *newEntrypoint = genTrampoline(hookMethod); - LOGI("origin ep is %p, new ep is %p", - readAddr((char *) targetMethod + OFFSET_entry_point_from_quick_compiled_code_in_ArtMethod), - newEntrypoint - ); - if (newEntrypoint) { - writeAddr((char *) targetMethod + OFFSET_entry_point_from_quick_compiled_code_in_ArtMethod, - newEntrypoint); - } else { - LOGE("failed to allocate space for trampoline of target method"); - return 1; - } - - if (OFFSET_entry_point_from_interpreter_in_ArtMethod != 0) { - writeAddr((char *) targetMethod + OFFSET_entry_point_from_interpreter_in_ArtMethod, - readAddr((char *) hookMethod + OFFSET_entry_point_from_interpreter_in_ArtMethod)); - - } - - if (SDKVersion >= __ANDROID_API_Q__) { - uint32_t access_flags = read32((char *) targetMethod + OFFSET_access_flags_in_ArtMethod); - // On API 29 whether to use the fast path or not is cached in the ART method structure - access_flags &= ~kAccFastInterpreterToInterpreterInvoke; - write32((char *) targetMethod + OFFSET_access_flags_in_ArtMethod, access_flags); - } - - LOGI("hook and backup done"); - hookCount += 1; - return 0; } -void *getArtMethodYahfa(JNIEnv *env, jobject jmethod) { - void *artMethod = nullptr; +namespace yahfa { - if (jmethod == nullptr) { - return artMethod; + void init(JNIEnv *env, [[maybe_unused]] jclass clazz, jint sdkVersion) { + SDKVersion = sdkVersion; + jclass classExecutable = env->FindClass("java/lang/reflect/Executable"); + fieldArtMethod = env->GetFieldID(classExecutable, "artMethod", "J"); + LOGI("init to SDK %d", sdkVersion); + switch (sdkVersion) { + case __ANDROID_API_S__: + OFFSET_entry_point_from_quick_compiled_code_in_ArtMethod = + roundUpToPtrSize(4 * 3 + 2 * 2) + pointer_size; + ArtMethodSize = roundUpToPtrSize(4 * 3 + 2 * 2) + pointer_size * 2; + break; + case __ANDROID_API_R__: + case __ANDROID_API_Q__: + case __ANDROID_API_P__: + OFFSET_entry_point_from_quick_compiled_code_in_ArtMethod = + roundUpToPtrSize(4 * 4 + 2 * 2) + pointer_size; + ArtMethodSize = roundUpToPtrSize(4 * 4 + 2 * 2) + pointer_size * 2; + break; + case __ANDROID_API_O_MR1__: + case __ANDROID_API_O__: + OFFSET_entry_point_from_quick_compiled_code_in_ArtMethod = + roundUpToPtrSize(4 * 4 + 2 * 2) + pointer_size * 2; + ArtMethodSize = roundUpToPtrSize(4 * 4 + 2 * 2) + pointer_size * 3; + break; + default: + LOGE("not compatible with SDK %d", sdkVersion); + break; + } + + setupTrampoline(); } - if (SDKVersion >= __ANDROID_API_R__) { - artMethod = (void *) env->GetLongField(jmethod, fieldArtMethod); - } else { - artMethod = (void *) env->FromReflectedMethod(jmethod); - } - - LOGI("ArtMethod: %p", artMethod); - return artMethod; -} - -extern "C" jobject Java_lab_galaxy_yahfa_HookMain_findMethodNative(JNIEnv *env, jclass clazz, - jclass targetClass, jstring methodName, - jstring methodSig) { - const char *c_methodName = env->GetStringUTFChars(methodName, nullptr); - const char *c_methodSig = env->GetStringUTFChars(methodSig, nullptr); - jobject ret = nullptr; - - - //Try both GetMethodID and GetStaticMethodID -- Whatever works :) - jmethodID method = env->GetMethodID(targetClass, c_methodName, c_methodSig); - if (!env->ExceptionCheck()) { - ret = env->ToReflectedMethod(targetClass, method, JNI_FALSE); - } else { - env->ExceptionClear(); - method = env->GetStaticMethodID(targetClass, c_methodName, c_methodSig); - if (!env->ExceptionCheck()) { - ret = env->ToReflectedMethod(targetClass, method, JNI_TRUE); + void *getArtMethod(JNIEnv *env, jobject jmethod) { + if (jmethod == nullptr) { + return nullptr; } else { - env->ExceptionClear(); + return (void *) env->GetLongField(jmethod, fieldArtMethod); } } - env->ReleaseStringUTFChars(methodName, c_methodName); - env->ReleaseStringUTFChars(methodSig, c_methodSig); - return ret; -} + jobject findMethodNative(JNIEnv *env, [[maybe_unused]] jclass clazz, + jclass targetClass, + jstring methodName, + jstring methodSig) { + const char *c_methodName = env->GetStringUTFChars(methodName, nullptr); + const char *c_methodSig = env->GetStringUTFChars(methodSig, nullptr); + jobject ret = nullptr; -extern "C" jboolean Java_lab_galaxy_yahfa_HookMain_backupAndHookNative(JNIEnv *env, jclass clazz, - jobject target, jobject hook, - jobject backup) { - if (!doBackupAndHook(env, - getArtMethodYahfa(env, target), - getArtMethodYahfa(env, hook), - getArtMethodYahfa(env, backup) - )) { - env->NewGlobalRef(hook); // keep a global ref so that the hook method would not be GCed - if (backup) env->NewGlobalRef(backup); - return JNI_TRUE; - } else { - return JNI_FALSE; + //Try both GetMethodID and GetStaticMethodID -- Whatever works :) + jmethodID method = env->GetMethodID(targetClass, c_methodName, c_methodSig); + if (!env->ExceptionCheck()) { + ret = env->ToReflectedMethod(targetClass, method, JNI_FALSE); + } else { + env->ExceptionClear(); + method = env->GetStaticMethodID(targetClass, c_methodName, c_methodSig); + if (!env->ExceptionCheck()) { + ret = env->ToReflectedMethod(targetClass, method, JNI_TRUE); + } else { + env->ExceptionClear(); + } + } + + env->ReleaseStringUTFChars(methodName, c_methodName); + env->ReleaseStringUTFChars(methodSig, c_methodSig); + return ret; + } + + jboolean backupAndHookNative(JNIEnv *env, [[maybe_unused]] jclass clazz, + jobject target, jobject hook, + jobject backup) { + + if (!doBackupAndHook(getArtMethod(env, target), + getArtMethod(env, hook), + getArtMethod(env, backup) + )) { + env->NewGlobalRef(hook); // keep a global ref so that the hook method would not be GCed + if (backup) env->NewGlobalRef(backup); + return JNI_TRUE; + } else { + return JNI_FALSE; + } } } diff --git a/core/src/main/cpp/main/src/jni/art_class_linker.cpp b/core/src/main/cpp/main/src/jni/art_class_linker.cpp index a5536495..af72280a 100644 --- a/core/src/main/cpp/main/src/jni/art_class_linker.cpp +++ b/core/src/main/cpp/main/src/jni/art_class_linker.cpp @@ -31,7 +31,7 @@ namespace lspd { static std::unordered_set deopted_methods; LSP_DEF_NATIVE_METHOD(void, ClassLinker, setEntryPointsToInterpreter, jobject method) { - void *reflected_method = getArtMethodYahfa(env, method); + void *reflected_method = yahfa::getArtMethod(env, method); if (deopted_methods.contains(reflected_method)) { LOGD("method %p has been deopted before, skip...", reflected_method); return; diff --git a/core/src/main/cpp/main/src/jni/pending_hooks.cpp b/core/src/main/cpp/main/src/jni/pending_hooks.cpp index f6134669..3802e339 100644 --- a/core/src/main/cpp/main/src/jni/pending_hooks.cpp +++ b/core/src/main/cpp/main/src/jni/pending_hooks.cpp @@ -65,7 +65,7 @@ namespace lspd { LSP_DEF_NATIVE_METHOD(void, PendingHooks, recordPendingMethodNative, jobject method_ref, jclass class_ref){ auto *class_ptr = art::Thread::Current().DecodeJObject(class_ref); - auto *method = getArtMethodYahfa(env, method_ref); + auto *method = yahfa::getArtMethod(env, method_ref); art::mirror::Class mirror_class(class_ptr); if (auto def = mirror_class.GetClassDef(); LIKELY(def)) { LOGD("record pending: %p (%s) with %p", class_ptr, mirror_class.GetDescriptor().c_str(), diff --git a/core/src/main/cpp/main/src/jni/yahfa.cpp b/core/src/main/cpp/main/src/jni/yahfa.cpp index 74f923b7..36f352f4 100644 --- a/core/src/main/cpp/main/src/jni/yahfa.cpp +++ b/core/src/main/cpp/main/src/jni/yahfa.cpp @@ -32,13 +32,13 @@ namespace lspd { using namespace startop::dex; LSP_DEF_NATIVE_METHOD(void, Yahfa, init, jint sdkVersion) { - Java_lab_galaxy_yahfa_HookMain_init(env, clazz, sdkVersion); + yahfa::init(env, clazz, sdkVersion); } LSP_DEF_NATIVE_METHOD(jobject, Yahfa, findMethodNative, jclass targetClass, jstring methodName, jstring methodSig) { - return Java_lab_galaxy_yahfa_HookMain_findMethodNative(env, clazz, targetClass, methodName, - methodSig); + return yahfa::findMethodNative(env, clazz, targetClass, methodName, + methodSig); } LSP_DEF_NATIVE_METHOD(jboolean, Yahfa, backupAndHookNative, jobject target, @@ -47,21 +47,23 @@ namespace lspd { art::gc::kGcCauseDebugger, art::gc::kCollectorTypeDebugger); art::thread_list::ScopedSuspendAll suspend("Yahfa Hook", false); - return Java_lab_galaxy_yahfa_HookMain_backupAndHookNative(env, clazz, target, hook, backup); + return yahfa::backupAndHookNative(env, clazz, target, hook, backup); } LSP_DEF_NATIVE_METHOD(void, Yahfa, recordHooked, jobject member) { - lspd::recordHooked(getArtMethodYahfa(env, member)); + lspd::recordHooked(yahfa::getArtMethod(env, member)); } LSP_DEF_NATIVE_METHOD(jboolean, Yahfa, isHooked, jobject member) { - return lspd::isHooked(getArtMethodYahfa(env, member)); + return lspd::isHooked(yahfa::getArtMethod(env, member)); } - LSP_DEF_NATIVE_METHOD(jclass, Yahfa, buildHooker, jobject app_class_loader, jclass return_class, jobjectArray classes, jstring method_name) { - static auto in_memory_classloader = (jclass)env->NewGlobalRef(env->FindClass( "dalvik/system/InMemoryDexClassLoader")); + LSP_DEF_NATIVE_METHOD(jclass, Yahfa, buildHooker, jobject app_class_loader, jclass return_class, + jobjectArray classes, jstring method_name) { + static auto in_memory_classloader = (jclass) env->NewGlobalRef( + env->FindClass("dalvik/system/InMemoryDexClassLoader")); static jmethodID initMid = JNI_GetMethodID(env, in_memory_classloader, "", - "(Ljava/nio/ByteBuffer;Ljava/lang/ClassLoader;)V"); + "(Ljava/nio/ByteBuffer;Ljava/lang/ClassLoader;)V"); DexBuilder dex_file; auto parameter_length = env->GetArrayLength(classes); @@ -69,7 +71,9 @@ namespace lspd { parameter_types.reserve(parameter_length); std::string storage; auto current_thread = art::Thread::Current(); - auto return_type = TypeDescriptor::FromDescriptor(art::mirror::Class(current_thread.DecodeJObject(return_class)).GetDescriptor(&storage)); + auto return_type = TypeDescriptor::FromDescriptor( + art::mirror::Class(current_thread.DecodeJObject(return_class)).GetDescriptor( + &storage)); for (int i = 0; i < parameter_length; ++i) { auto param = (jclass) env->GetObjectArrayElement(classes, i); auto *param_ref = current_thread.DecodeJObject(param); @@ -153,14 +157,15 @@ namespace lspd { slicer::MemView image{dex_file.CreateImage()}; - auto dex_buffer = env->NewDirectByteBuffer(const_cast(image.ptr()), image.size()); + auto dex_buffer = env->NewDirectByteBuffer(const_cast(image.ptr()), image.size()); jobject my_cl = JNI_NewObject(env, in_memory_classloader, initMid, dex_buffer, app_class_loader); static jmethodID mid = JNI_GetMethodID(env, in_memory_classloader, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;"); if (!mid) { - mid = JNI_GetMethodID(env, in_memory_classloader, "findClass", "(Ljava/lang/String;)Ljava/lang/Class;"); + mid = JNI_GetMethodID(env, in_memory_classloader, "findClass", + "(Ljava/lang/String;)Ljava/lang/Class;"); } jobject target = env->CallObjectMethod(my_cl, mid, env->NewStringUTF("LspHooker_")); // LOGD("Created %zd", image.size()); @@ -178,7 +183,8 @@ namespace lspd { "(Ljava/lang/reflect/Executable;Ljava/lang/reflect/Method;Ljava/lang/reflect/Method;)Z"), LSP_NATIVE_METHOD(Yahfa, recordHooked, "(Ljava/lang/reflect/Executable;)V"), LSP_NATIVE_METHOD(Yahfa, isHooked, "(Ljava/lang/reflect/Executable;)Z"), - LSP_NATIVE_METHOD(Yahfa, buildHooker, "(Ljava/lang/ClassLoader;Ljava/lang/Class;[Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Class;"), + LSP_NATIVE_METHOD(Yahfa, buildHooker, + "(Ljava/lang/ClassLoader;Ljava/lang/Class;[Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Class;"), }; void RegisterYahfa(JNIEnv *env) {