dylib的默认调用问题


#1

《iOS应用逆向工程》这本书里介绍了用Reveal查看其它app UI布局方法,实际就是在startReveal方法中通过dlopen函数来加载libReveal.dylib,然后利用postNotificationName来发送一个通知来调用。这是一个很高明的用法,不需要引用头文件,发一个通知就能触发Reveal运行。问题在于postNotificationName之前肯定先要注册Notification通接收方,postNotificationName才会有效,那么这个注册过程是在哪里?我想是加载dylib时dylib默认会调用一个内部初始化方法,比如init,在这个方法里注册Notification通知的。
但是在作者后来的一篇文章《Reveal查看任意app的高级技巧》中,仅仅是把libReveal.dylib文件上传到设备的/Library/MobileSubstrate/DynamicLibraries目录,重启机器就可以达到目的,无需调用postNotificationName方法。我知道把dylib放在/Library/MobileSubstrate/DynamicLibraries目录里在设备启动时是会自动调用的,如果说自动调用的时候也会默认调用init方法,那么怎么会不使用postNotificationName就能触发Reveal运行呢?

不知道有没有人想过这个问题,至少在我看来是有点矛盾的

可能我对dylib的运作流程不太清楚,搜了不少资料没找到dylib默认调用的资料,求大神指点


#2

我没有太看懂你的问题,你是说,你不知道dylib是如何加载的,是吗?
如果放在你的例子里,拿Reveal举例的话,就是libReveal.dylib是由CydiaSubstrate来加载进目标App的(所有/Library/MobileSubstrate/DynamicLibraries/下的dylib都是这样加载的),然后libReveal.dylib来跟OSX上的Reveal通信。
至于dynamic library的一些基本概念,iOS倒是讳莫如深,但OSX上却是开诚布公,可以直接参考Apple的官方文档


#3

书里面的方法是用postNotificationName来触发libReveal.dylib来跟OSX上的Reveal通信,而把libReveal.dylib放在/Library/MobileSubstrate/DynamicLibraries/里面无需postNotificationName就能触发,关键是这个有无postNotificationName的区别,为什么前者需要postNotificationName而后者不需要?


#4

我逆向看了一下libReveal.dylib,其内部实现确实需要IBARevealRequestStart来调用requestStart:这个函数,如图所示:
我个人没有尝试过直接使用MobileSubstrate加载的这种方法,你可以问问hangcom问题出在哪里;或者采用我个人推荐的另一种方法


#5

你推荐的方法我是知道的,不过那不是我的目的,我问这个问题主要是想知道其中的原理/奥妙,也在微博上私信过hangcom,石沉大海啊

这个问题的来由是Flipboard推出了一个iOS设备调试工具FLEX,链接是https://github.com/Flipboard/FLEX,和Reveal不同的是它只需要在设备上调试,介绍里说它适用于任何APP,方法是代码注入但并没有介绍具体步骤而是作为一个问题留给读者。我立马想到了可以参考Reveal做成一个dylib的形式来实现,不过你现在也知道了,有些问题没想明白。


#6

我大概看了一下书上的代码,看那个意思是说post这个notification是官方文档要求的,但我不是100%确定,你可以在群里问一下hangcom


#7

群号多少?


#8

251453531


#9

狗神大大 我翻贴看到这个群号我申请被拒说要先回答入群问题,请问问题在哪里啊?


#10

个人理解:
CydiaSubstrate法的顺序是:

  1. [User] Open App
  2. [System] load app
    2.1 [System] load libReveal.dylib
    2.1.1 [libReveal] 添加 FinishLaunching 通知监听
  3. [System] Post FinishLaunching notification
  4. [Reveal] start.

dlopen 法的顺序

  1. [User] Open App
  2. [System] load app
  3. [System] Post FinishLaunching notification
  4. [System] dlopen Reveal
    4.1 [System] load libReveal.dylib
    4.1.1 [libReveal] 添加 FinishLaunching 通知监听
  5. post notification 手动启动。

最大的区别在于 dlopen 加载的时候 AppDidFinishLaunching 的通知已经发过了,Reveal 错过了这个通知,只能手动启动;
但是 CydiaSubstrate 加载 Reveal 的时候,AppDidFinishLaunching 的通知还没发过,所以 Reveal 可以收到这个通知,实现自启动。