Opt mem fun & fix hook mem fun
This commit is contained in:
parent
f78355a189
commit
981094e06f
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue