p-x9/MachOKit

GitHub: p-x9/MachOKit

一个用 Swift 编写的 Mach-O 文件解析库,支持从文件和内存中提取二进制结构信息并解析 dyld 共享缓存。

Stars: 224 | Forks: 21

# MachOKit 用于解析 MachO 文件以获取各种信息的库。 除了读取文件外,还支持通过 `_dyld_get_image_header` 解析内存中的镜像。 [![Github issues](https://img.shields.io/github/issues/p-x9/MachOKit)](https://github.com/p-x9/MachOKit/issues) [![Github forks](https://img.shields.io/github/forks/p-x9/MachOKit)](https://github.com/p-x9/MachOKit/network/members) [![Github stars](https://img.shields.io/github/stars/p-x9/MachOKit)](https://github.com/p-x9/MachOKit/stargazers) [![Github top language](https://img.shields.io/github/languages/top/p-x9/MachOKit)](https://github.com/p-x9/MachOKit/) ## 功能特性 - 解析 load commands - 符号列表 - 获取所有 cstrings - rebase 操作 - binding 操作 - 导出 trie - ... ## 用法 ### 从内存加载 要从内存中读取,请使用 `MachOImage` 结构体。 可以使用通过 `_dyld_get_image_header` 获取的 Mach-O Header 指针来进行初始化。 ``` guard let mh = _dyld_get_image_header(0) else { return } let machO = MachOImage(ptr: mh) ``` 或者,也可以使用名称进行初始化。 ``` // /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation guard let machO = MachOImage(name: "Foundation") else { return } ``` ### 从文件加载 要从文件中读取,请使用 `MachOFile` 结构体。 从文件读取的操作如下。 由于存在 Fat 文件和单一 MachO 文件的情况,因此需要进行条件分支处理。 ``` let path = "Path to MachO file" let url = URL(string: path) let file = try MachOKit.loadFromFile(url: url) switch file { case .machO(let machOFile): // single MachO file print(machOFile) case .fat(let fatFile): // Fat file let machOFiles = try fatFile.machOFiles() print(machOFiles) } ``` ### 主要属性和方法 `MachOImage` 和 `MachOFile` 都可以使用基本相同的属性和方法。 可用的方法在以下文件中定义为 `MachORepresentable` 协议。 [MachORepresentable](./Sources/MachOKit/Protocol/MachORepresentable.swift) ### Dyld 缓存 也支持加载 `dyld_shared_cache`。 可用的方法在以下文件中定义为 `DyldCacheRepresentable` 协议。 [DyldCacheRepresentable](./Sources/MachOKit/Protocol/DyldCacheRepresentable.swift) #### Dyld 缓存 (文件) ``` let path = "/System/Volumes/Preboot/Cryptexes/OS/System/Library/dyld/dyld_shared_cache_arm64e" let url = URL(fileURLWithPath: path) let cache = try! DyldCache(url: url) ``` 还可以提取包含在 `dyld_shared_cache` 中的 machO 信息。 提取出的 machO 类型为 `MachOFile`。 与从单一 MachO 文件读取一样,可以进行各种分析。 ``` let machOs = cache.machOFiles() for machO in machOs { print( String(machO.headerStartOffsetInCache, radix: 16), machO.imagePath, machO.header.ncmds ) } // 5c000 /usr/lib/libobjc.A.dylib 22 // 98000 /usr/lib/dyld 15 // 131000 /usr/lib/system/libsystem_blocks.dylib 24 // ... ``` #### 完整 Dyld 缓存 (文件) 除了 `DyldCache` 之外,还可以使用 `FullDyldCache` 将多个 dyld 缓存文件(主缓存和子缓存)作为单个统一的缓存进行处理。 ``` let path = "/System/Volumes/Preboot/Cryptexes/OS/System/Library/dyld/dyld_shared_cache_arm64e" let url = URL(fileURLWithPath: path) let fullCache = try! FullDyldCache(url: url) // Access all Mach-O files across main and subcaches let machOs = fullCache.machOFiles() for machO in machOs { print( String(machO.headerStartOffsetInCache, radix: 16), machO.imagePath, machO.header.ncmds ) } ``` `FullDyldCache` 类型提供了诸如 `mainCache`、`subCaches`、`allCaches` 和 `urls` 等属性,用于访问各个组件的缓存文件。 #### Dyld 缓存 (内存中) 在 Apple 平台上,dyld 缓存被部署在内存中。 ``` var size = 0 guard let ptr = _dyld_get_shared_cache_range(&size) else { return } let cache = try! DyldCacheLoaded(ptr: ptr) ``` 也可以提取包含在 `dyld_shared_cache` 中的 machO 信息。 提取出的 machO 类型为 `MachOImage`。 与从单一 MachO 镜像读取一样,可以进行各种分析。 ``` let machOs = cache.machOImages() for machO in machOs { print( String(Int(bitPattern: machO.ptr), radix: 16), machO.path!, machO.header.ncmds ) } // 193438000 /usr/lib/libobjc.A.dylib 24 // 193489000 /usr/lib/dyld 15 // 193513000 /usr/lib/system/libsystem_blocks.dylib 24 // ... ``` ### 示例代码 有各种不同的用法,但大多数都在 Test 目录中展示了打印输出的基本示例。 #### 从内存加载 以下文件包含示例代码。 [MachOPrintTests](./Tests/MachOKitTests/MachOPrintTests.swift) #### 从文件加载 以下文件包含示例代码。 [MachOFilePrintTests](./Tests/MachOKitTests/MachOFilePrintTests.swift) #### Dyld 缓存 (文件) 以下文件包含示例代码。 [DyldCachePrintTests](./Tests/MachOKitTests/DyldCachePrintTests.swift) #### Dyld 缓存 (内存中) 以下文件包含示例代码。 [DyldCacheLoadedPrintTests](./Tests/MachOKitTests/DyldCacheLoadedPrintTests.swift) ## 相关项目 - [MachOKitSPM](https://github.com/p-x9/MachOKit-SPM) MachOKit 的预构建版本 - [SwiftHook](https://github.com/p-x9/swift-hook) ⚓️ 一个用于 hook swift 方法和函数的 Swift 库。 - [FishHook](https://github.com/p-x9/swift-fishhook) 使用 MachOKit 以 Swift 对 [facebook/fishhook](https://github.com/facebook/fishhook) 进行重新实现 - [AntiFishHook](https://github.com/p-x9/swift-anti-fishhook) 一个用于停用 fishhook 的 Swift 库。 ### 其他二进制类型 - [ELFKit](https://github.com/p-x9/ELFKit) Elf 格式 ## 许可证 MachOKit 在 MIT 许可证下发布。详情请见 [LICENSE](./LICENSE)
标签:dyld, Fat文件, iOS开发, Load Commands, Mach-O, macOS开发, Swift, 二进制解析, 云安全监控, 云资产清单, 内存解析, 动态库, 字符串提取, 导出符号, 文件解析, 符号表, 绑定操作, 逆向工程, 重定基操作, 静态分析