firebase / firebase-ios-sdk

Firebase SDK for Apple App Development
https://firebase.google.com
Apache License 2.0
5.47k stars 1.43k forks source link

When I use NSProxy to hook NSURLSession, I get a crash in +[GULSwizzler ivarObjectsForObject]. #9951

Open ritchie7 opened 2 years ago

ritchie7 commented 2 years ago
+ (NSArray<id> *)ivarObjectsForObject:(id)object {
  NSMutableArray *array = [NSMutableArray array];
  unsigned int count;
  Ivar *vars = class_copyIvarList([object class], &count);
  for (NSUInteger i = 0; i < count; i++) {
    const char *typeEncoding = ivar_getTypeEncoding(vars[i]);
    // Check to see if the ivar is an object.
    if (strncmp(typeEncoding, "@", 1) == 0) {
      id ivarObject = object_getIvar(object, vars[i]);
      [array addObject:ivarObject];
    }
  }
  free(vars);
  return array;
}

In my project, object is a real obj for NSURLSession's NSProxy, and class_copyIvarList([object class], &count) is the function that gets the real object (NSURLSession instance). When the code reaches object_getIvar(), an EXC_BAD_ACCESS crash will occur.

thanks.

google-oss-bot commented 2 years ago

I found a few problems with this issue:

rizafran commented 2 years ago

Thanks for reporting, @ritchie7. Please fill out the needed information from the template so we could try to reproduce the issue.

ritchie7 commented 2 years ago

Sorry, here is the information I added:

In my project, object is a real obj for NSURLSession's NSProxy, and class_copyIvarList([object class], &count) is the function that gets the real object (NSURLSession instance). When the code reaches object_getIvar(), an EXC_BAD_ACCESS crash will occur.


Here is my code for hooking NSURLSession.

// The implementation of `NSProxy1`/`NSProxy2` and GULProxy is the same.
+ (NSURLSession *)swizzling_sharedSession {
    NSURLSession *session = [NSProxy1 proxyWithTarget:[self swizzling_sharedSession]];
    return session;
}

+ (NSURLSession *)swizzling_sessionWithConfiguration:(NSURLSessionConfiguration *)configuration
                                    delegate:(id<NSURLSessionDelegate>)delegate
                               delegateQueue:(NSOperationQueue *)queue {

    id delegateProxy = [NSProxy2  proxyWithTarget:delegate];

    NSURLSession *session = [self swizzling_sessionWithConfiguration:configuration
                                                    delegate:delegateProxy
                                               delegateQueue:queue];
    return (id<NSObject>)[NSProxy1 proxyWithTarget:session];
}

Thanks

paulb777 commented 2 years ago

Does removing FirebasePerformance make a difference?

ritchie7 commented 2 years ago

Thank you for your reply. If firebasePerformance is removed, the crash will not occur, because -[FPRNSURLSessionInstrument registerProxyObject:] is not executed.

paulb777 commented 2 years ago

Thanks. I'll assign to the Performance team for investigation.