@@ -73,13 +73,19 @@ int dyld_hook_routine(void **dyld, int idx, void *hook, void **orig, uint16_t pa
7373 return -1 ;
7474}
7575
76+ // All dlopen/dlsym calls use __builtin_return_address(0) to determine what library called it
77+ // Since we hook them, if we just call the original function on our own, the return address will always point to systemhook
78+ // Therefore we must ensure the call to the original function is a tail call,
79+ // which ensures that the stack and lr are restored and the compiler turns the call into a direct branch
80+ // This is done via __attribute__((musttail)), this way __builtin_return_address(0) will point to the original calling library instead of systemhook
81+
7682void * (* dyld_dlopen_orig )(void * dyld , const char * path , int mode );
7783void * dyld_dlopen_hook (void * dyld , const char * path , int mode )
7884{
7985 if (path && !(mode & RTLD_NOLOAD )) {
8086 jbclient_trust_library (path , __builtin_return_address (0 ));
8187 }
82- return dyld_dlopen_orig (dyld , path , mode );
88+ __attribute__(( musttail )) return dyld_dlopen_orig (dyld , path , mode );
8389}
8490
8591void * (* dyld_dlopen_from_orig )(void * dyld , const char * path , int mode , void * addressInCaller );
@@ -88,7 +94,7 @@ void* dyld_dlopen_from_hook(void *dyld, const char* path, int mode, void* addres
8894 if (path && !(mode & RTLD_NOLOAD )) {
8995 jbclient_trust_library (path , addressInCaller );
9096 }
91- return dyld_dlopen_from_orig (dyld , path , mode , addressInCaller );
97+ __attribute__(( musttail )) return dyld_dlopen_from_orig (dyld , path , mode , addressInCaller );
9298}
9399
94100void * (* dyld_dlopen_audited_orig )(void * dyld , const char * path , int mode );
@@ -97,7 +103,7 @@ void* dyld_dlopen_audited_hook(void *dyld, const char* path, int mode)
97103 if (path && !(mode & RTLD_NOLOAD )) {
98104 jbclient_trust_library (path , __builtin_return_address (0 ));
99105 }
100- return dyld_dlopen_audited_orig (dyld , path , mode );
106+ __attribute__(( musttail )) return dyld_dlopen_audited_orig (dyld , path , mode );
101107}
102108
103109bool (* dyld_dlopen_preflight_orig )(void * dyld , const char * path );
@@ -106,7 +112,7 @@ bool dyld_dlopen_preflight_hook(void *dyld, const char* path)
106112 if (path ) {
107113 jbclient_trust_library (path , __builtin_return_address (0 ));
108114 }
109- return dyld_dlopen_preflight_orig (dyld , path );
115+ __attribute__(( musttail )) return dyld_dlopen_preflight_orig (dyld , path );
110116}
111117
112118void * (* dyld_dlsym_orig )(void * dyld , void * handle , const char * name );
@@ -117,7 +123,7 @@ void *dyld_dlsym_hook(void *dyld, void *handle, const char *name)
117123 // Because we can just return a different pointer, we avoid doing instruction replacements
118124 return sandbox_apply_hook ;
119125 }
120- return dyld_dlsym_orig (dyld , handle , name );
126+ __attribute__(( musttail )) return dyld_dlsym_orig (dyld , handle , name );
121127}
122128
123129int ptrace_hook (int request , pid_t pid , caddr_t addr , int data )
0 commit comments