- Mach-O文件類型
- Mach-O文件基本結(jié)構(gòu)
- 通用二進(jìn)制文件
Mach-O是Mach object的縮寫,是Mac\iOS上用于存儲(chǔ)程序、庫(kù)的標(biāo)準(zhǔn)格式
一 Mach-O文件類型
#define MH_OBJECT 0x1 /* 目標(biāo)文件*/
#define MH_EXECUTE 0x2 /* 可執(zhí)行文件 */
#define MH_FVMLIB 0x3 /* fixed VM shared library file */
#define MH_CORE 0x4 /*核心轉(zhuǎn)儲(chǔ)文件 */
#define MH_PRELOAD 0x5 /* preloaded executable file */
#define MH_DYLIB 0x6 /* dynamically bound shared library */
#define MH_DYLINKER 0x7 /* dynamic link editor */
#define MH_BUNDLE 0x8 /* dynamically bound bundle file */
#define MH_DYLIB_STUB 0x9 /* shared library stub for static */
/* linking only, no section contents */
#define MH_DSYM 0xa /* companion file with only debug */
/* sections */
#define MH_KEXT_BUNDLE 0xb /* x86_64 kexts */
可以在xnu源碼中,查看到Mach-O格式的詳細(xì)定義(https://opensource.apple.com/tarballs/xnu/)
EXTERNAL_HEADERS/mach-o/fat.h
-
EXTERNAL_HEADERS/mach-o/loader.h
Mach-O文件的格式還是挺多的,我們簡(jiǎn)單的了解一下常用的一些類型。
1 MH_OBJECT
- 目標(biāo)文件(.o)
- 靜態(tài)庫(kù)文件(.a),靜態(tài)庫(kù)其實(shí)就是N個(gè).o合并在一起
我們常用的目標(biāo)文件正勒,靜態(tài)庫(kù)都是Mach-O格式的
2 MH_EXECUTE:可執(zhí)行文件
- .app/xx
app里面的可執(zhí)行文件也是Mach-O格式的
3 MH_DYLIB:動(dòng)態(tài)庫(kù)文件
- .dylib
- .framework/xx
動(dòng)態(tài)庫(kù)文件也是Mach-O格式的
4 MH_DYLINKER:動(dòng)態(tài)鏈接編輯器
- /usr/lib/dyld
動(dòng)態(tài)鏈接器也是Mach-O格式的
5 MH_DSYM:存儲(chǔ)著二進(jìn)制文件符號(hào)信息的文件
- .dSYM/Contents/Resources/DWARF/xx(常用于分析APP的崩潰信息)
我們常用與分析app奔潰信息的符號(hào)表文件也是Mach-O格式的。
2 如何查看Mach-O格式的文件
1 使用MachOView工具
下載地址:https://github.com/gdbinit/MachOView
2 otool:查看Mach-O特定部分和段的內(nèi)容
xmldeMacBook-Pro:iOS學(xué)習(xí) xml$ otool
Usage: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/otool [-arch arch_type] [-fahlLDtdorSTMRIHGvVcXmqQjCP] [-mcpu=arg] [--version] <object file> ...
-f print the fat headers
-a print the archive header
-h print the mach header
-l print the load commands
-L print shared libraries used
-D print shared library id name
-t print the text section (disassemble with -v)
-p <routine name> start dissassemble from routine name
-s <segname> <sectname> print contents of section
-d print the data section
-o print the Objective-C segment
-r print the relocation entries
-S print the table of contents of a library (obsolete)
-T print the table of contents of a dynamic shared library (obsolete)
-M print the module table of a dynamic shared library (obsolete)
-R print the reference table of a dynamic shared library (obsolete)
-I print the indirect symbol table
-H print the two-level hints table (obsolete)
-G print the data in code table
-v print verbosely (symbolically) when possible
-V print disassembled operands symbolically
-c print argument strings of a core file
-X print no leading addresses or headers
-m don't use archive(member) syntax
-B force Thumb disassembly (ARM objects only)
-q use llvm's disassembler (the default)
-Q use otool(1)'s disassembler
-mcpu=arg use `arg' as the cpu for disassembly
-j print opcode bytes
-P print the info plist section as strings
-C print linker optimization hints
--version print the version of /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/otool
xmldeMacBook-Pro:iOS學(xué)習(xí) xml$ otool -h Calculator
Mach header
magic cputype cpusubtype caps filetype ncmds sizeofcmds flags
0xfeedfacf 16777228 0 0x00 2 36 5016 0x00200085
二 Mach-O文件基本結(jié)構(gòu)
Mach-O文件包含3個(gè)主要區(qū)域
1 Header
文件類型傻铣、目標(biāo)架構(gòu)類型等
2 Load commands
描述文件在虛擬內(nèi)存中的邏輯結(jié)構(gòu)章贞、布局
3 Raw segment data
在Load commands中定義的Segment的原始數(shù)據(jù)
具體每一項(xiàng)的含義可參看官方文檔:https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/MachOTopics/0-Introduction/introduction.html
了解Mach-O文件的細(xì)節(jié),是我們逆向工程的基礎(chǔ)非洲,無(wú)論是我們用class_dump導(dǎo)出頭文件鸭限,還是使用hopper disassembler分析代碼實(shí)現(xiàn),都是要用到Mach-O的知識(shí)两踏。其實(shí)它們都是在根據(jù)Mach-O文件的格式里覆,做了圖形化的展示。
三 通用二進(jìn)制文件
mac系統(tǒng)所支持的cpu及硬件平臺(tái)發(fā)生了很大的變化缆瓣,為了解決軟件在多個(gè)硬件平臺(tái)上的兼容性問(wèn)題喧枷,蘋果開發(fā)了一個(gè)通用的二進(jìn)制文件格式(Universal Binary),又稱胖二進(jìn)制(Fat Binary)。
系統(tǒng)還提供了一個(gè)命令行工具lipo來(lái)操作通用二進(jìn)制文件弓坞。它可以添加隧甚,提取,刪除以及替換通用二進(jìn)制文件中特定架構(gòu)的二進(jìn)制文件渡冻。
下面我們來(lái)探討一下胖二進(jìn)制的格式戚扳,其頭部結(jié)構(gòu)fat_header定義如下:
#define FAT_MAGIC 0xcafebabe
#define FAT_CIGAM 0xbebafeca
struct fat_header {
uint32_t magic;
uint32_t nfat_arch;
};
magic字段被定義為常量FAT_MAGIC,表示這是一個(gè)胖二進(jìn)制族吻,nfat_arch表示有多少個(gè)Mach-O文件帽借。
每個(gè)胖二進(jìn)制都用fat_arch結(jié)構(gòu)表示珠增,在fat_header之后,緊接著一個(gè)或多個(gè)連續(xù)的fat_arch結(jié)構(gòu)體砍艾。
struct fat_arch {
cpu_type_t cputype;
cpu_subtype_t cpusubtype;
uint32_t offset;
uint32_t size;
uint32_t align;
};
cputype指定了CPU類型蒂教,cpusubtype指定了CPU的子類型,offset指定了當(dāng)前CPU架構(gòu)數(shù)據(jù)相對(duì)于當(dāng)前文件開頭的偏移值脆荷,size字段指明了數(shù)據(jù)的大小凝垛。align字段指明了數(shù)據(jù)的內(nèi)存對(duì)齊邊界,取值必須是2的次方蜓谋,它確保了當(dāng)前CPU架構(gòu)的目標(biāo)文件在加載到內(nèi)存中時(shí)梦皮,數(shù)據(jù)是經(jīng)過(guò)內(nèi)存優(yōu)化對(duì)齊的。
2 用lipo來(lái)抽取或合并胖二進(jìn)制文件
- 查看架構(gòu)信息:lipo -info 文件路徑
- 導(dǎo)出某種特定架構(gòu):lipo 文件路徑 -thin 架構(gòu)類型 -output 輸出文件路徑
- 合并多種架構(gòu):lipo 文件路徑1 文件路徑2 -output 輸出文件路徑
這個(gè)Mach-O比較重要應(yīng)該屬于逆相中基礎(chǔ)儲(chǔ)備知識(shí)剑肯,多了解它,我們才能進(jìn)行后續(xù)的工作观堂。