[iOS逆向]5、Mach-O

2022-01-01  本文已影响0人  史记_d5da

1、定义

Mach-O其实是Mach Object文件格式的缩写,是mac以及iOS上可执行文件的格式, 类似于windows上的PE格式 (Portable Executable ), linux上的elf格式 (Executable and Linking Format)

1.1、clang下的Mach-O

1、创建文件test.c

#include <stdio.h>
int main() {
  printf("Hello world\n");
  return;
}

clang -c test.c
file test.o

test.o: Mach-O 64-bit object arm64

clang test.o
file a.out

a.out: Mach-O 64-bit executable arm64

./a.out

Hello world

2、指定生成test2文件
clang -o test2 test.c
3、将多个文件合并成一个文件
test1.c

#include <stdio.h>
void test1();
int main() {
  printf("test\n");
  test1();
  return 0; 
}

test2.c

#include <stdio.h>
void test1() {
  printf("test1\n");
}

直接生成目标文件
clang -o demo test1.c test2.c
./demo

test
test1

生成中间文件
clang -c demo1 test1.c test2.c
4、查看demo中的mach-o信息
objdump --macho -d demo

100003f48:  ff 83 00 d1 sub sp, sp, #32
100003f4c:  fd 7b 01 a9 stp x29, x30, [sp, #16]
100003f50:  fd 43 00 91 add x29, sp, #16
100003f54:  08 00 80 52 mov w8, #0
100003f58:  e8 0b 00 b9 str w8, [sp, #8]
100003f5c:  bf c3 1f b8 stur    wzr, [x29, #-4]
100003f60:  00 00 00 90 adrp    x0, 0 ; 0x100003000
100003f64:  00 a0 3e 91 add x0, x0, #4008 ; literal pool for: "test\n"
100003f68:  0d 00 00 94 bl  0x100003f9c ; symbol stub for: _printf
100003f6c:  05 00 00 94 bl  _test1
100003f70:  e0 0b 40 b9 ldr w0, [sp, #8]
100003f74:  fd 7b 41 a9 ldp x29, x30, [sp, #16]
100003f78:  ff 83 00 91 add sp, sp, #32
100003f7c:  c0 03 5f d6 ret
_test1:
100003f80:  fd 7b bf a9 stp x29, x30, [sp, #-16]!
100003f84:  fd 03 00 91 mov x29, sp
100003f88:  00 00 00 90 adrp    x0, 0 ; 0x100003000
100003f8c:  00 b8 3e 91 add x0, x0, #4014 ; literal pool for: "test1\n"
100003f90:  03 00 00 94 bl  0x100003f9c ; symbol stub for: _printf
100003f94:  fd 7b c1 a8 ldp x29, x30, [sp], #16
100003f98:  c0 03 5f d6 ret

2、Mach-O文件格式

2.1、Mach-O文件格式定义

Mach-O为Mach object文件格式的缩写,它是一种用于可执行文件、目标代码、动态库的文件格式。作为a.out格式的替代,Mach-O提供了更强的扩展性。

2.2、MachO格式的常见文件

1、目标库
.o
2、库文件
.a.dylib.Framework
3、可以执行文件
dyld.dsym

3、lipo命令

3.1、通用二进制文件(Universial binary)

苹果公司提出的一种程序代码。能同时适用多种架构的二进制文件.
同一个程序包中同时为多种架构提供最理想的性能。

3.2、lipo

1、查看MachO文件包含的架构
lipo -info xxxx
2、用lipo –thin 拆分某种架构
lipo MachO文件 –thin 架构 –output 输出文件路径
3、使用lipo -create 合并多种架构
lipo -create MachO1 MachO2 -output 输出文件路径

4、Mach-O文件结构

mach-o
4.1、Header 包含该二进制文件的一般信息

1、字节顺序、架构类型、加载指令的数量等
2、使得可以快速确认一些信息,比如当前文件用于32位还是64位,对应的处理器是什么、文件类型是什么


mach-o header
4.2、Load commands 一张包含很多内容的表

内容包括区域的位置、符号表、动态符号表等
1、将文件中(32位或64位)的段映射到进程地址空间中

LC_SEGMENT_64

2、LC_DYLD_INFO_ONLY 动态链接相关信息


LC_DYLD_INFO_ONLY

3、LC_SYMTAB 符号表地址


LC_SYMTAB

4、LC_DYSYMTAB 动态符号表地址


LC_DYSYMTAB
5、LC_LOAD_DYLINKER 动态链接库
6、LC_SOURCE_VERSION 代码版本

7、LC_MAIN main函数入口
8、LC_ENCRYPTION_INFO_64 加密信息
9、LC_RPATH 动态库framwork的地址
10、LC_FUNCTION_STARTS 函数的起始位置表
11、LC_DATA_IN_CODE
12、LC_CODE_SIGNATURE 代码签名

4.3、Data 通常是对象文件中最大的部分

包含Segement的具体数据
1、Section64(__TEXT,__text) 主程序的入口
2、Section64(__TEXT,__stubs) 符号绑定
3、Section64(__TEXT,__objc_methname) 方法名称
4、Section64(__TEXT,__objc_classname) 类名
5、Section64(__TEXT,__objc_methtype) 方法类型(方法签名)
6、Section64(__TEXT,__cstring) 常量
7、Section64(__DATA,__got) 启动时绑定
查看fat文件信息
otool -f Demo

上一篇下一篇

猜你喜欢

热点阅读