一、Mach-O是什么?
Mach-O(mach object file format)macOS上的可执行文件、目标代码、动态库的文件格式。
二、Mach- O文件结构
Mach-O文件结构分为Header、Load commands、Data。
1.Header
描述了二进制文件的一般信息,如:CPU类型、文件类型、加载命令的数量和大小等。可以快速确认一些信息,比如当前文件用于32位还是64位,对应处理器是什么,文件类型是什么。
2.Load commands
加载命令部分描述了需要内核加载器或者动态连接器等进行的操作指令,如加载数据段、加载动态库等(具体字段可参看mach-o/load.h文件)。在内存中load commands是紧跟在header之后的。
3.Data
Data是MachO文件中最大的部分,其中_TEXT段、_DATA段能给到很多信息。Data段分为多个Section,存放了各类代码、数据等。
三、MachOView安装
1.下载MachOView源码:https://github.com/gdbinit/MachOView
2.在Xcode上运行代码,报错的话先修改一下截图中的地方
3.运行成功后,将MachOView文件在finder中打开,拖入应用程序中
4.最后在应用程序中打开MachOView,就可以使用MachOView打开文件查看文件结构了。
5.如果有崩溃,可以修改下面两处代码后再重新运行,重复3、4步骤就可以了。
第一处是DataController.m中字符串为空的情况没有判断,改为下面的代码即可
- (void)writeString:(NSString *)str toFile:(FILE *)pFile
{
if (str && str.length>0) {
fwrite(CSTRING(str), [str length] + 1, 1, pFile);
}
}
第二处是MVDocument.m中的handleThreadStateChanged:方法,有两段需要放到主线程中,改为下面的即可
- (void)handleThreadStateChanged:(NSNotification *)notification
{
if ([notification object] == dataController)
{
NSString * threadState = [[notification userInfo] objectForKey:MVStatusUserInfoKey];
if ([threadState isEqualToString:MVStatusTaskStarted] == YES)
{
if (OSAtomicIncrement32(&threadCount) == 1)
{
dispatch_async(dispatch_get_main_queue(), ^{
[progressIndicator setUsesThreadedAnimation:YES];
[progressIndicator startAnimation:nil];
[stopButton setHidden:NO];
});
}
}
else if ([threadState isEqualToString:MVStatusTaskTerminated] == YES)
{
if (OSAtomicDecrement32(&threadCount) == 0)
{
dispatch_async(dispatch_get_main_queue(), ^{
[progressIndicator stopAnimation:nil];
[statusText setStringValue:@""];
[stopButton setHidden:YES];
});
}
}
}
}