Properly handle GetOatQuickMethodHeader

This commit is contained in:
kotori0 2020-12-20 00:55:56 +08:00
parent c22e8a60fc
commit 5f3dc9220d
2 changed files with 16 additions and 14 deletions

View File

@ -125,19 +125,18 @@ void *getEntryPoint(void* method) {
static int replaceMethod(void *fromMethod, void *toMethod, int isBackup) { static int replaceMethod(void *fromMethod, void *toMethod, int isBackup) {
// replace entry point // replace entry point
void *newEntrypoint = nullptr; void *newEntrypoint = nullptr;
void* fromEntrypoint = (char *) fromMethod + OFFSET_entry_point_from_quick_compiled_code_in_ArtMethod;
if(isBackup) { if(isBackup) {
void *originEntrypoint = readAddr((char *) toMethod + OFFSET_entry_point_from_quick_compiled_code_in_ArtMethod); void *originEntrypoint = readAddr((char *) toMethod + OFFSET_entry_point_from_quick_compiled_code_in_ArtMethod);
// entry point hardcoded // entry point hardcoded
newEntrypoint = genTrampoline(toMethod, originEntrypoint); newEntrypoint = genTrampoline(toMethod, originEntrypoint);
replaced_entrypoint[fromMethod] = newEntrypoint;
} }
else { else {
// entry point from ArtMethod struct // entry point from ArtMethod struct
newEntrypoint = genTrampoline(toMethod, nullptr); 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", LOGI("replace entry point from %p to %p",
readAddr(fromEntrypoint), readAddr(fromEntrypoint),
newEntrypoint newEntrypoint

View File

@ -16,19 +16,22 @@ namespace art {
inline static size_t oat_header_length; inline static size_t oat_header_length;
inline static int32_t oat_header_code_length_offset; inline static int32_t oat_header_code_length_offset;
CREATE_HOOK_STUB_ENTRIES(void *, GetOatQuickMethodHeader, void *thiz, uintptr_t pc) { 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. // This is a partial copy from AOSP. We only touch them if they are hooked.
if (LIKELY(edxp::isHooked(thiz))) { if (LIKELY(edxp::isHooked(thiz))) {
LOGD("GetOatQuickMethodHeader: isHooked=true, thiz=%p", thiz); uintptr_t original_ep = reinterpret_cast<uintptr_t>(getOriginalEntryPointFromTargetMethod(thiz));
char* thiz_ = static_cast<char *>(thiz); if(original_ep) {
char* code_length_loc = thiz_ + oat_header_code_length_offset; char* code_length_loc = reinterpret_cast<char *>(original_ep) + oat_header_code_length_offset;
uint32_t code_length = *reinterpret_cast<uint32_t *>(code_length_loc); uint32_t code_length = *reinterpret_cast<uint32_t *>(code_length_loc) & ~0x80000000;
uintptr_t original_ep = reinterpret_cast<uintptr_t>( LOGD("GetOatQuickMethodHeader: isHooked=true, original_ep=0x%x, code_length=0x%x, pc=0x%x", original_ep, code_length, pc);
getOriginalEntryPointFromTargetMethod(thiz)); if (original_ep <= pc && pc <= original_ep + code_length)
if (original_ep <= pc <= original_ep + code_length) return thiz_ - oat_header_length; return reinterpret_cast<void *>(original_ep - oat_header_length);
// If PC is not in range, we mark it as not found. // If PC is not in range, we mark it as not found.
LOGD("GetOatQuickMethodHeader: PC not found in current method."); LOGD("GetOatQuickMethodHeader: PC not found in current method.");
return nullptr; return nullptr;
} else {
LOGD("GetOatQuickMethodHeader: isHooked but not backup, fallback to system");
}
} }
return GetOatQuickMethodHeaderBackup(thiz, pc); return GetOatQuickMethodHeaderBackup(thiz, pc);
} }