iOS逆向之Mach-O文件(下)

本文主要介紹Mach-O文件的內(nèi)部結(jié)構(gòu)的演示

Mach-O內(nèi)部結(jié)構(gòu)

因為MachO文件本身是一種文件格式,所以我們一定需要了解其文件內(nèi)部結(jié)構(gòu)。

Mach-O 的組成結(jié)構(gòu)主要分為三部分

  • Header 包含該二進制文件的一般信息

    • 字節(jié)順序、架構(gòu)類型、加載指令的數(shù)量等。
    • 使得可以快速確認一些信息,比如當(dāng)前文件用于32位還是64位,對應(yīng)的處理器是什么、文件類型是什么
  • Load commands(加載命令) 一張包含很多內(nèi)容的表

    • 內(nèi)容包括區(qū)域的位置、符號表、動態(tài)符號表等。
  • Data(數(shù)據(jù)) 通常是對象文件中最大的部分

    • 包含Segement的具體數(shù)據(jù),首先是分段,然后段中`分節(jié)

終端命令:otool

在終端中,我們通過otool 查看Mach-O的一些指令

  • 查看Mach-O的Header信息:otool -f 12-macho

MachOView軟件

  • 通過MachOView查看Mach-O文件
  • 驗證ARM_V7與ARM_V7s之間是否是分頁?
*   ARM_V7與ARM_V7s的差值:`16384+79376 - 98304 = -2544`

*   `ARM_V7`的大?。篳-2544 - 79376 = - 81920`,查看這個值是否是 pageSize(4096)的倍數(shù)

*   是否是PAGESIZE的倍數(shù):`81920 / 4096 = 20`(MacOS中),但是由于是iOS,所以 `20 / 4 = 5`頁,說明是分頁了,即按頁對齊

兩者對比

  • otool與MachOView查看的Mach-O進行對比

MachOView演示

通過MachOView查看Mach-O結(jié)構(gòu),分為三部分:Header、Load CommandsData

  • 1、查看arm64下Mach-O的Header
  • 2、查看Load Commands
*   `VM Addr` : 虛擬內(nèi)存地址

-`VM Size`: 虛擬內(nèi)存大小,在運行時刻,在內(nèi)存中的大小,4g
- 64位地址:0x12345678a2345678
- 32位地址:0x12345678

*   `File offset`: 數(shù)據(jù)在文件中偏移量
*   `File size`: 數(shù)據(jù)在文件中的大小
  • 3、 Section中分為兩大類:__TEXT(代碼)、__DATA(數(shù)據(jù))

1、Header的數(shù)據(jù)結(jié)構(gòu)

  • CMD+shift+O搜索loader.h,找到Mach_Header_64(arm64架構(gòu))的數(shù)據(jù)結(jié)構(gòu)如下所示,與mach_header相比,只是多了一個reverse
<!--1、mach_header-->
struct mach_header {
    uint32_t    magic;      /* 魔數(shù),快速定位屬于64還是32位 */
    cpu_type_t  cputype;    /* CPU類型 */
    cpu_subtype_t   cpusubtype; /* CPU的具體類型 */
    uint32_t    filetype;   /* 文件類型,比如可執(zhí)行文件 */
    uint32_t    ncmds;      /* Load Commands的條數(shù) */
    uint32_t    sizeofcmds; /* Load Commands的大小 */
    uint32_t    flags;      /* 標(biāo)志位標(biāo)識二進制文件支持的功能,主要是和系統(tǒng)加載、鏈接有關(guān) */
};

<!--2、mach_header_64-->
struct mach_header_64 {
    uint32_t    magic;      /* 魔數(shù),快速定位屬于64還是32位 */
    cpu_type_t  cputype;    /* CPU類型 */
    cpu_subtype_t   cpusubtype; /* CPU的具體類型 */
    uint32_t    filetype;   /* 文件類型,比如可執(zhí)行文件 */
    uint32_t    ncmds;      /* Load Commands的條數(shù) */
    uint32_t    sizeofcmds; /* Load Commands的大小 */
    uint32_t    flags;      /* 標(biāo)志位標(biāo)識二進制文件支持的功能,主要是和系統(tǒng)加載、鏈接有關(guān) */
    uint32_t    reserved;   /* reserved */
};

  • 2、查看filetype種類
    • OC文件:#define MH_OBJECT 0x1

    • 可執(zhí)行文件:#define MH_EXECUTE 0x2

    • ...

2、Load Commands

Load Commands中的相關(guān)字段含義如下所示

