MachOKit

用于解析 MachO 文件以获取各种信息的库。

除了读取文件,还支持通过 _dyld_get_image_header 解析内存中的镜像。

Github issues Github forks Github stars Github top language

特性

用法

从内存加载

要从内存读取,请使用 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)
}

主要属性和方法

MachOImageMachOFile 基本上都可以使用相同的属性和方法。 可用的方法在以下文件中定义为 MachORepresentable 协议。

MachORepresentable

Dyld 缓存 (Dyld Cache)

也支持加载 dyld_shared_cache

可用的方法在以下文件中定义为 DyldCacheRepresentable 协议。

DyldCacheRepresentable

Dyld 缓存 (文件) (Dyld Cache (File))

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 缓存 (内存中) (Dyld Cache (on memory))

在 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

从文件加载

以下文件包含示例代码。 MachOFilePrintTests

Dyld 缓存(文件)(Dyld Cache (file))

以下文件包含示例代码。 DyldCachePrintTests

Dyld 缓存 (内存中) (Dyld Cache (on memory))

以下文件包含示例代码。 DyldCacheLoadedPrintTests

相关项目

其他二进制类型

许可协议

MachOKit 在 MIT 许可证下发布。 见 LICENSE