iOS逆向之五-MACH-O文件解析
来源:互联网 发布:java web发布到服务器 编辑:程序博客网 时间:2024/06/03 17:28
MachO文件是苹果可执行二进制文件的格式
Load Commands
LC_SEGMENT_64
将可执行文件(64位)映射到进程地址空间
32位系统的是LC_SEGMENT
是加载的主要命令,负责指导内核来设置进程的内存空间
LC_DYLD_INFO_ONLY
动态链接相关信息
LC_SYMTAB
符号表地址
LC_DYSYMTAB
动态符号地址表
LC_LOAD_DYLINKER
加载一个动态链接器,路径“/usr/lib/dyld”
LC_UUID
二进制文件的标识ID,dSYM文件、crash中都存在这个值,确定两个文件是否匹配,分析出对应的崩溃位置
LC_VERSION_MIN_MACOSX
二进制文件要求的最低系统版本,和xcode中配置的target有关
LC_MAIN
设置程序的入口,编译型的语言需要指定入口地址,解释器语言对此没有邀请
LC_SOURCE_VERSION
构建二进制文件使用的源代码版本
LC_FUNCTION_STARTS
定义函数的起始地址表,使我们的调试器很容易看到地址
LC_DATA_IN_CODE
定义在代码段内的非指令数据
segment数据结构
#import <mach-o/loader.h> struct segment_command { /* for 32-bit architectures */uint32_tcmd;/* LC_SEGMENT */uint32_tcmdsize;/* includes sizeof section structs */charsegname[16];/* segment name */uint32_tvmaddr;/* memory address of this segment */uint32_tvmsize;/* memory size of this segment */uint32_tfileoff;/* file offset of this segment */uint32_tfilesize;/* amount to map from the file */vm_prot_tmaxprot;/* maximum VM protection */vm_prot_tinitprot;/* initial VM protection */uint32_tnsects;/* number of sections in segment */uint32_tflags;/* flags */};
struct segment_command_64 { /* for 64-bit architectures */uint32_tcmd;/* LC_SEGMENT_64 */uint32_tcmdsize;/* includes sizeof section_64 structs */charsegname[16];/* segment name */uint64_tvmaddr;/* memory address of this segment */uint64_tvmsize;/* memory size of this segment */uint64_tfileoff;/* file offset of this segment */uint64_tfilesize;/* amount to map from the file */vm_prot_tmaxprot;/* maximum VM protection */vm_prot_tinitprot;/* initial VM protection */uint32_tnsects;/* number of sections in segment */uint32_tflags;/* flags */};
** 段结构图(代码段__TEXT): **
段(segment)和节(section)
"__TEXT"代表的是segment, “__text”代表的是section
__PAGEZERO段
一个全用0填充的段,用户抓取空指针引用(非法内存访问)。通常不会占用物理内存
__TEXT段
代码段:只有可执行代码和其他只读数据
__text主程序的代码__stubs动态库链接的桩__stub_helper动态库链接的桩的辅助__cstring字符串常量(代码中写固定的字符)立即数(代码中直接写的数字,成为模数)常量字符串表的描述信息,通过该信息,可以获取常量字符符号的表地址__unwind_info用于异常处理
__DATA段
用于读取和写入数据的一个段
__nl_symbol_ptr非延时导入符号表指针_la_symbol_ptr延时导入符号表指针
__LINKEDIT
包含给动态链接库链接器(ldyd)的原始数据段,包含符号表和字符串表,压缩动态链接信息,以及动态符号表
节的数据结构
struct section { /* for 32-bit architectures */charsectname[16];/* name of this section */charsegname[16];/* segment this section goes in */uint32_taddr;/* memory address of this section */uint32_tsize;/* size in bytes of this section */uint32_toffset;/* file offset of this section */uint32_talign;/* section alignment (power of 2) */uint32_treloff;/* file offset of relocation entries */uint32_tnreloc;/* number of relocation entries */uint32_tflags;/* flags (section type and attributes)*/uint32_treserved1;/* reserved (for offset or index) */uint32_treserved2;/* reserved (for count or sizeof) */};
struct section_64 { /* for 64-bit architectures */charsectname[16];/* name of this section */charsegname[16];/* segment this section goes in */uint64_taddr;/* memory address of this section */uint64_tsize;/* size in bytes of this section */uint32_toffset;/* file offset of this section */uint32_talign;/* section alignment (power of 2) */uint32_treloff;/* file offset of relocation entries */uint32_tnreloc;/* number of relocation entries */uint32_tflags;/* flags (section type and attributes)*/uint32_treserved1;/* reserved (for offset or index) */uint32_treserved2;/* reserved (for count or sizeof) */uint32_treserved3;/* reserved */};
节结构图(代码段):
charsectname[16];/* Section名字 */charsegname[16];/* Section所在的segment的名字 */uint32_taddr;/* 内存中起始位置 */uint32_tsize;/* Section大小 */uint32_toffset;/* Section的文件偏移 */uint32_talign;/* 对其 */uint32_treloff;/* file offset of relocation entries */uint32_tnreloc;/* number of relocation entries */uint32_tflags;/* flags (section type and attributes)*/uint32_treserved1;/* reserved (for offset or index) */uint32_treserved2;/* reserved (for count or sizeof) */
__TEXT:__cstring 分析源代码:
static int PI = 3.1415;int main(int argc, const char * argv[]) { @autoreleasepool { // insert code here... NSString* hello = @"hello"; NSLog(@"%@", hello); NSLog(@"Hello, World!!"); NSLog(@"Hello Hello"); NSLog(@"Hello Hello"); NSLog(@"PI = %d", PI); int a = 100; int b = 200; int c = a + b; NSLog(@"c = %d", c); } return 0;}
对应的_cstring 节内容如下:

可以看到所有的字符串保存在一张字符串表中,对应的内容是可以被修改的,运行的时候执行的结果也会变成修改之后的内容。
动态库链接信息
LC_DYLD_INFO_ONLY
数据结构:
struct dyld_info_command { uint32_t cmd;/* LC_DYLD_INFO or LC_DYLD_INFO_ONLY */ uint32_t cmdsize;/* sizeof(struct dyld_info_command) */ uint32_t rebase_off;/* file offset to rebase info */ uint32_t rebase_size;/* size of rebase info */ uint32_t bind_off;/* file offset to binding info */ uint32_t bind_size;/* size of binding info */ uint32_t weak_bind_off;/* file offset to weak binding info */ uint32_t weak_bind_size; /* size of weak binding info */ uint32_t lazy_bind_off;/* file offset to lazy binding info */ uint32_t lazy_bind_size; /* size of lazy binding infs */ uint32_t export_off;/* file offset to lazy binding info */ uint32_t export_size;/* size of lazy binding infs */};
REBASE_INFO

** 重定向数据rebase(命令码:高四位、低四位) **11:REBASE_OPCODE_SET_TYPE_IMM 高四位0x10表示设置立即数类型 低四0x01位表示立即数类型为指针
22:REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB + 2 重定向到数据段的第2个section

Action 为翻译出来的内容,指向的是数据段的第2个节(Load Commands中的所以)具体的内容

NSLog是库中的函数,所以需要重定向,其他的几个函数也是类似的。
Binding Info

绑定数据bind:进行动态绑定的dyld的函数(dyld_stub_binder)
弱绑定数据 weak_bind
延时绑定 lazy_bind
对于需要从动态库加载的函数符号(_printf)
Export Info
可以使用nm工具查看二进制文件的导出符号【 nm - display name list (symbol table)】
➜ Debug nm MachOTest U _NSLog0000000100001100 d _PI U ___CFConstantStringClassReference0000000100000000 T __mh_execute_header0000000100000e40 T _main U _objc_autoreleasePoolPop U _objc_autoreleasePoolPush U _objc_retain U _objc_storeStrong U dyld_stub_binder

使用工具查看可以看到导出符号有两个
动态链接库的运行方式
TODO
- iOS逆向之五-MACH-O文件解析
- iOS瘦身之删除FrameWork中无用mach-O文件
- python 解析 mach-o
- IOS安全–了解Mach-o文件结构
- IOS安全–了解Mach-o文件结构
- ios之常见错误:Apple Mach-O Linker Error
- 了解mach-o文件结构
- iOS 系列译文:Mach-O 可执行文件
- iOS 系列译文:Mach-O 可执行文件
- iOS 系列译文:Mach-O 可执行文件
- iOS 系列译文:Mach-O 可执行文件
- Apple Mach-O Linker Error-iOS
- Mach-o
- Mach-O
- 获取iOS任意线程调用堆栈(二)符号化理论:Mach-o文件结构
- 减小ipa体积之删除frameWork中无用mach-O文件
- 减小ipa体积之删除frameWork中无用mach-O文件
- IOS开发中Apple Mach-O Linker Error 错误
- jquery ajax
- iOS逆向之四-FishHook的简单使用
- 前端js MD5加密,浏览器端的处理用户的敏感信息
- iOS逆向之三-authorized_keys ssh登录越狱手机免验证设置
- 将博客搬至CSDN
- iOS逆向之五-MACH-O文件解析
- mysql5.6基于schema的同步的问题总结
- IOS自动进行View标记
- 微信小程序手记
- cocos2dx clippingNode裁剪
- iOS模式分析-使用适配器模式重构TableView
- 设计模式简介
- test
- iOS使用UITableView实现的富文本编辑器