iOS编译原理

hook改变函数的执行流程。

1.重定向:ASLR(随机值) + 偏移值 = 内存值
0x5FCC + 0x0000000102edc000 = 0x102ee1fcc
内存中的可执行文件叫做镜像

viewdidload
0x102ee1fcc

可执行文件
0x0000000102edc000

0x5FCC

重定向:通过计算找到内部函数地址.
汇编指令和二进制是一一对应关系,如1f 20 03 d5 代表 nop
指针在arm64架构下占8个字节

2.什么是符号绑定?
本质是修改符号表,符号绑定的是外部函数。
内部函数是重定向确定调用地址的。

3.每次调用外部符号的过程?
Symbol Stubs -> Lazy Symbol Pointers -> Non-Lazy
Symbol Pointers
1.找桩(Symbol Stubs),就是根据懒加载符号表里面的值调用
2.Lazy Symbol Pointers符号表里面的值(默认值是执行dyld_stub_binder)
3.首次调用:dyld_stub_binder,改变符号表里面的值,指向真实地址.

第二次再次调用的话就直接调用符号表里的值了就是NSLog的真实地址了
Symbol Stubs -> Lazy Symbol Pointers

口述没用,汇编+lldb调试才是王道

symbols是个总表:
内部符号、
外部符号:懒加载符号Lazy Symbol Pointers(运行时确定地址),非懒加载符号Non-Lazy
Symbol Pointers(如dyld_stub_binder,编译时就确定了地址)。
每一个外部函数都对应一个桩

4.Fishhook如何修改符号?原理?
Fishhook专门hook外部函数的

text 只读的不能改的,所以改的是Lazy Symbol Pointers

5.Fishhook 如何通过字符串找到符号?即Fishhook改符号原理
string Table Index -> symbols Index -> Indirect Symbols Index -> Lazy Symbol Pointers -> 修改Lazy Symbol Pointers值

1、去MachO 中寻找 string Table 完全可以用 . 来分割! 得到偏移值(string Table Index)
2、通过string Table Index 去找Symbols(符号表)!得到符号表的偏移值(symbols Index)
3、通过 symbols Index 去找 Indirect Symbols! 得到符号的偏移值 ( Indirect Symbols Index)
4、由于Lazy Symbol Pointers 的 Index 和 Indirect Symbols Index 一一对应! 所以很容易就找到了对应的符号!!

最后去修改Lazy Symbol 里面的值!!
(因为外部符号的调用,都是找桩!桩去寻找Lazy Symbol 里面的地址执行!)

6.如何去掉符号?
build setting strip style 默认去掉符号表中的所有符号

strip style
APP的话选择 All Symbols 去掉本地符号,只剩间接符号
动态库的话选择 Non-Global Symbols 去掉本地符号,剩下全局符号、间接符号
Debugging Symbols 去掉调试符号 剩下本地、全局、间接符号

Deployment Postprocessing 设置 yes debug阶段去除符号 no是在打包时去除符号即默认值

本地符号,如果不使用,符号不会生成

7.如何恢复符号?
在终端执行下面语句使用使用restore-symbol工具
./restore-symbol restore-symbol -o SymbolDemo1

  1. 如何通过函数调用栈算出函数名?
    将函数调用栈地址-程序的镜像地址 然后在hopper中搜索改地址

9.两个动态库中的同名类调用会冲突吗?
并不会,动态库方法的调用,先找动态库,再去里面找符号,所以动态库不存在符号冲突。
谁在上边就先找到谁

静态库:
1.当静态库没有使用的符号(符号 的最小单位是类),那么静态库不会被链接。
2.当链接器找到符号之后,就不会再链接相同的符号了
谁在上边就先连接到谁

使用静态库中的分类方法会发生什么?会找不到方法,因为分类时动态添加的,静态库中的分类方法默认不会链接进来。如何解决?在Other Link Flags 添加 -ObjC 就是把所有OC代码都链接进来

如何可以发生静态库冲突?一个静态库是-ObjC,另一个也有同名类方法,这时候编译就会报错。
如何解决?在Other Link Flags中加2行,-force_load ,绝对路径(也可以使用环境变量)
设置主链接

如果用到了2个静态库,各自又有相同名字的的类目方法,导致了符号冲突怎么解决?
这个时候就只能使用工具llvm-objcopy去添加前缀去修改符号了。

你可能感兴趣的:(iOS编译原理)