IosBX's Blog

IosbX's Blog
记录自己的每一次进步
  1. 首页
  2. iOS
  3. 正文

iOS逆向-Static Inline Hook分析篇

2025年 5月 5日 729点热度 3人点赞 0条评论

前提说明:在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的作用

  1. - Magic Number是位于Mach-O文件开头的32位标识符

  2. - 用于快速识别文件类型和架构

  3. - 决定后续的解析方式

  • FAT_CIGAM : 0xBEBAFECA - 表示这是一个FAT二进制文件(32位)

  • FAT_CIGAM_64 : 0xBFBAFECA - 表示这是一个FAT二进制文件(64位)

  • MH_MAGIC_64 : 0xFEEDFACF - 表示这是一个64位Mach-O文件

看等于FAT_CIGAM_64的结果,将二进制数据转换为fat_header结构体fat_header,获取架构信息,指针偏移到fat_header后的位置获取64位架构信息fat_arch_64。

NXSwapLong检查架构数量是否为1,验证CPU类型是否为ARM64且子类型为0。从FAT二进制文件中提取ARM64架构的Mach-O数据存储到macho返回。

NSMakeRange() 函数接收两个参数:
- 第一个参数: NXSwapLong(archdr->offset) - 目标架构代码的起始偏移量
- 第二个参数: NXSwapLong(archdr->size) - 目标架构代码的大小
NXSwapLong() 函数用于处理字节序转换
- FAT文件使用大端字节序(Big-Endian)存储
- 需要转换为当前系统的字节序(通常是小端Little-Endian)
- archdr->offset - FAT文件中特定架构代码的偏移量
- archdr->size - 特定架构代码的大小

回到StaticInlineHookPatch,定义四个变量cryptid(检查二进制文件是否加密)、header(Mach-O文件头指针)、text_seg(Hook代码段指针)、data_seg(Hook数据段指针),while(true) 循环持续处理直到找到所需段,从文件头开始遍历所有加载命令。

遍历所有 LC_SEGMENT_64 类型的加载命令,查找名为"__HOOK_TEXT"的代码段,查找名为"__HOOK_DATA"的数据段,同时检查文件的加密状态使用mutableBytes获取可修改的文件数据。

通过 LC_ENCRYPTION_INFO_64 命令获取加密信息存储在 cryptid 变量中。

如果找到所需段,则退出循环,如果没找到,调用 add_hook_section 添加新的段,添加失败则返回失败。

macho文件加密了或没找到text_seg和data_seg也返回失败。

1 2下一页
本作品采用 知识共享署名 4.0 国际许可协议 进行许可
标签: 暂无
最后更新:2025年 5月 5日

IosBX

这个人很懒,什么都没留下

点赞
< 上一篇
下一篇 >

文章评论

razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
取消回复

COPYRIGHT © 2026 IosBX's Blog. ALL RIGHTS RESERVED.