我有一个项目,我同时使用Objective C和Swift。 出于安全原因,对于使用Objective C编写的一些类和方法,我使用了混淆。
这是我的代码:
#ifndef AccessManager_h
#define AccessManager ySbIXoscpewLLSwVacDpZvPvQeNDtG
#define loginWithUsername TEWhYyXaCdGrCViPbZZHWXoBiUPvPn
#endif
@interface AccessManager : AFHTTPSessionManager
-(void)loginWithUsername:(NSString*)username password:(NSString*)password success:(WSSuccessBlock)success failure:(WSFailureBlock)failure;
@end
这是我试图访问混淆类的快速代码
AccessManager.instance().login(withUsername: "my_user", password: "password", success: { (response) in
//TODO
}) { (error) in
//TODO
}
这是我在构建项目时得到的错误
Undefined symbols for architecture armv7:
"_OBJC_CLASS_$_AccessManager", referenced from:
objc-class-ref in MySwiftClass.o
ld: symbol(s) not found for architecture armv7
clang: error: linker command failed with exit code 1 (use -v to see invocation)
如何访问从Swift中混淆的Objective C类?
答案 0 :(得分:0)
通过使用宏,您更改了类的名称和方法名称。这是一种简单的混淆方法。
但是,如果您尝试使用原始类名及其方法,那也会破坏Swift-Objective-C的互操作性。
当然,您仍然可以通过Swift类中的重新定义的名称使用您的obj-c类(为简单起见,将块参数更改为简单的BOOL):
let accessManager = ySbIXoscpewLLSwVacDpZvPvQeNDtG()
accessManager.teWhYyXaCdGrCViPbZZHWXoBiUPvPn("", password: "", success: true, failure: true)
答案 1 :(得分:0)
下面是一个非常基本的例子,但是可以了解你可以做什么:
通过可从Swift代码调用的全局C函数,为您的类和方法的运行时表示提供接口。
与Objective-C方法不同,后者使用动态分派,并且其名称因此作为普通字符串(选择器)存在于二进制文件中,C函数调用被编译为跳转指令到相应的内存地址;函数名称不存在于二进制文件中,供黑客反编译/检查。
<强> AccessManager.h:强>
#import <Foundation/Foundation.h>
#ifndef AccessManager_h
#define AccessManager ySbIXoscpewLLSwVacDpZvPvQeNDtG
#define loginWithUsername TEWhYyXaCdGrCViPbZZHWXoBiUPvPn
#endif
/// Provides the class object at runtime
Class accessManagerClass();
/// Provides the method name at runtime
SEL loginMethodName();
@interface AccessManager : NSObject
- (instancetype) init;
- (void) loginWithUsername:(NSString*) userName;
@end
<强> AccessManager.m:强>
#import "AccessManager.h"
Class accessManagerClass() {
return [AccessManager self];
}
SEL loginMethodName() {
return @selector(loginWithUsername:);
}
@implementation AccessManager
- (void) loginWithUsername:(NSString*) userName {
// Dummy implementation, for demonstration purposes:
NSLog(@"%s", __func__);
NSLog(userName);
}
@end
桥接标题:
#import "AccessManager.h"
ViewController.swift(省略了大部分类):
override func viewDidLoad() {
super.viewDidLoad()
if let managerClass: AnyClass = accessManagerClass(), let methodName = loginMethodName() {
// Instantiate the manager from the class:
let manager = (managerClass as! NSObject.Type).init()
// (I'm still a bit fuzzy about metatypes on Swift,
// perhaps the line above can be improved)
// Call the obfuscated method:
manager.perform(methodName, with: "AAAA")
}
}
运行时,会打印:
% -[ySbIXoscpewLLSwVacDpZvPvQeNDtG TEWhYyXaCdGrCViPbZZHWXoBiUPvPn:]
% AAAA
......证明:
我将示例项目与on GitHub上方的所有代码放在一起。