我们在日常的开发的过程中,Xcode默认在发布的时候会帮我们脱去符号。当然,这里脱去的是除了间接符号表以外的其他符号。我们在Xcode中的设置如下:
- 如果我们在
Debug
模式下,将符号脱离,那么我们的断点将不再起作用。我们可以来测试一下。- 首先我们在工程中定义一个方法,如下:
image
将APP包里面的可执行文件放到MachOView
里面查看一下符号表:
image - 接下来我我们在
Debug
模式下,进行脱符号;然后再去查看一下符号表:
image
我们会发现,当我们再次去符号表里面搜索我们自定义的符号的时候,搜索不到了:
image
这个时候还会有一个现象,那就是我们此时在工程中进行断点调试的时候,是没有效果的。这是因为符号被脱离,断点无法定位。
image
- 首先我们在工程中定义一个方法,如下:
这个时候,就要请出我们今天第一个要介绍的逆向工具restore-symbol
来帮我们恢复符号。
符号表的恢复
-
恢复符号表的原理
通过上面的探索,大家知道了我们的APP里面的符号暂时被脱离。那么现在大家思考一个问题,既然符号被脱离了,那么方法名
是否还存在于可执行文件
中?
答案是:存在。
因为在我们的可执行文件中,是包含类
的方法列表的,同时也包含类的名称。下面给大家看一下我们日常开发中常用的一些API
,帮助大家去理解一下这个事情:
/// 获取类
NSClassFromString(<#NSString * _Nonnull aClassName#>)
/// 获取方法
@selector(<#selector#>)
这些不都是通过字符串
去获取对应的方法和类吗!!!
对应的在可执行文件
中的位置如下:
image
到这里我想大家已经能够猜想到符号表的恢复的理论基础是什么了。如果我们在APP发布的时候进行了符号脱离(一般情况这样做是为了减少包的大小),那我们我们也可以通过其他的表,将符号表里面的内容恢复。
-
restore-symbol的使用
restore-symbol的地址-
首先我们要知道,我们主要使用的是
imagerestore-symbol
这个可执行文件,所以我们在restore-symbol文件夹里面使用,或者在其他文件里面用,都是可行的。! -
接着我们要将我们刚刚
编译后的MachO文件(已经脱符号的)
拷贝出来到一个文件夹里面(这里我们就复制到restore-symbol文件夹里面)。 -
打开
终端
,执行下面的指令
// 第一个参数是 ·脱符号的MachO文件· // 第二个参数是 ·恢复符号后的MachO文件· // `-o` 代表输出 $ ./restore-symbol SymbolDemo -o SymbolDemo2
执行结果如下
image -
此时我们再通过MachOView
来查看一下SymbolDemo2
:
可以看到之前别脱离的符号已经恢复。
这里有一个知识点大家要注意,这样的符号表的恢复只能去恢复OC的符号,C语言的方法是恢复的(也可以说静态方法无法恢复)。因为这是建立在
Runtime
的基础上的。
关于静态语言的HOOK,可以看12、HOOK原理(下)--- InlineHook这篇文章。
网友评论