In the development of the Mac, have you ever wondered what the Mac did to make our program run when we clicked on the executable file? For application-level developers or ordinary users, it is not necessary to know the details, but for the kernel developers, if you can understand this series of processes, it will enhance our core development skills.
So below we begin to analyze what our Mac has done after we click on the mouse.
1. History of Mac
There are better articles in this section.
2. Preparatory work
(1). You need to download XNU kernel source code and DYLD source code.
(2). Xcode,vim or any other tool that browses the source code.
3. Analysis
When analyzing the loading process, there are two parts that need to be involved in the kernel and application layer. Therefore, this article will be divided into two parts separately elaborated.
3.1 Kernel section
The Mac's kernel has evolved several times, and this is now known as XNU. Specifically why this name, we can go to search. When initially designing XNU, Apple was planning to design a microkernel that would put the most important things in the kernel and that the kernel would only be responsible for quorum rather than logical processing. This kernel is the kernel used on Mac OS 9, but this product is an efficient system. So when Steve Jobs went back and changed the kernel, we introduced the FreeBSD part of the kernel, which is the kernel xnu of Mac OSX we're using now. The simple history is finished, let's have some dry goods.
Analysis of 3.1.1 Mac-o file format
Since it is necessary to analyze the loading process of the Mac-o file, the format of the Mach-o must be addressed. For this format, we can refer to the following diagram:
From this picture, we can see that the Mach-o file can be divided into three parts in terms of structure:
(1) File header
(2) Command area
(3) Data area (including data, code, etc.)
The three sections together make up the Mach-o file format. Here we will discuss the three parts, and in the end I'll give some of the parts and some code that need attention.
3.1.1.1 Mach-o File Header
The Mach-o file header is defined as follows:
struct Mach_header (_64)
Code from: ${xnu_root}/external_header/mach-o/loader.h:
struct mach_header { uint32_t magic; cpu_type_t cputype; cpu_subtype_t cpusubtype; uint32_t filetype; uint32_t ncmds; uint32_t sizeofcmds; uint32_t flags; };struct mach_header_64 { uint32_t magic; cpu_type_t cputype; cpu_subtype_t cpusubtype; uint32_t filetype; uint32_t ncmds; uint32_t sizeofcmds; uint32_t flags; uint32_t reserved; };
The above header definition contains the 32bit and 64bit heads. The meaning of the field is as follows (as described in the head of 64bit):
Command |
meaning |
Description |
Magic |
Magic number |
It is mainly used to differentiate the CPU architectures currently supported by Mach-o (currently only 32bit and 64bit). |
Cputype |
CPU Type |
The main CPU type (32/64bit), as well as other properties. |
Cpusubtype |
CPU sub-type |
The specific type of CPU. |
FileType |
File type |
There are many file types, such as Mh_execute for executable files. |
Ncmds |
Number of commands |
This is the number of segment in the next segment. |
Sizeofcmd |
The size of the third part |
None. |
Flags |
Properties of the current Mach-o |
The more common properties include Mh_pie (the current file execution ASLR), and so on. |
More values can be referenced here.
3.1.1.2 mach-o Command Area
This section is the most important part of the Mach-o file, and we can see from the MACH-O structure above that the so-called segment is actually an index of the data region. Each segment corresponds to its own area in the data area. All we need to do is find these parts and execute them. First we look at the structure of the segment:
The structure of the segment is defined as follows:
struct Load_command
Code from: ${xnu_root}/external_header
struct load_command { uint32_t cmd; /* type of load command */ uint32_t cmdsize; /* total size of command in bytes */};
This structure corresponds to fewer members, and CMD represents the type of the current segment. Cmdsize the size of the current segment. We mainly look at the types of CMD, which is critical. What I need to explain here is that the following commands do not represent all of them, the reason why they are listed here is that these commands will be loaded in the kernel. So you might ask, what about the other orders? You and Dyld go to the deal. The list is as follows:
Command |
hexadecimal |
function |
Lc_segment Lc_segment_64 |
0x01/0x19 |
Load these segments into the corresponding process space (distinguish between 32-bit and 64-bit) |
Lc_load_dylinker |
0x0E |
Loading Dyld, it is worth noting that each Mach-o file can only have one segment |
Lc_uuid |
0x1B |
The value of the UUID is saved in the context of the execution process, and there can be only one segment per Mach-o file |
Lc_thread |
0x04 |
Opens a Mach thread, but does not allocate stacks (this is uncommon) |
Lc_unixthread |
0x05 |
The main purpose of opening a UNIX thread is to tell the loader where the current main function is. This command was replaced by Lc_main after 10.8. |
Lc_main |
0x80000028 |
After 10.8 instead of Lc_unixthread, tell the loader where the current main function is |
Lc_code_signature |
0x1D |
This is a digital signature segment. |
Lc_encryption_info |
0x21 |
Encrypted binaries, which seem to be used more frequently under iOS. |
3.1.1.3 mach-o Data region
We will focus on this part in the Dyld. Let's skip it now.
3.1.1.4 Example
Let's take a look at the binary file format of MAC for QQ:
First, we look at the QQ file header, we found that this file is a 32-bit Mach-o file. The file type is Mh_exexute, which is the executable file. There are 56 segment in this execution file, and all segment have a size of 6580. The last data room flag data, you can see this executable file, when loading must use the ASLR protection technology, in addition to a flag bit MH_NO_HEAP_ Execution, this flag bit is to prevent the data part of the current executable file has Execute permission, once has the execution permission, the hacker can carry on so-called "heap jet Attack".
Looking at the second picture, we found that the current segment LC_SEGMENTM can exist more than one, and as we said above, for Lc_uuid, Lc_main, Lc_load_dylinker and other segments, there is only one.
It is worth noting that the current executable file exists in paragraph lc_main, so that the current compilation environment of QQ is Mac OSX 10.8+, because we said in the table Lc_main was introduced in 10.8, Therefore, only 10.8 or later systems can compile this binary file.
http://blog.csdn.net/dongaxis/article/details/41114071
Mac-o file Load whole process (i)