The main principle is that Apple will shell the APP. If the shell is added, the data will be moved from the __Text section to the section we created, and the read and write permission will be granted, so the slimming effect can be achieved.

Before iOS 7, the total of all __TEXT segments in a binary file must not exceed 80 MB

From iOS 7.x to iOS 8.x, in binaries, the __TEXT segment in each particular schema must not exceed 60 MB

After iOS 9.0, the sum of all __TEXT segments in a binary file must not exceed 500 MB

  • There are 5 segments in the Data section.

    • __PAGEZERO
    • __TEXT
    • __DATA_CONST
    • __DATA
    • __LINKEDIT
  • There are multiple sections in each Section except __PAGEZERO and __LINKEDIT.

Note: Data and __DATA are two different concepts. Data is part of the Mach-O file and contains multiple segments. __DATA is just a segment of Data.

__PAGEZERO is 4 GB in size, but not its true size in mach-O files. This is the size of __PAGEZERO after Mach-o has loaded it into memory. It is not readable or writable, and is mainly used to catch references to NULL Pointers. An EXC_BAD_ACCESS error is raised if the __PAGEZERO segment is accessed. __PAGEZERO doesn’t actually take up space in the Data section in Mach-o.

  • __TEXT, __DATA_CONST, and __DATA are used to hold program code instructions and data.

  • __LINKEDIT contains the information needed to start the App, such as the address of bind & Rebase, code signature, symbol table, etc.

Core but is added in Build Settings Other Linker Flags

-Wl,-rename_section,__TEXT,__text,__BD_TEXT,__text
-Wl,-segprot,__BD_TEXT,rx,rx
Copy the code

Where -wl tells Xcode that the parameters following it are added to the Ld linker and will take effect during the link phase

The first argument creates a new BD_TEXT segment and moves TEXT to BD_TEXT

The second line of arguments grants readable and executable permissions to __BD_TEXT.

You can see that TEXT has been moved to __BD_TEXT and its address has changed from 0x100005e5c to 0x100010000

This is because the operating system only cares about the read/write/execute permissions of the segment, not the name of the segment or section. Even if -rename_p is used to move the Segment/Section, the address of each symbol is fixed by the linker, so the program can run properly after the Segment is moved.

Note:

  1. Dyld checks the unwind_info and EH_frame sections during startup. If you move these two sections, the program will Crash after startup

  2. Swift related sections cannot be moved, otherwise a Crash will occur

  3. Specify the Section you want to read in your code

Let’s open MachO and look at the two packages and you can see

New Section64(__BD_TEXT,__text)

Open the__TextSo let’s take a look and see__text sectionIt was moved