diff --git a/core/src/main/cpp/main/include/art/runtime/art_method.h b/core/src/main/cpp/main/include/art/runtime/art_method.h index 6dcbf7b5..27533528 100644 --- a/core/src/main/cpp/main/include/art/runtime/art_method.h +++ b/core/src/main/cpp/main/include/art/runtime/art_method.h @@ -42,8 +42,7 @@ namespace art { return PrettyMethod(thiz, true); } - static void Setup(void *handle) { - LOGD("art_method hook setup, handle=%p", handle); + static void Setup(const SandHook::ElfImg &handle) { RETRIEVE_MEM_FUNC_SYMBOL(PrettyMethod, "_ZN3art9ArtMethod12PrettyMethodEb"); } } diff --git a/core/src/main/cpp/main/include/art/runtime/class_linker.h b/core/src/main/cpp/main/include/art/runtime/class_linker.h index 4f4e5a81..20404270 100644 --- a/core/src/main/cpp/main/include/art/runtime/class_linker.h +++ b/core/src/main/cpp/main/include/art/runtime/class_linker.h @@ -107,8 +107,7 @@ namespace art { } // @ApiSensitive(Level.MIDDLE) - static void Setup(void *handle) { - LOGD("Classlinker hook setup, handle=%p", handle); + static void Setup(const SandHook::ElfImg &handle) { int api_level = lspd::GetAndroidApiLevel(); size_t OFFSET_classlinker; // Get offset from art::Runtime::RunRootClinits() call in IDA switch (api_level) { diff --git a/core/src/main/cpp/main/include/art/runtime/gc/scoped_gc_critical_section.h b/core/src/main/cpp/main/include/art/runtime/gc/scoped_gc_critical_section.h index e060fc60..f761b95e 100644 --- a/core/src/main/cpp/main/include/art/runtime/gc/scoped_gc_critical_section.h +++ b/core/src/main/cpp/main/include/art/runtime/gc/scoped_gc_critical_section.h @@ -51,7 +51,7 @@ namespace art { destructor(this); } - static void Setup(void *handle) { + static void Setup(const SandHook::ElfImg &handle) { RETRIEVE_MEM_FUNC_SYMBOL(constructor, "_ZN3art2gc23ScopedGCCriticalSectionC2EPNS_6ThreadENS0_7GcCauseENS0_13CollectorTypeE"); RETRIEVE_MEM_FUNC_SYMBOL(destructor, "_ZN3art2gc23ScopedGCCriticalSectionD2Ev"); } diff --git a/core/src/main/cpp/main/include/art/runtime/hidden_api.h b/core/src/main/cpp/main/include/art/runtime/hidden_api.h index 5b629140..c1dbe671 100644 --- a/core/src/main/cpp/main/include/art/runtime/hidden_api.h +++ b/core/src/main/cpp/main/include/art/runtime/hidden_api.h @@ -115,7 +115,7 @@ namespace art { } ); - static void DisableHiddenApi(void *handle) { + static void DisableHiddenApi(const SandHook::ElfImg &handle) { const int api_level = lspd::GetAndroidApiLevel(); if (api_level < __ANDROID_API_P__) { diff --git a/core/src/main/cpp/main/include/art/runtime/instrumentation.h b/core/src/main/cpp/main/include/art/runtime/instrumentation.h index 7993f0e6..5ef453f4 100644 --- a/core/src/main/cpp/main/include/art/runtime/instrumentation.h +++ b/core/src/main/cpp/main/include/art/runtime/instrumentation.h @@ -38,7 +38,7 @@ namespace art { } }); - static void DisableUpdateHookedMethodsCode(void *handle) { + static void DisableUpdateHookedMethodsCode(const SandHook::ElfImg &handle) { lspd::HookSym(handle, UpdateMethodsCode); } } diff --git a/core/src/main/cpp/main/include/art/runtime/jni_env_ext.h b/core/src/main/cpp/main/include/art/runtime/jni_env_ext.h index 17fcbf92..2f6f23e2 100644 --- a/core/src/main/cpp/main/include/art/runtime/jni_env_ext.h +++ b/core/src/main/cpp/main/include/art/runtime/jni_env_ext.h @@ -40,7 +40,7 @@ namespace art { JNIEnvExt(void *thiz) : HookedObject(thiz) {} // @ApiSensitive(Level.MIDDLE) - static void Setup(void *handle) { + static void Setup(const SandHook::ElfImg &handle) { RETRIEVE_MEM_FUNC_SYMBOL(NewLocalRef, "_ZN3art9JNIEnvExt11NewLocalRefEPNS_6mirror6ObjectE"); RETRIEVE_MEM_FUNC_SYMBOL(DeleteLocalRef, "_ZN3art9JNIEnvExt14DeleteLocalRefEP8_jobject"); } @@ -55,4 +55,4 @@ namespace art { }; -} \ No newline at end of file +} diff --git a/core/src/main/cpp/main/include/art/runtime/mirror/class.h b/core/src/main/cpp/main/include/art/runtime/mirror/class.h index b7871d6a..d698fa9a 100644 --- a/core/src/main/cpp/main/include/art/runtime/mirror/class.h +++ b/core/src/main/cpp/main/include/art/runtime/mirror/class.h @@ -51,7 +51,7 @@ namespace art { Class(void *thiz) : HookedObject(thiz) {} // @ApiSensitive(Level.MIDDLE) - static void Setup(void *handle) { + static void Setup(const SandHook::ElfImg &handle) { RETRIEVE_MEM_FUNC_SYMBOL(GetDescriptor, "_ZN3art6mirror5Class13GetDescriptorEPNSt3__112" "basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE"); RETRIEVE_MEM_FUNC_SYMBOL(GetClassDef, "_ZN3art6mirror5Class11GetClassDefEv"); diff --git a/core/src/main/cpp/main/include/art/runtime/runtime.h b/core/src/main/cpp/main/include/art/runtime/runtime.h index 56596c8b..c073c2a4 100644 --- a/core/src/main/cpp/main/include/art/runtime/runtime.h +++ b/core/src/main/cpp/main/include/art/runtime/runtime.h @@ -45,7 +45,7 @@ namespace art { } // @ApiSensitive(Level.LOW) - static void Setup(void *handle) { + static void Setup(const SandHook::ElfImg &handle) { RETRIEVE_FIELD_SYMBOL(instance, "_ZN3art7Runtime9instance_E"); RETRIEVE_MEM_FUNC_SYMBOL(SetJavaDebuggable, "_ZN3art7Runtime17SetJavaDebuggableEb"); void *thiz = *reinterpret_cast(instance); diff --git a/core/src/main/cpp/main/include/art/runtime/thread.h b/core/src/main/cpp/main/include/art/runtime/thread.h index d2d9b2a3..d3892aa6 100644 --- a/core/src/main/cpp/main/include/art/runtime/thread.h +++ b/core/src/main/cpp/main/include/art/runtime/thread.h @@ -32,22 +32,24 @@ namespace art { else return {.data=nullptr}; } + CREATE_FUNC_SYMBOL_ENTRY(void *, CurrentFromGdb) { if (LIKELY(CurrentFromGdbSym)) - return CurrentFromGdbSym(); + return CurrentFromGdbSym(); else return nullptr; } public: Thread(void *thiz) : HookedObject(thiz) {} + static Thread Current() { return Thread(CurrentFromGdb()); } - static void Setup(void *handle) { + static void Setup(const SandHook::ElfImg &handle) { RETRIEVE_MEM_FUNC_SYMBOL(DecodeJObject, - "_ZNK3art6Thread13DecodeJObjectEP8_jobject"); + "_ZNK3art6Thread13DecodeJObjectEP8_jobject"); RETRIEVE_FUNC_SYMBOL(CurrentFromGdb, "_ZN3art6Thread14CurrentFromGdbEv"); } diff --git a/core/src/main/cpp/main/include/art/runtime/thread_list.h b/core/src/main/cpp/main/include/art/runtime/thread_list.h index 203aff66..7d2384ed 100644 --- a/core/src/main/cpp/main/include/art/runtime/thread_list.h +++ b/core/src/main/cpp/main/include/art/runtime/thread_list.h @@ -42,7 +42,7 @@ namespace art { destructor(this); } - static void Setup(void *handle) { + static void Setup(const SandHook::ElfImg &handle) { RETRIEVE_MEM_FUNC_SYMBOL(constructor, "_ZN3art16ScopedSuspendAllC2EPKcb"); RETRIEVE_MEM_FUNC_SYMBOL(destructor, "_ZN3art16ScopedSuspendAllD2Ev"); } diff --git a/core/src/main/cpp/main/include/base/object.h b/core/src/main/cpp/main/include/base/object.h index 3ff705dd..3975ee10 100644 --- a/core/src/main/cpp/main/include/base/object.h +++ b/core/src/main/cpp/main/include/base/object.h @@ -25,6 +25,7 @@ #include #include "config.h" #include "native_hook.h" +#include "elf_util.h" #include #define _uintval(p) reinterpret_cast(p) @@ -114,13 +115,18 @@ namespace lspd { return dlsym(handle, name); } - template - inline void *Dlsym(void *handle, T first, Args... last) { - auto ret = Dlsym(handle, first); + [[gnu::always_inline]] + inline void *Dlsym(const SandHook::ElfImg &handle, const char *name) { + return handle.getSymbAddress(name); + } + + template + inline void *Dlsym(H &&handle, T first, Args... last) { + auto ret = Dlsym(std::forward(handle), first); if (ret) { return ret; } - return Dlsym(handle, last...); + return Dlsym(std::forward(handle), last...); } inline int HookFunction(void *original, void *replace, void **backup) { @@ -250,15 +256,16 @@ namespace lspd { } } - template - inline static bool HookSym(void *handle, T &arg) { - auto original = Dlsym(handle, arg.sym); + template + inline static bool HookSym(H &&handle, T &arg) { + auto original = Dlsym(std::forward(handle), arg.sym); return HookSymNoHandle(original, arg); } - template - inline static bool HookSyms(void *handle, T &first, Args &...rest) { - if (!(HookSym(handle, first) || ... || HookSym(handle, rest))) { + template + inline static bool HookSyms(H &&handle, T &first, Args &...rest) { + if (!(HookSym(std::forward(handle), first) || ... || HookSym(std::forward(handle), + rest))) { LOGW("Hook Fails: %s", first.sym); return false; } diff --git a/core/src/main/cpp/main/include/config.h b/core/src/main/cpp/main/include/config.h index b66ab3bc..f2f29fd4 100644 --- a/core/src/main/cpp/main/include/config.h +++ b/core/src/main/cpp/main/include/config.h @@ -65,20 +65,6 @@ namespace lspd { inline static constexpr auto kLibArtName = "libart.so"_tstr; inline static constexpr auto kLibFwName = "libandroidfw.so"_tstr; - inline static constexpr auto kLinkerName = LP_SELECT("linker"_tstr, "linker64"_tstr); - inline static constexpr auto kLibcName = "libc.so"_tstr; - inline static constexpr auto kLibbaseName = "libbase.so"_tstr; - - inline static constexpr auto kLibBasePath = - LP_SELECT("/system/lib/"_tstr, - "/system/lib64/"_tstr); - - inline static constexpr auto kBinBasePath = "/system/bin/"_tstr; - - inline static constexpr auto kLibFwPath = kLibBasePath + kLibFwName; - inline static constexpr auto kLinkerPath = kBinBasePath + kLinkerName; - inline static constexpr auto kLibcPath = kLibBasePath + kLibcName; - inline static constexpr auto kLibbasePath = kLibBasePath + kLibbaseName; inline constexpr const char *BoolToString(bool b) { return b ? "true" : "false"; diff --git a/core/src/main/cpp/main/include/framework/androidfw/resource_types.h b/core/src/main/cpp/main/include/framework/androidfw/resource_types.h index 3fe45aa1..b02b71a9 100644 --- a/core/src/main/cpp/main/include/framework/androidfw/resource_types.h +++ b/core/src/main/cpp/main/include/framework/androidfw/resource_types.h @@ -173,7 +173,7 @@ namespace android { return {nullptr, 0u}; } - static bool setup(void* handle) { + static bool setup(const SandHook::ElfImg &handle) { RETRIEVE_MEM_FUNC_SYMBOL(stringAt, LP_SELECT("_ZNK7android13ResStringPool8stringAtEjPj", "_ZNK7android13ResStringPool8stringAtEmPm")); RETRIEVE_MEM_FUNC_SYMBOL(stringAtS, LP_SELECT("_ZNK7android13ResStringPool8stringAtEj", "_ZNK7android13ResStringPool8stringAtEm")); return !stringAtSym || !stringAtSSym; diff --git a/core/src/main/cpp/main/src/elf_util.cpp b/core/src/main/cpp/main/src/elf_util.cpp index 949b0dc7..ca6cd124 100644 --- a/core/src/main/cpp/main/src/elf_util.cpp +++ b/core/src/main/cpp/main/src/elf_util.cpp @@ -35,7 +35,12 @@ inline constexpr auto offsetOf(ElfW(Ehdr) *head, ElfW(Off) off) { reinterpret_cast(head) + off); } -ElfImg::ElfImg(std::string_view elf) : elf(elf) { +ElfImg::ElfImg(std::string_view base_name) : elf(base_name) { + if (!findModuleBase()) { + base = nullptr; + return; + } + //load elf int fd = open(elf.data(), O_RDONLY); if (fd < 0) { @@ -120,9 +125,6 @@ ElfImg::ElfImg(std::string_view elf) : elf(elf) { } } } - - //load module base - base = getModuleBase(); } ElfW(Addr) ElfImg::ElfLookup(std::string_view name, uint32_t hash) const { @@ -218,56 +220,44 @@ ElfImg::getSymbOffset(std::string_view name, uint32_t gnu_hash, uint32_t elf_has } -void *ElfImg::getModuleBase() const { +bool ElfImg::findModuleBase() { char buff[256]; off_t load_addr; int found = 0; FILE *maps = fopen("/proc/self/maps", "r"); - char name[PATH_MAX] = {'\0'}; - - strncpy(name, elf.data(), PATH_MAX); - { - struct stat buf{}; - while (lstat(name, &buf) == 0 && S_ISLNK(buf.st_mode)) { - if (auto s = readlink(name, name, PATH_MAX); s >= 0) { - name[s] = '\0'; - } else { - fclose(maps); - LOGE("cannot read link for %s with %s", name, strerror(errno)); - return nullptr; - } - } - } - -// fs::path name(elf); -// std::error_code ec; -// while(fs::is_symlink(name, ec) && !ec) { -// name = fs::read_symlink(name); -// } while (fgets(buff, sizeof(buff), maps)) { - if ((strstr(buff, "r-xp") || strstr(buff, "r--p")) && strstr(buff, name)) { + if ((strstr(buff, "r-xp") || strstr(buff, "r--p")) && strstr(buff, elf.data())) { found = 1; LOGD("found: %s", buff); + std::string_view b = buff; + if (auto begin = b.find_last_of(' '); begin != std::string_view::npos) { + elf = b.substr(begin + 1); + if (elf.back() == '\n') elf.pop_back(); + } else { + return false; + } + LOGD("update path: %s", elf.data()); break; } } if (!found) { - LOGE("failed to read load address for %s", name); + LOGE("failed to read load address for %s", elf.data()); fclose(maps); - return nullptr; + return false; } if (char *next = buff; load_addr = strtoul(buff, &next, 16), next == buff) { - LOGE("failed to read load address for %s", name); + LOGE("failed to read load address for %s", elf.data()); } fclose(maps); - LOGD("get module base %s: %lx", name, load_addr); + LOGD("get module base %s: %lx", elf.data(), load_addr); - return reinterpret_cast(load_addr); + base = reinterpret_cast(load_addr); + return true; } diff --git a/core/src/main/cpp/main/src/elf_util.h b/core/src/main/cpp/main/src/elf_util.h index 9772cd56..e1f5c5b6 100644 --- a/core/src/main/cpp/main/src/elf_util.h +++ b/core/src/main/cpp/main/src/elf_util.h @@ -39,18 +39,25 @@ namespace SandHook { return getSymbOffset(name, GnuHash(name), ElfHash(name)); } - void *getModuleBase() const; - constexpr ElfW(Addr) getSymbAddress(std::string_view name) const { ElfW(Addr) offset = getSymbOffset(name); if (offset > 0 && base != nullptr) { return static_cast((uintptr_t) base + offset - bias); } else { - LOGE("fail to get symbol %s from %s ", name.data(), elf.data()); return 0; } } + template + requires(std::is_pointer_v) + constexpr T getSymbAddress(std::string_view name) const { + return reinterpret_cast(getSymbAddress(name)); + } + + bool isValid() const { + return base != nullptr; + } + ~ElfImg(); private: @@ -66,7 +73,9 @@ namespace SandHook { constexpr static uint32_t GnuHash(std::string_view name); - std::string_view elf; + bool findModuleBase(); + + std::string elf; void *base = nullptr; char *buffer = nullptr; off_t size = 0; diff --git a/core/src/main/cpp/main/src/jni/resources_hook.cpp b/core/src/main/cpp/main/src/jni/resources_hook.cpp index 75f56164..b28957c7 100644 --- a/core/src/main/cpp/main/src/jni/resources_hook.cpp +++ b/core/src/main/cpp/main/src/jni/resources_hook.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include "native_util.h" #include "resources_hook.h" @@ -49,24 +50,24 @@ namespace lspd { static TYPE_GET_ATTR_NAME_ID ResXMLParser_getAttributeNameID = nullptr; static bool PrepareSymbols() { - ScopedDlHandle fw_handle(kLibFwPath.c_str()); - if (!fw_handle.IsValid()) { + SandHook::ElfImg fw(kLibFwName); + if (!fw.isValid()) { return false; }; - if (!(ResXMLParser_next = fw_handle.DlSym( + if (!(ResXMLParser_next = fw.getSymbAddress( "_ZN7android12ResXMLParser4nextEv"))) { return false; } - if (!(ResXMLParser_restart = fw_handle.DlSym( + if (!(ResXMLParser_restart = fw.getSymbAddress( "_ZN7android12ResXMLParser7restartEv"))) { return false; }; - if (!(ResXMLParser_getAttributeNameID = fw_handle.DlSym( + if (!(ResXMLParser_getAttributeNameID = fw.getSymbAddress( LP_SELECT("_ZNK7android12ResXMLParser18getAttributeNameIDEj", "_ZNK7android12ResXMLParser18getAttributeNameIDEm")))) { return false; } - return android::ResStringPool::setup(fw_handle.Get()); + return android::ResStringPool::setup(fw); } LSP_DEF_NATIVE_METHOD(jboolean, ResourcesHook, initXResourcesNative) { diff --git a/core/src/main/cpp/main/src/native_hook.cpp b/core/src/main/cpp/main/src/native_hook.cpp index c01f3734..b654d33b 100644 --- a/core/src/main/cpp/main/src/native_hook.cpp +++ b/core/src/main/cpp/main/src/native_hook.cpp @@ -47,6 +47,10 @@ namespace lspd { return; } LOGD("Start to install inline hooks"); + SandHook::ElfImg &handle_libart = *art_img; + if (!handle_libart.isValid()) { + LOGE("Failed to fetch libart.so"); + } art::Runtime::Setup(handle_libart); art::hidden_api::DisableHiddenApi(handle_libart); art::art_method::Setup(handle_libart); @@ -57,6 +61,7 @@ namespace lspd { art::instrumentation::DisableUpdateHookedMethodsCode(handle_libart); art::thread_list::ScopedSuspendAll::Setup(handle_libart); art::gc::ScopedGCCriticalSection::Setup(handle_libart); + art_img.reset(); LOGD("Inline hooks installed"); } } diff --git a/core/src/main/cpp/main/src/service.cpp b/core/src/main/cpp/main/src/service.cpp index dff63e0e..5113242f 100644 --- a/core/src/main/cpp/main/src/service.cpp +++ b/core/src/main/cpp/main/src/service.cpp @@ -131,10 +131,7 @@ namespace lspd { auto binderClass = JNI_FindClass(env, "android/os/Binder"); exec_transact_backup_methodID_ = JNI_GetMethodID(env, binderClass, "execTransact", "(IJJI)Z"); - auto set_table_override = reinterpret_cast(Dlsym(handle_libart, - "_ZN3art9JNIEnvExt16SetTableOverrideEPK18JNINativeInterface")); - if (!set_table_override) { + if (!sym_set_table_override) { LOGE("set table override not found"); } memcpy(&native_interface_replace_, env->functions, sizeof(JNINativeInterface)); @@ -142,8 +139,9 @@ namespace lspd { call_boolean_method_va_backup_ = env->functions->CallBooleanMethodV; native_interface_replace_.CallBooleanMethodV = &call_boolean_method_va_replace; - if (set_table_override != nullptr) { - set_table_override(&native_interface_replace_); + if (sym_set_table_override != nullptr) { + reinterpret_cast(sym_set_table_override)( + &native_interface_replace_); } LOGD("Done InitService"); diff --git a/core/src/main/cpp/main/src/symbol_cache.cpp b/core/src/main/cpp/main/src/symbol_cache.cpp index bb077e60..d9c79d00 100644 --- a/core/src/main/cpp/main/src/symbol_cache.cpp +++ b/core/src/main/cpp/main/src/symbol_cache.cpp @@ -33,129 +33,43 @@ namespace lspd { bool sym_initialized = false; void *sym_do_dlopen = nullptr; - void *handle_libart = nullptr; void *sym_openInMemoryDexFilesNative = nullptr; void *sym_createCookieWithArray = nullptr; void *sym_createCookieWithDirectBuffer = nullptr; void *sym_openDexFileNative = nullptr; void *sym_setTrusted = nullptr; + void *sym_set_table_override = nullptr; + std::unique_ptr art_img = nullptr; - struct soinfo; - - soinfo *solist = nullptr; - soinfo *somain = nullptr; - - template - constexpr inline T *getStaticVariable(const SandHook::ElfImg &linker, std::string_view name) { - auto *addr = reinterpret_cast(linker.getSymbAddress(name)); - return addr == nullptr ? nullptr : *addr; - } - - struct soinfo { - soinfo *next() { - return *(soinfo **) ((uintptr_t) this + solist_next_offset); - } - - const char *get_realpath() { - return get_realpath_sym ? get_realpath_sym(this) : ((std::string *) ( - (uintptr_t) this + - solist_realpath_offset))->c_str(); - } - - const char *get_soname() { - return get_soname_sym ? get_soname_sym(this) : *((const char **) ( - (uintptr_t) this + - solist_realpath_offset - sizeof(void *))); - } - - void *to_handle() { - return to_handle_sym ? to_handle_sym(this) : nullptr; - } - - static bool setup(const SandHook::ElfImg &linker) { - get_realpath_sym = reinterpret_cast(linker.getSymbAddress( - "__dl__ZNK6soinfo12get_realpathEv")); - get_soname_sym = reinterpret_cast(linker.getSymbAddress( - "__dl__ZNK6soinfo10get_sonameEv")); - to_handle_sym = reinterpret_cast(linker.getSymbAddress( - "__dl__ZN6soinfo9to_handleEv")); - auto vsdo = getStaticVariable(linker, "__dl__ZL4vdso"); - for (size_t i = 0; i < 1024 / sizeof(void *); i++) { - auto *possible_next = *(void **) ((uintptr_t) solist + i * sizeof(void *)); - if (possible_next == somain || (vsdo && possible_next == vsdo)) { - solist_next_offset = i * sizeof(void *); - return (get_realpath_sym && get_soname_sym && to_handle_sym); - } - } - LOGW("%s", "failed to search next offset"); - // shortcut - return false; - } - -#ifdef __LP64__ - inline static size_t solist_next_offset = 0x30; - constexpr static size_t solist_realpath_offset = 0x1a8; -#else - inline static size_t solist_next_offset = 0xa4; - constexpr static size_t solist_realpath_offset = 0x174; -#endif - - // since Android 8 - inline static const char *(*get_realpath_sym)(soinfo *) = nullptr; - - inline static const char *(*get_soname_sym)(soinfo *) = nullptr; - - inline static void *(*to_handle_sym)(soinfo *) = nullptr; - }; - - std::vector linker_get_solist() { - std::vector linker_solist{}; - for (auto *iter = solist; iter; iter = iter->next()) { - linker_solist.push_back(iter); - } - return linker_solist; - } - - void *findLibArt() { - for (const auto &soinfo : linker_get_solist()) { - if (const auto &real_path = soinfo->get_realpath(), &soname = soinfo->get_soname(); - (real_path && - std::string_view(real_path).find(kLibArtName) != std::string_view::npos)) { - auto art = SandHook::ElfImg(real_path); - auto api_level = GetAndroidApiLevel(); - if (api_level < __ANDROID_API_P__ || ( - (sym_openDexFileNative = reinterpret_cast(art.getSymbAddress( - "_ZN3artL25DexFile_openDexFileNativeEP7_JNIEnvP7_jclassP8_jstringS5_iP8_jobjectP13_jobjectArray"))) && + bool findLibArt() { + art_img = std::make_unique(kLibArtName); + if (!art_img->isValid()) return false; + auto api_level = GetAndroidApiLevel(); + return (sym_set_table_override = art_img->getSymbAddress( + "_ZN3art9JNIEnvExt16SetTableOverrideEPK18JNINativeInterface")) != nullptr + && (api_level < __ANDROID_API_P__ || ( + (sym_openDexFileNative = art_img->getSymbAddress( + "_ZN3artL25DexFile_openDexFileNativeEP7_JNIEnvP7_jclassP8_jstringS5_iP8_jobjectP13_jobjectArray")) && + ( + (sym_openInMemoryDexFilesNative = art_img->getSymbAddress( + "_ZN3artL34DexFile_openInMemoryDexFilesNativeEP7_JNIEnvP7_jclassP13_jobjectArrayS5_P10_jintArrayS7_P8_jobjectS5_")) || ( - (sym_openInMemoryDexFilesNative = reinterpret_cast(art.getSymbAddress( - "_ZN3artL34DexFile_openInMemoryDexFilesNativeEP7_JNIEnvP7_jclassP13_jobjectArrayS5_P10_jintArrayS7_P8_jobjectS5_"))) || - ( - (sym_createCookieWithArray = reinterpret_cast(art.getSymbAddress( - "_ZN3artL29DexFile_createCookieWithArrayEP7_JNIEnvP7_jclassP11_jbyteArrayii"))) && - (sym_createCookieWithDirectBuffer = reinterpret_cast(art.getSymbAddress( - "_ZN3artL36DexFile_createCookieWithDirectBufferEP7_JNIEnvP7_jclassP8_jobjectii"))) - ) - ) && - (sym_setTrusted = reinterpret_cast(art.getSymbAddress( - "_ZN3artL18DexFile_setTrustedEP7_JNIEnvP7_jclassP8_jobject"))))) - return soinfo->to_handle(); - } - } - return nullptr; + (sym_createCookieWithArray = art_img->getSymbAddress( + "_ZN3artL29DexFile_createCookieWithArrayEP7_JNIEnvP7_jclassP11_jbyteArrayii")) && + (sym_createCookieWithDirectBuffer = art_img->getSymbAddress( + "_ZN3artL36DexFile_createCookieWithDirectBufferEP7_JNIEnvP7_jclassP8_jobjectii")) + ) + ) && + (sym_setTrusted = art_img->getSymbAddress( + "_ZN3artL18DexFile_setTrustedEP7_JNIEnvP7_jclassP8_jobject")))); } void InitSymbolCache() { if (UNLIKELY(sym_initialized)) return; LOGD("InitSymbolCache"); - auto linker = SandHook::ElfImg(kLinkerPath.c_str()); - auto libc = SandHook::ElfImg(kLibcPath.c_str()); - auto libbase = SandHook::ElfImg(kLibbasePath.c_str()); - sym_initialized = (solist = getStaticVariable(linker, "__dl__ZL6solist")) && - (somain = getStaticVariable(linker, "__dl__ZL6somain")) && - (sym_do_dlopen = reinterpret_cast(linker.getSymbAddress( - "__dl__Z9do_dlopenPKciPK17android_dlextinfoPKv"))) && - soinfo::setup(linker) && (handle_libart = findLibArt()); + sym_initialized = findLibArt(); if (UNLIKELY(!sym_initialized)) { + art_img.reset(); LOGE("Init symbol cache failed"); } } diff --git a/core/src/main/cpp/main/src/symbol_cache.h b/core/src/main/cpp/main/src/symbol_cache.h index 49cc6752..1aa97eff 100644 --- a/core/src/main/cpp/main/src/symbol_cache.h +++ b/core/src/main/cpp/main/src/symbol_cache.h @@ -25,15 +25,21 @@ #ifndef LSPOSED_SYMBOL_CACHE_H #define LSPOSED_SYMBOL_CACHE_H +#include +namespace SandHook { + class ElfImg; +} + namespace lspd { extern bool sym_initialized; + extern std::unique_ptr art_img; extern void *sym_do_dlopen; - extern void *handle_libart; extern void *sym_openInMemoryDexFilesNative; extern void *sym_createCookieWithArray; extern void *sym_createCookieWithDirectBuffer; extern void *sym_openDexFileNative; extern void *sym_setTrusted; + extern void *sym_set_table_override; void InitSymbolCache(); }