From 5f3dc9220d92088a1d942de3c676f725cf18999c Mon Sep 17 00:00:00 2001 From: kotori0 Date: Sun, 20 Dec 2020 00:55:56 +0800 Subject: [PATCH] Properly handle GetOatQuickMethodHeader --- .../main/cpp/external/yahfa/src/HookMain.cpp | 5 ++-- .../cpp/main/include/art/runtime/art_method.h | 25 +++++++++++-------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/edxp-core/src/main/cpp/external/yahfa/src/HookMain.cpp b/edxp-core/src/main/cpp/external/yahfa/src/HookMain.cpp index 0a1c270f..3b1c1561 100644 --- a/edxp-core/src/main/cpp/external/yahfa/src/HookMain.cpp +++ b/edxp-core/src/main/cpp/external/yahfa/src/HookMain.cpp @@ -125,19 +125,18 @@ void *getEntryPoint(void* method) { static int replaceMethod(void *fromMethod, void *toMethod, int isBackup) { // replace entry point void *newEntrypoint = nullptr; + void* fromEntrypoint = (char *) fromMethod + OFFSET_entry_point_from_quick_compiled_code_in_ArtMethod; if(isBackup) { void *originEntrypoint = readAddr((char *) toMethod + OFFSET_entry_point_from_quick_compiled_code_in_ArtMethod); // entry point hardcoded newEntrypoint = genTrampoline(toMethod, originEntrypoint); + replaced_entrypoint[fromMethod] = newEntrypoint; } else { // entry point from ArtMethod struct newEntrypoint = genTrampoline(toMethod, nullptr); } - void* fromEntrypoint = (char *) fromMethod + OFFSET_entry_point_from_quick_compiled_code_in_ArtMethod; - replaced_entrypoint[fromMethod] = newEntrypoint; - LOGI("replace entry point from %p to %p", readAddr(fromEntrypoint), newEntrypoint diff --git a/edxp-core/src/main/cpp/main/include/art/runtime/art_method.h b/edxp-core/src/main/cpp/main/include/art/runtime/art_method.h index da39bb60..d91106bf 100644 --- a/edxp-core/src/main/cpp/main/include/art/runtime/art_method.h +++ b/edxp-core/src/main/cpp/main/include/art/runtime/art_method.h @@ -16,19 +16,22 @@ namespace art { inline static size_t oat_header_length; inline static int32_t oat_header_code_length_offset; CREATE_HOOK_STUB_ENTRIES(void *, GetOatQuickMethodHeader, void *thiz, uintptr_t pc) { - LOGD("GetOatQuickMethodHeader called"); + // LOGD("GetOatQuickMethodHeader called, thiz=%p", thiz); // This is a partial copy from AOSP. We only touch them if they are hooked. if (LIKELY(edxp::isHooked(thiz))) { - LOGD("GetOatQuickMethodHeader: isHooked=true, thiz=%p", thiz); - char* thiz_ = static_cast(thiz); - char* code_length_loc = thiz_ + oat_header_code_length_offset; - uint32_t code_length = *reinterpret_cast(code_length_loc); - uintptr_t original_ep = reinterpret_cast( - getOriginalEntryPointFromTargetMethod(thiz)); - if (original_ep <= pc <= original_ep + code_length) return thiz_ - oat_header_length; - // If PC is not in range, we mark it as not found. - LOGD("GetOatQuickMethodHeader: PC not found in current method."); - return nullptr; + uintptr_t original_ep = reinterpret_cast(getOriginalEntryPointFromTargetMethod(thiz)); + if(original_ep) { + char* code_length_loc = reinterpret_cast(original_ep) + oat_header_code_length_offset; + uint32_t code_length = *reinterpret_cast(code_length_loc) & ~0x80000000; + LOGD("GetOatQuickMethodHeader: isHooked=true, original_ep=0x%x, code_length=0x%x, pc=0x%x", original_ep, code_length, pc); + if (original_ep <= pc && pc <= original_ep + code_length) + return reinterpret_cast(original_ep - oat_header_length); + // If PC is not in range, we mark it as not found. + LOGD("GetOatQuickMethodHeader: PC not found in current method."); + return nullptr; + } else { + LOGD("GetOatQuickMethodHeader: isHooked but not backup, fallback to system"); + } } return GetOatQuickMethodHeaderBackup(thiz, pc); }