初探私有API

首先表明態(tài)度,私有API僅供研究,不能在AppStore上架,蘋果在review guide里也明確禁止使用私有API。當(dāng)然,如果你是企業(yè)版,覺得無所謂,可以拿來使用,暫時(shí)不知道企業(yè)版發(fā)布的app,被蘋果檢測(cè)到使用了私有API會(huì)有什么后果。

下面介紹幾個(gè)在探索私有API時(shí)常用的方法

1.加載/卸載framework

很多私有API不在public的framework里,這時(shí)候我們就要通過path加載出framework,加載完成之后,才能通過類名創(chuàng)建對(duì)象,注意使用動(dòng)態(tài)加載framework的方法,需要手動(dòng)卸載,使用該framework中的類,需要在卸載操作之前。

#import <dlfcn.h>
//加載framework
void *FTServicesHandle = dlopen("/System/Library/PrivateFrameworks/FTServices.framework/FTServices", RTLD_LAZY);
//卸載framework
dlclose(FTServicesHandle);

2.獲取類的所有方法

當(dāng)我們知道這個(gè)類的時(shí)候,需要知道所有的方法,才能取根據(jù)方法名猜測(cè)改方法的功能,下面就是在runtime中獲取一個(gè)類的所有方法的代碼。

#import <objc/runtime.h>
unsigned int count;
Method *methods = class_copyMethodList([self class], &count);
for (int i = 0; i < count; i++) {
    Method method = methods[i];
    SEL selector = method_getName(method);
    NSString *name = NSStringFromSelector(selector);
    NSLog(@"->%@",name);
}

3.調(diào)用私有API的方法

調(diào)用私有API可以直接通過performSelector,但我們都知道performSelector的限制,沒有返回值,這樣我們?nèi)绻肽玫揭粋€(gè)類的屬性,就比較麻煩。下面介紹一種我的使用方法,現(xiàn)在不知道會(huì)出現(xiàn)什么問題,還請(qǐng)大佬幫忙review,大概邏輯就是使用protocol定義相應(yīng)的屬性和方法,已獲取手機(jī)上已安裝的app為例(僅在iOS11以前生效),介紹這個(gè)方法。
相關(guān)的類有:LSApplicationWorkspace和LSApplicationProxy,定義LSApplicationProxy_JTAppProtocol和LSApplicationWorkspace_JTAppProtocol兩個(gè)協(xié)議,里面的方法和屬性分別和上面兩個(gè)類的方法和屬性對(duì)應(yīng),名字和返回值都一致。

@protocol LSApplicationProxy_JTAppProtocol <NSObject>
+ (instancetype)applicationProxyForIdentifier:(NSString*)identifier;
@property (nonatomic, readonly) NSString    *localizedShortName;
@property (nonatomic, readonly) NSString    *localizedName;
@property (nonatomic, readonly) NSString    *bundleId;
@property (nonatomic, readonly) NSArray     *appTags;
@end

@protocol LSApplicationWorkspace_JTAppProtocol <NSObject>
- (NSArray *)allInstalledApplications;
@end

使用的方法也很簡單,用id<LSApplicationProxy_JTAppProtocol>對(duì)象接收LSApplicationProxy對(duì)象,用id<LSApplicationWorkspace_JTAppProtocol>對(duì)象接收LSApplicationWorkspace對(duì)象,這樣我們認(rèn)為該對(duì)象是服從自己定義的protocol的,就可以直接調(diào)用方法和屬性,也能保證有返回值,使用如下。

@interface JTAppService ()
@property (nonatomic, strong) id<LSApplicationWorkspace_JTAppProtocol>  applicationWorkspace;
@end

@implementation JTAppService
+ (instancetype)sharedInstance {
    static dispatch_once_t once;
    static id sharedInstance;
    dispatch_once(&once, ^{
        sharedInstance = [[self alloc] init];
    });
    return sharedInstance;
}

- (instancetype)init {
    if(self = [super init]) {
        self.applicationWorkspace = [[NSClassFromString(@"LSApplicationWorkspace") alloc] init];
    }
    return self;
}

- (NSArray *)readInstalledApplicationNames {
    NSArray *allInstalledApplications = [self.applicationWorkspace allInstalledApplications];
    NSMutableArray *allApplicationNames = [NSMutableArray arrayWithCapacity:allInstalledApplications.count];
    for(id<LSApplicationProxy_JTAppProtocol> proxy in allInstalledApplications) {
        if([[proxy appTags] indexOfObject:@"hidden"] != NSNotFound) {
            [allApplicationNames addObject:proxy.localizedName ?: proxy.localizedShortName];
        }
    }
    return allApplicationNames;
}
@end

4.代碼混淆

代碼混淆說起來不是私有API研究中的一項(xiàng),但很多人看到私有API的功能之后,想用上,又不想被AppStore的review reject,那要么用熱更新動(dòng)態(tài)下發(fā)代碼,要么就走代碼混淆方案,混淆也很簡單,方法就是用ASCII碼的char型數(shù)組表示想混淆的字符串,當(dāng)然混淆之后也有風(fēng)險(xiǎn),慎用?。。?/p>

#define LSApplicationWorkspaceChar (char[]){0x4c,0x53,0x41,0x70,0x70,0x6c,0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,0x57,0x6f,0x72,0x6b,0x73,0x70,0x61,0x63,0x65,'\0'}
self.applicationWorkspace = [[NSClassFromString([NSString stringWithUTF8String:LSApplicationWorkspaceChar]) alloc] init];

總結(jié)

私有API的研究方法很簡單,難點(diǎn)在于如何找到相關(guān)功能的framework和類名,知道了這些,就可以取出方法名和屬性,然后就是一個(gè)一個(gè)猜測(cè),然后試,需要兼容所有機(jī)型和系統(tǒng)版本,是一個(gè)比較大的工作量,建議只做研究,不上線。

參考

[iOS]私有API的使用-焚雪殘陽
ZIKCellularAuthorization

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,812評(píng)論 25 709
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 15,085評(píng)論 4 61
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,506評(píng)論 19 139
  • 讓父母幸福的這十六件小事,請(qǐng)記在心上! 1、給父母留足夠的錢,以免他們對(duì)你張口犯難。 2、與老人說話時(shí),注意“一慢...
    希望_閱讀 329評(píng)論 0 0
  • 春華芳菲終如畫,夏酷額肩濕待發(fā)。 秋雨瑟瑟?dú)埜蚕?,冬雪藏眉陣前發(fā)。 匹夫躍馬戰(zhàn)鼓雷,寒笑陣前幾敵對(duì)。 志雖千里時(shí)難...
    尤小鑫閱讀 468評(píng)論 0 0

友情鏈接更多精彩內(nèi)容