Remove symbol cache (#2872)
It only caches one symbol now, and thus is unnecessary to use cache anymore
This commit is contained in:
parent
6acdd1cf6b
commit
42190f1fb8
|
|
@ -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<SymbolCache> symbol_cache;
|
||||
|
||||
void InitSymbolCache(SymbolCache *other);
|
||||
|
||||
std::unique_ptr<const SandHook::ElfImg> &GetArt(bool release=false);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,13 +24,13 @@
|
|||
|
||||
#include "native_api.h"
|
||||
#include "logging.h"
|
||||
#include "symbol_cache.h"
|
||||
#include "utils/hook_helper.hpp"
|
||||
#include <sys/mman.h>
|
||||
#include <dobby.h>
|
||||
#include <list>
|
||||
#include <dlfcn.h>
|
||||
#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;
|
||||
|
|
|
|||
|
|
@ -31,8 +31,6 @@
|
|||
#include <logging.h>
|
||||
|
||||
namespace lspd {
|
||||
std::unique_ptr<SymbolCache> symbol_cache = std::make_unique<SymbolCache>();
|
||||
|
||||
std::unique_ptr<const SandHook::ElfImg> &GetArt(bool release) {
|
||||
static std::unique_ptr<const SandHook::ElfImg> 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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<decltype(ashmem_create_region)>(
|
||||
dlsym(cutils, "ashmem_create_region")) : nullptr;
|
||||
ashmem_set_prot_region = cutils ? reinterpret_cast<decltype(ashmem_set_prot_region)>(
|
||||
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<SymbolCache *>(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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue