如何从内存转储的二进制文件中修复 Mach-O 标头以使其再次可用?

逆向工程 内存转储 男子气概
2021-06-29 14:36:15

我正在尝试从内存中恢复二进制文件。我重新构建了二进制文件并使用反汇编程序对其进行了分析,看起来不错,但是在使用 otool 检查头文件时,我得到了:

truncated or malformed object (addr field plus size of section 8 in LC_SEGMENT_64 command 0 greater than than the segment's vmaddr plus vmsize)

查看命令:

 struct __macho_segment_command_64 {
  LC_SEGMENT_64,                       // LC_SEGMENT_64
  0x368,                               // includes sizeof section_64 structs
  "__TEXT", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // segment name
  0x0,                                 // memory address of this segment
  0x339000,                            // memory size of this segment
  0x0,                                 // file offset of this segment
  0x339000,                            // amount to map from the file
  0x7,                                 // maximum VM protection
  0x5,                                 // initial VM protection
  0xa,                                 // number of sections in segment
  0               

然后是该命令的第 8 部分:

struct __macho_section_64 { 
  "__objc_classname",                  // name of this section
  "__TEXT", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // segment this section goes in
  0x2dee36,                            // memory address of this section
  0x6a,                                // size in bytes of this section
  0x2dee36,                            // file offset of this section
  0x0,                                 // section alignment (power of 2)
  0x0,                                 // file offset of relocation entries
  0x0,                                 // number of relocation entries
  S_CSTRING_LITERALS,                  // flags (section type and attributes
  0x0,                                 // reserved (for offset or index)
  0x0,                                 // reserved (for count or sizeof)
  0x0                                  // reserved
}

此命令的 vmsize 是0x339000. 第 8 节开始于0x2dee360x6a在大小上。所以本节结束于0x2DEEA0

鉴于此命令的 VM 大小,我在理解“LC_SEGMENT_64 命令 0 中的第 8 节的 addr 字段加大小大于段的 vmaddr 加 vmsize”时遇到问题 0x339000

我怀疑我可能遗漏了一些东西,所以我的问题是:需要进行哪些调整才能恢复二进制文件并使其再次可执行?

1个回答

otool 对加载命令和节号使用基于 0 的索引,因此可能是下一节有问题。

请注意,操作系统加载程序仅使用将映像映射到内存,因此即使段的文件偏移量关闭,也不应影响程序的可运行性。某些部分可能会被动态加载器或 Objective-C 运行时等运行时组件使用,但通常它们只使用内存地址而不使用文件偏移量。