You are absolutely right, -autoContentAccessingProxy completely broken. NSAutoContentAccessingProxy is a subclass of NSProxy and therefore must implement the methodSignatureForSelector: and forwardInvocation: methods or the forwardingTargetForSelector: method when running on iOS 4 or higher.
Here is a hardcore way to set the NSAutoContentAccessingProxy class by adding the methodSignatureForSelector: and forwardInvocation: methods at run time. Just add the following to your project (do not compile this with ARC).
#import <mach-o/dyld.h> #import <mach-o/nlist.h> __attribute__((constructor)) void FixAutoContentAccessingProxy(void); static id _target(id autoContentAccessingProxy); static NSMethodSignature *NSAutoContentAccessingProxy_methodSignatureForSelector(id self, SEL _cmd, SEL selector); static void NSAutoContentAccessingProxy_forwardInvocation(id self, SEL _cmd, NSInvocation *invocation); __attribute__((constructor)) void FixAutoContentAccessingProxy(void) { Class NSAutoContentAccessingProxy = objc_lookUpClass("NSAutoContentAccessingProxy"); Method methodSignatureForSelector = class_getInstanceMethod([NSObject class], @selector(methodSignatureForSelector:)); Method forwardInvocation = class_getInstanceMethod([NSObject class], @selector(forwardInvocation:)); class_addMethod(NSAutoContentAccessingProxy, @selector(methodSignatureForSelector:), (IMP)NSAutoContentAccessingProxy_methodSignatureForSelector, method_getTypeEncoding(methodSignatureForSelector)); class_addMethod(NSAutoContentAccessingProxy, @selector(forwardInvocation:), (IMP)NSAutoContentAccessingProxy_forwardInvocation, method_getTypeEncoding(forwardInvocation)); } static id _target(id autoContentAccessingProxy) { static uint32_t targetIvarOffset; static dispatch_once_t once; dispatch_once(&once, ^{ struct nlist symlist[] = {{"_OBJC_IVAR_$_NSAutoContentAccessingProxy._target", 0, 0, 0, 0}, NULL}; for(uint32_t i = 0; i < _dyld_image_count(); i++) { if (nlist(_dyld_get_image_name(i), symlist) == 0 && symlist[0].n_value != 0) { uint32_t *_OBJC_IVAR_NSAutoContentAccessingProxy_target = (uint32_t*)((uint32_t)_dyld_get_image_header(i) + symlist[0].n_value); targetIvarOffset = *_OBJC_IVAR_NSAutoContentAccessingProxy_target; break; } } }); return *(id*)((uint32_t)autoContentAccessingProxy + targetIvarOffset); } static NSMethodSignature *NSAutoContentAccessingProxy_methodSignatureForSelector(id self, SEL _cmd, SEL selector) { return [_target(self) methodSignatureForSelector:selector]; } static void NSAutoContentAccessingProxy_forwardInvocation(id self, SEL _cmd, NSInvocation *invocation) { [invocation setTarget:_target(self)]; [invocation invoke]; }
This workaround should only be used to demonstrate how NSAutoContentAccessingProxy violated. In any case, this will only work on the simulator, because the nlist call nlist not work on the device. You could make it work on the device using APEFindSymbol from APELite-arm instead of nlist , but I do not recommend it.
You must write a bug report about this to Apple.
0xced
source share