Skip to content

Commit 4b7618d

Browse files
authored
merge: Clean up injection traces of ReZygisk (#101)
This merge commit merges the Pull Request by JingMatrix that cleans up the rest of detection points of ReZygisk in non-KSU environments.
2 parents 8fb5d91 + 0671f2e commit 4b7618d

File tree

8 files changed

+182
-126
lines changed

8 files changed

+182
-126
lines changed

.gitmodules

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
[submodule "loader/src/external/lsplt"]
22
path = loader/src/external/lsplt
3-
url = https://github.com/LSPosed/lsplt
3+
url = https://github.com/JingMatrix/LSPlt

loader/src/include/solist.hpp

Lines changed: 85 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,27 @@ namespace SoList {
1111
class SoInfo {
1212
public:
1313
#ifdef __LP64__
14-
inline static size_t solist_next_offset = 0x30;
14+
inline static size_t solist_size_offset = 0x18;
15+
inline static size_t solist_next_offset = 0x28;
1516
constexpr static size_t solist_realpath_offset = 0x1a8;
1617
#else
18+
inline static size_t solist_size_offset = 0x90;
1719
inline static size_t solist_next_offset = 0xa4;
1820
constexpr static size_t solist_realpath_offset = 0x174;
1921
#endif
2022

2123
inline static const char *(*get_realpath_sym)(SoInfo *) = NULL;
2224
inline static const char *(*get_soname_sym)(SoInfo *) = NULL;
25+
inline static void (*soinfo_free)(SoInfo *) = NULL;
2326

2427
inline SoInfo *get_next() {
2528
return *(SoInfo **) ((uintptr_t) this + solist_next_offset);
2629
}
2730

31+
inline size_t get_size() {
32+
return *(size_t *) ((uintptr_t) this + solist_size_offset);
33+
}
34+
2835
inline const char *get_path() {
2936
if (get_realpath_sym) return get_realpath_sym(this);
3037

@@ -40,6 +47,10 @@ namespace SoList {
4047
void set_next(SoInfo *si) {
4148
*(SoInfo **) ((uintptr_t) this + solist_next_offset) = si;
4249
}
50+
51+
void set_size(size_t size) {
52+
*(size_t *) ((uintptr_t) this + solist_size_offset) = size;
53+
}
4354
};
4455

4556
class ProtectedDataGuard {
@@ -69,8 +80,8 @@ namespace SoList {
6980
private:
7081
using FuncType = void (ProtectedDataGuard::*)();
7182

72-
static FuncType ctor;
73-
static FuncType dtor;
83+
inline static FuncType ctor = NULL;
84+
inline static FuncType dtor = NULL;
7485

7586
union MemFunc {
7687
FuncType f;
@@ -86,8 +97,9 @@ namespace SoList {
8697
static SoInfo *solist = NULL;
8798
static SoInfo *somain = NULL;
8899
static SoInfo **sonext = NULL;
89-
ProtectedDataGuard::FuncType ProtectedDataGuard::ctor = NULL;
90-
ProtectedDataGuard::FuncType ProtectedDataGuard::dtor = NULL;
100+
101+
static uint64_t *g_module_load_counter = NULL;
102+
static uint64_t *g_module_unload_counter = NULL;
91103

92104
static bool Initialize();
93105

@@ -98,28 +110,51 @@ namespace SoList {
98110
return addr == NULL ? NULL : *addr;
99111
}
100112

101-
static void DropSoPath(const char* target_path) {
113+
static bool DropSoPath(const char* target_path) {
114+
bool path_found = false;
102115
if (solist == NULL && !Initialize()) {
103116
LOGE("Failed to initialize solist");
104-
return;
117+
return path_found;
105118
}
106-
SoInfo *prev = NULL;
107119
for (auto iter = solist; iter; iter = iter->get_next()) {
108-
if (prev != NULL && iter->get_name() && iter->get_path() && strstr(iter->get_path(), target_path)) {
120+
if (iter->get_name() && iter->get_path() && strstr(iter->get_path(), target_path)) {
109121
SoList::ProtectedDataGuard guard;
110-
prev->set_next(iter->get_next());
111-
if (iter == *sonext) {
112-
*sonext = prev;
122+
LOGI("dropping solist record for %s loaded at %s with size %zu", iter->get_name(), iter->get_path(), iter->get_size());
123+
if (iter->get_size() > 0) {
124+
iter->set_size(0);
125+
SoInfo::soinfo_free(iter);
126+
path_found = true;
113127
}
114-
LOGI("Dropped solist record for %s loaded at %s", iter->get_name(), iter->get_path());
115128
}
116-
prev = iter;
129+
}
130+
return path_found;
131+
}
132+
133+
static void ResetCounters(size_t load, size_t unload) {
134+
if (solist == NULL && !Initialize()) {
135+
LOGE("Failed to initialize solist");
136+
return;
137+
}
138+
if (g_module_load_counter == NULL || g_module_unload_counter == NULL) {
139+
LOGI("g_module counters not defined, skip reseting them");
140+
return;
141+
}
142+
auto loaded_modules = *g_module_load_counter;
143+
auto unloaded_modules = *g_module_unload_counter;
144+
if (loaded_modules >= load) {
145+
*g_module_load_counter = loaded_modules - load;
146+
LOGD("reset g_module_load_counter to %zu", (size_t) *g_module_load_counter);
147+
}
148+
if (unloaded_modules >= unload) {
149+
*g_module_unload_counter = unloaded_modules - unload;
150+
LOGD("reset g_module_unload_counter to %zu", (size_t) *g_module_unload_counter);
117151
}
118152
}
119153

120154
static bool Initialize() {
121155
SandHook::ElfImg linker("/linker");
122156
if (!ProtectedDataGuard::setup(linker)) return false;
157+
LOGD("found symbol ProtectedDataGuard");
123158

124159
/* INFO: Since Android 15, the symbol names for the linker have a suffix,
125160
this makes it impossible to hardcode the symbol names. To allow
@@ -131,6 +166,11 @@ namespace SoList {
131166

132167
std::string_view solist_sym_name = linker.findSymbolNameByPrefix("__dl__ZL6solist");
133168
if (solist_sym_name.empty()) return false;
169+
LOGD("found symbol name %s", solist_sym_name.data());
170+
171+
std::string_view soinfo_free_name = linker.findSymbolNameByPrefix("__dl__ZL11soinfo_freeP6soinfo");
172+
if (soinfo_free_name.empty()) return false;
173+
LOGD("found symbol name %s", soinfo_free_name.data());
134174

135175
/* INFO: The size isn't a magic number, it's the size for the string: .llvm.7690929523238822858 */
136176
char llvm_sufix[25 + 1];
@@ -143,37 +183,60 @@ namespace SoList {
143183

144184
solist = getStaticPointer<SoInfo>(linker, solist_sym_name.data());
145185
if (solist == NULL) return false;
186+
LOGD("found symbol solist");
146187

147188
char somain_sym_name[sizeof("__dl__ZL6somain") + sizeof(llvm_sufix)];
148189
snprintf(somain_sym_name, sizeof(somain_sym_name), "__dl__ZL6somain%s", llvm_sufix);
149190

150191
char sonext_sym_name[sizeof("__dl__ZL6sonext") + sizeof(llvm_sufix)];
151192
snprintf(sonext_sym_name, sizeof(somain_sym_name), "__dl__ZL6sonext%s", llvm_sufix);
152193

153-
char vsdo_sym_name[sizeof("__dl__ZL4vdso") + sizeof(llvm_sufix)];
154-
snprintf(vsdo_sym_name, sizeof(vsdo_sym_name), "__dl__ZL4vdso%s", llvm_sufix);
194+
char vdso_sym_name[sizeof("__dl__ZL4vdso") + sizeof(llvm_sufix)];
195+
snprintf(vdso_sym_name, sizeof(vdso_sym_name), "__dl__ZL4vdso%s", llvm_sufix);
155196

156197
somain = getStaticPointer<SoInfo>(linker, somain_sym_name);
157198
if (somain == NULL) return false;
199+
LOGD("found symbol somain");
158200

159201
sonext = linker.getSymbAddress<SoInfo **>(sonext_sym_name);
160202
if (sonext == NULL) return false;
203+
LOGD("found symbol sonext");
161204

162-
SoInfo *vsdo = getStaticPointer<SoInfo>(linker, vsdo_sym_name);
163-
if (vsdo == NULL) return false;
205+
SoInfo *vdso = getStaticPointer<SoInfo>(linker, vdso_sym_name);
206+
if (vdso != NULL) LOGD("found symbol vdso");
164207

165208
SoInfo::get_realpath_sym = reinterpret_cast<decltype(SoInfo::get_realpath_sym)>(linker.getSymbAddress("__dl__ZNK6soinfo12get_realpathEv"));
209+
if (SoInfo::get_realpath_sym == NULL) return false;
210+
LOGD("found symbol get_realpath_sym");
211+
166212
SoInfo::get_soname_sym = reinterpret_cast<decltype(SoInfo::get_soname_sym)>(linker.getSymbAddress("__dl__ZNK6soinfo10get_sonameEv"));
213+
if (SoInfo::get_soname_sym == NULL) return false;
214+
LOGD("found symbol get_soname_sym");
215+
216+
SoInfo::soinfo_free = reinterpret_cast<decltype(SoInfo::soinfo_free)>(linker.getSymbAddress(soinfo_free_name));
217+
if (SoInfo::soinfo_free == NULL) return false;
218+
LOGD("found symbol soinfo_free");
219+
220+
g_module_load_counter = reinterpret_cast<decltype(g_module_load_counter)>(linker.getSymbAddress("__dl__ZL21g_module_load_counter"));
221+
if (g_module_load_counter != NULL) LOGD("found symbol g_module_load_counter");
222+
223+
g_module_unload_counter = reinterpret_cast<decltype(g_module_unload_counter)>(linker.getSymbAddress("__dl__ZL23g_module_unload_counter"));
224+
if (g_module_unload_counter != NULL) LOGD("found symbol g_module_unload_counter");
167225

168226
for (size_t i = 0; i < 1024 / sizeof(void *); i++) {
169-
auto *possible_next = *(void **) ((uintptr_t) solist + i * sizeof(void *));
170-
if (possible_next == somain || (vsdo != NULL && possible_next == vsdo)) {
227+
auto possible_field = (uintptr_t) solist + i * sizeof(void *);
228+
auto possible_size_of_somain = *(size_t *)((uintptr_t) somain + i * sizeof(void *));
229+
if (possible_size_of_somain < 0x100000 && possible_size_of_somain > 0x100) {
230+
SoInfo::solist_size_offset = i * sizeof(void *);
231+
LOGD("solist_size_offset is %zu * %zu = %p", i, sizeof(void *), (void*) SoInfo::solist_size_offset);
232+
}
233+
if (*(void **)possible_field == somain || (vdso != NULL && *(void **)possible_field == vdso)) {
171234
SoInfo::solist_next_offset = i * sizeof(void *);
172-
235+
LOGD("solist_next_offset is %zu * %zu = %p", i, sizeof(void *), (void*) SoInfo::solist_next_offset);
173236
break;
174237
}
175238
}
176239

177-
return (SoInfo::get_realpath_sym != NULL && SoInfo::get_soname_sym != NULL);
240+
return true;
178241
}
179242
}

loader/src/injector/entry.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
#include "daemon.h"
22
#include "logging.h"
33
#include "zygisk.hpp"
4-
#include "module.hpp"
54

65
using namespace std;
76

8-
void *self_handle = nullptr;
7+
void *start_addr = nullptr;
8+
size_t block_size = 0;
99

1010
extern "C" [[gnu::visibility("default")]]
11-
void entry(void* handle, const char* path) {
11+
void entry(void* addr, size_t size, const char* path) {
1212
LOGI("Zygisk library injected, version %s", ZKSU_VERSION);
13-
self_handle = handle;
13+
start_addr = addr;
14+
block_size = size;
1415
zygiskd::Init(path);
1516

1617
if (!zygiskd::PingHeartbeat()) {
@@ -22,6 +23,7 @@ void entry(void* handle, const char* path) {
2223
logging::setfd(zygiskd::RequestLogcatFd());
2324
#endif
2425

25-
LOGI("Start hooking");
26+
LOGI("start plt hooking");
2627
hook_functions();
28+
clean_trace(path, 1, 0, false);
2729
}

0 commit comments

Comments
 (0)