在深刻學習Mach-O文件以前,先來回顧一下以前學習的Mach-O的基本結構,能夠到官網查看Mach-O文件的介紹html
Mach-O文件有三部分組成python
在Mach-O文件中,Header部分存放了文件的基本描述信息,以下:sass
Load Commands指定了文件在虛擬內存中的邏輯結構和佈局,以下安全
在Load Commands中存儲了各類段的基本信息,下面以LC_SEMENT_64(__PAGEZERO)中的信息爲例bash
__PAGEZERO是Mach-O加載進內存以後附加的一塊區域,它不可讀,不可寫,主要用來捕捉NULL指針的引用。若是訪問__PAGEZERO段,會引發程序崩潰架構
在Raw Segment Data中就存放了全部段的原始數據app
size -l -m -x Mach-O文件路徑
複製代碼
ASLR其實就是Address Space Layout Randomization,地址空間佈局隨機化。它是一種針對緩衝區溢出的安全保護技術,經過對堆、棧、共享庫映射等線性區佈局的隨機化,經過增長攻擊者預測目的地址的難度,防止攻擊者直接定位攻擊代碼位置,達到阻止溢出攻擊的目的的一種技術。在iOS 4.3開始引入ASLR技術dom
在未使用ASLR技術時,Mach-O被加載進內存後,是從地址0x000000000開始存放,前文說到,Mach-O文件自己是不存在__PAGEZERO的,在Mach-O文件被加載到虛擬內存以後,系統會給Mach-O文件分配一個__PAGEZERO,它的開始位置是0x000000000,結束位置是0x100000000。而且它的大小是固定的。ssh
Mach-O自己的內容在虛擬內存中存放的開始位置從0x100000000開始,也就是緊接着__PAGEZERO的結束地址存放。並且在下圖中,__TEXT段的File Offset爲0,File Size爲63062016,這表明着在Mach-O文件中,從0x000000000位置開始到0x003C24000爲止存放的都是__TEXT段的內容。tcp
而__TEXT段在虛擬內存中存放的開始位置是0x100000000,終止位置是0x103C24000,這說明__TEXT段是原封不動的從Mach-O文件加載進虛擬內存中,緊接着__PAGEZERO存放的。
經過分析剩下的__DATA段、__LinkEDIT段等等能夠得出如下結論
PS:在arm64架構中,__PAGEZERO段的終止位置是從0x100000000(8個0)而在非arm64架構中,__PAGEZERO段的終止位置是從0x4000(3個0)開始
在使用了ASLR技術以後,在Mach-O文件加載進內存以後,__PAGEZERO的開始位置就不是從0x000000000開始存放了,ASLR會隨機產生一個地址偏移Offset,而__PAGEZERO的開始位置須要在0x000000000的基礎上加上偏移量Offset的值,纔是真正的存放地址。 假設隨機偏移量Offset是0x000005000,那麼__PAGEZERO的開始位置就是0x000005000,結束位置就是0x100005000。剩下的__TEXT段、__DATA段和__LINKEDIT段則依次偏移Offset便可,以下:
於Mach-O文件被加載進虛擬內存中時,因爲使用了ASLR技術,致使內存地址產生Offset,因此要想獲取函數的準確的內存地址,就須要知道當前具體的偏移量。而後使用如下公式就可得出函數在虛擬內存中的內存地址
函數的內存地址(VM Address) = File Offset + ASLR Offset + __PAGEZERO Size
複製代碼
一般咱們使用Hopper、IDA等工具查看Mach-O文件所看到的地址都是未使用ASLR的VM Address,要想獲取函數的真實虛擬內存地址,就須要找到Mach-O加載進虛擬內存後的隨機偏移量Offset
上圖中函數test的起始地址是0x6558,也就是說它的File Offset爲0x6558。這個是它在Mach-O文件中的地址偏移。
運用上一章動態調試的知識,咱們來一步一步獲取ASLR的偏移量
python tcprelay.py -t 22:10088 9999:10089
複製代碼
ssh root@localhost -p 10088
複製代碼
debugserver *:9999 -a ting
複製代碼
➜ ~ lldb
(lldb) process connect connect://localhost:10089
複製代碼
(lldb) image list -o -f grep | ting
[ 0] 0x0000000000080000 /var/mobile/Containers/Bundle/Application/14C4F899-BD7B-41A4-BC1A-61892E7B943B/ting.app/ting(0x0000000100080000)
複製代碼