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) {
// 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

View File

@ -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<char *>(thiz);
char* code_length_loc = thiz_ + oat_header_code_length_offset;
uint32_t code_length = *reinterpret_cast<uint32_t *>(code_length_loc);
uintptr_t original_ep = reinterpret_cast<uintptr_t>(
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<uintptr_t>(getOriginalEntryPointFromTargetMethod(thiz));
if(original_ep) {
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) & ~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<void *>(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);
}