{"id":13861442,"url":"https://github.com/pstirparo/machofile","last_synced_at":"2025-07-14T09:31:55.013Z","repository":{"id":199611264,"uuid":"703309445","full_name":"pstirparo/machofile","owner":"pstirparo","description":"machofile is a module to parse Mach-O binary files","archived":false,"fork":false,"pushed_at":"2024-01-30T12:13:03.000Z","size":46,"stargazers_count":47,"open_issues_count":6,"forks_count":3,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-08-05T06:03:19.195Z","etag":null,"topics":["mach-o","macos","malware-analysis","malware-research","python","python3"],"latest_commit_sha":null,"homepage":"http://threatresearch.ch","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pstirparo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-10-11T02:20:52.000Z","updated_at":"2024-08-05T06:03:22.369Z","dependencies_parsed_at":"2024-08-05T06:13:24.427Z","dependency_job_id":null,"html_url":"https://github.com/pstirparo/machofile","commit_stats":{"total_commits":16,"total_committers":2,"mean_commits":8.0,"dds":0.25,"last_synced_commit":"0a486a56001b83cb9cee47b695d8399c23501ca0"},"previous_names":["pstirparo/machofile"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pstirparo%2Fmachofile","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pstirparo%2Fmachofile/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pstirparo%2Fmachofile/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pstirparo%2Fmachofile/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pstirparo","download_url":"https://codeload.github.com/pstirparo/machofile/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225968819,"owners_count":17553143,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["mach-o","macos","malware-analysis","malware-research","python","python3"],"created_at":"2024-08-05T06:01:22.419Z","updated_at":"2024-11-22T21:30:37.848Z","avatar_url":"https://github.com/pstirparo.png","language":"Python","funding_links":[],"categories":["Python"],"sub_categories":[],"readme":"# machofile\nmachofile is a module to parse Mach-O binary files\n\nInspired by Ero Carrera's pefile, this module aims to provide a similar capability but for Mach-O binaries instead. \nReference material and documentation used to gain the file format knowledge, the basic structures and constant are taken from the resources listed below.\n\nmachofile is self-contained. The module has no dependencies; it is endianness independent; and it works on macOS, Windows, and Linux.\n\nWhile there are other mach-o parsing modules out there, the motivations behind developing this one are:\n- first and foremost, for me this was a great way to deep dive and learn more about the Mach-O format and structures\n- to provide a simple way to parse Mach-O files for analysis\n- to not depend on external modules (e.g. lief, macholib, macho, etc.), since everything is directly extracted from the file and is all in pure python.\n\nThis is the very first/alpha version still (2023.11.04), so please let me know if you try or find bugs but also be gentle ;) code will be optimized and more features will be added in the near future.\n\n**Current Features:**\n- Parse Mach-O Header\n- Parse Load Commands\n- Parse File Segments\n- Parse Dylib Commands\n- Parse Dylib List\n\n_Note: as of now, this has initially be tested against x86 and x86_64 Mach-O samples._\n\n**Next features to be implemented:**\n- extract Entry Point \n- Parse Code Signature information\n- Embedded strings\n- File Attributes\n- data entropy calculation\n- flag for suspicious libraries\n- Packer detection\n- Hashes: dylib hash, import hash, export hash, ...\n- prettify output to console\n- add output option to yaml and json\n- add options to parse only specific structures\n\n## Credits\nThose are the people that I would like to thank for being the inspiration that led me to write this module:\n- Ero Carrera ([@erocarrera](https://twitter.com/erocarrera)) for writing and maintaining the [pefile](https://github.com/erocarrera/pefile/tree/master) module\n- Patrick Wardle ([@patrickwardle](https://twitter.com/patrickwardle)) for the great work in sharing his macOS malware analysis and research, and brigning to life [OBTS](https://objectivebythesea.org/) :)\n- Greg Lesnewich ([@greglesnewich](https://twitter.com/greglesnewich)) for his work on [macho-similarity](https://github.com/g-les/macho_similarity)\n\n## Usage and example\nYou can either use it from command line or import it as a module in your python code, and call each function individually to parse only the structures you are interested in.\n\n### Module version\nIt expect to be supplied with either a file path or a data buffer to parse.\n\n```\nimport machofile\nmacho = MachO(file_path='/path/to/machobinary')\nmacho = MachO('/path/to/machobinary')\n```\nThe above two lines are equivalent and would load the Mach-O file and parse it.\nIf the data buffer is already available, it can be supplied directly with:\n\n```\nimport machofile\nmacho = MachO(data=bytes_variable)\n```\n\nYou will then need to invoke the `parse()` method to start the parsing process,\nand can then call each function individually to parse only the structures you are interested in.\n\n```\nmacho.parse()\ndylib_cmd_list, dylib_lst = macho.get_dylib_commands()\n...\n```\n\n### Command Line version\nFrom CLI, at the moment it just retrieves all the structures parsed, in the future there will be flags to just get one specific structure or a list of them.\n```\n% python3 machofile-cli.py -h\nusage: machofile-cli.py [-h] -f FILE [-a] [-i] [-hd] [-l] [-sg] [-d]\n\nParse Mach-O file structures.\n\noptions:\n  -h, --help            show this help message and exit\n  -f FILE, --file FILE  Path to the file to be parsed\n  -a, --all             Print all info about the file\n  -i, --info            Print general info about the file\n  -hd, --header         Print Mach-O header info\n  -l, --load_cmd_t      Print Load Command Table and Command list\n  -sg, --segments       Print File Segments info\n  -d, --dylib           Print Dylib Command Table and Dylib list\n```\n\nExample output:\n```\n% python3 machofile-cli.py -a -f b4f68a58658ceceb368520dafc35b270272ac27b8890d5b3ff0b968170471e2b \n\n[General File Info]\n        Filename:    b4f68a58658ceceb368520dafc35b270272ac27b8890d5b3ff0b968170471e2b\n        Filesize:    54240\n        Filetype:    Mach-O i386 executable\n        Flags:       \u003cNOUNDEFS|DYLDLINK|TWOLEVEL\u003e\n        MD5:         20ffe440e4f557b9e03855b5da2b3c9c\n        SHA1:        1bf61ecad8568a774f9fba726a254a9603d09f33\n        SHA256:      b4f68a58658ceceb368520dafc35b270272ac27b8890d5b3ff0b968170471e2b\n\n[Mac-O Header]\n        magic:       MH_MAGIC (32-bit)\n        cputype:     Intel i386\n        cpusubtype:  x86_ALL, x86_64_H, x86_64_LIB64\n        filetype:    MH_EXECUTE\n        ncmds:       13\n        sizeofcmds:  1180\n        flags:       MH_NOUNDEFS, MH_DYLDLINK, MH_TWOLEVEL\n\n[Load Cmd table]\n        {'cmd': 'LC_SEGMENT', 'cmdsize': 56}\n        {'cmd': 'LC_SEGMENT', 'cmdsize': 192}\n        {'cmd': 'LC_SEGMENT', 'cmdsize': 328}\n        {'cmd': 'LC_SEGMENT', 'cmdsize': 192}\n        {'cmd': 'LC_SEGMENT', 'cmdsize': 56}\n        {'cmd': 'LC_SYMTAB', 'cmdsize': 24}\n        {'cmd': 'LC_DYSYMTAB', 'cmdsize': 80}\n        {'cmd': 'LC_LOAD_DYLINKER', 'cmdsize': 28}\n        {'cmd': 'LC_UUID', 'cmdsize': 24}\n        {'cmd': 'LC_UNIXTHREAD', 'cmdsize': 80}\n        {'cmd': 'LC_LOAD_DYLIB', 'cmdsize': 52}\n        {'cmd': 'LC_LOAD_DYLIB', 'cmdsize': 52}\n        {'cmd': 'LC_CODE_SIGNATURE', 'cmdsize': 16}\n\n[Load Commands]\n        LC_CODE_SIGNATURE\n        LC_DYSYMTAB\n        LC_LOAD_DYLIB\n        LC_LOAD_DYLINKER\n        LC_SYMTAB\n        LC_UNIXTHREAD\n        LC_UUID\n\n[File Segments]\n        SEGNAME    VADDR VSIZE OFFSET SIZE  MAX_VM_PROTECTION INITIAL_VM_PROTECTION NSECTS FLAGS\n        ----------------------------------------------------------------------------------------\n        __PAGEZERO 0     4096  0      0     0                 0                     0      0    \n        __TEXT     4096  28672 0      28672 7                 5                     2      0    \n        __DATA     32768 4096  28672  4096  7                 3                     4      0    \n        __IMPORT   36864 4096  32768  4096  7                 7                     2      0    \n        __LINKEDIT 40960 20480 36864  17376 7                 1                     0      0    \n\n[Dylib Commands]\n        DYLIB_NAME_OFFSET DYLIB_TIMESTAMP DYLIB_CURRENT_VERSION DYLIB_COMPAT_VERSION DYLIB_NAME                   \n        ----------------------------------------------------------------------------------------------------------\n        24                2               65536                 65536                b'/usr/lib/libgcc_s.1.dylib' \n        24                2               7274759               65536                b'/usr/lib/libSystem.B.dylib'\n\n[Dylib Names]\n        b'/usr/lib/libgcc_s.1.dylib'\n        b'/usr/lib/libSystem.B.dylib'\n```\n\n## Reference/Documentation links:\n- https://opensource.apple.com/source/xnu/xnu-2050.18.24/EXTERNAL_HEADERS/mach-o/loader.h\n- https://github.com/apple-oss-distributions/lldb/blob/10de1840defe0dff10b42b9c56971dbc17c1f18c/llvm/include/llvm/Support/MachO.h\n- https://iphonedev.wiki/Mach-O_File_Format\n- https://lowlevelbits.org/parsing-mach-o-files/\n- https://github.com/aidansteele/osx-abi-macho-file-format-reference\n- https://lief-project.github.io/doc/latest/tutorials/11_macho_modification.html\n- https://github.com/VirusTotal/yara/blob/master/libyara/include/yara/macho.h\n- https://github.com/corkami/pics/blob/master/binary/README.md\n- https://github.com/qyang-nj/llios/tree/main\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpstirparo%2Fmachofile","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpstirparo%2Fmachofile","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpstirparo%2Fmachofile/lists"}