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 size_t oat_header_length;
|
||||||
inline static int32_t oat_header_code_length_offset;
|
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))
|
if (UNLIKELY(thiz == nullptr))
|
||||||
return "null";
|
return "null";
|
||||||
if (LIKELY(PrettyMethodSym))
|
if (LIKELY(PrettyMethodSym))
|
||||||
return edxp::call_as_member_func(PrettyMethodSym, thiz, with_signature);
|
return PrettyMethodSym(thiz, with_signature);
|
||||||
else return "null sym";
|
else return "null sym";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -26,7 +26,7 @@ namespace art {
|
||||||
return PrettyMethod(thiz, true);
|
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.
|
// 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>(getOriginalEntryPointFromTargetMethod(
|
uintptr_t original_ep = reinterpret_cast<uintptr_t>(getOriginalEntryPointFromTargetMethod(
|
||||||
|
|
@ -75,12 +75,12 @@ namespace art {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if constexpr (edxp::is64) {
|
if constexpr (edxp::is64) {
|
||||||
HOOK_FUNC(GetOatQuickMethodHeader, "_ZN3art9ArtMethod23GetOatQuickMethodHeaderEm");
|
HOOK_MEM_FUNC(GetOatQuickMethodHeader, "_ZN3art9ArtMethod23GetOatQuickMethodHeaderEm");
|
||||||
} else {
|
} 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:
|
private:
|
||||||
inline static ClassLinker *instance_;
|
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))
|
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) {
|
CREATE_MEM_HOOK_STUB_ENTRIES(void, FixupStaticTrampolines, void *thiz, void *clazz_ptr) {
|
||||||
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) {
|
|
||||||
FixupStaticTrampolinesBackup(thiz, clazz_ptr);
|
FixupStaticTrampolinesBackup(thiz, clazz_ptr);
|
||||||
art::mirror::Class mirror_class(clazz_ptr);
|
art::mirror::Class mirror_class(clazz_ptr);
|
||||||
auto class_def = mirror_class.GetClassDef();
|
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) {
|
void *self, bool wait) {
|
||||||
if (LIKELY(MakeInitializedClassesVisiblyInitializedSym))
|
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);
|
LOGD("Classlinker object: %p", thiz);
|
||||||
instance_ = new ClassLinker(thiz);
|
instance_ = new ClassLinker(thiz);
|
||||||
|
|
||||||
HOOK_FUNC(Constructor, "_ZN3art11ClassLinkerC2EPNS_11InternTableE",
|
RETRIEVE_MEM_FUNC_SYMBOL(SetEntryPointsToInterpreter,
|
||||||
"_ZN3art11ClassLinkerC2EPNS_11InternTableEb"); // 10.0
|
|
||||||
RETRIEVE_FUNC_SYMBOL(SetEntryPointsToInterpreter,
|
|
||||||
"_ZNK3art11ClassLinker27SetEntryPointsToInterpreterEPNS_9ArtMethodE");
|
"_ZNK3art11ClassLinker27SetEntryPointsToInterpreterEPNS_9ArtMethodE");
|
||||||
|
|
||||||
HOOK_FUNC(FixupStaticTrampolines,
|
HOOK_MEM_FUNC(FixupStaticTrampolines,
|
||||||
"_ZN3art11ClassLinker22FixupStaticTrampolinesENS_6ObjPtrINS_6mirror5ClassEEE");
|
"_ZN3art11ClassLinker22FixupStaticTrampolinesENS_6ObjPtrINS_6mirror5ClassEEE");
|
||||||
|
|
||||||
HOOK_FUNC(ShouldUseInterpreterEntrypoint,
|
HOOK_FUNC(ShouldUseInterpreterEntrypoint,
|
||||||
|
|
|
||||||
|
|
@ -16,10 +16,10 @@ namespace art {
|
||||||
private:
|
private:
|
||||||
inline static Heap *instance_;
|
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) {
|
void *thiz, GcCause cause, void *threadSelf) {
|
||||||
if (LIKELY(WaitForGcToCompleteSym))
|
if (LIKELY(WaitForGcToCompleteSym))
|
||||||
return edxp::call_as_member_func(WaitForGcToCompleteSym, thiz, cause, threadSelf);
|
return WaitForGcToCompleteSym(thiz, cause, threadSelf);
|
||||||
return art::gc::collector::GcType::kGcTypeNone;
|
return art::gc::collector::GcType::kGcTypeNone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -83,7 +83,7 @@ namespace art {
|
||||||
reinterpret_cast<size_t>(Runtime::Current()->Get()) + OFFSET_heap);
|
reinterpret_cast<size_t>(Runtime::Current()->Get()) + OFFSET_heap);
|
||||||
LOGD("art::runtime::Heap object: %p", thiz);
|
LOGD("art::runtime::Heap object: %p", thiz);
|
||||||
instance_ = new Heap(thiz);
|
instance_ = new Heap(thiz);
|
||||||
RETRIEVE_FUNC_SYMBOL(WaitForGcToComplete,
|
RETRIEVE_MEM_FUNC_SYMBOL(WaitForGcToComplete,
|
||||||
"_ZN3art2gc4Heap19WaitForGcToCompleteENS0_7GcCauseEPNS_6ThreadE");
|
"_ZN3art2gc4Heap19WaitForGcToCompleteENS0_7GcCauseEPNS_6ThreadE");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ namespace art {
|
||||||
|
|
||||||
namespace jit {
|
namespace jit {
|
||||||
|
|
||||||
CREATE_HOOK_STUB_ENTRIES(const void*, GetSavedEntryPointOfPreCompiledMethod, void *thiz,
|
CREATE_MEM_HOOK_STUB_ENTRIES(const void*, GetSavedEntryPointOfPreCompiledMethod, void *thiz,
|
||||||
void *art_method) {
|
void *art_method) {
|
||||||
if (UNLIKELY(edxp::isHooked(art_method))) {
|
if (UNLIKELY(edxp::isHooked(art_method))) {
|
||||||
LOGD("Found hooked method %p (%s), return entrypoint as jit entrypoint", 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.
|
// our hooked entry point won't be overwritten.
|
||||||
// This is for SandHook and YAHFA
|
// This is for SandHook and YAHFA
|
||||||
if (api_level >= __ANDROID_API_R__) {
|
if (api_level >= __ANDROID_API_R__) {
|
||||||
HOOK_FUNC(GetSavedEntryPointOfPreCompiledMethod,
|
HOOK_MEM_FUNC(GetSavedEntryPointOfPreCompiledMethod,
|
||||||
"_ZN3art3jit12JitCodeCache37GetSavedEntryPointOfPreCompiledMethodEPNS_9ArtMethodE");
|
"_ZN3art3jit12JitCodeCache37GetSavedEntryPointOfPreCompiledMethodEPNS_9ArtMethodE");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,12 +9,12 @@ namespace art {
|
||||||
class JNIEnvExt : edxp::HookedObject {
|
class JNIEnvExt : edxp::HookedObject {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CREATE_FUNC_SYMBOL_ENTRY(jobject, NewLocalRef, void *thiz, void *mirror_ptr) {
|
CREATE_MEM_FUNC_SYMBOL_ENTRY(jobject, NewLocalRef, void *thiz, void *mirror_ptr) {
|
||||||
return edxp::call_as_member_func(NewLocalRefSym, thiz, mirror_ptr);
|
return NewLocalRefSym(thiz, mirror_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
CREATE_FUNC_SYMBOL_ENTRY(void, DeleteLocalRef, void *thiz, jobject obj) {
|
CREATE_MEM_FUNC_SYMBOL_ENTRY(void, DeleteLocalRef, void *thiz, jobject obj) {
|
||||||
return edxp::call_as_member_func(DeleteLocalRefSym, thiz, obj);
|
return DeleteLocalRefSym(thiz, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -22,8 +22,8 @@ namespace art {
|
||||||
|
|
||||||
// @ApiSensitive(Level.MIDDLE)
|
// @ApiSensitive(Level.MIDDLE)
|
||||||
static void Setup(void *handle, HookFunType hook_func) {
|
static void Setup(void *handle, HookFunType hook_func) {
|
||||||
RETRIEVE_FUNC_SYMBOL(NewLocalRef, "_ZN3art9JNIEnvExt11NewLocalRefEPNS_6mirror6ObjectE");
|
RETRIEVE_MEM_FUNC_SYMBOL(NewLocalRef, "_ZN3art9JNIEnvExt11NewLocalRefEPNS_6mirror6ObjectE");
|
||||||
RETRIEVE_FUNC_SYMBOL(DeleteLocalRef, "_ZN3art9JNIEnvExt14DeleteLocalRefEP8_jobject");
|
RETRIEVE_MEM_FUNC_SYMBOL(DeleteLocalRef, "_ZN3art9JNIEnvExt14DeleteLocalRefEP8_jobject");
|
||||||
}
|
}
|
||||||
|
|
||||||
jobject NewLocalRefer(void *mirror_ptr) {
|
jobject NewLocalRefer(void *mirror_ptr) {
|
||||||
|
|
|
||||||
|
|
@ -14,15 +14,15 @@ namespace art {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
CREATE_FUNC_SYMBOL_ENTRY(const char *, GetDescriptor, void *thiz,
|
CREATE_MEM_FUNC_SYMBOL_ENTRY(const char *, GetDescriptor, void *thiz,
|
||||||
std::string *storage) {
|
std::string *storage) {
|
||||||
if (GetDescriptorSym)
|
if (GetDescriptorSym)
|
||||||
return edxp::call_as_member_func(GetDescriptorSym, thiz, storage);
|
return GetDescriptorSym(thiz, storage);
|
||||||
else
|
else
|
||||||
return "";
|
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;
|
std::string storage1, storage2;
|
||||||
const char *thisDesc = GetDescriptor(thiz, &storage1);
|
const char *thisDesc = GetDescriptor(thiz, &storage1);
|
||||||
const char *thatDesc = GetDescriptor(that, &storage2);
|
const char *thatDesc = GetDescriptor(that, &storage2);
|
||||||
|
|
@ -43,9 +43,9 @@ namespace art {
|
||||||
return IsInSamePackageBackup(thiz, that);
|
return IsInSamePackageBackup(thiz, that);
|
||||||
}
|
}
|
||||||
|
|
||||||
CREATE_FUNC_SYMBOL_ENTRY(void*, GetClassDef, void* thiz) {
|
CREATE_MEM_FUNC_SYMBOL_ENTRY(void*, GetClassDef, void* thiz) {
|
||||||
if (LIKELY(GetClassDefSym))
|
if (LIKELY(GetClassDefSym))
|
||||||
return edxp::call_as_member_func(GetClassDefSym, thiz);
|
return GetClassDefSym(thiz);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -54,15 +54,15 @@ namespace art {
|
||||||
|
|
||||||
// @ApiSensitive(Level.MIDDLE)
|
// @ApiSensitive(Level.MIDDLE)
|
||||||
static void Setup(void *handle, HookFunType hook_func) {
|
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");
|
"basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE");
|
||||||
|
|
||||||
RETRIEVE_FUNC_SYMBOL(GetClassDef, "_ZN3art6mirror5Class11GetClassDefEv");
|
RETRIEVE_MEM_FUNC_SYMBOL(GetClassDef, "_ZN3art6mirror5Class11GetClassDefEv");
|
||||||
|
|
||||||
// RETRIEVE_FIELD_SYMBOL(mutator_lock_, "_ZN3art5Locks13mutator_lock_E");
|
// RETRIEVE_FIELD_SYMBOL(mutator_lock_, "_ZN3art5Locks13mutator_lock_E");
|
||||||
// LOGE("mutator_lock_: %p", mutator_lock_);
|
// LOGE("mutator_lock_: %p", mutator_lock_);
|
||||||
|
|
||||||
HOOK_FUNC(IsInSamePackage,
|
HOOK_MEM_FUNC(IsInSamePackage,
|
||||||
"_ZN3art6mirror5Class15IsInSamePackageENS_6ObjPtrIS1_EE", //8.0-
|
"_ZN3art6mirror5Class15IsInSamePackageENS_6ObjPtrIS1_EE", //8.0-
|
||||||
"_ZN3art6mirror5Class15IsInSamePackageEPS1_"); //5.0-7.1
|
"_ZN3art6mirror5Class15IsInSamePackageEPS1_"); //5.0-7.1
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,9 +11,9 @@ namespace art {
|
||||||
private:
|
private:
|
||||||
inline static Runtime *instance_;
|
inline static Runtime *instance_;
|
||||||
|
|
||||||
CREATE_FUNC_SYMBOL_ENTRY(void, DeoptimizeBootImage, void *thiz) {
|
CREATE_MEM_FUNC_SYMBOL_ENTRY(void, DeoptimizeBootImage, void *thiz) {
|
||||||
if (LIKELY(DeoptimizeBootImageSym))
|
if (LIKELY(DeoptimizeBootImageSym))
|
||||||
edxp::call_as_member_func(DeoptimizeBootImageSym, thiz);
|
DeoptimizeBootImageSym(thiz);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -25,7 +25,7 @@ namespace art {
|
||||||
|
|
||||||
// @ApiSensitive(Level.LOW)
|
// @ApiSensitive(Level.LOW)
|
||||||
static void Setup(void *handle, HookFunType hook_func) {
|
static void Setup(void *handle, HookFunType hook_func) {
|
||||||
RETRIEVE_FUNC_SYMBOL(DeoptimizeBootImage,
|
RETRIEVE_MEM_FUNC_SYMBOL(DeoptimizeBootImage,
|
||||||
"_ZN3art7Runtime19DeoptimizeBootImageEv");
|
"_ZN3art7Runtime19DeoptimizeBootImageEv");
|
||||||
RETRIEVE_FIELD_SYMBOL(instance, "_ZN3art7Runtime9instance_E");
|
RETRIEVE_FIELD_SYMBOL(instance, "_ZN3art7Runtime9instance_E");
|
||||||
void * thiz = *reinterpret_cast<void**>(instance);
|
void * thiz = *reinterpret_cast<void**>(instance);
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,9 @@ namespace art {
|
||||||
|
|
||||||
class Thread : public edxp::HookedObject {
|
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)
|
if (DecodeJObjectSym)
|
||||||
return edxp::call_as_member_func(DecodeJObjectSym, thiz, obj);
|
return DecodeJObjectSym(thiz, obj);
|
||||||
else
|
else
|
||||||
return {.data=nullptr};
|
return {.data=nullptr};
|
||||||
}
|
}
|
||||||
|
|
@ -27,7 +27,7 @@ namespace art {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Setup(void *handle, [[maybe_unused]] HookFunType hook_func) {
|
static void Setup(void *handle, [[maybe_unused]] HookFunType hook_func) {
|
||||||
RETRIEVE_FUNC_SYMBOL(DecodeJObject,
|
RETRIEVE_MEM_FUNC_SYMBOL(DecodeJObject,
|
||||||
"_ZNK3art6Thread13DecodeJObjectEP8_jobject");
|
"_ZNK3art6Thread13DecodeJObjectEP8_jobject");
|
||||||
RETRIEVE_FUNC_SYMBOL(CurrentFromGdb,
|
RETRIEVE_FUNC_SYMBOL(CurrentFromGdb,
|
||||||
"_ZN3art6Thread14CurrentFromGdbEv");
|
"_ZN3art6Thread14CurrentFromGdbEv");
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,17 @@ typedef void (*HookFunType)(void *, void *, void **);
|
||||||
inline static ret (*func##Backup)(__VA_ARGS__); \
|
inline static ret (*func##Backup)(__VA_ARGS__); \
|
||||||
static ret func##Replace(__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, ...) \
|
#define CREATE_ORIGINAL_ENTRY(ret, func, ...) \
|
||||||
static ret func(__VA_ARGS__)
|
static ret func(__VA_ARGS__)
|
||||||
|
|
||||||
|
|
@ -35,6 +46,10 @@ typedef void (*HookFunType)(void *, void *, void **);
|
||||||
name##Sym = reinterpret_cast<name##Type>( \
|
name##Sym = reinterpret_cast<name##Type>( \
|
||||||
edxp::Dlsym(handle, __VA_ARGS__))
|
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, ...) \
|
#define RETRIEVE_FIELD_SYMBOL(name, ...) \
|
||||||
void *name = edxp::Dlsym(handle, __VA_ARGS__)
|
void *name = edxp::Dlsym(handle, __VA_ARGS__)
|
||||||
|
|
||||||
|
|
@ -43,6 +58,11 @@ typedef void (*HookFunType)(void *, void *, void **);
|
||||||
inline static ret (*func##Sym)(__VA_ARGS__); \
|
inline static ret (*func##Sym)(__VA_ARGS__); \
|
||||||
ALWAYS_INLINE static ret func(__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 {
|
namespace edxp {
|
||||||
|
|
||||||
class ShadowObject {
|
class ShadowObject {
|
||||||
|
|
@ -83,7 +103,7 @@ namespace edxp {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ObjPtr {
|
struct ObjPtr {
|
||||||
void* data;
|
void *data;
|
||||||
};
|
};
|
||||||
|
|
||||||
ALWAYS_INLINE static void *Dlsym(void *handle, const char *name) {
|
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>
|
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>,
|
static_assert(std::is_same_v<T, void> || std::is_same_v<Class, T>,
|
||||||
"Not viable cast");
|
"Not viable cast");
|
||||||
union {
|
union {
|
||||||
|
|
@ -145,39 +165,45 @@ namespace edxp {
|
||||||
return u.f;
|
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>>>
|
typename = std::enable_if_t<!std::is_same_v<T, void>>>
|
||||||
inline auto memfun_cast(Return (*func)(T *, Args...)) {
|
inline auto memfun_cast(Return (*func)(T *, Args...)) {
|
||||||
return memfun_cast<T>(func);
|
return memfun_cast<T>(func);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Return, typename... Args, typename T, typename U,
|
template<typename, typename=void>
|
||||||
typename = std::enable_if_t<!std::is_same_v<T, void> || !std::is_same_v<U, void>>>
|
class MemberFunction;
|
||||||
inline Return
|
|
||||||
call_as_member_func(Return (*func)(U *, std::remove_reference_t<Args>...), T *thiz,
|
template<typename This, typename Return, typename ... Args>
|
||||||
Args &&... args) {
|
class MemberFunction<Return(Args...), This> {
|
||||||
using Class = std::conditional_t<std::is_same_v<T, void>, U, T>;
|
using SelfType = MemberFunction<Return(This *, Args...), This>;
|
||||||
return (reinterpret_cast<Class *>(thiz)->*memfun_cast<Class>
|
using ThisType = std::conditional_t<std::is_same_v<This, void>, SelfType, This>;
|
||||||
(func))(
|
using MemFunType = Return(ThisType::*)(Args...);
|
||||||
std::forward<Args>(args)...);
|
public:
|
||||||
|
using FunType = Return (*)(This *, Args...);
|
||||||
|
private:
|
||||||
|
MemFunType f_ = nullptr;
|
||||||
|
public:
|
||||||
|
MemberFunction() = default;
|
||||||
|
|
||||||
|
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)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Class, typename Return, typename... Args>
|
inline operator bool() {
|
||||||
inline Return
|
return f_ != nullptr;
|
||||||
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 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)...);
|
// 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
|
} // namespace edxp
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue