I am trying to restore a binary from memory. I re-constructed the binary and analyzed it with a disassembler and it looks okay, but when inspecting the headers with otool I'm getting:

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)

Looking at the command:

 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

Then section 8 of that command:

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 of this command is 0x339000. Section 8 starts at 0x2dee36 and is 0x6a in size. So the section ends at 0x2DEEA0.

I have problems understanding how this is "addr field plus size of section 8 in LC_SEGMENT_64 command 0 greater than than the segment's vmaddr plus vmsize" given that the VM size of this command is 0x339000

I'm suspecting I'm probably missing something, so my question: What adjustments are needed to restore a binary and make it executable again?

  • 2
    are you counting sections 1-based or 0-based?
    – Igor Skochinsky
    Jun 25 '20 at 14:30
  • @IgorSkochinsky thanks for this, I was indeed counting 1-based. Offsetting everything by 1 gave me the command that exceeded the VM size. Towards the original question, would adjusting the command's vmsize and subsequent offsets be enough in header adjustments to make the binary usable again?
    – dvcrn
    Jun 26 '20 at 2:20

otool uses 0-based indexing for load commands and section numbers so it's probably the next section which is problematic.

Note that the OS loader only uses segments for mapping the image to the memory so even if the file offsets of the sections are off it should not affect runnability of the program. Some sections may be used by the runtime components like the dynamic loader or Objective-C runtime but normally they only use memory addresses and not file offsets.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.