[core] Use ashmem_create_region (#1304)
This commit is contained in:
parent
c166163885
commit
eeb8aa6ae3
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include <sys/socket.h>
|
||||
#include <fcntl.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include "jni/zygisk.h"
|
||||
#include "logging.h"
|
||||
|
|
@ -181,9 +182,9 @@ namespace lspd {
|
|||
return;
|
||||
}
|
||||
|
||||
if (int fd; read_int(companion) == 0 && (fd = recv_fd(companion)) != -1) {
|
||||
Context::GetInstance()->PreLoadDex(
|
||||
"/proc/self/fd/" + std::to_string(fd));
|
||||
if (int fd = -1, size = 0; (size = read_int(companion)) > 0 &&
|
||||
(fd = recv_fd(companion)) != -1) {
|
||||
Context::GetInstance()->PreLoadDex(fd, size);
|
||||
close(fd);
|
||||
} else {
|
||||
LOGE("Failed to read dex fd");
|
||||
|
|
@ -211,19 +212,49 @@ namespace lspd {
|
|||
}
|
||||
};
|
||||
|
||||
bool InitCompanion() {
|
||||
LOGD("onModuleLoaded: welcome to LSPosed!");
|
||||
LOGD("onModuleLoaded: version v%s (%d)", versionName, versionCode);
|
||||
return true;
|
||||
std::tuple<int, std::size_t> InitCompanion() {
|
||||
LOGI("onModuleLoaded: welcome to LSPosed!");
|
||||
LOGI("onModuleLoaded: version v%s (%d)", versionName, versionCode);
|
||||
|
||||
int (*ashmem_create_region)(const char *name, std::size_t size) = nullptr;
|
||||
int (*ashmem_set_prot_region)(int fd, int prot) = nullptr;
|
||||
|
||||
std::string path = "/data/adb/modules/"s + lspd::moduleName + "/" + kDexPath;
|
||||
int fd = open(path.data(), O_RDONLY | O_CLOEXEC);
|
||||
if (fd < 0) {
|
||||
LOGE("Failed to load dex: %s", path.data());
|
||||
return {-1, 0};
|
||||
}
|
||||
auto fsize = lseek(fd, 0, SEEK_END);
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
auto *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;
|
||||
int tmp_fd = -1;
|
||||
if (void *addr = nullptr;
|
||||
ashmem_create_region && ashmem_set_prot_region &&
|
||||
(tmp_fd = ashmem_create_region("lspd.dex", fsize)) > 0 &&
|
||||
(addr = mmap(nullptr, fsize, PROT_WRITE, MAP_SHARED, tmp_fd, 0)) &&
|
||||
read(fd, addr, fsize) > 0 && munmap(addr, fsize) == 0) {
|
||||
LOGD("using memfd");
|
||||
ashmem_set_prot_region(tmp_fd, PROT_READ);
|
||||
std::swap(fd, tmp_fd);
|
||||
} else {
|
||||
LOGD("using raw fd");
|
||||
}
|
||||
|
||||
close(tmp_fd);
|
||||
dlclose(cutils);
|
||||
return {fd, fsize};
|
||||
}
|
||||
|
||||
void CompanionEntry(int client) {
|
||||
using namespace std::string_literals;
|
||||
static bool inited = InitCompanion();
|
||||
static std::string path = "/data/adb/modules/"s + lspd::moduleName + "/" + kDexPath;
|
||||
static int fd = open(path.data(), O_RDONLY | O_CLOEXEC);
|
||||
if (inited && fd > 0) {
|
||||
write_int(client, 0);
|
||||
static auto[fd, size] = InitCompanion();
|
||||
if (fd > 0 && size > 0) {
|
||||
write_int(client, size);
|
||||
send_fd(client, fd);
|
||||
} else write_int(client, -1);
|
||||
close(client);
|
||||
|
|
|
|||
|
|
@ -58,11 +58,8 @@ namespace lspd {
|
|||
}
|
||||
}
|
||||
|
||||
Context::PreloadedDex::PreloadedDex(FILE *f) {
|
||||
fseek(f, 0, SEEK_END);
|
||||
auto size = ftell(f);
|
||||
rewind(f);
|
||||
if (auto addr = mmap(nullptr, size, PROT_READ, MAP_SHARED, fileno(f), 0); addr) {
|
||||
Context::PreloadedDex::PreloadedDex(int fd, std::size_t size) {
|
||||
if (auto addr = mmap(nullptr, size, PROT_READ, MAP_SHARED, fd, 0); addr) {
|
||||
addr_ = addr;
|
||||
size_ = size;
|
||||
} else {
|
||||
|
|
@ -74,17 +71,25 @@ namespace lspd {
|
|||
if (*this) munmap(addr_, size_);
|
||||
}
|
||||
|
||||
void Context::PreLoadDex(int fd, std::size_t size) {
|
||||
dex_ = PreloadedDex{fd, size};
|
||||
}
|
||||
|
||||
void Context::PreLoadDex(std::string_view dex_path) {
|
||||
if (dex_) [[unlikely]] return;
|
||||
|
||||
std::unique_ptr<FILE, decltype(&fclose)> f{fopen(dex_path.data(), "rb"), &fclose};
|
||||
|
||||
if (!f || !(dex_ = PreloadedDex(f.get()))) {
|
||||
if (!f) {
|
||||
LOGE("Fail to open dex from %s", dex_path.data());
|
||||
return;
|
||||
} else {
|
||||
fseek(f.get(), 0, SEEK_END);
|
||||
auto size = ftell(f.get());
|
||||
rewind(f.get());
|
||||
PreLoadDex(fileno(f.get()), size);
|
||||
}
|
||||
|
||||
LOGI("Loaded %s with size %zu", dex_path.data(), dex_.size());
|
||||
LOGD("Loaded %s with size %zu", dex_path.data(), dex_.size());
|
||||
}
|
||||
|
||||
void Context::LoadDex(JNIEnv *env) {
|
||||
|
|
@ -272,4 +277,4 @@ namespace lspd {
|
|||
*allowUnload = unload ? 1 : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace lspd
|
||||
|
|
|
|||
|
|
@ -61,6 +61,8 @@ namespace lspd {
|
|||
|
||||
void PreLoadDex(std::string_view dex_paths);
|
||||
|
||||
void PreLoadDex(int fd, std::size_t size);
|
||||
|
||||
void Init();
|
||||
|
||||
private:
|
||||
|
|
@ -80,6 +82,8 @@ namespace lspd {
|
|||
|
||||
PreloadedDex &operator=(const PreloadedDex &) = delete;
|
||||
|
||||
PreloadedDex(int fd, std::size_t size);
|
||||
|
||||
PreloadedDex &operator=(PreloadedDex &&other) {
|
||||
addr_ = other.addr_;
|
||||
size_ = other.size_;
|
||||
|
|
@ -99,8 +103,6 @@ namespace lspd {
|
|||
|
||||
auto data() const { return addr_; }
|
||||
|
||||
PreloadedDex(FILE *f);
|
||||
|
||||
~PreloadedDex();
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -927,9 +927,8 @@ public class ConfigManager {
|
|||
|
||||
public static List<String> getDenyListPackages() {
|
||||
List<String> result = new ArrayList<>();
|
||||
try {
|
||||
final SQLiteDatabase magiskDb =
|
||||
SQLiteDatabase.openDatabase(ConfigFileManager.magiskDbPath, new SQLiteDatabase.OpenParams.Builder().addOpenFlags(SQLiteDatabase.OPEN_READONLY).build());
|
||||
try (final SQLiteDatabase magiskDb =
|
||||
SQLiteDatabase.openDatabase(ConfigFileManager.magiskDbPath, new SQLiteDatabase.OpenParams.Builder().addOpenFlags(SQLiteDatabase.OPEN_READONLY).build())) {
|
||||
try (Cursor cursor = magiskDb.query(true, "denylist", new String[]{"package_name"}, null, null, null, null, null, null, null)) {
|
||||
if (cursor == null) return result;
|
||||
int packageNameIdx = cursor.getColumnIndex("package_name");
|
||||
|
|
|
|||
Loading…
Reference in New Issue