MachOKit

0.18.0

🔬 A Swift library for parsing mach-o files to obtain various information.
p-x9/MachOKit

What's New

0.18.0

2024-06-13T06:21:04Z

What's Changed

  • ObjC optimization infos in dyld_shared_cache by @p-x9 in #86
  • Expose support functions with @_spi. by @p-x9 in #87
  • Add description of additional dyld chainded ptr by @p-x9 in #88
  • Improve null terminated string reading by @p-x9 in #89

Full Changelog: 0.17.1...0.18.0

MachOKit
c4ccea892a92f064a611524a9045179a62665878c8675c0e481a608116c43d56

MachOKitC
238aec062a03e6b9a9653744fdb527b55a7a3589d6e8bf7c6f97f9c1d4eaae04

MachOKit

Library for parsing MachO files to obtain various information.

In addition to file reading, parsing of images in memory by _dyld_get_image_header is also supported.

Github issues Github forks Github stars Github top language

Features

  • parse load commands
  • symbol list
  • get all cstrings
  • rebase operations
  • binding operations
  • export tries
  • ...

Usage

Load from memory

For reading from memory, use the MachO structure.

It can be initialized by using the Mach-O Header pointer obtained by _dyld_get_image_header.

guard let mh = _dyld_get_image_header(0) else { return }
let machO = MachOImage(ptr: mh)

Alternatively, it can be initialized using the name.

// /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation
guard let machO = MachOImage(name: "Foundation") else { return }

Load from file

For reading from file, use the MachOFile structure.

Reading from a file can be as follows. There is a case of a Fat file and a single MachO file, so a conditional branching process is required.

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)
}

Main properties and methods

Both MachO and MachOFile can use essentially the same properties and methods. The available methods are defined in the following file as the MachORepresentable protocol.

MachORepresentable

Dyld Cache

loading of dyld_shared_cache is also supported.

let path = "/System/Volumes/Preboot/Cryptexes/OS/System/Library/dyld/dyld_shared_cache_x86_64h"
let url = URL(fileURLWithPath: path)

let cache = try! DyldCache(url: url)

It is also possible to extract machO information contained in dyld _shared _cache. The machO extracted is of type MachOFile. As with reading from a single MachO file, various analyses are possible.

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
// ...

Example Codes

There are a variety of uses, but most show a basic example that prints output to the Test directory.

Load from memory

The following file contains sample code. MachOPrintTests

Load from file

The following file contains sample code. MachOFilePrintTests

Dyld Cache

The following file contains sample code. DyldCachePrintTests

Related Projects

License

MachOKit is released under the MIT License. See LICENSE

Description

  • Swift Tools 5.9.0
View More Packages from this Author

Dependencies

  • None
Last updated: Sun Oct 06 2024 21:20:22 GMT-0900 (Hawaii-Aleutian Daylight Time)