一、Mach-O 的一些詞匯了解
- VM Address
- Virtual Memory Address,內(nèi)存地址,在內(nèi)存中的位置
- VM Size
- Virtual Memory Size,內(nèi)存大小,占用多少內(nèi)存
- File Offset
- 文件所在位置偏移量
- File Size
- 文件的大小
二、回顧一下 Mach-O 文件的結(jié)構(gòu)圖

Mach-O 結(jié)構(gòu)

對(duì)應(yīng)的 Mach-OView 結(jié)構(gòu)圖
如果 Mach-O 文件被執(zhí)行,在內(nèi)存中的情況呢?

Mach-O 被載入 RAM64 的內(nèi)存中,并且不考慮 ASLR
- 函數(shù)代碼存放在
__TEXT段中 - 全局變量存放在
__DATA段中
三、ASLR
- ASLR 是什么?
- Address Space Layout Random ,地址空間布局隨機(jī)化
- 是一種針對(duì)緩沖區(qū)溢出的安全保護(hù)技術(shù),通過對(duì)堆、棧、共享庫(kù)映射等線性區(qū)布局的隨機(jī)化,通過增加攻擊者預(yù)測(cè)目的地址的難度,防止攻擊者指針定位攻擊代碼位置,達(dá)到阻止溢出攻擊的一種技術(shù)

Mach-O 被載入 RAM64 的內(nèi)存中,有 ASLR
四、基于以上知識(shí),我們來驗(yàn)證一些問題。
-
Hopper Disassembler工具中顯示的函數(shù)地址值的含義到底是什么?

Hopper Disassembler 分析圖
由于 ASLR 是動(dòng)態(tài)的,在程序未跑起來的情況下,沒任何辦法可以預(yù)測(cè)這個(gè)值,所以
Hopper Disassembler分析的這個(gè)值是未包括 ASLR 的地址。-
我們可以觀察發(fā)現(xiàn),這些地址都是 0x100000000 開始的,所以
Hopper Disassembler大概率顯示的就包括的PageZero,但是未包括ASLR的內(nèi)存地址,這一點(diǎn)我們可以通過對(duì)比Mach-OView的地址值來論證:
可以發(fā)現(xiàn) 0x10000432C - 0x100000000 = 0x0000432C
- 接下來我們拿到
Hopper Disassembler中的地址0000000100004dd0

-[ViewController tableView:didSelectRowAtIndexPath:]: 函數(shù)地址
- 在利用 mac 的 lldb 連接到 Demo 項(xiàng)目的 debugserver , 利用
image list找到第一個(gè)輸出內(nèi)容,也就是 Demo 加入內(nèi)存時(shí)候的地址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得到一個(gè)地址,最后在 lldb 中breakpoint set -a 0x100F4CDD0設(shè)置一個(gè)斷點(diǎn),獲得如下信息,說明我們的猜測(cè)正確:
(lldb) breakpoint set -a 0x100F4CDD0
Breakpoint 2: where = Demo`-[ViewController tableView:didSelectRowAtIndexPath:] at ViewController.m:120, address = 0x0000000100f4cdd0
- 如何證明全局變量是在
_Data段。
-
我們?cè)?Xocde 中定義三個(gè)全局變量
三個(gè)全局變量 然后使用 Xcode 斷點(diǎn)模式,打印出三個(gè)變量運(yùn)行時(shí)地址
(lldb) p &a
(int *) $0 = 0x0000000100996020
(lldb) p &b
(int *) $1 = 0x0000000100996024
(lldb) p &c
(int *) $2 = 0x0000000100996028
- 然后使用 Xcode 斷點(diǎn)模式,打印出Demo 這個(gè)模塊被加載的初始地址,獲得 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
用運(yùn)行時(shí)c 變量的地址 - ASLR 地址 =
0x100996028 - 0x98c000 = 0x10000A028-
然后我們打開
Mach-OView得到如下分析結(jié)果
從圖中地址和所存貯的值,我們可以充分證明,靜態(tài)變量在__DATA 段中


