iOS 底层 day 11 Mach-O 结构 ASLR 各种
2020-08-03 本文已影响0人
望穿秋水小作坊
一、Mach-O 的一些词汇了解
- VM Address
- Virtual Memory Address,内存地址,在内存中的位置
- VM Size
- Virtual Memory Size,内存大小,占用多少内存
- File Offset
- 文件所在位置偏移量
- File Size
- 文件的大小
二、回顾一下 Mach-O 文件的结构图


如果 Mach-O 文件被执行,在内存中的情况呢?

- 函数代码存放在
__TEXT
段中 - 全局变量存放在
__DATA
段中
三、ASLR
- ASLR 是什么?
- Address Space Layout Random ,地址空间布局随机化
- 是一种针对缓冲区溢出的安全保护技术,通过对堆、栈、共享库映射等线性区布局的随机化,通过增加攻击者预测目的地址的难度,防止攻击者指针定位攻击代码位置,达到阻止溢出攻击的一种技术

四、基于以上知识,我们来验证一些问题。
-
Hopper Disassembler
工具中显示的函数地址值的含义到底是什么?

-
由于 ASLR 是动态的,在程序未跑起来的情况下,没任何办法可以预测这个值,所以
Hopper Disassembler
分析的这个值是未包括 ASLR 的地址。 -
我们可以观察发现,这些地址都是 0x100000000 开始的,所以
Hopper Disassembler
大概率显示的就包括的PageZero
,但是未包括ASLR
的内存地址,这一点我们可以通过对比Mach-OView
的地址值来论证:
可以发现 0x10000432C - 0x100000000 = 0x0000432C
- 接下来我们拿到
Hopper Disassembler
中的地址0000000100004dd0

- 在利用 mac 的 lldb 连接到 Demo 项目的 debugserver , 利用
image list
找到第一个输出内容,也就是 Demo 加入内存时候的地址0x0000000100f48000
(lldb) image list
[ 0] 1396569F-D0D0-3300-8A91-C28EA9F62DF2 0x0000000100f48000 /var/containers/Bundle/Application/2227BC81-41C9-4B49-A3A9-4C23FFC2A0D1/Demo.app/Demo (0x0000000100f48000)
[ 1] 9C893B6A-A3B1-3D95-9632-6EF6952E7195 0x0000000101254000 /Library/Caches/cy-jCNXTu.dylib (0x0000000101254000)
[ 2] E668256B-2890-35A6-8F6C-413E5129F8AB 0x0000000100f98000 /Library/MobileSubstrate/MobileSubstrate.dylib (0x0000000100f98000)
- 利用我们上面的算法
f48000 + 100004dd0 = 0x100F4CDD0
得到一个地址,最后在 lldb 中breakpoint set -a 0x100F4CDD0
设置一个断点,获得如下信息,说明我们的猜测正确:
(lldb) breakpoint set -a 0x100F4CDD0
Breakpoint 2: where = Demo`-[ViewController tableView:didSelectRowAtIndexPath:] at ViewController.m:120, address = 0x0000000100f4cdd0
- 如何证明全局变量是在
_Data
段。
-
我们在 Xocde 中定义三个全局变量
三个全局变量
-
然后使用 Xcode 断点模式,打印出三个变量运行时地址
(lldb) p &a
(int *) $0 = 0x0000000100996020
(lldb) p &b
(int *) $1 = 0x0000000100996024
(lldb) p &c
(int *) $2 = 0x0000000100996028
- 然后使用 Xcode 断点模式,打印出Demo 这个模块被加载的初始地址,获得 ASLR 地址
0x98c000
(lldb) image list -o -f | grep Demo
[ 0] 0x000000000098c000 /Users/carrot__lsp/Library/Developer/Xcode/DerivedData/Demo-azxmdanoosovrnaycaajglqvzbko/Build/Products/Debug-iphoneos/Demo.app/Demo
-
用运行时c 变量的地址 - ASLR 地址 =
0x100996028 - 0x98c000 = 0x10000A028
-
然后我们打开
Mach-OView
得到如下分析结果
从图中地址和所存贮的值,我们可以充分证明,静态变量在__DATA 段中