Skip to content

Commit 4bd85ae

Browse files
committed
add: CSOLoader
This commit implements the use of CSOLoader in ReZygisk. In a long time, ReZygisk relied on system linker to load Zygisk modules, bringing numerous detections due to gigantic amount of traces left inside it. To simplify and future-proof ReZygisk hiding, while improving compatibility with new Android versions and different devices, CSOLoader links all necessary parts, and provides the necessary information through linker APIs for the loaded shared libraries.
1 parent 3d90521 commit 4bd85ae

File tree

10 files changed

+56
-322
lines changed

10 files changed

+56
-322
lines changed

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
[submodule "LSPlt"]
22
path = loader/src/external/lsplt
33
url = https://github.com/PerformanC/LSPlt
4+
[submodule "CSOLoader"]
5+
path = loader/src/external/csoloader
6+
url = https://github.com/ThePedroo/CSOLoader

README.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,12 @@ The Zygisk Next developers are famous and trusted in the Android community, howe
2222
|-----------------|----------------------------------------|
2323
| `Android NDK` | Native Development Kit for Android |
2424

25-
### C++ Dependencies
25+
### C Dependencies
2626

27-
| Dependency | Description |
28-
|------------|-------------------------------|
29-
| `lsplt` | Simple PLT Hook for Android |
27+
| Dependency | Description |
28+
|-------------|-------------------------------|
29+
| `LSPLt` | Simple PLT Hook for Android |
30+
| `CSOLoader` | SOTA Linux custom linker |
3031

3132
## Installation
3233

loader/src/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ target_link_libraries(common log)
1515
aux_source_directory(injector INJECTOR_SRC_LIST)
1616
add_library(zygisk SHARED ${INJECTOR_SRC_LIST})
1717
target_include_directories(zygisk PRIVATE include)
18-
target_link_libraries(zygisk cxx::cxx log common lsplt_static)
18+
target_link_libraries(zygisk cxx::cxx log common lsplt_static csoloader)
1919

2020
aux_source_directory(ptracer PTRACER_SRC_LIST)
2121
add_executable(libzygisk_ptrace.so ${PTRACER_SRC_LIST})

loader/src/external/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ project(external)
22

33
OPTION(LSPLT_BUILD_SHARED OFF)
44
add_subdirectory(lsplt/lsplt/src/main/jni)
5+
add_subdirectory(csoloader)

loader/src/external/csoloader

Submodule csoloader added at d4d1922

