diff --git a/loader/src/common/elf_util.c b/loader/src/common/elf_util.c index ff656ce..72d067d 100644 --- a/loader/src/common/elf_util.c +++ b/loader/src/common/elf_util.c @@ -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; } diff --git a/loader/src/ptracer/ptracer.c b/loader/src/ptracer/ptracer.c index 58f211b..d2655f6 100644 --- a/loader/src/ptracer/ptracer.c +++ b/loader/src/ptracer/ptracer.c @@ -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"); diff --git a/loader/src/ptracer/utils.c b/loader/src/ptracer/utils.c index dce68df..76aae16 100644 --- a/loader/src/ptracer/utils.c +++ b/loader/src/ptracer/utils.c @@ -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; } diff --git a/loader/src/ptracer/utils.h b/loader/src/ptracer/utils.h index 858a88d..4d469ac 100644 --- a/loader/src/ptracer/utils.h +++ b/loader/src/ptracer/utils.h @@ -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);