66#include < string>
77#include " elf_util.h"
88
9- namespace SoList
10- {
11- class SoInfo {
12- public:
13- #ifdef __LP64__
9+ namespace SoList {
10+ class SoInfo {
11+ public:
12+ #ifdef __LP64__
1413 inline static size_t solist_next_offset = 0x30 ;
1514 constexpr static size_t solist_realpath_offset = 0x1a8 ;
16- #else
15+ #else
1716 inline static size_t solist_next_offset = 0xa4 ;
1817 constexpr static size_t solist_realpath_offset = 0x174 ;
19- #endif
18+ #endif
2019
21- inline static const char *(*get_realpath_sym)(SoInfo *) = nullptr ;
22- inline static const char *(*get_soname_sym)(SoInfo *) = nullptr ;
20+ inline static const char *(*get_realpath_sym)(SoInfo *) = NULL ;
21+ inline static const char *(*get_soname_sym)(SoInfo *) = NULL ;
2322
24- inline SoInfo *get_next () {
25- return *(SoInfo **) ((uintptr_t ) this + solist_next_offset);
26- }
23+ inline SoInfo *get_next () {
24+ return *(SoInfo **) ((uintptr_t ) this + solist_next_offset);
25+ }
2726
28- inline const char *get_path () {
29- return get_realpath_sym ? get_realpath_sym (this ) : ((std::string *) ((uintptr_t ) this + solist_realpath_offset))->c_str ();
30- }
27+ inline const char *get_path () {
28+ if (get_realpath_sym) return get_realpath_sym (this );
3129
32- inline const char *get_name () {
33- return get_soname_sym ? get_soname_sym (this ) : *((const char **) ((uintptr_t ) this + solist_realpath_offset - sizeof (void *)));
34- }
30+ return ((std::string *) ((uintptr_t ) this + solist_realpath_offset))->c_str ();
31+ }
3532
36- void nullify_name () {
37- const char ** name = ( const char **) get_soname_sym (this );
33+ inline const char * get_name () {
34+ if (get_soname_sym) return get_soname_sym (this );
3835
39- static const char * empty_string = " " ;
40- *name = reinterpret_cast <const char *>(&empty_string);
41- }
36+ return ((std::string *) ((uintptr_t ) this + solist_realpath_offset - sizeof (void *)))->c_str ();
37+ }
4238
43- void nullify_path () {
44- const char ** name = (const char **)get_realpath_sym (this );
39+ void nullify_name () {
40+ const char ** name = (const char **)get_soname_sym (this );
4541
46- static const char * empty_string = " " ;
47- *name = reinterpret_cast <const char *>(&empty_string);
48- }
49- };
42+ static const char *empty_string = " " ;
43+ *name = reinterpret_cast <const char *>(&empty_string);
44+ }
5045
51- static SoInfo *solist = nullptr ;
52- static SoInfo *somain = nullptr ;
46+ void nullify_path () {
47+ const char **name = ( const char **) get_realpath_sym ( this ) ;
5348
54- template <typename T>
55- inline T *getStaticPointer (const SandHook::ElfImg &linker, const char * name)
56- {
57- auto *addr = reinterpret_cast <T **>(linker.getSymbAddress (name));
58- return addr == nullptr ? nullptr : *addr;
49+ static const char *empty_string = " " ;
50+ *name = reinterpret_cast <const char *>(&empty_string);
51+ }
52+ };
53+
54+ static SoInfo *solist = NULL ;
55+ static SoInfo *somain = NULL ;
56+
57+ template <typename T>
58+ inline T *getStaticPointer (const SandHook::ElfImg &linker, const char *name) {
59+ auto *addr = reinterpret_cast <T **>(linker.getSymbAddress (name));
60+
61+ return addr == NULL ? NULL : *addr;
62+ }
63+
64+ static void NullifySoName (const char * target_name) {
65+ for (auto *iter = solist; iter; iter = iter->get_next ()) {
66+ if (iter->get_name () && iter->get_path () && strstr (iter->get_path (), target_name)) {
67+ iter->nullify_path ();
68+ LOGI (" Cleared SOList entry for %s" , target_name);
69+ }
70+ }
71+
72+ for (auto *iter = somain; iter; iter = iter->get_next ()) {
73+ if (iter->get_name () && iter->get_path () && strstr (iter->get_path (), target_name)) {
74+ iter->nullify_path ();
75+
76+ break ;
77+ }
5978 }
79+ }
80+
81+ static bool Initialize () {
82+ SandHook::ElfImg linker (" /linker" );
83+
84+ /* INFO: Since Android 15, the symbol names for the linker have a suffix,
85+ this makes it impossible to hardcode the symbol names. To allow
86+ this to work on all versions, we need to iterate over the loaded
87+ symbols and find the correct ones.
88+
89+ See #63 for more information.
90+ */
6091
61- static void NullifySoName (const char * target_name) {
62- for (auto *iter = solist; iter; iter = iter->get_next ()) {
63- if (iter->get_name () && iter->get_path () && strstr (iter->get_path (), target_name)) {
64- iter->nullify_path ();
65- LOGI (" Cleared SOList entry for %s" , target_name);
66- }
67- }
68-
69- for (auto *iter = somain; iter; iter = iter->get_next ()) {
70- if (iter->get_name () && iter->get_path () && strstr (iter->get_path (), target_name)) {
71- iter->nullify_path ();
72- break ;
73- }
74- }
92+ std::string_view solist_sym_name = linker.findSymbolNameByPrefix (" __dl__ZL6solist" );
93+ if (solist_sym_name.empty ()) return false ;
94+
95+ /* INFO: The size isn't a magic number, it's the size for the string: .llvm.7690929523238822858 */
96+ char llvm_sufix[25 + 1 ];
97+
98+ if (solist_sym_name.length () != strlen (" __dl__ZL6solist" )) {
99+ strncpy (llvm_sufix, solist_sym_name.data () + strlen (" __dl__ZL6solist" ), sizeof (llvm_sufix));
100+ } else {
101+ llvm_sufix[0 ] = ' \0 ' ;
75102 }
76103
77- static bool Initialize () {
78- SandHook::ElfImg linker (" /linker" );
79- solist = getStaticPointer<SoInfo>(linker, " __dl__ZL6solist" );
80- somain = getStaticPointer<SoInfo>(linker, " __dl__ZL6somain" );
81-
82- if (solist != nullptr && somain != nullptr )
83- {
84- SoInfo::get_realpath_sym = reinterpret_cast <decltype (SoInfo::get_realpath_sym)>(linker.getSymbAddress (" __dl__ZNK6soinfo12get_realpathEv" ));
85- SoInfo::get_soname_sym = reinterpret_cast <decltype (SoInfo::get_soname_sym)>(linker.getSymbAddress (" __dl__ZNK6soinfo10get_sonameEv" ));
86- auto vsdo = getStaticPointer<SoInfo>(linker, " __dl__ZL4vdso" );
87-
88- for (size_t i = 0 ; i < 1024 / sizeof (void *); i++)
89- {
90- auto *possible_next = *(void **) ((uintptr_t ) solist + i * sizeof (void *));
91- if (possible_next == somain || (vsdo != nullptr && possible_next == vsdo))
92- {
93- SoInfo::solist_next_offset = i * sizeof (void *);
94- break ;
95- }
96- }
97-
98- return (SoInfo::get_realpath_sym != nullptr && SoInfo::get_soname_sym != nullptr );
99- }
100-
101- return false ;
104+ solist = getStaticPointer<SoInfo>(linker, solist_sym_name.data ());
105+ if (solist == NULL ) return false ;
106+
107+ char somain_sym_name[sizeof (" __dl__ZL6somain" ) + sizeof (llvm_sufix)];
108+ snprintf (somain_sym_name, sizeof (somain_sym_name), " __dl__ZL6somain%s" , llvm_sufix);
109+
110+ char vsdo_sym_name[sizeof (" __dl__ZL4vdso" ) + sizeof (llvm_sufix)];
111+ snprintf (vsdo_sym_name, sizeof (vsdo_sym_name), " __dl__ZL4vdso%s" , llvm_sufix);
112+
113+ somain = getStaticPointer<SoInfo>(linker, somain_sym_name);
114+ if (somain == NULL ) return false ;
115+
116+ auto vsdo = getStaticPointer<SoInfo>(linker, vsdo_sym_name);
117+
118+ SoInfo::get_realpath_sym = reinterpret_cast <decltype (SoInfo::get_realpath_sym)>(linker.getSymbAddress (" __dl__ZNK6soinfo12get_realpathEv" ));
119+ SoInfo::get_soname_sym = reinterpret_cast <decltype (SoInfo::get_soname_sym)>(linker.getSymbAddress (" __dl__ZNK6soinfo10get_sonameEv" ));
120+
121+ for (size_t i = 0 ; i < 1024 / sizeof (void *); i++) {
122+ auto *possible_next = *(void **) ((uintptr_t ) solist + i * sizeof (void *));
123+ if (possible_next == somain || (vsdo != NULL && possible_next == vsdo)) {
124+ SoInfo::solist_next_offset = i * sizeof (void *);
125+
126+ break ;
127+ }
102128 }
103- }
129+
130+ return (SoInfo::get_realpath_sym != NULL && SoInfo::get_soname_sym != NULL );
131+ }
132+ }
0 commit comments