当前位置:   article > 正文

【iOS】class-dump源码学习(一)_class-dump工具可以直接dump出mach-o源码头

class-dump工具可以直接dump出mach-o源码头

学习版本:class-dump-3.5.dmg


Build

上手打开工程先build一次(Xcode10)

报错缺少openssl的头文件

命令行指令 which openssl 打印 LibreSSL 2.6.5,说明苹果已经将openssl替换成了libressl

使用 brew install openssl安装openssl

安装完毕后会有这样的提示,应该是和现有有冲突,暂不做处理。

  1. openssl@1.1 is keg-only, which means it was not symlinked into /usr/local,
  2. because openssl/libressl is provided by macOS so don't link an incompatible version.
  3. If you need to have openssl@1.1 first in your PATH run:
  4. echo 'export PATH="/usr/local/opt/openssl@1.1/bin:$PATH"' >> ~/.bash_profile
  5. For compilers to find openssl@1.1 you may need to set:
  6. export LDFLAGS="-L/usr/local/opt/openssl@1.1/lib"
  7. export CPPFLAGS="-I/usr/local/opt/openssl@1.1/include"

打开/usr/local/opt/openssl@1.1/1.1.1d/include,把里面的openssl拷贝一份到/Applications/Xcode.app/Contents/DeveloperPlatforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/

/usr/local/opt/openssl@1.1/1.1.1d/lib也拷贝一份放到对应目录下

再次build,success


直接从class-dump.m的main函数入手

处理参数的代码略过

从读取文件入手

CDFile *file = [CDFile fileWithContentsOfFile:executablePath searchPathState:classDump.searchPathState];

CDFile是基本的文件单位,子类有CDFatFiIe、CDMachOFile,对应fat文件(胖二进制文件,可以看作是多个mach-o文件的聚合体)、mach-o文件。

关注CDFile静态方法

+ (id)fileWithContentsOfFile:(NSString *)filename searchPathState:(CDSearchPathState *)searchPathState;

核心逻辑是分别调用两个子类的initWithData:filename:searchPathState:方法。

先看CDFatFile中的initWithData:filename:searchPathState:方法

  1. - (id)initWithData:(NSData *)data filename:(NSString *)filename searchPathState:(CDSearchPathState *)searchPathState;
  2. {
  3. if ((self = [super initWithData:data filename:filename searchPathState:searchPathState])) {
  4. CDDataCursor *cursor = [[CDDataCursor alloc] initWithData:data];
  5. struct fat_header header;
  6. header.magic = [cursor readBigInt32];
  7. //NSLog(@"(testing fat) magic: 0x%x", header.magic);
  8. if (header.magic != FAT_MAGIC) {
  9. return nil;
  10. }
  11. _arches = [[NSMutableArray alloc] init];
  12. header.nfat_arch = [cursor readBigInt32];
  13. //NSLog(@"nfat_arch: %u", header.nfat_arch);
  14. for (NSUInteger index = 0; index < header.nfat_arch; index++) {
  15. CDFatArch *arch = [[CDFatArch alloc] initWithDataCursor:cursor];
  16. arch.fatFile = self;
  17. [_arches addObject:arch];
  18. }
  19. }
  20. return self;
  21. }

CDDataCursor很好理解,就是一个可以读取定长数据的指针。而fat_header是系统定义的fat文件头结构。

第一步读取魔数magic。加载器通过这个数值来判断当前文件是什么文件,主要区分32位和64位

  1. #define FAT_MAGIC 0xcafebabe
  2. #define FAT_MAGIC_64 0xcafebabf

不过能看到class-dump并没有处理FAT_MAGIC_64的情况(return nil;意味着会走到mach-o文件的逻辑),个人理解fat文件的魔数并不重要,不能作为加载器选择执行文件的参考。

同时这里有个点,如果使用machoview打开

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/空白诗007/article/detail/891369
推荐阅读
相关标签
  

闽ICP备14008679号