奇怪的私有api调用出错问题

旧笔记整理出来发一波:
CALayer有一个私有api doubleBounds, 想访问这个私有api返回的数据,用了下面的代码:

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

结果发现崩了,提示-[CALayer doubleBounds]: unrecognized selector sent to instance
根据链接:CALayer.h 3 可以知道doubleBounds是下面这样定义的,返回一个结构体数据,并且查看历史记录知道从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;

我是在非越狱环境下调用这个私有api的,目前测试iOS10.3.3和iOS7越狱设备调用这个api都会崩,虽然调用这个私有api 不是必需,但很想知道为什么调用这个私有api就会出错

同样的环境下,调用UIView的私有api recursiveDescription就完全没问题

在一个逆向论坛发贴问了一下,答案水落石出,做梦都没有想到是在MapKit里啊,因为我是在逆向UIScrollView里的某一个方法看到这个方法的,"image list"命令 真是个好东西
刚才还发现我在老项目调用 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来定位,大神就是大神,有关键字就好说了,新技能Get:

#import 
#include 
#include 

    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");
    }

结果:

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

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

打印的函数列表里会有显示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]

你可能感兴趣的:(奇怪的私有api调用出错问题)