获取iOS任意线程调用堆栈(二)符号化理论:Mach-o文件结构
我們知道Windows下的文件都是PE文件,同樣在OS X和iOS中可執(zhí)行文件是Mach-o格式的。
所以我們?nèi)绻M行逆向分析,首先要熟悉Mach-o文件結構。
Mach-o包含三個基本區(qū)域:
- 頭部(header structure)。
- 加載命令(load command)。
- 段(segment)。可以擁有多個段(segment),每個段可以擁有零個或多個區(qū)域(section)。每一個段(segment)都擁有一段虛擬地址映射到進程的地址空間。
- 鏈接信息。一個完整的用戶級Mach-o文件的末端是鏈接信息。其中包含了動態(tài)加載器用來鏈接可執(zhí)行文件或者依賴庫所需使用的符號表,字符串表等等。
你也可以在這里找到Mach-o的官方資料。
一、我們先使用otool工具來查看Mach-o的頭部,看看都包含哪些信息。
頭部的的結構如下(32位):
| 1 2 3 4 5 6 7 8 9 | struct?mach_header{ ? ??uint32_t?? ?magic; ? ? cpu_type_t? cputype; ? ? cpu_subtype_t ? cpusubtype; ? ??uint32_t? ? filetype; ? ??uint32_t? ? ncmds; ? ??uint32_t? ? sizeofcmds; ? ??uint32_t? ? flags; } |
1.magic,是mach-o文件的魔數(shù),0xfeedface代表的是32位,0xfeedfacf代表64位
2.cputype和cupsubtype代表的是cpu的類型和其子類型,例子中分別是c和9,定義如下:
#define CPU_TYPE_ARM((cpu_type_t) 12)
#define CPU_SUBTYPE_ARM_V7((cpu_subtype_t) 9
即為:armv7
3.接著是filetype,2,代表可執(zhí)行的文件
#defineMH_EXECUTE 0×2
4.ncmds 指的是加載命令(load commands)的數(shù)量,例子中一共23個,編號0-22
5.sizeofcmds 表示23個load commands的總字節(jié)大小, load commands區(qū)域是緊接著header區(qū)域的。
6.最后個flags,例子中是0×00200085,可以按文檔分析之。
當然不用工具,直接使用UE看也是一樣的。按照定義的結構來就行了。
二、頭部之后就是加載命令。加載命令的數(shù)目以及總的大小在header中已經(jīng)給出。
1.cmd 是load command的類型,本文中值=1就是LC_SEGMENT,,LC_SEGMENT的含義是(將文件中的段映射到進程地址空間)
2.cmdsize 代表load command的大小(0×58個字節(jié))。
3.segname 16字節(jié)的段名字,當前是__PAGEZERO。
4.vmaddr 段的虛擬內(nèi)存起始地址
5.vmsize 段的虛擬內(nèi)存大小
6.fileoff 段在文件中的偏移量
7.filesize 段在文件中的大小
8.maxprot 段頁面所需要的最高內(nèi)存保護(4=r,2=w,1=x)
9.initprot 段頁面初始的內(nèi)存保護
10.nsects 段中包含section的數(shù)量
11.flags 其他雜項標志位
三、接下來就是節(jié)了:
結構如下:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 | struct?section?{? ? ??char?sectname[16];? ? ??char?segname[16];? ? ??uint32_t?addr;? ? ??uint32_t?size;? ? ??uint32_t?offset;? ? ??uint32_t?align;? ? ??uint32_t?reloff;? ? ??uint32_t?nreloc;? ? ??uint32_t?flags;? ? ??uint32_t?reserved1;? ? ??uint32_t?reserved2; }; |
1.sectname 第一個是__text ,就是主程序代碼
2.segname 該section所屬的 segment名,第一個是__TEXT
3.addr 該section在內(nèi)存的啟始位置,0xa588。
4.size 該section的大小,0x84a
5.offset 該section的文件偏移,28116 ? 0x6dd4
6.align 字節(jié)大小對齊 ,4
7. reloff 重定位入口的文件偏移,0
8.nreloc 需要重定位的入口數(shù)量,0
9.flags 包含section的type和attributes
S_REGULAR—This section has no particular type. The standard tools create a __TEXT,__text section of this type.
結構中的最后2項保留用。
段的命名規(guī)則是兩個下劃線緊跟著大寫字母(如__TEXT),而section的命名則是兩個下劃線緊跟著小寫字母(__text)。
下面列出段中可能包含的section:
__TEXT段:
__text, __cstring, __picsymbol_stub, __symbol_stub, __const, __litera14, __litera18;
__DATA段
__data, __la_symbol_ptr, __nl_symbol_ptr, __dyld, __const, __mod_init_func, __mod_term_func, __bss, __commom;
__IMPORT段
__jump_table, __pointers;
其中__TEXT段中的__text是實際上的代碼部分;__DATA段的__data是實際的初始數(shù)據(jù)。
可以通過otool –s查看某segment的某個section。
可以通過otool –t直接查看代碼段(__TEXT)的反匯編代碼:
其它的大家參考官方文檔就行了。
轉(zhuǎn)載自:http://www.blogfshare.com/ioss-mach-o.html
總結
以上是生活随笔為你收集整理的获取iOS任意线程调用堆栈(二)符号化理论:Mach-o文件结构的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: HashMap源码解释
- 下一篇: iOS中的MVC设计模式