Skip to content

Commit

Permalink
Opt mem fun & fix hook mem fun
Browse files Browse the repository at this point in the history
  • Loading branch information
LoveSy authored and kotori2 committed Jan 8, 2021
1 parent f78355a commit 981094e
Show file tree
Hide file tree
Showing 9 changed files with 93 additions and 78 deletions.
12 changes: 6 additions & 6 deletions edxp-core/src/main/cpp/main/include/art/runtime/art_method.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,19 @@ 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";
}

inline static std::string PrettyMethod(void *thiz) {
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(
Expand Down Expand Up @@ -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");
}
}
}
Expand Down
25 changes: 7 additions & 18 deletions edxp-core/src/main/cpp/main/include/art/runtime/class_linker.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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);
}


Expand Down Expand Up @@ -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,
Expand Down
6 changes: 3 additions & 3 deletions edxp-core/src/main/cpp/main/include/art/runtime/gc/heap.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down Expand Up @@ -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");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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");
}
}
Expand Down
12 changes: 6 additions & 6 deletions edxp-core/src/main/cpp/main/include/art/runtime/jni_env_ext.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,21 @@ 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:
JNIEnvExt(void *thiz) : HookedObject(thiz) {}

// @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) {
Expand Down
16 changes: 8 additions & 8 deletions edxp-core/src/main/cpp/main/include/art/runtime/mirror/class.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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;
}

Expand All @@ -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

Expand Down
6 changes: 3 additions & 3 deletions edxp-core/src/main/cpp/main/include/art/runtime/runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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);
Expand Down
6 changes: 3 additions & 3 deletions edxp-core/src/main/cpp/main/include/art/runtime/thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -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};
}
Expand All @@ -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");
Expand Down
84 changes: 55 additions & 29 deletions edxp-core/src/main/cpp/main/include/base/object.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,28 @@ 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__)

#define RETRIEVE_FUNC_SYMBOL(name, ...) \
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__)

Expand All @@ -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 {
Expand Down Expand Up @@ -83,7 +103,7 @@ namespace edxp {
};

struct ObjPtr {
void* data;
void *data;
};

ALWAYS_INLINE static void *Dlsym(void *handle, const char *name) {
Expand Down Expand Up @@ -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 {
Expand All @@ -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

0 comments on commit 981094e

Please sign in to comment.