loader/src/injector/entry.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ void entry(void *addr, size_t size) {
2525
LOGD("start plt hooking");
2626
hook_functions();
2727

28-
solist_drop_so_path(addr, true);
29-
solist_reset_counters(1, 1);
28+
solist_drop_so_path(addr);
29+
solist_reset_counters(1);
3030

3131
struct kernel_version version = parse_kversion();
3232
if (version.major > 3 || (version.major == 3 && version.minor >= 8)) {

loader/src/injector/hook.cpp

Lines changed: 9 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -715,52 +715,35 @@ bool load_modules_only() {
715715
for (size_t i = 0; i < ms.modules_count; i++) {
716716
char *lib_path = ms.modules[i];
717717

718-
void *handle = dlopen(lib_path, RTLD_NOW);
719-
if (!handle) {
720-
LOGE("Failed to load module [%s]: %s", lib_path, dlerror());
718+
if (!csoloader_load(&zygisk_modules[zygisk_module_length].lib, lib_path)) {
719+
LOGE("Failed to load module [%s]", lib_path);
721720

722721
continue;
723722
}
724723

725-
void *entry = dlsym(handle, "zygisk_module_entry");
724+
void *entry = csoloader_get_symbol(&zygisk_modules[zygisk_module_length].lib, "zygisk_module_entry");
726725
if (!entry) {
727-
LOGE("Failed to find entry point in module [%s]: %s", lib_path, dlerror());
726+
LOGE("Failed to find entry point in module [%s]", lib_path);
728727

729-
dlclose(handle);
728+
csoloader_unload(&zygisk_modules[zygisk_module_length].lib);
730729

731730
continue;
732731
}
733732

734733
zygisk_modules[zygisk_module_length].api.register_module = rezygisk_module_register;
735734
zygisk_modules[zygisk_module_length].api.impl = (void *)zygisk_module_length;
736735

737-
zygisk_modules[zygisk_module_length].handle = handle;
738736
zygisk_modules[zygisk_module_length].zygisk_module_entry = (void (*)(void *, void *))entry;
739737

740-
zygisk_modules[zygisk_module_length].base = solist_get_base(entry);
741-
zygisk_modules[zygisk_module_length].size = solist_get_size(entry);
742-
743-
zygisk_modules[zygisk_module_length].deconstructors = solist_get_deconstructors(entry);
744-
745-
LOGD("Loaded module [%s]. Entry: %p, Base: %p, Size: %zu, Deconstructors: fini_func=%p, fini_array=%p (size: %zu)",
738+
LOGD("Loaded module [%s]. Entry: %p",
746739
lib_path,
747-
entry,
748-
zygisk_modules[zygisk_module_length].base,
749-
zygisk_modules[zygisk_module_length].size,
750-
zygisk_modules[zygisk_module_length].deconstructors.fini_func,
751-
zygisk_modules[zygisk_module_length].deconstructors.fini_array,
752-
zygisk_modules[zygisk_module_length].deconstructors.fini_array_size);
740+
entry);
753741

754742
zygisk_modules[zygisk_module_length].unload = false;
755743

756-
/* INFO: Early removal to avoid gaps in solist */
757-
solist_drop_so_path(entry, false);
758-
759744
zygisk_module_length++;
760745
}
761746

762-
solist_reset_counters(zygisk_module_length, zygisk_module_length);
763-
764747
free_modules(&ms);
765748

766749
return true;
@@ -786,25 +769,10 @@ void ZygiskContext::run_modules_post() {
786769
if (flags[APP_SPECIALIZE]) rezygisk_module_call_post_app_specialize(m, args.app);
787770
else if (flags[SERVER_FORK_AND_SPECIALIZE]) rezygisk_module_call_post_server_specialize(m, args.server);
788771

789-
/* INFO: If module is unloaded by dlclose, there's no need to
790-
hide it from soinfo manually. */
791772
if (!m->unload) continue;
792773

793-
/* INFO: Deconstructors are called in the inverted order, and following fini array then fini
794-
function order. It must not change. */
795-
for (size_t j = m->deconstructors.fini_array_size; j > 0; j--) {
796-
void (*destructor)(void) = m->deconstructors.fini_array[j - 1];
797-
if (destructor) {
798-
LOGD("Calling destructor %p for module %p", (void *)destructor, (void *)m->zygisk_module_entry);
799-
800-
destructor();
801-
}
802-
}
803-
804-
if (m->deconstructors.fini_func) m->deconstructors.fini_func();
805-
806-
if (munmap(m->base, m->size) == -1) {
807-
PLOGE("Failed to unmap module library at %p with size %zu", m->base, m->size);
774+
if (csoloader_unload(&m->lib) == false) {
775+
LOGE("Failed to unload module library");
808776

809777
continue;
810778
}

loader/src/injector/module.h

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#ifndef MODULE_H
22
#define MODULE_H
33

4+
#include <csoloader.h>
5+
46
#include "logging.h"
57
#include "solist.h"
68

@@ -146,14 +148,9 @@ struct rezygisk_module {
146148
struct rezygisk_abi abi;
147149
struct rezygisk_api api;
148150

149-
void *handle;
151+
struct csoloader lib;
150152
void (*zygisk_module_entry)(void *, void *);
151153

152-
void *base;
153-
size_t size;
154-
155-
struct soinfo_deconstructor deconstructors;
156-
157154
bool unload;
158155
};
159156

0 commit comments

Comments
 (0)