常用命令
file
查看文件格式
➜ InHouse.app file InHouse
InHouse: Mach-O 64-bit executable arm64
lipo
查看文件有哪些架构
➜ InHouse.app lipo -info InHouse
Non-fat file: InHouse is architecture: arm64
otool
查看Mach-O头部信息
➜ InHouse.app otool -h InHouse
InHouse:
Mach header
magic cputype cpusubtype caps filetype ncmds sizeofcmds flags
0xfeedfacf 16777228 0 0x00 2 95 10720 0x00a18085
➜ InHouse.app otool -hv InHouse
InHouse:
Mach header
magic cputype cpusubtype caps filetype ncmds sizeofcmds flags
MH_MAGIC_64 ARM64 ALL 0x00 EXECUTE 95 10720 NOUNDEFS DYLDLINK TWOLEVEL WEAK_DEFINES BINDS_TO_WEAK PIE MH_HAS_TLV_DESCRIPTORS
查看Load Command区域信息
➜ InHouse.app otool -lv InHouse
查看是否加密
otool -l InHouse | grep cryptid
查看某个节的信息
otool -s __TEXT __text InHouse
otool -s __TEXT __stubs InHouse
查看代码段反汇编的前10行
otool -tv InHouse | head -n 10
Mach-O是Mach object的缩写,是Mac\iOS上用于存储程序、库的标准格式。
MachOView下载地址:sourceforge.net/projects/ma…
MachOView源码地址:github.com/gdbinit/Mac…
常见的Mach-O格式
属于Mach-O格式的文件类型有。
#define MH_OBJECT 0x1 /* relocatable object file */
#define MH_EXECUTE 0x2 /* demand paged executable file */
#define MH_FVMLIB 0x3 /* fixed VM shared library file */
#define MH_CORE 0x4 /* core file */
#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 */
#define MH_FILESET 0xc /* set of mach-o's */
- MH_OBJECT: 目标文件 .o文件
- MH_EXECUTE: 普通的可执行文件
- MH_DYLIB: .a、.dylib、.framework
- MH_DYLINKER: 动态库链接编译器 比如iPhone目录/usr/lib/dyld属于MH_DYLINKER类型的Mach-O格式文件。
- MH_DSYM: 存储着二进制文件符号信息的文件。项目编译生成的不仅有程序还有一个与之对应的.dsym文件。
针对该MachO文件我们做几个操作,利用lipo命令拆分合并架构
利用lipo-info查看MachO文件架构
lipo -info libLeaksAtExit.dylib
Architectures in the fat file: libLeaksAtExit.dylib are: x86_64 arm64e
瘦身MachO文件,拆分
lipo libLeaksAtExit.dylib -thin arm64e -output lib_arm64e
lipo -info lib_arm64e
Non-fat file: lib_arm64e is architecture: arm64e
增加架构,合并
lipo -create lib_arm64e lib_x86_64 -output lib
lipo -info lib
Architectures in the fat file: lib are: x86_64 arm64e
Mach-O文件格式
从loader.h中查看具体的定义:
Header
magic: 0xCAFEBABE表示FAT,0xFEEDFACF表示ARM64(多数文件起始固定的数据,标识文件格式)
LoadCommands
说明操作系统如何加载文件中的数据,对系统内核加载器和动态连接器起知道作用
| 段名 | 作用 |
|---|---|
| __PAGEZERO | 空指针陷阱段,映射到虚拟内存空间的第一页,用于捕获对NULL指针的引用 |
| __TEXT | 包含了执行代码和其他只读数据,可读可执行,不可修改 |
| __DATA | 程序数据,可读可写,不可执行 |
| __LINKEDIT | 链接器使用的符号以及其他表,只读 |
SEGMENT:
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 */
};
SECTION:
struct section { /* for 32-bit architectures */
char sectname[16]; /* name of this section */
char segname[16]; /* segment this section goes in */
uint32_t addr; /* memory address of this section */
uint32_t size; /* size in bytes of this section */
uint32_t offset; /* file offset of this section */
uint32_t align; /* section alignment (power of 2) */
uint32_t reloff; /* file offset of relocation entries */
uint32_t nreloc; /* number of relocation entries */
uint32_t flags; /* flags (section type and attributes)*/
uint32_t reserved1; /* reserved (for offset or index) */
uint32_t reserved2; /* reserved (for count or sizeof) */
};
struct section_64 { /* for 64-bit architectures */
char sectname[16]; /* name of this section */
char segname[16]; /* segment this section goes in */
uint64_t addr; /* memory address of this section */
uint64_t size; /* size in bytes of this section */
uint32_t offset; /* file offset of this section */
uint32_t align; /* section alignment (power of 2) */
uint32_t reloff; /* file offset of relocation entries */
uint32_t nreloc; /* number of relocation entries */
uint32_t flags; /* flags (section type and attributes)*/
uint32_t reserved1; /* reserved (for offset or index) */
uint32_t reserved2; /* reserved (for count or sizeof) */
uint32_t reserved3; /* reserved */
};