@@ -16,11 +16,11 @@ size_t DetectModules() {
1616}
1717
1818SoInfo *DetectInjection () {
19- if (solist == NULL && !Initialize ()) {
19+ if (solinker == NULL && !Initialize ()) {
2020 LOGE (" Failed to initialize solist" );
2121 return NULL ;
2222 }
23- SoInfo *prev = solist ;
23+ SoInfo *prev = solinker ;
2424 size_t gap = 0 ;
2525 auto gap_repeated = 0 ;
2626 bool app_process_loaded = false ;
@@ -30,7 +30,7 @@ SoInfo *DetectInjection() {
3030 bool nativehelper_loaded =
3131 false ; // Not necessarily loaded after AppSpecialize
3232
33- for (auto iter = solist ; iter; iter = iter->get_next ()) {
33+ for (auto iter = solinker ; iter; iter = iter->get_next ()) {
3434 // No soinfo has empty path name
3535 if (iter->get_path () == NULL || iter->get_path ()[0 ] == ' \0 ' ) {
3636 return iter;
@@ -69,7 +69,7 @@ SoInfo *DetectInjection() {
6969 } else {
7070 gap_repeated--;
7171 if (gap != 0 )
72- LOGD (" Suspicious gap 0x%lx or 0x%lx != 0x%lx between %s and %s" ,
72+ LOGI (" Suspicious gap 0x%lx or 0x%lx != 0x%lx between %s and %s" ,
7373 iter - prev, prev - iter, gap, prev->get_name (), iter->get_name ());
7474 }
7575
@@ -97,67 +97,93 @@ bool Initialize() {
9797 SandHook::ElfImg linker (" /linker" );
9898 if (!ProtectedDataGuard::setup (linker))
9999 return false ;
100+ LOGI (" found symbol ProtectedDataGuard" );
100101
101- std::string_view solist_sym_name =
102- linker.findSymbolNameByPrefix (" __dl__ZL6solist " );
103- if (solist_sym_name .empty ())
102+ std::string_view somain_sym_name =
103+ linker.findSymbolNameByPrefix (" __dl__ZL6somain " );
104+ if (somain_sym_name .empty ())
104105 return false ;
106+ LOGI (" found symbol name %s" , somain_sym_name.data ());
105107
106108 /* INFO: The size isn't a magic number, it's the size for the string:
107109 * .llvm.7690929523238822858 */
108110 char llvm_sufix[25 + 1 ];
109111
110- if (solist_sym_name .length () != strlen (" __dl__ZL6solist " )) {
111- strncpy (llvm_sufix, solist_sym_name .data () + strlen (" __dl__ZL6solist " ),
112+ if (somain_sym_name .length () != strlen (" __dl__ZL6somain " )) {
113+ strncpy (llvm_sufix, somain_sym_name .data () + strlen (" __dl__ZL6somain " ),
112114 sizeof (llvm_sufix));
113115 } else {
114116 llvm_sufix[0 ] = ' \0 ' ;
115117 }
116118
117- solist = getStaticPointer<SoInfo>(linker, solist_sym_name. data ()) ;
118- if (solist == NULL )
119- return false ;
119+ char solinker_sym_name[ sizeof ( " __dl__ZL8solinker " ) + sizeof (llvm_sufix)] ;
120+ snprintf (solinker_sym_name, sizeof (solinker_sym_name), " __dl__ZL8solinker%s " ,
121+ llvm_sufix) ;
120122
121- char somain_sym_name[sizeof (" __dl__ZL6somain" ) + sizeof (llvm_sufix)];
122- snprintf (somain_sym_name, sizeof (somain_sym_name), " __dl__ZL6somain%s" ,
123+ // for SDK < 36 (Android 16), the linker binary is loaded with name solist
124+ char solist_sym_name[sizeof (" __dl__ZL6solist" ) + sizeof (llvm_sufix)];
125+ snprintf (solist_sym_name, sizeof (solist_sym_name), " __dl__ZL6solist%s" ,
123126 llvm_sufix);
124127
125128 char sonext_sym_name[sizeof (" __dl__ZL6sonext" ) + sizeof (llvm_sufix)];
126- snprintf (sonext_sym_name, sizeof (somain_sym_name ), " __dl__ZL6sonext%s" ,
129+ snprintf (sonext_sym_name, sizeof (sonext_sym_name ), " __dl__ZL6sonext%s" ,
127130 llvm_sufix);
128131
129- char vdso_sym_name[sizeof (" __dl__ZL4vdso" ) + sizeof (llvm_sufix)];
130- snprintf (vdso_sym_name, sizeof (vdso_sym_name), " __dl__ZL4vdso%s" , llvm_sufix);
131-
132- somain = getStaticPointer<SoInfo>(linker, somain_sym_name);
133- if (somain == NULL )
134- return false ;
135-
136- sonext = linker.getSymbAddress <SoInfo **>(sonext_sym_name);
137- if (sonext == NULL )
138- return false ;
139-
140- SoInfo *vdso = getStaticPointer<SoInfo>(linker, vdso_sym_name);
132+ solinker = getStaticPointer<SoInfo>(linker, solinker_sym_name);
133+ if (solinker == nullptr ) {
134+ solinker = getStaticPointer<SoInfo>(linker, solist_sym_name);
135+ if (solinker == nullptr )
136+ return false ;
137+ LOGI (" found symbol solist at %p" , solinker);
138+ } else {
139+ LOGI (" found symbol solinker at %p" , solinker);
140+ }
141141
142142 SoInfo::get_realpath_sym =
143143 reinterpret_cast <decltype (SoInfo::get_realpath_sym)>(
144144 linker.getSymbAddress (" __dl__ZNK6soinfo12get_realpathEv" ));
145- SoInfo::get_soname_sym = reinterpret_cast < decltype (SoInfo::get_soname_sym)>(
146- linker. getSymbAddress ( " __dl__ZNK6soinfo10get_sonameEv " ) );
145+ if ( SoInfo::get_realpath_sym != nullptr )
146+ LOGI ( " found symbol get_realpath_sym " );
147147
148148 g_module_unload_counter = reinterpret_cast <decltype (g_module_unload_counter)>(
149149 linker.getSymbAddress (" __dl__ZL23g_module_unload_counter" ));
150- if (g_module_unload_counter != NULL )
151- LOGD (" found symbol g_module_unload_counter" );
152-
153- for (size_t i = 0 ; i < 1024 / sizeof (void *); i++) {
154- auto *possible_next = *(void **)((uintptr_t )solist + i * sizeof (void *));
155- if (possible_next == somain || (vdso != NULL && possible_next == vdso)) {
156- SoInfo::solist_next_offset = i * sizeof (void *);
157- break ;
150+ if (g_module_unload_counter != nullptr )
151+ LOGI (" found symbol g_module_unload_counter" );
152+
153+ somain = getStaticPointer<SoInfo>(linker, somain_sym_name.data ());
154+ if (solinker == nullptr )
155+ return false ;
156+ LOGI (" found symbol somain at %p" , somain);
157+
158+ return findHeuristicOffsets (linker.name ());
159+ }
160+
161+ bool findHeuristicOffsets (std::string linker_name) {
162+ const size_t size_block_range = 1024 ;
163+ const size_t linker_realpath_size = linker_name.size ();
164+
165+ bool field_realpath_found = false ;
166+ for (size_t i = 0 ; i < size_block_range / sizeof (void *); i++) {
167+ auto field_of_solinker =
168+ reinterpret_cast <uintptr_t >(solinker) + i * sizeof (void *);
169+ auto size_of_somain = *reinterpret_cast <size_t *>(
170+ reinterpret_cast <uintptr_t >(somain) + i * sizeof (void *));
171+
172+ std::string *realpath_of_solinker =
173+ reinterpret_cast <std::string *>(field_of_solinker);
174+ if (realpath_of_solinker->size () == linker_realpath_size) {
175+ if (strcmp (linker_name.c_str (), realpath_of_solinker->c_str ()) == 0 ) {
176+ SoInfo::solist_realpath_offset = i * sizeof (void *);
177+ LOGI (" heuristic field_realpath_offset is %zu * %zu = %p" , i,
178+ sizeof (void *),
179+ reinterpret_cast <void *>(SoInfo::solist_realpath_offset));
180+ field_realpath_found = true ;
181+ break ;
182+ }
158183 }
159184 }
160185
161- return (SoInfo::get_realpath_sym != NULL && SoInfo::get_soname_sym != NULL ) ;
186+ return field_realpath_found ;
162187}
188+
163189} // namespace SoList
0 commit comments