前提说明:在iOS应用开发和测试过程中,经常需要对已经编译好的二进制文件进行修改和功能扩展。传统的方案通常需要越狱设备才能实现,这极大地限制了应用场景。本文介绍的静态二进制补丁技术,通过直接修改Mach-O文件结构,实现了无需越狱的基址修补。
一、分析
最开始发现H5GG可以实现免越狱基址修补,疑问是怎么实现的,直到看到h5frida15.1.24。我已经把关键的函数以及使用实例提取到static-inline,主要看static-inline.mm,有这几个函数。
BOOL ActiveCodePatch(char* machoPath, uint64_t vaddr, char* patch);
BOOL DeactiveCodePatch(char* machoPath, uint64_t vaddr, char* patch);
NSString* StaticInlineHookPatch(char* machoPath, uint64_t vaddr, char* patch);
void* StaticInlineHookFunction(char* machoPath, uint64_t vaddr, void* replace);
BOOL StaticInlineHookInstrument(char* machoPath, uint64_t vaddr, void(*callback)(RegisterContext*));
ActiveCodePatch和DeactiveCodePatch并不是要的关键实现函数,找下一个StaticInlineHookPatch函数。
可以看到用NSBundle.mainBundle.bundlePath获取了macho文件在.app文件夹里的完整路径,存储到path变量里,用
从全局缓存字典gStaticInlineHookMachO中查找是否已经处理过该文件检查,如果该文件已经被处理过,newPath将包含处理后的文件路径,如果是首次处理,newPath将为nil。
下一段if里判断newPath是否存在,如果存在newPath(即该文件之前已被处理过)就用load_macho_data加载newPath,如果文件未被处理过,则加载原始文件,搜索看看load_macho_data函数怎么实现的,
用传入的文件路径加载二进制数据存储到macho,失败就返回nil。读取的macho的Magic Number用于识别文件类型,
Magic Number的作用
-
- Magic Number是位于Mach-O文件开头的32位标识符
-
- 用于快速识别文件类型和架构
-
- 决定后续的解析方式
-
FAT_CIGAM : 0xBEBAFECA - 表示这是一个FAT二进制文件(32位)
-
FAT_CIGAM_64 : 0xBFBAFECA - 表示这是一个FAT二进制文件(64位)
-
MH_MAGIC_64 : 0xFEEDFACF - 表示这是一个64位Mach-O文件




文章评论