Created
July 3, 2024 13:07
-
-
Save janodev/474ec593c4aded82dc3081904284cabe to your computer and use it in GitHub Desktop.
Reads a Mach-O header
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
import MachO.dyld | |
func readMachOHeader(path: String) { | |
guard let data = try? Data(contentsOf: URL(fileURLWithPath: path)) else { | |
print("Failed to read file") | |
return | |
} | |
data.withUnsafeBytes { rawBufferPointer in | |
guard let baseAddress = rawBufferPointer.baseAddress else { | |
print("Failed to get base address") | |
return | |
} | |
let header = baseAddress.assumingMemoryBound(to: mach_header_64.self).pointee | |
if header.magic == MH_MAGIC_64 { | |
printHeader64Info(data: data) | |
} else { | |
print("Not a valid 64-bit Mach-O file.") | |
} | |
} | |
} | |
func printHeader64Info(data: Data) { | |
data.withUnsafeBytes { (rawBufferPointer: UnsafeRawBufferPointer) in | |
guard let header = rawBufferPointer.bindMemory(to: mach_header_64.self).baseAddress?.pointee else { | |
print("Failed to read header") | |
return | |
} | |
print("Mach-O Header Information:") | |
print("Magic: 0x\(String(format: "%X", header.magic))") | |
print("CPU Type: \(header.cputype)") | |
print("CPU Subtype: \(header.cpusubtype)") | |
print("File Type: \(header.filetype)") | |
print("Number of Load Commands: \(header.ncmds)") | |
print("Size of Load Commands: \(header.sizeofcmds)") | |
print("Flags: 0x\(String(format: "%X", header.flags))") | |
let headerSize = MemoryLayout<mach_header_64>.size | |
var offset = headerSize | |
for _ in 0..<header.ncmds { | |
let loadCmd = rawBufferPointer.loadUnaligned(fromByteOffset: offset, as: load_command.self) | |
print("\nLoad Command:") | |
print(" Type: \(loadCmd.cmd)") | |
print(" Size: \(loadCmd.cmdsize)") | |
if loadCmd.cmd == LC_SEGMENT_64 { | |
let segmentCmd = rawBufferPointer.loadUnaligned(fromByteOffset: offset, as: segment_command_64.self) | |
let segmentName = withUnsafeBytes(of: segmentCmd.segname) { bytes in | |
String(bytes: bytes.prefix(while: { $0 != 0 }), encoding: .ascii) ?? "" | |
} | |
print(" Segment Name: \(segmentName)") | |
print(" VM Address: 0x\(String(format: "%llX", segmentCmd.vmaddr))") | |
print(" VM Size: \(segmentCmd.vmsize)") | |
print(" File Offset: \(segmentCmd.fileoff)") | |
print(" File Size: \(segmentCmd.filesize)") | |
} | |
offset += Int(loadCmd.cmdsize) | |
} | |
} | |
} | |
let path = "/Users/jano/Desktop/Hello/UseHello" | |
readMachOHeader(path: path) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment