The reason behind this addition is that before undertaking the next big step in the road map of the Profiler there was some spare time to dedicate to some extra features for the upcoming 0.9.6 version. There have also been some customer requests for Mach-O support, so we hope that this will satisfy their request. While there are still some things left which would be useful and nice to add to the Mach-O support, they are not many.
The first screenshot as you can see features the Mach-O layout.
The logic of Mach-Os starts with their load commands which describe everything else:
Segments and sections:
Entry points (LC_MAIN, LC_UNIXTHREAD):
Then the LC_DYLD_INFO can describle some VM operations for rebasing and binding:
Also the DyldInfo export section is represented as in the file as a tree:
Of course, Mach-O support makes little sense without Fat/Universal Binary support:
While the upcoming version won’t yet support validation of Apple Code Signatures embedded in Mach-Os, it’s already possible to inspect their format and the embedded certificates.
As usual all the formats added have been exposed to Python as well. I paste some of the SDK class documentation here excluding constants, which are just too many.
class MachObject : CFFObject AddressToOffset(MaxUInt address) -> MaxUInt AddressToSection(MaxUInt address) -> CFFStruct AddressToSegment(MaxUInt address) -> CFFStruct BuildSymbolsValueHash(CFFStruct symtablc) -> NTHash< MaxUInt,UInt32 > CertificateLCs() -> NTUIntVector DyLibModules(CFFStruct dysymtablc) -> CFFStruct DySymTableLC() -> CFFStruct DyTableOfContents(CFFStruct dysymtablc) -> CFFStruct DyldDisassembleBind(NTTextStream out, MaxUInt offset, UInt32 size) DyldDisassembleBind(NTTextStream out, CFFStruct dyldinfo) DyldDisassembleLazyBind(NTTextStream out, CFFStruct dyldinfo) DyldDisassembleRebase(NTTextStream out, MaxUInt offset, UInt32 size) DyldDisassembleRebase(NTTextStream out, CFFStruct dyldinfo) DyldDisassembleWeakBind(NTTextStream out, CFFStruct dyldinfo) DyldFindExportedSymbol(CFFStruct dyldinfo, char const * symbol) -> MaxUInt DyldInfoLC() -> CFFStruct EntryPointAddress(CFFStruct lc) -> MaxUInt EntryPointLCs() -> NTUIntVector ExternalSymbolReferences(CFFStruct dysymtablc) -> CFFStruct FunctionStartsLC() -> CFFStruct FunctionStartsOffsetsAndValues(CFFStruct funcstartslc, NTVector< MaxUInt > & values) -> NTUIntVector GetLC(LoadCmdInfo info) -> CFFStruct GetLC(UInt32 index) -> CFFStruct GetLCCount() -> UInt32 GetLCDescription(CFFStruct s) -> NTString GetLCDescription(UInt32 index) -> NTString GetLCInfo(UInt32 index) -> LoadCmdInfo GetLCInfoFromOffset(MaxUInt offset) -> LoadCmdInfo static GetLCName(UInt32 cmd) -> NTString IndirectSymbolTable(CFFStruct dysymtablc) -> CFFStruct IsMachO64() -> bool MachHeader() -> CFFStruct OffsetToAddress(MaxUInt offset) -> MaxUInt OffsetToSection(MaxUInt offset) -> CFFStruct OffsetToSegment(MaxUInt offset) -> CFFStruct ProcessLoadCommands() -> bool ReadSLEB128(NTBuffer b) -> Int64 ReadSLEB128(MaxUInt offset, UInt32 & size) -> Int64 ReadULEB128(NTBuffer b) -> UInt64 ReadULEB128(MaxUInt offset, UInt32 & size) -> UInt64 SectionFromOffset(UInt32 cmd, MaxUInt offset) -> CFFStruct SegmentSections(CFFStruct seg) -> CFFStruct SymTableLC() -> CFFStruct SymbolNList(CFFStruct symtablc) -> CFFStruct class FatObject : CFFObject Architectures() -> CFFStruct class AppleCodeSignatureObject : CFFObject BlobFromOffset(UInt32 offset) -> CFFStruct BlobIndexes(CFFStruct supblob) -> CFFStruct BlobName(UInt32 magic) -> NTString BlobName(CFFStruct blob) -> NTString IsSuperBlob(UInt32 magic) -> bool IsSuperBlob(CFFStruct blob) -> bool TopBlob() -> CFFStruct
Given the SDK capabilities, it’s easy to perform custom scans on Mach-Os or to create plugins.
That’s all. Hope you enjoyed and don’t be shy if you have feature requests or suggestions. 😉