奇怪的私有api調(diào)用出錯問題

舊筆記整理出來發(fā)一波:
CALayer有一個私有api doubleBounds, 想訪問這個私有api返回的數(shù)據(jù),用了下面的代碼:

id valuedoubleBounds = [view.layer performSelector:NSSelectorFromString(@"doubleBounds")];

結(jié)果發(fā)現(xiàn)崩了,提示-[CALayer doubleBounds]: unrecognized selector sent to instance
根據(jù)鏈接:CALayer.h 3 可以知道doubleBounds是下面這樣定義的,返回一個結(jié)構(gòu)體數(shù)據(jù),并且查看歷史記錄知道從iOS7到iOS10這個方法是一直存在于CALayer里面的

(struct CADoubleRect { 
  struct CADoublePoint { 
  double x_1_1_1; double x_1_1_2; 
  } x1; 
  struct CADoubleSize { double x_2_1_1; double x_2_1_2;
   } x2; 
})doubleBounds;

我是在非越獄環(huán)境下調(diào)用這個私有api的,目前測試iOS10.3.3和iOS7越獄設(shè)備調(diào)用這個api都會崩,雖然調(diào)用這個私有api 不是必需,但很想知道為什么調(diào)用這個私有api就會出錯

同樣的環(huán)境下,調(diào)用UIView的私有api recursiveDescription就完全沒問題

在一個逆向論壇發(fā)貼問了一下,答案水落石出,做夢都沒有想到是在MapKit里啊,因為我是在逆向UIScrollView里的某一個方法看到這個方法的,"image list"命令 真是個好東西
剛才還發(fā)現(xiàn)我在老項目調(diào)用 id valuedoubleBounds = [self.view.layer performSelector:NSSelectorFromString(@"doubleBounds")];還是有問題的,居然返回的是一個CALayer對象,這個還是不可靠,最后還是通過下面的代碼得到真實的值:

SEL selector = NSSelectorFromString(@"doubleBounds");
IMP imp = [self.view.layer methodForSelector:selector];
CGRect (*func)(id, SEL) = (void*)imp;
CGRect doubleBounds = func(self.view.layer, selector);
NSLog(@"doubleBounds is %@", NSStringFromCGRect(doubleBounds));

搜了一下老項目的代碼,果然是有一個地方寫了 #import "MapKit/MapKit.h",不過是在SDWebImage中,沒見項目配置中添加有MapKit.framework,而新建的項目必須要添加這個framework才會不崩,猜測前者是某個第三方framework自行添加了MapKit.framework吧

不過也有大神提示使用dladdr來定位,大神就是大神,有關(guān)鍵字就好說了,新技能Get:

#import <objc/runtime.h>
#include <dlfcn.h>
#include <objc/objc.h>

    Dl_info info;
    if (dladdr(imp, &info)) {
        printf("dli_fname: %s\n", info.dli_fname);
        printf("dli_sname: %s\n", info.dli_sname);
        printf("dli_fbase: %p\n", info.dli_fbase);
        printf("dli_saddr: %p\n", info.dli_saddr);
    } else {
        printf("error: can't find that symbol.\n");
    }

結(jié)果:

dli_fname: /System/Library/Frameworks/MapKit.framework/MapKit
dli_sname: <redacted>
dli_fbase: 0x194256000
dli_saddr: 0x1943c7c0c

如果在使用self.view.layer后加上斷點,在console入敲上:
po [CALayer _shortMethodDescription]

打印的函數(shù)列表里會有顯示doubleBounds
會打印出所有的類方法,屬性和實例方法

- (void) setDoublePosition:(struct CGPoint)arg1; (0x1943c7c00)
        - (struct CGRect) doubleBounds; (0x1943c7c0c)

也還可以通過 下面的查詢:

(IMP) imp = 0x00000001943c7c0c (MapKit`-[CALayer(MKDoubleLayer) doubleBounds])
(lldb) image lookup -a 0x00000001943c7c0c
      Address: MapKit[0x000000018de53c0c] (MapKit.__TEXT.__text + 1505440)
      Summary: MapKit`-[CALayer(MKDoubleLayer) doubleBounds]
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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

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