是一种文件格式
- 就像png/jpg是存储图片的格式,avi/mov/mpeg4是存储视频的文件格式,txt存储字符 一样,就是一种按照固定格式存储数据的文件格式。
- 主要用于存储 可执行文件Exec,动态库/静态库等
格式解析
- Header : 存储该Mach-O文件的基本信息,大小和Load Comand的个数等
//usr/include/mach-o/Loader.h
struct mach_header {
uint32_t magic; /* mach magic number identifier */
cpu_type_t cputype; /* cpu specifier */
cpu_subtype_t cpusubtype; /* machine specifier */
uint32_t filetype; /* type of file */
uint32_t ncmds; /* number of load commands */
uint32_t sizeofcmds; /* the size of all the load commands */
uint32_t flags; /* flags */
};
struct mach_header_64 {
uint32_t magic; /* mach magic number identifier */
cpu_type_t cputype; /* cpu specifier */
cpu_subtype_t cpusubtype; /* machine specifier */
uint32_t filetype; /* type of file */
uint32_t ncmds; /* number of load commands */
uint32_t sizeofcmds; /* the size of all the load commands */
uint32_t flags; /* flags */
uint32_t reserved; /* reserved */
};
- Load Command : 加载命令指定了这个文件在虚拟内存中的逻辑结构和文件布局,紧随着Header,是连续存储的
- Segment command
LC_SEGMENT(__PAZEZERO) : 空指针陷阱,主要用作区分32位和64位指令数据
struct segment_command { /* for 32-bit architectures */
uint32_t cmd; /* LC_SEGMENT */
uint32_t cmdsize; /* includes sizeof section structs */
char segname[16]; /* segment name */
uint32_t vmaddr; /* memory address of this segment */
uint32_t vmsize; /* memory size of this segment */
uint32_t fileoff; /* file offset of this segment */
uint32_t filesize; /* amount to map from the file */
vm_prot_t maxprot; /* maximum VM protection */
vm_prot_t initprot; /* initial VM protection */
uint32_t nsects; /* number of sections in segment */
uint32_t flags; /* flags */
};
struct segment_command_64 { /* for 64-bit architectures */
uint32_t cmd; /* LC_SEGMENT_64 */
uint32_t cmdsize; /* includes sizeof section_64 structs */
char segname[16]; /* segment name */
uint64_t vmaddr; /* memory address of this segment */
uint64_t vmsize; /* memory size of this segment */
uint64_t fileoff; /* file offset of this segment */
uint64_t filesize; /* amount to map from the file */
vm_prot_t maxprot; /* maximum VM protection */
vm_prot_t initprot; /* initial VM protection */
uint32_t nsects; /* number of sections in segment */
uint32_t flags; /* flags */
};
LC_DYLD_INFO_ONLY //动态链接时的信息
- ASLR(Slider)随机偏移值
- Rebase + ASLR = 函数地址 //rebase是根据ASLR偏移计算函数地址
LC_SYMTAB //符号表,字符串
LC_DYSYMTAB //动态符号表
LD_LOAD_DYLINKER //dyld地址
LC_UUID //uuid
LC_VERSION_MIN_IPHONEOS //最低支持版本
LC_SOURCE_VERSION //当前程序版本
LC_MAIN //main函数地址,快速定位到main函数很重要,有的app防护了会闪退
LC_ENCRYPTION_INFO_64 //加密信息
LC_LOAD_DYLIB //动态库,主要看这里改这里
LC_RPATH //地址
LC_FUNCTION_STARTS//方法开始地方
LC_DATA_IN_CODE
LD_CODE_SIGNATURE //代码签名
- Data:包含数据段具体数据
__TEXT //代码段
__stubs //符号绑定
__stub_helper //符号绑定
__DATA //数据段
__got //外部符号绑定,非懒加载
__la_symbol_ptr //外部符号,懒加载
__LINKEDIT
- VM Address //虚拟内存地址,看这个偏移值
- VM Size //虚拟内存大小
- File offset : 数据在文件中的偏移量
- File size :数据大小
胖二进制(Fat Binary)多种cpu架构的Mach-O 打包在一起
//合并二进制文件
lipo -create <file1> <file2> -o <outFile>
//拆分二进制文件
lipo <demo> -thin i386 -output <outFile>
//查看信息
lipo -info
工具推荐
- MachOView(烂苹果)
- Hopper Disassable
相关命令
//查看文件格式
file filename
//查看二进制文件
objdump <filename>
objdump --macho --exports-trie <filename>
//生成中间文件.0
clang -c <fileName>
clang -o <inFile> <outFile>
// 查看二进制信息
otool -f <filename>
//内存页大小
pagesize
网友评论