iOS逆向?qū)W習(xí)筆記8(MachO文件)

1 什么是MachO文件

??Mach-O其實(shí)就是Mach Object文件格式的縮寫,是Mac以及iOS上可執(zhí)行文件的格式棚点,類似于Windows上的PE格式(Portable Exectable)、linux上的elf格式(executable and Linking Format)坪创。
??MachO是一種可執(zhí)行文件、目標(biāo)代碼以及動(dòng)態(tài)庫等類型文件的格式勒庄。作為a.out格式的替代挣轨,Mach-O提供了更強(qiáng)的擴(kuò)展性军熏。
??屬于MachO格式的常見文件:

  • 目標(biāo)文件.o
  • 庫文件[.a(靜態(tài)庫) .dylib(動(dòng)態(tài)庫) framework]
  • 可執(zhí)行文件
  • dyld
  • .dsym
    可以通過File指令來查看文件的類型
    file指令使用格式:file 文件路徑

2 查看各種MachO文件的信息

2.1查看一個(gè).c文件生成的可執(zhí)行文件的信息

??打開XCode使用快捷鍵command+N創(chuàng)建一個(gè)名為test的c文件,文件內(nèi)容如下所示:

#include <stdio.h>

int main() {
    printf("test\n");
    
    return 0;
}

打開終端將這個(gè).c文件使用clang命令編譯為.o文件



再通過file指令查看編譯之后生成的.o文件的信息



可以看到這個(gè)test.o文件是一個(gè)MachO格式卷扮,架構(gòu)是x86_64的64位的object文件荡澎,架構(gòu)是x86_64表示只有英特爾芯片的Mac電腦能讀取這個(gè)文件。
再使用clang命令將這個(gè).o文件鏈接成為可執(zhí)行文件

使用file命令查看a.out文件的信息


image.png

可以看到這個(gè)a.out文件是一個(gè)MachO格式晤锹,架構(gòu)是x86_64的64位的可執(zhí)行文件摩幔,架構(gòu)是x86_64表示只有英特爾芯片的Mac電腦能讀取這個(gè)文件。
也可以直接將.c文件通過使用clang命令直接編譯鏈接成為可執(zhí)行文件鞭铆,如下圖所示:

還可以直接將.o文件通過使用clang命令直接鏈接成為可執(zhí)行文件或衡,如下圖所示:

現(xiàn)在所生成的a.out、test以及test2文件是不是一樣的呢车遂?我們通過md5命令來查看這三個(gè)文件的hash值是否一致封断。



通過hash值對(duì)比我們可以得知這三個(gè)文件是一樣的。因?yàn)檫@三個(gè)文件的源碼文件test.c是一樣的舶担,clang編譯時(shí)的編譯方式是一樣的坡疼,所有生成的可執(zhí)行文件是一樣的。

2.2 查看兩個(gè).c文件生成的可執(zhí)行文件的信息

創(chuàng)建一個(gè)test.c文件衣陶,文件內(nèi)容為:

#include <stdio.h>

void test2();

int main() {
    printf("test\n");
    
    return 0;
}

創(chuàng)建一個(gè)test2.c文件回梧,文件內(nèi)容為:

#include <stdio.h>

void test2() {
    printf("test2\n");
}

使用clang命令將兩個(gè).c文件(test.c在前)進(jìn)行編譯以及鏈接生成一個(gè)test可執(zhí)行文件,文件信息如下:



使用clang命令將兩個(gè).c文件(test2.c在前)進(jìn)行編譯以及鏈接生成一個(gè)test可執(zhí)行文件祖搓,文件信息如下:



再來看看生成的兩個(gè)執(zhí)行文件是否一樣狱意。

我們可以看到這兩個(gè)可執(zhí)行文件的hash值是不一樣的,但使用的確是兩個(gè)相同的.c文件編譯鏈接而成的拯欧,這是為什么呢详囤?
因?yàn)榭蓤?zhí)行文件實(shí)際上是多個(gè).o文件的集合,鏈接時(shí)候的這些.o文件的順序不一樣镐作,所生成的可執(zhí)行文件的內(nèi)容就不一樣藏姐。
我們可以使用objdump命令來查看以下這兩個(gè)執(zhí)行文件的內(nèi)容:


可執(zhí)行文件test文件內(nèi)容

可執(zhí)行文件test2文件內(nèi)容

