I'm analyzing load commands section of executable Mach-O file in iOS 9.3.3, Twitter app is used for ilustration.

# otool -hV Twitter 
Mach header
      magic cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
MH_MAGIC_64 16777228          0  0x00     EXECUTE    49       4208   NOUNDEFS DYLDLINK TWOLEVEL PIE

I've read that every executable contains LC_UNIXTHREAD command which is responsible for starting the binary's main thread. However, there's no such command in examined file.

# otool -l Twitter | grep LC_
      cmd LC_SEGMENT_64
      cmd LC_SEGMENT_64
      cmd LC_SEGMENT_64
      cmd LC_SEGMENT_64
     cmd LC_SYMTAB
            cmd LC_DYSYMTAB
          cmd LC_LOAD_DYLINKER
     cmd LC_UUID
          cmd LC_LOAD_DYLIB
          cmd LC_LOAD_DYLIB
          cmd LC_LOAD_DYLIB
          [...repetition omitted...]
          cmd LC_RPATH
          cmd LC_RPATH

I cannot understand why it's not there. Does it have anything in common with the fact that this app runs with mobile user privileges or that it's proprietary app of the third party? I found this LC command e.g. for /bin/ls, but not for any of tested proprietary apps.

1 Answer 1


Since a few versions ago, LC_UNIXTHREAD has been deprecated in favor of the new command, LC_MAIN.

#define LC_MAIN (0x28|LC_REQ_DYLD) /* replacement for LC_UNIXTHREAD */
struct entry_point_command {
    uint32_t  cmd;  /* LC_MAIN only used in MH_EXECUTE filetypes */
    uint32_t  cmdsize;  /* 24 */
    uint64_t  entryoff; /* file (__TEXT) offset of main() */
    uint64_t  stacksize;/* if not zero, initial stack size */

Possibly your otool is a little old and does not support it.

  • You've been right. When I used JTool, it correctly displayed LC_MAIN. Thanks for tip.
    – karfi
    Feb 22, 2017 at 13:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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