From 42190f1fb8dd3efe8c241bc60dc5fc38f4c3e6aa Mon Sep 17 00:00:00 2001 From: LoveSy Date: Wed, 6 Dec 2023 19:54:15 +0800 Subject: [PATCH] Remove symbol cache (#2872) It only caches one symbol now, and thus is unnecessary to use cache anymore --- core/src/main/jni/include/symbol_cache.h | 19 -- core/src/main/jni/src/native_api.cpp | 10 +- core/src/main/jni/src/symbol_cache.cpp | 20 -- magisk-loader/src/main/jni/api/riru_main.cpp | 1 - .../src/main/jni/api/zygisk_main.cpp | 297 +----------------- .../src/main/jni/src/magisk_loader.cpp | 6 +- 6 files changed, 8 insertions(+), 345 deletions(-) diff --git a/core/src/main/jni/include/symbol_cache.h b/core/src/main/jni/include/symbol_cache.h index 7369c311..e4d2f0e4 100644 --- a/core/src/main/jni/include/symbol_cache.h +++ b/core/src/main/jni/include/symbol_cache.h @@ -32,25 +32,6 @@ namespace SandHook { } namespace lspd { - struct SymbolCache { - std::atomic_flag initialized{}; - void *do_dlopen; - - SymbolCache() = default; - - SymbolCache(const SymbolCache &other) : - do_dlopen(other.do_dlopen) {} - - SymbolCache &operator=(const SymbolCache &other) { - new(this)SymbolCache(other); - return *this; - } - }; - - extern std::unique_ptr symbol_cache; - - void InitSymbolCache(SymbolCache *other); - std::unique_ptr &GetArt(bool release=false); } diff --git a/core/src/main/jni/src/native_api.cpp b/core/src/main/jni/src/native_api.cpp index 49880045..3650832b 100644 --- a/core/src/main/jni/src/native_api.cpp +++ b/core/src/main/jni/src/native_api.cpp @@ -24,13 +24,13 @@ #include "native_api.h" #include "logging.h" -#include "symbol_cache.h" #include "utils/hook_helper.hpp" #include #include #include #include #include "native_util.h" +#include "elf_util.h" /* @@ -133,9 +133,11 @@ namespace lspd { }); bool InstallNativeAPI(const lsplant::HookHandler & handler) { - LOGD("InstallNativeAPI: {}", symbol_cache->do_dlopen); - if (symbol_cache->do_dlopen) [[likely]] { - HookSymNoHandle(handler, symbol_cache->do_dlopen, do_dlopen); + auto *do_dlopen_sym = SandHook::ElfImg("/linker").getSymbAddress( + "__dl__Z9do_dlopenPKciPK17android_dlextinfoPKv"); + LOGD("InstallNativeAPI: {}", do_dlopen_sym); + if (do_dlopen_sym) [[likely]] { + HookSymNoHandle(handler, do_dlopen_sym, do_dlopen); return true; } return false; diff --git a/core/src/main/jni/src/symbol_cache.cpp b/core/src/main/jni/src/symbol_cache.cpp index db27ac62..552ae38f 100644 --- a/core/src/main/jni/src/symbol_cache.cpp +++ b/core/src/main/jni/src/symbol_cache.cpp @@ -31,8 +31,6 @@ #include namespace lspd { - std::unique_ptr symbol_cache = std::make_unique(); - std::unique_ptr &GetArt(bool release) { static std::unique_ptr kArtImg = nullptr; if (release) { @@ -42,22 +40,4 @@ namespace lspd { } return kArtImg; } - - - void InitSymbolCache(SymbolCache *other) { - LOGD("InitSymbolCache"); - if (other && other->initialized.test(std::memory_order_acquire)) { - LOGD("Already initialized"); - *symbol_cache = *other; - symbol_cache->initialized.test_and_set(std::memory_order_relaxed); - return; - } - symbol_cache->do_dlopen = SandHook::ElfImg("/linker").getSymbAddress( - "__dl__Z9do_dlopenPKciPK17android_dlextinfoPKv"); - symbol_cache->initialized.test_and_set(std::memory_order_relaxed); - if (other) { - *other = *symbol_cache; - other->initialized.test_and_set(std::memory_order_acq_rel); - } - } } // namespace lspd diff --git a/magisk-loader/src/main/jni/api/riru_main.cpp b/magisk-loader/src/main/jni/api/riru_main.cpp index c33f9180..957c1488 100644 --- a/magisk-loader/src/main/jni/api/riru_main.cpp +++ b/magisk-loader/src/main/jni/api/riru_main.cpp @@ -42,7 +42,6 @@ namespace lspd { void onModuleLoaded() { LOGI("onModuleLoaded: welcome to LSPosed!"); LOGI("onModuleLoaded: version v{} ({})", versionName, versionCode); - InitSymbolCache(nullptr); MagiskLoader::Init(); ConfigImpl::Init(); } diff --git a/magisk-loader/src/main/jni/api/zygisk_main.cpp b/magisk-loader/src/main/jni/api/zygisk_main.cpp index 5e2bbd8f..0668742a 100644 --- a/magisk-loader/src/main/jni/api/zygisk_main.cpp +++ b/magisk-loader/src/main/jni/api/zygisk_main.cpp @@ -30,251 +30,9 @@ #include "symbol_cache.h" namespace lspd { - namespace { - ssize_t xsendmsg(int sockfd, const struct msghdr *msg, int flags) { - int sent = sendmsg(sockfd, msg, flags); - if (sent < 0) { - PLOGE("sendmsg"); - } - return sent; - } - - ssize_t xrecvmsg(int sockfd, struct msghdr *msg, int flags) { - int rec = recvmsg(sockfd, msg, flags); - if (rec < 0) { - PLOGE("recvmsg"); - } - return rec; - } - - // Read exact same size as count - ssize_t xxread(int fd, void *buf, size_t count) { - size_t read_sz = 0; - ssize_t ret; - do { - ret = read(fd, (std::byte *) buf + read_sz, count - read_sz); - if (ret < 0) { - if (errno == EINTR) - continue; - PLOGE("read"); - return ret; - } - read_sz += ret; - } while (read_sz != count && ret != 0); - if (read_sz != count) { - PLOGE("read ({} != {})", count, read_sz); - } - return read_sz; - } - - // Write exact same size as count - ssize_t xwrite(int fd, const void *buf, size_t count) { - size_t write_sz = 0; - ssize_t ret; - do { - ret = write(fd, (std::byte *) buf + write_sz, count - write_sz); - if (ret < 0) { - if (errno == EINTR) - continue; - PLOGE("write"); - return ret; - } - write_sz += ret; - } while (write_sz != count && ret != 0); - if (write_sz != count) { - PLOGE("write ({} != {})", count, write_sz); - } - return write_sz; - } - - int send_fds(int sockfd, void *cmsgbuf, size_t bufsz, const int *fds, int cnt) { - iovec iov = { - .iov_base = &cnt, - .iov_len = sizeof(cnt), - }; - msghdr msg = { - .msg_iov = &iov, - .msg_iovlen = 1, - }; - - if (cnt) { - msg.msg_control = cmsgbuf; - msg.msg_controllen = bufsz; - cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); - cmsg->cmsg_len = CMSG_LEN(sizeof(int) * cnt); - cmsg->cmsg_level = SOL_SOCKET; - cmsg->cmsg_type = SCM_RIGHTS; - - memcpy(CMSG_DATA(cmsg), fds, sizeof(int) * cnt); - } - - return xsendmsg(sockfd, &msg, 0); - } - - int send_fd(int sockfd, int fd) { - if (fd < 0) { - return send_fds(sockfd, nullptr, 0, nullptr, 0); - } - char cmsgbuf[CMSG_SPACE(sizeof(int))]; - return send_fds(sockfd, cmsgbuf, sizeof(cmsgbuf), &fd, 1); - } - - void *recv_fds(int sockfd, char *cmsgbuf, size_t bufsz, int cnt) { - iovec iov = { - .iov_base = &cnt, - .iov_len = sizeof(cnt), - }; - msghdr msg = { - .msg_iov = &iov, - .msg_iovlen = 1, - .msg_control = cmsgbuf, - .msg_controllen = bufsz - }; - - xrecvmsg(sockfd, &msg, MSG_WAITALL); - cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); - - if (msg.msg_controllen != bufsz || - cmsg == nullptr || - cmsg->cmsg_len != CMSG_LEN(sizeof(int) * cnt) || - cmsg->cmsg_level != SOL_SOCKET || - cmsg->cmsg_type != SCM_RIGHTS) { - return nullptr; - } - - return CMSG_DATA(cmsg); - } - - int recv_fd(int sockfd) { - char cmsgbuf[CMSG_SPACE(sizeof(int))]; - - void *data = recv_fds(sockfd, cmsgbuf, sizeof(cmsgbuf), 1); - if (data == nullptr) - return -1; - - int result; - memcpy(&result, data, sizeof(int)); - return result; - } - - int read_int(int fd) { - int val; - if (xxread(fd, &val, sizeof(val)) != sizeof(val)) - return -1; - return val; - } - - void write_int(int fd, int val) { - if (fd < 0) return; - xwrite(fd, &val, sizeof(val)); - } - - int allow_unload = 0; - } - + int allow_unload = 0; int *allowUnload = &allow_unload; - class SharedMem { - inline static void *cutils = nullptr; - - inline static int (*ashmem_create_region)(const char *name, std::size_t size) = nullptr; - - inline static int (*ashmem_set_prot_region)(int fd, int prot) = nullptr; - - inline static bool init = false; - - static void Init() { - if (init) return; - cutils = dlopen("/system/lib" LP_SELECT("", "64") "/libcutils.so", 0); - ashmem_create_region = cutils ? reinterpret_cast( - dlsym(cutils, "ashmem_create_region")) : nullptr; - ashmem_set_prot_region = cutils ? reinterpret_cast( - dlsym(cutils, "ashmem_set_prot_region")) : nullptr; - init = true; - } - - int fd_ = -1; - std::size_t size_ = 0; - - class MappedMem { - void *addr_ = nullptr; - std::size_t size_ = 0; - - friend class SharedMem; - - MappedMem(int fd, std::size_t size, int prot, int flags, off_t offset) : addr_( - mmap(nullptr, size, prot, flags, fd, offset)), size_(size) { - if (addr_ == MAP_FAILED) { - PLOGE("failed to mmap"); - addr_ = nullptr; - size_ = 0; - } - } - - MappedMem(const MappedMem &) = delete; - - MappedMem &operator=(const MappedMem &other) = delete; - - public: - MappedMem(MappedMem &&other) : addr_(other.addr_), size_(other.size_) { - other.addr_ = nullptr; - other.size_ = 0; - } - - MappedMem &operator=(MappedMem &&other) { - new(this)MappedMem(std::move(other)); - return *this; - } - - constexpr operator bool() { return addr_; } - - ~MappedMem() { - if (addr_) { - munmap(addr_, size_); - } - } - - constexpr auto size() const { return size_; } - - constexpr auto get() const { return addr_; } - }; - - public: - MappedMem map(int prot, int flags, off_t offset) { - return {fd_, size_, prot, flags, offset}; - } - - constexpr bool ok() const { return fd_ > 0 && size_ > 0; } - - SharedMem(std::string_view name, std::size_t size) { - Init(); - if (ashmem_create_region && (fd_ = ashmem_create_region(name.data(), size)) > 0) { - size_ = size; - LOGD("using memfd"); - } else { - LOGD("using tmp file"); - auto *tmp = tmpfile(); - if (tmp) { - fd_ = fileno(tmp); - ftruncate(fd_, size); - size_ = size; - } - } - } - - void SetProt(int prot) { - ashmem_set_prot_region(fd_, prot); - } - - SharedMem() : fd_(-1), size_(0) { - Init(); - } - - constexpr auto get() const { return fd_; } - - constexpr auto size() const { return size_; } - }; - class ZygiskModule : public zygisk::ModuleBase { JNIEnv *env_; zygisk::Api *api_; @@ -284,29 +42,6 @@ namespace lspd { api_ = api; MagiskLoader::Init(); ConfigImpl::Init(); - - auto companion = api->connectCompanion(); - if (companion == -1) { - LOGE("Failed to connect to companion"); - return; - } - - if (int fd = -1, size = 0; (size = read_int(companion)) > 0 && - (fd = recv_fd(companion)) != -1) { - if (auto addr = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); - addr && addr != MAP_FAILED) { - InitSymbolCache(reinterpret_cast(addr)); - msync(addr, size, MS_SYNC); - munmap(addr, size); - } else { - InitSymbolCache(nullptr); - } - close(fd); - } else { - LOGE("Failed to read symbol fd"); - InitSymbolCache(nullptr); - } - close(companion); } void preAppSpecialize(zygisk::AppSpecializeArgs *args) override { @@ -338,36 +73,6 @@ namespace lspd { if (*allowUnload) api_->setOption(zygisk::DLCLOSE_MODULE_LIBRARY); } }; - - SharedMem InitCompanion() { - LOGI("ZygiskCompanion: welcome to LSPosed!"); - LOGI("ZygiskCompanion: version v{} ({})", versionName, versionCode); - - SharedMem symbol{"symbol", sizeof(lspd::SymbolCache)}; - - if (!symbol.ok()) { - PLOGE("Failed to allocate shared mem"); - return {}; - } - - if (auto symbol_map = symbol.map(PROT_WRITE, MAP_SHARED, 0); symbol_map) { - memcpy(symbol_map.get(), lspd::symbol_cache.get(), symbol_map.size()); - } - return symbol; - } - - void CompanionEntry(int client) { - using namespace std::string_literals; - static auto symbol = InitCompanion(); - LOGD("Got cache with fd={} size={}", symbol.get(), symbol.size()); - if (symbol.ok()) { - write_int(client, symbol.size()); - send_fd(client, symbol.get()); - } else write_int(client, -1); - close(client); - } } //namespace lspd REGISTER_ZYGISK_MODULE(lspd::ZygiskModule); - -REGISTER_ZYGISK_COMPANION(lspd::CompanionEntry); diff --git a/magisk-loader/src/main/jni/src/magisk_loader.cpp b/magisk-loader/src/main/jni/src/magisk_loader.cpp index d4f4a4d1..184d1d94 100644 --- a/magisk-loader/src/main/jni/src/magisk_loader.cpp +++ b/magisk-loader/src/main/jni/src/magisk_loader.cpp @@ -89,10 +89,6 @@ namespace lspd { void MagiskLoader::OnNativeForkSystemServerPre(JNIEnv *env) { Service::instance()->InitService(env); - skip_ = !symbol_cache->initialized.test(std::memory_order_acquire); - if (skip_) [[unlikely]] { - LOGW("skip system server due to symbol cache"); - } setAllowUnload(skip_); } @@ -167,7 +163,7 @@ namespace lspd { Service::instance()->InitService(env); const auto app_id = uid % PER_USER_RANGE; JUTFString process_name(env, nice_name); - skip_ = !symbol_cache->initialized.test(std::memory_order_acquire); + skip_ = false; if (!skip_ && !app_data_dir) { LOGD("skip injecting into {} because it has no data dir", process_name.get()); skip_ = true;