Machoview源码解析

delims 于 2021-04-30 发布

以解析一个 big sur 上的 App Store 应用为例,从macOS 11开始自带程序支持 x86_64 和 arm64e

  1. 生成 mach_header_64 信息 ,使用 MATCH_STRUCT(mach_header_64,imageOffset) 宏调用,通过 imageOffset + data起始指针快速定位到mach_header_64结构体数据所在位置,转成结构体赋给结构体mach_header_64变量。取出其中的 ncmds 和 sizeofcmds 然后 createMachONode 创建 mach64_header的Node
  2. 生成 “Load Commands” Node 并加入到根node,当前的根node就是MachOLayout的node ,node 就是左侧显示的可以展开的信息,对用户来说只显示一个node的caption,就是当前结点的名称。
  3. 遍历 ncmds 生成 所有的 load_command的作为”Load Commands” Node 的子node, 每个 load_command 只有8个字节。cmd 和 cmdsize ,通过 MATCH_STRUCT(load_command,fileOffset)快速取出对应位置的 lc 并添加 commands 数组(vector)中,然后创建当前 lc 结点 ,通过 cmd 获取到 caption ,把 lc 结点 添加到 load_commmands 的children 数组中。每次循环 fileOffset 往后移动 lc->cmdsize 大小,然后遍历下一个lc。
  4. 在遍历到 LC_SEGMENT_64 的时候,还会取出其中的 nsects 字段,即当前 LC_SEGMENT_64 包含的section数量,然后遍历其中的section,section就排列在 LC_SEGMENT_64后面,所以通过
    uint32_t sectionloc = location + sizeof(struct segment_command_64) + nsect * sizeof(struct section_64);
    

    就可以获取到第 nesct 个 section 的位置,获取 sectname 作为 caption,生成Node添加到LC_SEGMENT_64的children数组中。把 section_64 添加到sections数组中。section_64 中的fileOffset 指的是在当前架构macho内的offset,而不是整个fat文件。

  5. 每次生成Node的同时都要生成右侧显示的详细信息保存到node.details