LoadCommands 說明
LC_SEGMENT_64 將文件中(32位或64位)的段映射到進程地址空間中,主要分為__TEXT、__DATA、LINKEDIT幾大塊
LC_DYLD_INFO_ONLY 動態(tài)鏈接相關(guān)信息
LC_SYMTAB 符號地址
DYSYMTAB 動態(tài)符號表地址
LC_LOAD_DYLINKER 使用誰加載,我們使用dyld
LC_UUID Mach-O文件的唯一識別標(biāo)識 UUID
LC_VERSION_MIN_MACOSX 支持最低的操作系統(tǒng)版本
LC_SOURCE_VERSION 源代碼版本
LC_MAIN 設(shè)置程序主線程的入口地址和棧大小
LC_ENCRYPTION_INFO_64 加密信息
LC_LOAD_DYLIB 依賴庫的路徑,包含三方庫
LC_FUNCTION_STARTS 函數(shù)起始地址表
LC_CODE_SIGNATURE 代碼簽名

演示

  • 1、LC_SEGMENT_64__TEXT、__DATA、LINKEDIT的對應(yīng)關(guān)系如下圖所示
  • 2、查看LC_DYLD_INFO_ONLY動態(tài)鏈接信息
其中Rebase是重定向,重定向過程簡述如下:


*   1)`代碼段`放入Mach-O文件,在編譯時期,會生成一個偏移地址

*   2)在運行時期,`mach-o文件放入虛擬內(nèi)存`,其內(nèi)存也是隨機變化的(由系統(tǒng)分配 - ASLR)

*   3)所以之前的代碼段在mach-O中偏移值就不性能使用了,需要通過`ASLR + Rebase Info Offset重定向`,主要改變的是匯編代碼
  • 3、查看LC_SYMTAB符號地址
  • 4、查看LC_LOAD_DYLINKER,使用誰鏈接,這里使用的是dyld
  • 6、查看LC_UUID,mach-o文件識別的唯一標(biāo)識
  • 7、查看LC_VERSION_MIN_MACOSX,支持的最低版本信息
  • 8、查看LC_SOURCE_VERSION,代碼版本
  • 9、查看LC_MAIN,入口函數(shù)
*   **作用**:用于逆向時找不到切入點時(例如:做了防護,運行就閃退),可以從這里找到
  • 10、查看LC_ENCRYPTION_INFO_64,此時 Crypt ID0,表示還沒有加密

3、Data

  • 1、如果我們想快速定位代碼段,需要通過LC_SEGMENT_64(__TEXT)中的VM Adress
  • 2、查看 代碼段起始位置
也可以通過`objdump`命令來查看:`objdump --macho -d 12-macho`



從這里看出,正好與Mach-O文件中的對應(yīng)
  • 3、查看stub、stub_helper:主要是用于符號綁定,這里的 0x1000065d4 全是指向的 000325D4偏移,且前面6句匯編都是在做 符號綁定
  • 4、查看外部符號表(即 調(diào)用外部函數(shù),只有在運行時才綁定),有兩個:懶加載、非懶加載
這里是先`綁定`專門`用來綁定外部的函數(shù)`,在用這個函數(shù)去綁定其他函數(shù)

總結(jié)

作為一個開發(fā)者,有一個學(xué)習(xí)的氛圍跟一個交流圈子特別重要,這是一個我的iOS開發(fā)交流群:130 595 548,不管你是小白還是大牛都歡迎入駐 ,讓我們一起進步,共同發(fā)展?。ㄈ簝?nèi)會免費提供一些群主收藏的免費學(xué)習(xí)書籍資料以及整理好的幾百道面試題和答案文檔?。?/p>

  • Mach-O內(nèi)部結(jié)構(gòu)

    • Header:用于快速確定該文件的CPU類型、文件類型

    • Load Commands:指示加載器如何設(shè)置并加載二進制數(shù)據(jù)

    • Data:存放數(shù)據(jù),例如代碼、數(shù)據(jù)、字符串常量、類、方法等,

      • Section中分為兩大類:__TEXT(代碼)、__DATA(數(shù)據(jù))
  • 可以通過otool命令查看Mach-O信息,例如查看Header信息:otool -f 12-macho

  • 可以通過objdump命令來查看代碼段:objdump --macho -d 12-macho

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • iOS 底層原理 + 逆向 文章匯總[http://www.itdecent.cn/p/412b20d9a0f6...
    Style_月月閱讀 1,446評論 0 2
  • 上一篇說到源碼經(jīng)過預(yù)處理、編譯、匯編之后生成目標(biāo)文件,這一章介紹一下iOS、Mac OS中目標(biāo)文件的格式Mach-...
    Tenloy閱讀 2,227評論 2 9
  • 什么是Mach-O文件? Mach-O文件是Mach object文件的縮寫,它在NeXTSTEP.MacOS,i...
    SharaYuki閱讀 4,418評論 3 13
  • 熟悉Linux和windows開發(fā)的同學(xué)都知道,ELF是Linux下可執(zhí)行文件的格式,PE32/PE32+是win...
    Klaus_J閱讀 4,125評論 1 10
  • 我是黑夜里大雨紛飛的人啊 1 “又到一年六月,有人笑有人哭,有人歡樂有人憂愁,有人驚喜有人失落,有的覺得收獲滿滿有...
    陌忘宇閱讀 8,898評論 28 54

友情鏈接更多精彩內(nèi)容