fix GetOatQuickMethodHeader

This commit is contained in:
LoveSy 2020-12-21 02:29:08 +08:00 committed by kotori0
parent 4726fab4b5
commit f93af7cbc9
2 changed files with 11 additions and 26 deletions

View File

@ -126,24 +126,20 @@ 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; 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[toMethod] = originEntrypoint;
} }
else { else {
// entry point from ArtMethod struct // entry point from ArtMethod struct
newEntrypoint = genTrampoline(toMethod, nullptr); newEntrypoint = genTrampoline(toMethod, nullptr);
} }
replaced_entrypoint[fromMethod] = readAddr(fromEntrypoint);
LOGI("replace entry point from %p to %p", LOGI("replace entry point from %p to %p", readAddr(fromEntrypoint), newEntrypoint);
readAddr(fromEntrypoint),
newEntrypoint
);
if (newEntrypoint) { if (newEntrypoint) {
writeAddr(fromEntrypoint, writeAddr(fromEntrypoint, newEntrypoint);
newEntrypoint);
} else { } else {
LOGE("failed to allocate space for trampoline of target method"); LOGE("failed to allocate space for trampoline of target method");
return 1; return 1;
@ -152,8 +148,7 @@ static int replaceMethod(void *fromMethod, void *toMethod, int isBackup) {
// For pre Android M devices, should be not used by EdXposed. // For pre Android M devices, should be not used by EdXposed.
if (OFFSET_entry_point_from_interpreter_in_ArtMethod != 0) { if (OFFSET_entry_point_from_interpreter_in_ArtMethod != 0) {
void *interpEntrypoint = readAddr((char *) toMethod + OFFSET_entry_point_from_interpreter_in_ArtMethod); void *interpEntrypoint = readAddr((char *) toMethod + OFFSET_entry_point_from_interpreter_in_ArtMethod);
writeAddr(fromEntrypoint, writeAddr(fromEntrypoint, interpEntrypoint);
interpEntrypoint);
} }
return 0; return 0;

View File

@ -26,26 +26,17 @@ namespace art {
return PrettyMethod(thiz, true); return PrettyMethod(thiz, true);
} }
CREATE_HOOK_STUB_ENTRIES(uint32_t, ToDexPc, void** frame, const uintptr_t pc, bool abort_on_failure) {
void* method = *frame;
if (UNLIKELY(edxp::isHooked(method))) {
LOGD("art_method::ToDexPc: Method %p is hooked, return kDexNoIndex", method);
return 0xFFFFFFFF; // kDexNoIndex
}
return ToDexPcBackup(frame, pc, abort_on_failure);
}
CREATE_HOOK_STUB_ENTRIES(void *, GetOatQuickMethodHeader, void *thiz, uintptr_t pc) { CREATE_HOOK_STUB_ENTRIES(void *, GetOatQuickMethodHeader, void *thiz, uintptr_t pc) {
// 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 (UNLIKELY(edxp::isHooked(thiz))) { if (UNLIKELY(edxp::isHooked(thiz))) {
uintptr_t original_ep = reinterpret_cast<uintptr_t>( uintptr_t original_ep = reinterpret_cast<uintptr_t>(getOriginalEntryPointFromTargetMethod(
getOriginalEntryPointFromTargetMethod(thiz)); thiz)) & ~0x1;
if (original_ep) { if (original_ep) {
char *code_length_loc = char *code_length_loc =
reinterpret_cast<char *>(original_ep) + oat_header_code_length_offset; reinterpret_cast<char *>(original_ep) + oat_header_code_length_offset;
uint32_t code_length = uint32_t code_length =
*reinterpret_cast<uint32_t *>(code_length_loc) & ~0x80000000; *reinterpret_cast<uint32_t *>(code_length_loc) & ~0x80000000u;
LOGD("art_method::GetOatQuickMethodHeader: ArtMethod=%p (%s), isHooked=true, original_ep=0x%x, code_length=0x%x, pc=0x%x", LOGD("art_method::GetOatQuickMethodHeader: ArtMethod=%p (%s), isHooked=true, original_ep=0x%zux, code_length=0x%x, pc=0x%zux",
thiz, PrettyMethod(thiz).c_str(), original_ep, code_length, pc); thiz, PrettyMethod(thiz).c_str(), original_ep, code_length, pc);
if (original_ep <= pc && pc <= original_ep + code_length) if (original_ep <= pc && pc <= original_ep + code_length)
return reinterpret_cast<void *>(original_ep - oat_header_length); return reinterpret_cast<void *>(original_ep - oat_header_length);
@ -53,8 +44,8 @@ namespace art {
LOGD("art_method::GetOatQuickMethodHeader: PC not found in current method."); LOGD("art_method::GetOatQuickMethodHeader: PC not found in current method.");
return nullptr; return nullptr;
} else { } else {
LOGD("art_method::GetOatQuickMethodHeader: ArtMethod=%p (%s), isHooked=true, pc=0x%x, isHooked but not backup, fallback to system", LOGD("art_method::GetOatQuickMethodHeader: ArtMethod=%p (%s) isHooked but not backup, fallback to system",
thiz, PrettyMethod(thiz).c_str(), pc); thiz, PrettyMethod(thiz).c_str());
} }
} }
return GetOatQuickMethodHeaderBackup(thiz, pc); return GetOatQuickMethodHeaderBackup(thiz, pc);
@ -90,7 +81,6 @@ namespace art {
} }
RETRIEVE_FUNC_SYMBOL(PrettyMethod, "_ZN3art9ArtMethod12PrettyMethodEb"); RETRIEVE_FUNC_SYMBOL(PrettyMethod, "_ZN3art9ArtMethod12PrettyMethodEb");
HOOK_FUNC(ToDexPc, "_ZNK3art20OatQuickMethodHeader7ToDexPcEPPNS_9ArtMethodEjb");
} }
} }
} }