我正在处理一个处理敏感数据的静态库。使用库的开发人员必须不能在库中使用反射。
在Android上,我们通过使用aar
开发service
文件并将service
运行到单独的进程中来解决问题;(当服务运行到另一个进程时,开发人员不能使用反射)但我想知道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
是我图书馆的一个班级。在第一行中,我从这个类初始化一个对象。
在下一行中,我读取了类的变量,方法和属性列表并记录它。结果如下:
{
ivars = (
testValue
);
methods = (
printTestValue,
wannatTestIt,
"initWithFrame:"
);
properties = (
);
}
wannaTestIt
是私有方法,testValue
是私有变量。所以我希望使用该库的开发人员无法访问它们。但是,因为库的用户可以获取名称,所以用户最终可以调用该方法来读取iVar的值。
我该如何防止这种情况?
答案 0 :(得分:5)
如果你想完全“防止”反思,那么,你必须使用不同的语言。反射是目标C中的一个关键因素,它不可能“阻止”或“禁用”它。
但是,通过模糊处理,您可以使此运行时信息对研究人员的用处更少。例如,请查看此工具:https://github.com/Polidea/ios-class-guard。这只是一个例子。我与这个特定项目没有关系,您可以自由选择不同的混淆器或编写自己的混淆器。
如果您需要的是仅限制反映到公共API,甚至披露一些私人方法和ivars(没有他们的实际名称)对你来说不合适那么你别无选择用不同的语言写出敏感代码。您可以使用Pimpl设计模式来实现您的目标。这样,您的类只有公共方法和单个私有ivar _impl
(或类似的东西)。其中_impl
是用C ++编写的实现类的实例(如果需要访问ObjC API,则为Objective C ++),并且所有公共方法都像代理一样。像这样:
- (NSInteger)computeSuperSensitiveStuffWithFoo:(Foo *)foo Bar:(Bar *)bar {
return _impl->computeStuff(foo, bar);
}
这样,所有私有数据和方法都将封装在MyClassImpl
类中。如果您私下保留此类的声明和实现(即不向您的库分发MyClassImpl.h
文件)并使用C ++之类的语言来实现它,那么您将实现您想要的。
另请注意,如果您选择了Objective C ++,那么MyClassImpl
应该是C ++类(使用class
关键字声明)而不是Objective C类(使用@interface
/ {{1}声明阻止并在@end
/ @implementation
块内实现。否则,您的所有私人数据都可用于反思,但需要研究人员的其他步骤。