2022-02-16 07:24:35 +08:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include "art/mirror/class.hpp"
|
2022-02-19 03:47:26 +08:00
|
|
|
#include "art/runtime/art_method.hpp"
|
2022-02-16 07:24:35 +08:00
|
|
|
#include "art/thread.hpp"
|
|
|
|
#include "common.hpp"
|
|
|
|
|
|
|
|
namespace lsplant::art {
|
|
|
|
class ClassLinker {
|
|
|
|
private:
|
2022-02-19 03:47:26 +08:00
|
|
|
CREATE_MEM_FUNC_SYMBOL_ENTRY(void, SetEntryPointsToInterpreter, ClassLinker *thiz,
|
|
|
|
ArtMethod *art_method) {
|
2022-02-16 07:24:35 +08:00
|
|
|
if (SetEntryPointsToInterpreterSym) [[likely]] {
|
|
|
|
SetEntryPointsToInterpreterSym(thiz, art_method);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
CREATE_HOOK_STUB_ENTRY(
|
2022-02-19 03:47:26 +08:00
|
|
|
"_ZN3art11ClassLinker30ShouldUseInterpreterEntrypointEPNS_9ArtMethodEPKv", bool,
|
|
|
|
ShouldUseInterpreterEntrypoint, (ArtMethod * art_method, const void *quick_code), {
|
2022-03-12 02:04:58 +08:00
|
|
|
if (quick_code != nullptr && IsHooked(art_method)) [[unlikely]] {
|
2022-02-19 03:47:26 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return backup(art_method, quick_code);
|
|
|
|
});
|
2022-02-16 07:24:35 +08:00
|
|
|
|
2022-02-19 03:47:26 +08:00
|
|
|
CREATE_FUNC_SYMBOL_ENTRY(void, art_quick_to_interpreter_bridge, void *) {}
|
2022-02-16 07:24:35 +08:00
|
|
|
|
2022-02-19 03:47:26 +08:00
|
|
|
CREATE_FUNC_SYMBOL_ENTRY(void, art_quick_generic_jni_trampoline, void *) {}
|
2022-02-16 07:24:35 +08:00
|
|
|
|
2022-02-19 03:47:26 +08:00
|
|
|
CREATE_HOOK_STUB_ENTRY("_ZN3art11interpreter29ShouldStayInSwitchInterpreterEPNS_9ArtMethodE",
|
|
|
|
bool, ShouldStayInSwitchInterpreter, (ArtMethod * art_method), {
|
2022-03-12 02:04:58 +08:00
|
|
|
if (IsHooked(art_method)) [[unlikely]] {
|
2022-02-19 03:47:26 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return backup(art_method);
|
|
|
|
});
|
2022-02-16 07:24:35 +08:00
|
|
|
|
|
|
|
public:
|
|
|
|
static bool Init(const HookHandler &handler) {
|
2022-02-22 13:54:58 +08:00
|
|
|
int sdk_int = GetAndroidApiLevel();
|
2022-02-16 07:24:35 +08:00
|
|
|
|
2022-02-22 13:54:58 +08:00
|
|
|
if (sdk_int >= __ANDROID_API_N__) {
|
|
|
|
if (!HookSyms(handler, ShouldUseInterpreterEntrypoint, ShouldStayInSwitchInterpreter))
|
|
|
|
[[unlikely]] {
|
|
|
|
return false;
|
|
|
|
}
|
2022-02-16 07:24:35 +08:00
|
|
|
}
|
|
|
|
|
2022-02-23 05:31:03 +08:00
|
|
|
if (!RETRIEVE_MEM_FUNC_SYMBOL(
|
|
|
|
SetEntryPointsToInterpreter,
|
|
|
|
"_ZNK3art11ClassLinker27SetEntryPointsToInterpreterEPNS_9ArtMethodE")) {
|
|
|
|
if (!RETRIEVE_FUNC_SYMBOL(art_quick_to_interpreter_bridge,
|
|
|
|
"art_quick_to_interpreter_bridge")) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (!RETRIEVE_FUNC_SYMBOL(art_quick_generic_jni_trampoline,
|
|
|
|
"art_quick_generic_jni_trampoline")) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
LOGD("art_quick_to_interpreter_bridge = %p", art_quick_to_interpreter_bridgeSym);
|
|
|
|
LOGD("art_quick_generic_jni_trampoline = %p", art_quick_generic_jni_trampolineSym);
|
2022-02-16 07:24:35 +08:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2022-02-19 03:47:26 +08:00
|
|
|
[[gnu::always_inline]] static bool SetEntryPointsToInterpreter(ArtMethod *art_method) {
|
2022-02-22 13:54:58 +08:00
|
|
|
if (SetEntryPointsToInterpreterSym) [[likely]] {
|
|
|
|
SetEntryPointsToInterpreter(nullptr, art_method);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
// Android 13
|
2022-02-16 07:24:35 +08:00
|
|
|
if (art_quick_to_interpreter_bridgeSym && art_quick_generic_jni_trampolineSym) [[likely]] {
|
|
|
|
if (art_method->GetAccessFlags() & ArtMethod::kAccNative) [[unlikely]] {
|
|
|
|
art_method->SetEntryPoint(
|
2022-02-19 03:47:26 +08:00
|
|
|
reinterpret_cast<void *>(art_quick_generic_jni_trampolineSym));
|
2022-02-16 07:24:35 +08:00
|
|
|
} else {
|
|
|
|
art_method->SetEntryPoint(
|
2022-02-19 03:47:26 +08:00
|
|
|
reinterpret_cast<void *>(art_quick_to_interpreter_bridgeSym));
|
2022-02-16 07:24:35 +08:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
};
|
2022-02-19 03:47:26 +08:00
|
|
|
} // namespace lsplant::art
|