fix: injection when libdl.so is not in apex

This commit fixes the issue where "libdl.so" wouldn't be found, when trying to inject "lizygisk.so", in systems where apex is in "/system/lib/libdl.so".
This commit is contained in:
ThePedroo
2025-05-23 12:26:00 -03:00
parent 6272e0a2ac
commit d455117c49
4 changed files with 42 additions and 33 deletions

View File

@@ -535,8 +535,10 @@ ElfW(Addr) GnuLookup(ElfImg *restrict img, const char *name, uint32_t hash) {
((uintptr_t)1 << ((hash >> img->gnu_shift2_) % bloom_mask_bits));
if ((mask & bloom_word) != mask) {
LOGE("Symbol '%s' (hash %u) filtered out by GNU Bloom Filter (idx %zu, mask 0x%lx, word 0x%lx)",
name, hash, bloom_idx, (unsigned long)mask, (unsigned long)bloom_word);
/* INFO: Very loggy -- generates too much noise. GNU is rarely used for Zygisk context. */
/* LOGW("Symbol '%s' (hash %u) filtered out by GNU Bloom Filter (idx %zu, mask 0x%lx, word 0x%lx)",
name, hash, bloom_idx, (unsigned long)mask, (unsigned long)bloom_word);
*/
return 0;
}

View File

@@ -159,17 +159,30 @@ bool inject_on_main(int pid, const char *lib_path) {
void *libc_return_addr = find_module_return_addr(map, "libc.so");
LOGD("libc return addr %p", libc_return_addr);
const char *libdl_path = NULL;
for (size_t i = 0; i < local_map->size; i++) {
if (local_map->maps[i].path == NULL) continue;
const char *filename = position_after(local_map->maps[i].path, '/');
if (strcmp(filename, "libdl.so") == 0) {
libdl_path = local_map->maps[i].path;
break;
}
}
/* call dlopen */
#ifdef __LP64__
void *dlopen_addr = find_func_addr(local_map, map, "/apex/com.android.runtime/lib64/bionic/libdl.so", "dlopen");
#else
void *dlopen_addr = find_func_addr(local_map, map, "/apex/com.android.runtime/lib/bionic/libdl.so", "dlopen");
#endif
if (dlopen_addr == NULL) {
void *dlopen_addr = NULL;
if (!libdl_path || (dlopen_addr = find_func_addr(local_map, map, libdl_path, "dlopen")) == NULL) {
/* INFO: Android 7.1 and below doesn't have libdl.so loaded in Zygote */
LOGW("Failed to find dlopen from libdl.so, will load from linker");
dlopen_addr = find_func_addr(local_map, map, "/system/bin/linker", "__dl_dlopen");
#ifdef __LP64__
dlopen_addr = find_func_addr(local_map, map, "/system/bin/linker64", "__dl_dlopen");
#else
dlopen_addr = find_func_addr(local_map, map, "/system/bin/linker", "__dl_dlopen");
#endif
if (dlopen_addr == NULL) {
PLOGE("Find __dl_dlopen");
@@ -198,16 +211,16 @@ bool inject_on_main(int pid, const char *lib_path) {
LOGE("handle is null");
/* call dlerror */
#ifdef __LP64__
void *dlerror_addr = find_func_addr(local_map, map, "/apex/com.android.runtime/lib64/bionic/libdl.so", "dlerror");
#else
void *dlerror_addr = find_func_addr(local_map, map, "/apex/com.android.runtime/lib/bionic/libdl.so", "dlerror");
#endif
if (dlerror_addr == NULL) {
void *dlerror_addr = NULL;
if (!libdl_path || (dlerror_addr = find_func_addr(local_map, map, libdl_path, "dlerror")) == NULL) {
/* INFO: Android 7.1 and below doesn't have libdl.so loaded in Zygote */
LOGW("Failed to find dlerror from libdl.so, will load from linker");
dlerror_addr = find_func_addr(local_map, map, "/system/bin/linker", "__dl_dlerror");
#ifdef __LP64__
dlerror_addr = find_func_addr(local_map, map, "/system/bin/linker64", "__dl_dlerror");
#else
dlerror_addr = find_func_addr(local_map, map, "/system/bin/linker", "__dl_dlerror");
#endif
if (dlerror_addr == NULL) {
LOGE("Find __dl_dlerror");
@@ -273,16 +286,16 @@ bool inject_on_main(int pid, const char *lib_path) {
}
/* call dlsym(handle, "entry") */
#ifdef __LP64__
void *dlsym_addr = find_func_addr(local_map, map, "/apex/com.android.runtime/lib64/bionic/libdl.so", "dlsym");
#else
void *dlsym_addr = find_func_addr(local_map, map, "/apex/com.android.runtime/lib/bionic/libdl.so", "dlsym");
#endif
if (dlsym_addr == NULL) {
void *dlsym_addr = NULL;
if (!libdl_path || (dlsym_addr = find_func_addr(local_map, map, libdl_path, "dlsym")) == NULL) {
/* INFO: Android 7.1 and below doesn't have libdl.so loaded in Zygote */
LOGW("Failed to find dlsym from libdl.so, will load from linker");
dlsym_addr = find_func_addr(local_map, map, "/system/bin/linker", "__dl_dlsym");
#ifdef __LP64__
dlsym_addr = find_func_addr(local_map, map, "/system/bin/linker64", "__dl_dlsym");
#else
dlsym_addr = find_func_addr(local_map, map, "/system/bin/linker", "__dl_dlsym");
#endif
if (dlsym_addr == NULL) {
LOGE("find __dl_dlsym");

View File

@@ -313,20 +313,12 @@ void *find_module_return_addr(struct maps *map, const char *suffix) {
}
void *find_module_base(struct maps *map, const char *file) {
const char *suffix = position_after(file, '/');
if (!suffix) {
LOGE("failed to find suffix in %s", file);
return NULL;
}
for (size_t i = 0; i < map->size; i++) {
if (map->maps[i].path == NULL) continue;
const char *file_name = position_after(map->maps[i].path, '/');
if (!file_name) continue;
const char *file_path = map->maps[i].path;
if (strlen(file_name) < strlen(suffix) || map->maps[i].offset != 0 || strncmp(file_name, suffix, strlen(suffix)) != 0) continue;
if (strlen(file_path) != strlen(file) || map->maps[i].offset != 0 || strncmp(file_path, file, strlen(file)) != 0) continue;
return (void *)map->maps[i].start;
}

View File

@@ -62,6 +62,8 @@ bool set_regs(int pid, struct user_regs_struct *regs);
void get_addr_mem_region(struct maps *map, uintptr_t addr, char *buf, size_t buf_size);
const char *position_after(const char *str, const char needle);
void *find_module_return_addr(struct maps *map, const char *suffix);
void *find_func_addr(struct maps *local_info, struct maps *remote_info, const char *module, const char *func);