就如同你在項(xiàng)目中改變.m文件的編譯順序,所生成的可執(zhí)行文件的內(nèi)容也是不一樣的该贾,如下圖所示:

2.3 查看.a文件的信息

使用find命令在/usr目錄下查找.a文件
find命令使用格式:find 文件路徑 -name 文件名



查看.a文件的信息


2.4 查看.dylib文件的信息


image.png

2.5 查看dyld文件的信息


由上圖我們得知dyld實(shí)際上是一個(gè)動(dòng)態(tài)鏈接器(dynamic linker)羔杨,它不是一個(gè)可執(zhí)行文件,是一個(gè)通用二進(jìn)制文件杨蛋,當(dāng)啟動(dòng)系統(tǒng)的時(shí)候兜材,系統(tǒng)內(nèi)核會(huì)觸發(fā)這個(gè)文件理澎。

2.6 查看dSYM文件的信息

將項(xiàng)目工程的iOS版本改到13.1以下,并且當(dāng)前環(huán)境設(shè)置為release模式曙寡,編譯之后






可以看到這個(gè)是一個(gè)Macho-O類型的arm64架構(gòu)下64位的dSYM手冊(cè)文件糠爬。

3 通用二進(jìn)制(Universal binary)

  • 蘋果公司提出的一種程序代碼,能同時(shí)適用多種架構(gòu)的二進(jìn)制文件举庶。
  • 同一個(gè)程序包中同時(shí)為多種架構(gòu)提供最理想的性能执隧。
  • 因?yàn)樾枰鎯?chǔ)多種代碼,通用二進(jìn)制應(yīng)用程序通常比單一平臺(tái)二進(jìn)制的程序要大
  • 由于執(zhí)行中只調(diào)用一部分代碼户侥,運(yùn)行起來也不需要額外的內(nèi)存镀琉。
    iOS11以上的系統(tǒng)只支持64位以上的架構(gòu)

3.1iOS11版本以上可執(zhí)行文件的架構(gòu)

iOS11版本以上可執(zhí)行文件的架構(gòu)

3.2 iOS11版本以下可執(zhí)行文件的架構(gòu)

iOS11版本以下可執(zhí)行文件的架構(gòu)

3.2 添加armv7s架構(gòu)并查看iOS11版本以下可執(zhí)行文件的架構(gòu)

XCode中設(shè)置可執(zhí)行文件的架構(gòu)模式


XCode中設(shè)置可執(zhí)行文件的架構(gòu)

armv7s是生成iPhone5、iPhone 5c都能用的架構(gòu)


添加架構(gòu)

編譯之后查看可執(zhí)行文件支持的架構(gòu)

4 使用lipo命令對(duì)MachO文件包含的架構(gòu)進(jìn)行合并以及拆分

4.1 使用lipo命令查看MachO文件的架構(gòu)信息

命令格式:lipo -info MachO文件路徑


4.2 使用lipo命令拆分MachO文件的某種架構(gòu)

命令格式:lipo MachO文件 -thin 架構(gòu) -output 輸出文件路徑


剝離armv7架構(gòu)

剝離arm64架構(gòu)

4.3 使用lipo命令合并MachO文件的多種架構(gòu)

命令格式:lipo -create MachO1 MachO2 -output 輸出文件路徑


合并arm64以及armv7兩種架構(gòu)

5 MachO文件結(jié)構(gòu)

5.1 MachO文件基本結(jié)構(gòu)

MachO文件結(jié)構(gòu)

如上圖所示:Mach-O的組成結(jié)構(gòu)包括了

  • Header包含了該二進(jìn)制文件的一般信息(字節(jié)順序蕊唐、結(jié)構(gòu)類型滚粟、加載指令的數(shù)量等,使得可以快速確認(rèn)一些信息刃泌,比如當(dāng)前文件用于32位還是64位凡壤,對(duì)應(yīng)的處理器是什么,文件類型是什么)
  • Load commands是一張包含了很多內(nèi)容的表(內(nèi)容包括區(qū)域的位置耙替、符號(hào)表亚侠、動(dòng)態(tài)符號(hào)表等)
  • Data是對(duì)象文件中最大的部分(包含Segement的具體數(shù)據(jù))

5.1 使用otool命令查看MachO文件結(jié)構(gòu)

5.1.1 使用otool命令查看MachO文件的header信息

命令格式:otool -f MachO文件路徑



使用MachOView查看MachO文件信息



