Search code examples
shared-librariesdyldconceptualmach-o

Extend section in Mach-O file


I am trying to extract libraries from the Dyld_shared_cache, and need to fix in external references.

For example, the pointers in the __DATA.__objc_selrefs section usually point to data outside the mach-o file, to fix that I would have to copy the corresponding c-string from the dyld and append it to the __TEXT.__objc_methname section.

Though from my understanding of the Mach-O file format, this extension of the __TEXT.__objc_methname would shift all the sections after it and would force me to fix all the offsets and pointers that reference them. Is there a way to add data to a section without breaking a lot of things?

Thanks!


Solution

  • Thanks to @Kamil.S for the idea about adding a new load command and section.

    One way to achieve adding more data to a section is to create a duplicate segment and section and insert it before the __LINKEDIT segment.

    • Slide the __LINKEDIT segment so we have space to add the new section.
      1. define the slide amount, this must be page-aligned, so I choose 0x4000.
      2. add the slide amount to the relevant load commands, this includes but is not limited to:
        • __LINKEDIT segment (duh)
        • dyld_info_command
        • symtab_command
        • dysymtab_command
        • linkedit_data_commands
      3. physically move the __LINKEDIT in the file.
    • duplicate the section and change the following1
      • size, should be the length of your new data.
      • addr, should be in the free space.
      • offset, should be in the free space.
    • duplicate the segment and change the following1
      • fileoff, should be the start of the free space.
      • vmaddr, should be the start of the free space.
      • filesize, anything as long as it is bigger than your data.
      • vmsize, must be identical to filesize.
      • nsects, change to reflect how many sections your adding.
      • cmdsize, change to reflect the size of the segment command and its section commands.
    • insert the duplicated segment and sections before the __LINKEDIT segment
    • update the mach_header
      • ncmds
      • sizeofcmds
    • physically write the extra data in the file.

    1. you can optionally change the segname and sectname fields, though it isn't necessary. thanks Kamil.S!