防止在iOS上reflection(objc /运行时)

我正在处理敏感数据的静态库。 使用库的开发人员不能在库上使用reflection。

在Android上,我们通过开发带有serviceaar文件来解决问题,并将service运行到单独的进程中(当服务运行到另一个进程中时,开发人员不能使用reflection),但是我想知道如果iOS中存在类似的东西?

我们可以执行一个静态库到一个单独的进程? 如果没有,我们如何避免反思我们的静态库?

例如:

  MyTestObject *obj = [[[myTestView alloc] init ]; //=========================================== Class clazz = [obj class]; u_int count; Ivar* ivars = class_copyIvarList(clazz, &count); NSMutableArray* ivarArray = [NSMutableArray arrayWithCapacity:count]; for (int i = 0; i < count ; i++) { const char* ivarName = ivar_getName(ivars[i]); [ivarArray addObject:[NSString stringWithCString:ivarName encoding:NSUTF8StringEncoding]]; } free(ivars); objc_property_t* properties = class_copyPropertyList(clazz, &count); NSMutableArray* propertyArray = [NSMutableArray arrayWithCapacity:count]; for (int i = 0; i < count ; i++) { const char* propertyName = property_getName(properties[i]); [propertyArray addObject:[NSString stringWithCString:propertyName encoding:NSUTF8StringEncoding]]; } free(properties); Method* methods = class_copyMethodList(clazz, &count); NSMutableArray* methodArray = [NSMutableArray arrayWithCapacity:count]; for (int i = 0; i < count ; i++) { SEL selector = method_getName(methods[i]); const char* methodName = sel_getName(selector); [methodArray addObject:[NSString stringWithCString:methodName encoding:NSUTF8StringEncoding]]; } free(methods); NSDictionary* classDump = [NSDictionary dictionaryWithObjectsAndKeys: ivarArray, @"ivars", propertyArray, @"properties", methodArray, @"methods", nil]; NSLog(@"%@", classDump); //====================================================== int v2 = [[obj valueForKey:@"testValue"] intValue]; SEL s = NSSelectorFromString(@"wannatTestIt"); [obj performSelector:s]; 

MyTestObject是我的库中的一个类。 在第一行中,我从这个类初始化一个对象。

在下一行中,我读取了类的variables,方法和属性列表并logging下来。 结果如下:

  { ivars = ( testValue ); methods = ( printTestValue, wannatTestIt, "initWithFrame:" ); properties = ( ); } 

wannaTestIt是一个私有方法, testValue是一个私有variables。 所以我期望使用这个库的开发者不能访问它们。 但是,由于库的用户可以获取名称,用户最终可以调用该方法来读取iVar的值。

我怎样才能防止这个?

如果你想完全“防止”反思,那么,你必须使用不同的语言。 reflection是Objective C中的一个关键,不可能“阻止”或“禁用”它。

但是,通过混淆研究人员,可以使这个运行时信息对于研究人员来说非常有用。 例如,看看这个工具: https : //github.com/Polidea/ios-class-guard 。 这只是一个例子。 我不涉及这个特定的项目,你可以自由select一个不同的混淆器或写你自己的。

如果你需要的只是公开的API的reflection,甚至公开了一些私有方法和ivars(没有他们的真实姓名)对你来说是不好的,那么你别无select,只能用不同的语言写敏感的代码。 你可以使用Pimpl的devise模式来实现你想要的。 这样,你的课只有公共方法和一个单独的私人ivar _impl (或类似的东西)。 其中_impl是用C ++编写的实现类的实例(如果需要访问ObjC API,则为Objective C ++),所有公共方法都像代理一样工作。 像这样的东西:

 - (NSInteger)computeSuperSensitiveStuffWithFoo:(Foo *)foo Bar:(Bar *)bar { return _impl->computeStuff(foo, bar); } 

这样你所有的私有数据和方法都会封装在MyClassImpl类中。 如果你私下保留这个类的声明和实现(即不要将MyClassImpl.h文件分MyClassImpl.h你的库),并使用像C ++这样的语言来实现它,那么你将实现你想要的。

另外请注意,如果您select了Objective C ++,那么MyClassImpl应该是一个C ++类(用class关键字声明),而不是Objective C类(用@interface / @end块声明并在@implementation / @end块内部实现)。 否则,您的所有私人数据都可用于反思,但需要研究人员采取一些额外步骤。