13、符号脱离和恢复

我们在日常的开发的过程中,Xcode默认在发布的时候会帮我们脱去符号。当然,这里脱去的是除了间接符号表以外的其他符号。我们在Xcode中的设置如下:

image

  • 如果我们在Debug模式下,将符号脱离,那么我们的断点将不再起作用。我们可以来测试一下。
    • 首先我们在工程中定义一个方法,如下:
      image

      将APP包里面的可执行文件放到MachOView里面查看一下符号表:
      image
    • 接下来我我们在Debug模式下,进行脱符号;然后再去查看一下符号表:
      image

      我们会发现,当我们再次去符号表里面搜索我们自定义的符号的时候,搜索不到了:
      image

      这个时候还会有一个现象,那就是我们此时在工程中进行断点调试的时候,是没有效果的。这是因为符号被脱离,断点无法定位。
      image

这个时候,就要请出我们今天第一个要介绍的逆向工具restore-symbol来帮我们恢复符号。

符号表的恢复

  • 恢复符号表的原理
    通过上面的探索,大家知道了我们的APP里面的符号暂时被脱离。那么现在大家思考一个问题,既然符号被脱离了,那么方法名是否还存在于可执行文件中?
    答案是:存在
    因为在我们的可执行文件中,是包含的方法列表的,同时也包含类的名称。下面给大家看一下我们日常开发中常用的一些API,帮助大家去理解一下这个事情:
/// 获取类
NSClassFromString(<#NSString * _Nonnull aClassName#>)
/// 获取方法
@selector(<#selector#>)

这些不都是通过字符串去获取对应的方法和类吗!!!
对应的在可执行文件中的位置如下:

image

image

到这里我想大家已经能够猜想到符号表的恢复的理论基础是什么了。如果我们在APP发布的时候进行了符号脱离(一般情况这样做是为了减少包的大小),那我们我们也可以通过其他的表,将符号表里面的内容恢复。


  • restore-symbol的使用
    restore-symbol的地址
    1. 首先我们要知道,我们主要使用的是restore-symbol这个可执行文件,所以我们在restore-symbol文件夹里面使用,或者在其他文件里面用,都是可行的。!

      image

    2. 接着我们要将我们刚刚编译后的MachO文件(已经脱符号的)拷贝出来到一个文件夹里面(这里我们就复制到restore-symbol文件夹里面)。

    3. 打开终端,执行下面的指令

    // 第一个参数是 ·脱符号的MachO文件·
    // 第二个参数是 ·恢复符号后的MachO文件·
    // `-o` 代表输出
    $ ./restore-symbol SymbolDemo -o SymbolDemo2
    

    执行结果如下


    image

此时我们再通过MachOView来查看一下SymbolDemo2:

image

可以看到之前别脱离的符号已经恢复。

这里有一个知识点大家要注意,这样的符号表的恢复只能去恢复OC的符号,C语言的方法是恢复的(也可以说静态方法无法恢复)。因为这是建立在Runtime的基础上的。
关于静态语言的HOOK,可以看12、HOOK原理(下)--- InlineHook这篇文章。

你可能感兴趣的:(13、符号脱离和恢复)