Mach-O文件解析

简介

Mach-O是iOS/OS可执行文件。编译成功后,找到app文件->显示包内容,即可找到可执行文件。


Mach-O

常用指令

  • 查看Mach-O格式
lipo -info <可执行文件>
格式
  • 查看Mach-O架构
lipo -info <可执行文件>
架构
  • 查看Mach-O的Header
otool -h <可执行文件>
Header1
otool -hv <可执行文件>
Header2
  • 查看Mach-O的Load Commands
otool -lv <可执行文件>
image.png

Mach-O文件读取工具MachOView

工具下载地址

MachOView

Mach-O文件解析

  • Mach64Header

magic(魔数):0xfeedface-32位、0xfeedfacf-64位、0xcafebabe-通用格式
(魔数的读取:32位为小端读取,低地址在低位,高地址在高位、64位为大端读取,低地址在高位,高地址在低位)
cputype、cpusubtype:CPU的平台与版本
armv7:cputype-12、cpusubtype-9
arm64:cputype-16777228、cupsubtype-0

filetype:可执行文件(2)、库文件、Core、内核扩展
OBJECT(目标文件)-1、EXECUTE(可执行文件)-2、DYLIB(动态库)-6

ncmds、sizeofcmds:Load Commands的个数和长度
flags:dyld加载时需要的标志位,PIE表示开启地址空间随机化
Reserved:只有64位时才存在

  • Load Commands


    image.png

    LC_SEGMENT/LC_SEGMENT_64 - 将文件中(32位或64位)的段映射到进程地址空间中
    LC_SYMTAB - 符号表信息
    LC_DYSYMTAB - 动态符号表信息
    LC_LOAD_DYLINKER - 加载动态链接器(/usr/lib/dyld)
    LC_UUID - 文件的唯一标识,crash解析中也会有,去匹配dysm文件和crash文件
    LC_VERSION_MIN_IPHONEOS - 二进制文件要求最低操作系统版本
    LC_MAIN - 设置程序主线程的入口地址和栈大小
    LC_ENCRYPTION_INFO - 加密信息,查看文件加密信息(otool -l <可执行文件> | grep cryptid)
    LC_LOAD_DYLIB - 加载的动态库,包括动态库地址和名称,当前版本号,兼容版本号(otool -l <可执行文件>)
    LC_FUNCTION_STARTS - 函数起始地址表
    LC_CODE_SIGNATURE - 代码签名信息

main函数地址查看


image.png

某些Segment中包含Section,Section是具体数据存放的地方
__TEXT中节分类:
__text - 主程序代码
__stub_helper - 用于动态链接的存根
__picsymbolstub4 - 用于动态链接的存根
__objc_methname - Object-C的方法名
__objc_classname - Object-C的类名
__objc_methtype - Object-C的方法类型
__cstring - 字符串

指令查看节的信息
otool -s __TEXT __text <可执行文件>


image.png

显示最上面的10行数据
otool -tv <可执行文件名> |head -n 10


image.png

__DATA中节分类:
__la_symbol_ptr - 延迟加载节,通过dyld_stub_binder辅助链接(程序在加载时,符号的地址没有对应到真实的地址,只有在第一次使用这个符号时,才会去匹配这个符号的地址,第二次使用时就可以直接找到)
__nl_symbol_ptr - 非延迟加载节(程序在加载时,符号的地址已经确定下来,使用时可以直接找到)
__mod_init_func - 初始化的全局函数的地址,会在main函数之前执行
__mod__term_func - 结束函数地址
__cfstring - Core Foundation用到的字符串
__objc_classlist - Object-C的类列表
__objc_protollist - 协议的列表
__objc_nlclslist - Object-C的load函数列表,比__mod_init_func更早执行
__objc_const - Object-C的常量
__data - 初始化的可变的变量
__bss - 未初始化的静态变量

  • 查看可执行文件签名信息
codesign -dvvv <可执行文件名>
image.png

Mach-O解析案例

  • 主程序代码__text真实偏移的计算(以armv7为例)
    将可执行文件,拖入Mach-OView中


    image.png

    armv7起始偏移:16384->0x4000


    image.png

    Section Header偏移:24936->0x6168
    image.png

    Section(__TEXT,__text)真实偏移:0x4000+0x6168->0xA168
  • 通过Mach-O查看类名、方法名、字符串
    新建类MyObject,然后编译,将mach-o文件拖入MachOView中
#import "MyObject.h"
@implementation MyObject
- (void)my_init {
    char *cStr = "c string is there";
    NSString *ocStr = @"oc String is there";
}
@end

新建的类

image.png

新增的方法
image.png

代码中的字符串
image.png

__DATA,_cfstring中只有oc的字符串
image.png

生活如此美好,今天就点到为止。。。

你可能感兴趣的:(Mach-O文件解析)