Opt mem fun & fix hook mem fun

This commit is contained in:
LoveSy 2021-01-08 17:20:07 +08:00 committed by 双草酸酯
parent f78355a189
commit 981094e06f
9 changed files with 93 additions and 78 deletions

View File

@ -14,11 +14,11 @@ namespace art {
inline static size_t oat_header_length;
inline static int32_t oat_header_code_length_offset;
CREATE_FUNC_SYMBOL_ENTRY(std::string, PrettyMethod, void *thiz, bool with_signature) {
CREATE_MEM_FUNC_SYMBOL_ENTRY(std::string, PrettyMethod, void *thiz, bool with_signature) {
if (UNLIKELY(thiz == nullptr))
return "null";
if (LIKELY(PrettyMethodSym))
return edxp::call_as_member_func(PrettyMethodSym, thiz, with_signature);
return PrettyMethodSym(thiz, with_signature);
else return "null sym";
}
@ -26,7 +26,7 @@ namespace art {
return PrettyMethod(thiz, true);
}
CREATE_HOOK_STUB_ENTRIES(void *, GetOatQuickMethodHeader, void *thiz, uintptr_t pc) {
CREATE_MEM_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.
if (UNLIKELY(edxp::isHooked(thiz))) {
uintptr_t original_ep = reinterpret_cast<uintptr_t>(getOriginalEntryPointFromTargetMethod(
@ -75,12 +75,12 @@ namespace art {
break;
}
if constexpr (edxp::is64) {
HOOK_FUNC(GetOatQuickMethodHeader, "_ZN3art9ArtMethod23GetOatQuickMethodHeaderEm");
HOOK_MEM_FUNC(GetOatQuickMethodHeader, "_ZN3art9ArtMethod23GetOatQuickMethodHeaderEm");
} else {
HOOK_FUNC(GetOatQuickMethodHeader, "_ZN3art9ArtMethod23GetOatQuickMethodHeaderEj");
HOOK_MEM_FUNC(GetOatQuickMethodHeader, "_ZN3art9ArtMethod23GetOatQuickMethodHeaderEj");
}
RETRIEVE_FUNC_SYMBOL(PrettyMethod, "_ZN3art9ArtMethod12PrettyMethodEb");
RETRIEVE_MEM_FUNC_SYMBOL(PrettyMethod, "_ZN3art9ArtMethod12PrettyMethodEb");
}
}
}

View File

@ -20,21 +20,12 @@ namespace art {
private:
inline static ClassLinker *instance_;
CREATE_FUNC_SYMBOL_ENTRY(void, SetEntryPointsToInterpreter, void *thiz, void *art_method) {
CREATE_MEM_FUNC_SYMBOL_ENTRY(void, SetEntryPointsToInterpreter, void *thiz, void *art_method) {
if (LIKELY(SetEntryPointsToInterpreterSym))
edxp::call_as_member_func(SetEntryPointsToInterpreterSym, thiz, art_method);
SetEntryPointsToInterpreterSym(thiz, art_method);
}
CREATE_HOOK_STUB_ENTRIES(void *, Constructor, void *thiz, void *intern_table) {
LOGI("ConstructorReplace called");
if (LIKELY(instance_))
instance_->Reset(thiz);
else
instance_ = new ClassLinker(thiz);
return ConstructorBackup(thiz, intern_table);
}
CREATE_HOOK_STUB_ENTRIES(void, FixupStaticTrampolines, void *thiz, void *clazz_ptr) {
CREATE_MEM_HOOK_STUB_ENTRIES(void, FixupStaticTrampolines, void *thiz, void *clazz_ptr) {
FixupStaticTrampolinesBackup(thiz, clazz_ptr);
art::mirror::Class mirror_class(clazz_ptr);
auto class_def = mirror_class.GetClassDef();
@ -46,10 +37,10 @@ namespace art {
}
}
CREATE_FUNC_SYMBOL_ENTRY(void, MakeInitializedClassesVisiblyInitialized, void *thiz,
CREATE_MEM_FUNC_SYMBOL_ENTRY(void, MakeInitializedClassesVisiblyInitialized, void *thiz,
void *self, bool wait) {
if (LIKELY(MakeInitializedClassesVisiblyInitializedSym))
edxp::call_as_member_func(MakeInitializedClassesVisiblyInitializedSym, thiz, self, wait);
MakeInitializedClassesVisiblyInitializedSym(thiz, self, wait);
}
@ -115,12 +106,10 @@ namespace art {
LOGD("Classlinker object: %p", thiz);
instance_ = new ClassLinker(thiz);
HOOK_FUNC(Constructor, "_ZN3art11ClassLinkerC2EPNS_11InternTableE",
"_ZN3art11ClassLinkerC2EPNS_11InternTableEb"); // 10.0
RETRIEVE_FUNC_SYMBOL(SetEntryPointsToInterpreter,
RETRIEVE_MEM_FUNC_SYMBOL(SetEntryPointsToInterpreter,
"_ZNK3art11ClassLinker27SetEntryPointsToInterpreterEPNS_9ArtMethodE");
HOOK_FUNC(FixupStaticTrampolines,
HOOK_MEM_FUNC(FixupStaticTrampolines,
"_ZN3art11ClassLinker22FixupStaticTrampolinesENS_6ObjPtrINS_6mirror5ClassEEE");
HOOK_FUNC(ShouldUseInterpreterEntrypoint,

View File

@ -16,10 +16,10 @@ namespace art {
private:
inline static Heap *instance_;
CREATE_FUNC_SYMBOL_ENTRY(collector::GcType, WaitForGcToComplete,
CREATE_MEM_FUNC_SYMBOL_ENTRY(collector::GcType, WaitForGcToComplete,
void *thiz, GcCause cause, void *threadSelf) {
if (LIKELY(WaitForGcToCompleteSym))
return edxp::call_as_member_func(WaitForGcToCompleteSym, thiz, cause, threadSelf);
return WaitForGcToCompleteSym(thiz, cause, threadSelf);
return art::gc::collector::GcType::kGcTypeNone;
}
@ -83,7 +83,7 @@ namespace art {
reinterpret_cast<size_t>(Runtime::Current()->Get()) + OFFSET_heap);
LOGD("art::runtime::Heap object: %p", thiz);
instance_ = new Heap(thiz);
RETRIEVE_FUNC_SYMBOL(WaitForGcToComplete,
RETRIEVE_MEM_FUNC_SYMBOL(WaitForGcToComplete,
"_ZN3art2gc4Heap19WaitForGcToCompleteENS0_7GcCauseEPNS_6ThreadE");
}

View File

@ -7,7 +7,7 @@ namespace art {
namespace jit {
CREATE_HOOK_STUB_ENTRIES(const void*, GetSavedEntryPointOfPreCompiledMethod, void *thiz,
CREATE_MEM_HOOK_STUB_ENTRIES(const void*, GetSavedEntryPointOfPreCompiledMethod, void *thiz,
void *art_method) {
if (UNLIKELY(edxp::isHooked(art_method))) {
LOGD("Found hooked method %p (%s), return entrypoint as jit entrypoint", art_method,
@ -24,7 +24,7 @@ namespace art {
// our hooked entry point won't be overwritten.
// This is for SandHook and YAHFA
if (api_level >= __ANDROID_API_R__) {
HOOK_FUNC(GetSavedEntryPointOfPreCompiledMethod,
HOOK_MEM_FUNC(GetSavedEntryPointOfPreCompiledMethod,
"_ZN3art3jit12JitCodeCache37GetSavedEntryPointOfPreCompiledMethodEPNS_9ArtMethodE");
}
}

View File

@ -9,12 +9,12 @@ namespace art {
class JNIEnvExt : edxp::HookedObject {
private:
CREATE_FUNC_SYMBOL_ENTRY(jobject, NewLocalRef, void *thiz, void *mirror_ptr) {
return edxp::call_as_member_func(NewLocalRefSym, thiz, mirror_ptr);
CREATE_MEM_FUNC_SYMBOL_ENTRY(jobject, NewLocalRef, void *thiz, void *mirror_ptr) {
return NewLocalRefSym(thiz, mirror_ptr);
}
CREATE_FUNC_SYMBOL_ENTRY(void, DeleteLocalRef, void *thiz, jobject obj) {
return edxp::call_as_member_func(DeleteLocalRefSym, thiz, obj);
CREATE_MEM_FUNC_SYMBOL_ENTRY(void, DeleteLocalRef, void *thiz, jobject obj) {
return DeleteLocalRefSym(thiz, obj);
}
public:
@ -22,8 +22,8 @@ namespace art {
// @ApiSensitive(Level.MIDDLE)
static void Setup(void *handle, HookFunType hook_func) {
RETRIEVE_FUNC_SYMBOL(NewLocalRef, "_ZN3art9JNIEnvExt11NewLocalRefEPNS_6mirror6ObjectE");
RETRIEVE_FUNC_SYMBOL(DeleteLocalRef, "_ZN3art9JNIEnvExt14DeleteLocalRefEP8_jobject");
RETRIEVE_MEM_FUNC_SYMBOL(NewLocalRef, "_ZN3art9JNIEnvExt11NewLocalRefEPNS_6mirror6ObjectE");
RETRIEVE_MEM_FUNC_SYMBOL(DeleteLocalRef, "_ZN3art9JNIEnvExt14DeleteLocalRefEP8_jobject");
}
jobject NewLocalRefer(void *mirror_ptr) {

View File

@ -14,15 +14,15 @@ namespace art {
private:
CREATE_FUNC_SYMBOL_ENTRY(const char *, GetDescriptor, void *thiz,
CREATE_MEM_FUNC_SYMBOL_ENTRY(const char *, GetDescriptor, void *thiz,
std::string *storage) {
if (GetDescriptorSym)
return edxp::call_as_member_func(GetDescriptorSym, thiz, storage);
return GetDescriptorSym(thiz, storage);
else
return "";
}
CREATE_HOOK_STUB_ENTRIES(bool, IsInSamePackage, void *thiz, void *that) {
CREATE_MEM_HOOK_STUB_ENTRIES(bool, IsInSamePackage, void *thiz, void *that) {
std::string storage1, storage2;
const char *thisDesc = GetDescriptor(thiz, &storage1);
const char *thatDesc = GetDescriptor(that, &storage2);
@ -43,9 +43,9 @@ namespace art {
return IsInSamePackageBackup(thiz, that);
}
CREATE_FUNC_SYMBOL_ENTRY(void*, GetClassDef, void* thiz) {
CREATE_MEM_FUNC_SYMBOL_ENTRY(void*, GetClassDef, void* thiz) {
if (LIKELY(GetClassDefSym))
return edxp::call_as_member_func(GetClassDefSym, thiz);
return GetClassDefSym(thiz);
return nullptr;
}
@ -54,15 +54,15 @@ namespace art {
// @ApiSensitive(Level.MIDDLE)
static void Setup(void *handle, HookFunType hook_func) {
RETRIEVE_FUNC_SYMBOL(GetDescriptor, "_ZN3art6mirror5Class13GetDescriptorEPNSt3__112"
RETRIEVE_MEM_FUNC_SYMBOL(GetDescriptor, "_ZN3art6mirror5Class13GetDescriptorEPNSt3__112"
"basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE");
RETRIEVE_FUNC_SYMBOL(GetClassDef, "_ZN3art6mirror5Class11GetClassDefEv");
RETRIEVE_MEM_FUNC_SYMBOL(GetClassDef, "_ZN3art6mirror5Class11GetClassDefEv");
// RETRIEVE_FIELD_SYMBOL(mutator_lock_, "_ZN3art5Locks13mutator_lock_E");
// LOGE("mutator_lock_: %p", mutator_lock_);
HOOK_FUNC(IsInSamePackage,
HOOK_MEM_FUNC(IsInSamePackage,
"_ZN3art6mirror5Class15IsInSamePackageENS_6ObjPtrIS1_EE", //8.0-
"_ZN3art6mirror5Class15IsInSamePackageEPS1_"); //5.0-7.1

View File

@ -11,9 +11,9 @@ namespace art {
private:
inline static Runtime *instance_;
CREATE_FUNC_SYMBOL_ENTRY(void, DeoptimizeBootImage, void *thiz) {
CREATE_MEM_FUNC_SYMBOL_ENTRY(void, DeoptimizeBootImage, void *thiz) {
if (LIKELY(DeoptimizeBootImageSym))
edxp::call_as_member_func(DeoptimizeBootImageSym, thiz);
DeoptimizeBootImageSym(thiz);
}
public:
@ -25,7 +25,7 @@ namespace art {
// @ApiSensitive(Level.LOW)
static void Setup(void *handle, HookFunType hook_func) {
RETRIEVE_FUNC_SYMBOL(DeoptimizeBootImage,
RETRIEVE_MEM_FUNC_SYMBOL(DeoptimizeBootImage,
"_ZN3art7Runtime19DeoptimizeBootImageEv");
RETRIEVE_FIELD_SYMBOL(instance, "_ZN3art7Runtime9instance_E");
void * thiz = *reinterpret_cast<void**>(instance);

View File

@ -7,9 +7,9 @@ namespace art {
class Thread : public edxp::HookedObject {
CREATE_FUNC_SYMBOL_ENTRY(edxp::ObjPtr, DecodeJObject, void *thiz, jobject obj) {
CREATE_MEM_FUNC_SYMBOL_ENTRY(edxp::ObjPtr, DecodeJObject, void *thiz, jobject obj) {
if (DecodeJObjectSym)
return edxp::call_as_member_func(DecodeJObjectSym, thiz, obj);
return DecodeJObjectSym(thiz, obj);
else
return {.data=nullptr};
}
@ -27,7 +27,7 @@ namespace art {
}
static void Setup(void *handle, [[maybe_unused]] HookFunType hook_func) {
RETRIEVE_FUNC_SYMBOL(DecodeJObject,
RETRIEVE_MEM_FUNC_SYMBOL(DecodeJObject,
"_ZNK3art6Thread13DecodeJObjectEP8_jobject");
RETRIEVE_FUNC_SYMBOL(CurrentFromGdb,
"_ZN3art6Thread14CurrentFromGdbEv");

View File

@ -28,6 +28,17 @@ typedef void (*HookFunType)(void *, void *, void **);
inline static ret (*func##Backup)(__VA_ARGS__); \
static ret func##Replace(__VA_ARGS__)
#define HOOK_MEM_FUNC(func, ...) \
edxp::HookSyms(handle, hook_func, \
reinterpret_cast<void *>(func##Replace), \
reinterpret_cast<void **>(&func##BackupSym), \
__VA_ARGS__), func##Backup = func##BackupSym
#define CREATE_MEM_HOOK_STUB_ENTRIES(ret, func, thiz, ...) \
inline static edxp::MemberFunction<ret(__VA_ARGS__)> func##Backup; \
inline static ret (*func##BackupSym)(thiz, ## __VA_ARGS__); \
static ret func##Replace(thiz, ## __VA_ARGS__)
#define CREATE_ORIGINAL_ENTRY(ret, func, ...) \
static ret func(__VA_ARGS__)
@ -35,6 +46,10 @@ typedef void (*HookFunType)(void *, void *, void **);
name##Sym = reinterpret_cast<name##Type>( \
edxp::Dlsym(handle, __VA_ARGS__))
#define RETRIEVE_MEM_FUNC_SYMBOL(name, ...) \
name##Sym = reinterpret_cast<name##Type::FunType>( \
edxp::Dlsym(handle, __VA_ARGS__))
#define RETRIEVE_FIELD_SYMBOL(name, ...) \
void *name = edxp::Dlsym(handle, __VA_ARGS__)
@ -43,6 +58,11 @@ typedef void (*HookFunType)(void *, void *, void **);
inline static ret (*func##Sym)(__VA_ARGS__); \
ALWAYS_INLINE static ret func(__VA_ARGS__)
#define CREATE_MEM_FUNC_SYMBOL_ENTRY(ret, func, thiz, ...) \
using func##Type = edxp::MemberFunction<ret(__VA_ARGS__)>; \
inline static func##Type func##Sym; \
ALWAYS_INLINE static ret func(thiz, ## __VA_ARGS__)
namespace edxp {
class ShadowObject {
@ -83,7 +103,7 @@ namespace edxp {
};
struct ObjPtr {
void* data;
void *data;
};
ALWAYS_INLINE static void *Dlsym(void *handle, const char *name) {
@ -130,7 +150,7 @@ namespace edxp {
}
template<typename Class, typename Return, typename T, typename... Args>
inline auto memfun_cast(Return (*func)(T *, Args...)) {
inline static auto memfun_cast(Return (*func)(T *, Args...)) {
static_assert(std::is_same_v<T, void> || std::is_same_v<Class, T>,
"Not viable cast");
union {
@ -145,39 +165,45 @@ namespace edxp {
return u.f;
}
template<typename Return, typename... Args, typename T,
template<typename T, typename Return, typename... Args,
typename = std::enable_if_t<!std::is_same_v<T, void>>>
inline auto memfun_cast(Return (*func)(T *, Args...)) {
return memfun_cast<T>(func);
}
template<typename Return, typename... Args, typename T, typename U,
typename = std::enable_if_t<!std::is_same_v<T, void> || !std::is_same_v<U, void>>>
inline Return
call_as_member_func(Return (*func)(U *, std::remove_reference_t<Args>...), T *thiz,
Args &&... args) {
using Class = std::conditional_t<std::is_same_v<T, void>, U, T>;
return (reinterpret_cast<Class *>(thiz)->*memfun_cast<Class>
(func))(
std::forward<Args>(args)...);
}
template<typename, typename=void>
class MemberFunction;
template<typename Class, typename Return, typename... Args>
inline Return
call_as_member_func(Return (*func)(void *, std::remove_reference_t<Args>...), void *thiz,
Args &&... args) {
return (reinterpret_cast<Class *>(thiz)->*memfun_cast<Class>(func))(
std::forward<Args>(args)...);
}
template<typename This, typename Return, typename ... Args>
class MemberFunction<Return(Args...), This> {
using SelfType = MemberFunction<Return(This *, Args...), This>;
using ThisType = std::conditional_t<std::is_same_v<This, void>, SelfType, This>;
using MemFunType = Return(ThisType::*)(Args...);
public:
using FunType = Return (*)(This *, Args...);
private:
MemFunType f_ = nullptr;
public:
MemberFunction() = default;
template<typename Return, typename... Args>
inline Return
call_as_member_func(Return (*func)(void *, std::remove_reference_t<Args>...), void *thiz,
Args &&... args) {
struct DummyClass {
};
return (reinterpret_cast<DummyClass *>(thiz)->*memfun_cast<DummyClass>(func))(
std::forward<Args>(args)...);
}
MemberFunction(FunType f) : f_(memfun_cast<ThisType>(f)) {}
MemberFunction(MemFunType f) : f_(f) {}
Return operator()(This *thiz, Args... args) {
return (reinterpret_cast<ThisType *>(thiz)->*f_)(std::forward<Args>(args)...);
}
inline operator bool() {
return f_ != nullptr;
}
};
// deduction guide
template<typename This, typename Return, typename...Args>
MemberFunction(Return(*f)(This *, Args...)) -> MemberFunction<Return(Args...), This>;
template<typename This, typename Return, typename...Args>
MemberFunction(Return(This::*f)(Args...)) -> MemberFunction<Return(Args...), This>;
} // namespace edxp