-
小谷最近生病了几天,借此机会也研究了下符号~
-
今天来小叙一下符号。(这个东西大家应该都不会陌生~)
1. 符号的定义
1.1. 什么是符号
-
小谷说下自己的理解吧~
- 其实
符号
的概念比较广,我们开发中,编写的函数、变量
等等都可以成为符号
。
- 其实
-
这个时候不得不提一下
符号表
-
我们通过
烂苹果(MachOView)
可以知道:MachO
中有个总表·Symbol Table·(符号表)
,符号都被保存在这里. -
还有个他的子集,叫
·Indirect Symbol Table·(间接符号表)
,保存的是间接符号
(我们通常使用的NSLog
就属于间接符号
,有时候我们也称他为外部符号
). -
还有
String table
,保存的是符号的名称
.
-
这几张表的联系,我一会会说~
2. 符号绑定
说到绑定,不得不提一嘴
dyld
2.1. dyld
的加载流程(应用程序的启动~)
不知道大家有没有看过
dyld的加载流程
(我直接就阐述下吧。兄弟们有时间可以去看看,验证下)
-
首先,
dyld(dynamic linker,动态链接器)
最开始的地方,_dyld_start
-
然后通过
dyldbootstrap::start
进入dyld
的main
函数 -
主要流程开始了~
配置所需环境、重定向dyld
(由于应用程序运行时都在内存中(磁盘中的镜像(所以我们通常都会说image
)),由于苹果的安全协议,出现了一个ASLR
,所以需要重定向
)
加载共享缓存
(这个其实不用多说了。我们用到了系统的库,有可能之前已经加载过了~)
实例化主程序
(之前会判断是dyld
或者dyld3
.都是一样的。dyld3
是苹果为了提高效率新增的,采用的是回调函数模式(通常也成为闭包模式
))
加载动态库
(之前一篇博客,动态库的注入,大家也已经了解了,其实首先加载的是注入的动态库。)
链接主程序,绑定符号
(这个是很关键的~,这个操作的主要是非懒加载中的符号
,一会说到的,dyld_stub_binder
就是这一步操作绑定的,在load
方法之前)
然后就是初始化方法:initializeMainExecutable
(剩下的就是调用,链接objc_init之类的了,然后调用load,然后c++,然后main了,这就不多说了~)
- 本来想给大家展示代码的,感觉其实不重要,这流程就够用了~
2.2. 符号绑定
-
- 我们用
NSLog
举例吧(直接写代码)
- 我们用
// 我们都知道NSLog是外部符号,在间接符号表里面~
NSLog(@" 第一次调用外部符号~ ");
NSLog(@" 第二次调用外部符号~ ");
复制代码
-
- 我直接画了个简易的流程图(要是一步步写,文章就太长了,图片解决一切~)
由于
dyld_stub_binder
是在很早之前就加载好了(上面提到的~).外部符号的绑定看来是通过dyld_stub_binder
,下次再调用时候就不需要在次绑定了
-
- 我们从
MachOView
中观察到:在绑定之前NSLog
中已经有值了,这个称为NSLog的桩
- 我们从
3. 通过字符串查找符号
兄弟们应该都用过
fishhook
技术
fishhook
有一句:log.name = "NSLog";
-
那么通过字符串,如何找到的这个函数呢?
-
我们先看看
fishhook
的官方解释
是不是有点小懵逼。小谷陪兄弟们看一下~
- 我通过
MachOView
。以NSLog
举例~(他用的close
,其实流程差不多~)
这样是不是清楚很多了~
4. 脱符号
关于
脱符号和恢复符号
,我就简单说一下。
5. 恢复符号
恢复符号
的原理主要是通过OC方法的动态性
。
- 虽然
符号
去掉了,但是保存在methodlist
里面的方法,用到类
都会存在的(如果没有就么有办法调用了~)
有个工具叫做,
restore-symbol
就是通过方法名和类名称
,然后生成符号表插入到MachO
的。
6. 总结
-
- 其实做
逆向安防
的话,大多数都是用的工具-比较方便,但是我感觉还是要稍微懂一点原理比较好点~
- 其实做
-
- 这篇博客可能不是特别的细,就当给兄弟们开个口子。
-
- 最后希望和兄弟们共同进步~?
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END