對(duì)比上下兩張圖我們可以發(fā)現(xiàn):
cpuType 是12代碼arm架構(gòu)

cpuType 是16777228代表arm64架構(gòu)
cpusubType為9對(duì)應(yīng)的是arm_v7架構(gòu)
cpusubType為11對(duì)應(yīng)的是arm_v7s架構(gòu)
cpusubType為0對(duì)應(yīng)的是arm64架構(gòu)
Offset代表的是這個(gè)類型架構(gòu)的machO文件在整個(gè)MachO中首地址的偏移量,Size代表的是這個(gè)類型架構(gòu)的machO文件大小
各個(gè)架構(gòu)的MachO文件之間的空隙是因?yàn)榉猪撛蛟斐傻乃咨龋琺ac中是2的12次方(4k)也就是4096硝烂,iOS中分頁大小是2的14次方(16k)。


mac中分頁大小

5.1.2 使用MachOView查看具體架構(gòu)類型的MachO文件的header信息

/*
 * The 64-bit mach header appears at the very beginning of object files for
 * 64-bit architectures.
 */
struct mach_header_64 {
    uint32_t    magic;      /* mach magic number identifier */
    cpu_type_t  cputype;    /* cpu specifier */
    cpu_subtype_t   cpusubtype; /* machine specifier */
    uint32_t    filetype;   /* type of file */
    uint32_t    ncmds;      /* number of load commands */
    uint32_t    sizeofcmds; /* the size of all the load commands */
    uint32_t    flags;      /* flags */
    uint32_t    reserved;   /* reserved */
};

fileType類型

#define MH_OBJECT   0x1     /* relocatable object file */
#define MH_EXECUTE  0x2     /* demand paged executable file */
#define MH_FVMLIB   0x3     /* fixed VM shared library file */
#define MH_CORE     0x4     /* core file */
#define MH_PRELOAD  0x5     /* preloaded executable file */
#define MH_DYLIB    0x6     /* dynamically bound shared library */
#define MH_DYLINKER 0x7     /* dynamic link editor */
#define MH_BUNDLE   0x8     /* dynamically bound bundle file */
#define MH_DYLIB_STUB   0x9     /* shared library stub for static
                       linking only, no section contents */
#define MH_DSYM     0xa     /* companion file with only debug
                       sections */
#define MH_KEXT_BUNDLE  0xb     /* x86_64 kexts */
#define MH_FILESET  0xc     /* a file composed of other Mach-Os to
                       be run in the same userspace sharing
                       a single linkedit. */

image.png





MachO的四大組成

image.png

注意:第二行是外部符號(hào)綁定铜幽、

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末滞谢,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子除抛,更是在濱河造成了極大的恐慌狮杨,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件到忽,死亡現(xiàn)場離奇詭異橄教,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)喘漏,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門护蝶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人翩迈,你說我怎么就攤上這事持灰。” “怎么了负饲?”我有些...
    開封第一講書人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵堤魁,是天一觀的道長喂链。 經(jīng)常有香客問我,道長姨涡,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任吧慢,我火速辦了婚禮涛漂,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘检诗。我一直安慰自己匈仗,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開白布融涣。 她就那樣靜靜地躺著桥氏,像睡著了一般音诫。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上火架,一...
    開封第一講書人閱讀 51,631評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音忙菠,去河邊找鬼何鸡。 笑死,一個(gè)胖子當(dāng)著我的面吹牛牛欢,可吹牛的內(nèi)容都是我干的骡男。 我是一名探鬼主播,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼傍睹,長吁一口氣:“原來是場噩夢啊……” “哼隔盛!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起拾稳,我...
    開封第一講書人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤吮炕,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后访得,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體来屠,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年震鹉,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了俱笛。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡传趾,死狀恐怖迎膜,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情浆兰,我是刑警寧澤磕仅,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布珊豹,位于F島的核電站,受9級(jí)特大地震影響榕订,放射性物質(zhì)發(fā)生泄漏店茶。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一劫恒、第九天 我趴在偏房一處隱蔽的房頂上張望贩幻。 院中可真熱鬧,春花似錦两嘴、人聲如沸丛楚。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽趣些。三九已至,卻和暖如春贰您,著一層夾襖步出監(jiān)牢的瞬間坏平,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來泰國打工锦亦, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留功茴,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓孽亲,卻偏偏與公主長得像坎穿,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子返劲,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容