成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

為MacOS構建自定義Mach-O內存加載器

系統 其他OS
為了配合蘋果向ARM架構的遷移,這篇文章將重點介紹MacOS Ventura的AARCH64版本和針對MacOS 12.0及更高版本的XCode。

在上一篇文章中,我們介紹了如何修復dyld以恢復內存執行。這種方法的優點之一是,我們將加載Mach-O二進制文件的許多復雜工作委托給macOS。但如果我們在不使用dyld的情況下,創建我們自己的加載器呢?所有這些字節映射是如何工作的?

接下來,我們將介紹如何在不使用dyld的情況下在MacOS Ventura中為Mach-O包構建內存加載器,以及Mach-O文件的組成,dyld如何處理加載命令以將區域映射到內存中。

為了配合蘋果向ARM架構的遷移,這篇文章將重點介紹MacOS Ventura的AARCH64版本和針對MacOS 12.0及更高版本的XCode。

什么是Mach-O文件?

首先介紹一下Mach-O文件的架構,建議先閱讀一下Aidan Steele的Mach-O文件格式參考。

當我們在處理ARM版本的MacOS時,會假設正在查看的Mach-O沒有被封裝在Universal 2格式中,因此在文件開頭我們首先會遇到的是Mach_header_64:

為macOS構建自定義Mach-O內存加載器

要構造加載器,我們需要檢查以下幾個字段:

magic-此字段應包含MH_magic_64的值;

Cputype-對于M1,應為CPU_TYPE_ARM64。

filetype -我們將檢查這篇文章的MH_BUNDLE類型,但加載不同類型也應該很容易。

如果Mach-O是正常的,我們可以立即處理mach_header_64結構體后面的load命令。

加載命令

顧名思義,load命令是一種數據結構,用于指示dyld如何加載Mach-O區域。

每個load命令由load_command結構表示:

為macOS構建自定義Mach-O內存加載器

cmd字段最終決定load_command實際表示的內容,以LC_UUID的一個非常簡單的load_command為例,該命令用于將UUID與二進制數據關聯起來。其結構如下:

為macOS構建自定義Mach-O內存加載器

如上所述,這與load_command結構重疊,這就是為什么我們有匹配字段的原因。以下就是我們將看到的各種負載命令所支持的情況。

Mach-O段

加載Mach-O時,我們要處理的第一個load_command是LC_SEGMENT_64。

segment命令告訴dyld如何將Mach-O的一個區域映射到虛擬內存中,它應該有多大,應該有什么樣的保護,以及文件的內容在哪里。讓我們來看看它的結構:

為macOS構建自定義Mach-O內存加載器

出于本文的目的,我們將關注:

segname -段的名稱,例如__TEXT;

vmaddr -應該加載段的虛擬地址。例如,如果它被設置為0x4000,那么我們將在分配的內存基數+ 0x4000處加載段;

vmsize -要分配的虛擬內存的大小;

fileoff -從文件開始到應復制到虛擬內存的Mach-O內容的偏移量;

filesize -要從文件中復制的字節數;

maxprot-應分配給虛擬內存區域的最大內存保護值;

initprot -應分配給虛擬內存區域的初始內存保護;

nsects -遵循此段結構的節數。

要注意,雖然dyld依賴mmap將Mach-O的片段拉入內存,但如果我們的初始進程是作為一個加固進程執行的(并且沒有com.apple.security.cs. c . data . data之類的文件)。使用mmap是不可能的,除非我們提供的bundle是使用與代理應用程序相同的開發人員證書進行簽名的。此外,我們正在嘗試構建一個內存加載器,因此在這種情況下從磁盤拉二進制文件沒有多大意義。

為了解決這個問題,在此POC中,我們將預先分配我們的blob內存并復制它,例如:

為macOS構建自定義Mach-O內存加載器

與之前的dyld文章一樣,我們需要在主機二進制文件中使用正確的授權來允許無符號可執行內存。

從上面的字段中可以看到,段加載命令中存在另一個引用,這就是一個節(section)。

由于節位于段中,雖然它將繼承其內存保護,但它有自己的大小和要加載的文件內容。每個段的數據結構附加到segment命令中,其結構為:

為macOS構建自定義Mach-O內存加載器

同樣,我們將只關注其中幾個字段,這些字段對于我們構建加載器的直接目的很有幫助:

sectname -節的名稱,例如__text;

segname -與此節關聯的段的名稱;

addr -用于此節的虛擬地址偏移量;

size -文件中(以及虛擬內存中的)節的大小;

offset - Mach-O文件中部分內容的偏移量;

flags - flags可以分配給一個節,這個節幫助確定reserved1,reserved2和reserved3中的值。

由于我們已經分配了每個段,所以加載器將遍歷每個段描述符,確保將正確的文件內容復制到虛擬內存中。需要注意的是,在復制時可能需要更新內存保護。MacOS for ARM不允許讀/寫/執行內存頁(除非com.apple.security.cs. c。allow-jit授權與MAP_JIT一起使用),因此我們需要在復制時適應這一點:

為macOS構建自定義Mach-O內存加載器

符號

隨著我們的加載器開始成型,接下來需要看看如何處理符號(Symbol)。符號在Mach-O二進制文件的加載過程中扮演著重要的角色,它將名稱和序數關聯到內存區域,以供我們稍后參考。

符號是通過LC_SYMTAB的加載命令來處理的,如下所示:

為macOS構建自定義Mach-O內存加載器

同樣,我們將關注構建加載器所需的字段:

symoff -從文件開始到包含每個符號信息的nlist結構數組的偏移量;

nsyms -符號(或nlist結構)的數量;

stroff -符號查找所使用的字符串的文件偏移量。

顯然,接下來我們需要知道nlist是什么:

為macOS構建自定義Mach-O內存加載器

此結構為我們提供了有關命名符號的信息:

n_strx -從符號字符串字段到該符號字符串的偏移量;

n_value -包含符號的值,例如地址。

因為我們稍后需要引用符號,所以我們的加載器需要存儲這些信息以備以后使用:

為macOS構建自定義Mach-O內存加載器

dylib’s

接下來是LC_LOAD_DYLIB加載命令,該命令引用在運行時加載的額外dylib’s。

為macOS構建自定義Mach-O內存加載器

我們需要的項在dylib結構成員中找到,特別是dylib.name.offset,它是從這個加載命令的開頭到包含要加載的dylib的字符串的偏移量。

稍后,當涉及到重定位時,我們將需要這些信息,其中dylib’s的導入順序起著重要作用,因此我們將構建一個dylib’s數組,供以后使用:

為macOS構建自定義Mach-O內存加載器

遷移

現在就要介紹Mach-O更復雜的部分——遷移。

Mach-O是用XCode構建的,目標是macOS 12.0和更高版本,使用LC_DYLD_CHAINED_FIXUPS的加載命令。關于這一切是如何工作的,沒有太多的文檔,但Noah Martin對iOS 15查找鏈的研究值得參考,我們還可以在這里找到蘋果XNU repo中使用的結構體的詳細信息。

Dyld’s的源代碼告訴我們,該加載命令以結構linkedit_data_command開始:

為macOS構建自定義Mach-O內存加載器

使用dataoff便能找到標頭:

為macOS構建自定義Mach-O內存加載器

我們需要做的第一件事是收集所有導入并構造一個稍后將引用的有序數組。為此,我們將使用以下字段:

symbols_offset -從該結構開始到導入所使用的符號字符串的偏移量;

imports_count -導入項的數量;

imports_format -任何導入符號的格式。

imports_offset -從該結構開始到導入表的偏移量。

每個導入項的數據結構都依賴于imports_format字段,但通常我看到的是DYLD_CHAINED_IMPORT格式:

為macOS構建自定義Mach-O內存加載器

可以看出這是一個32位數組項,有lib_ordinal字段,它是我們之前從LC_LOAD_DYLIB加載命令構建的有序dylib數組的索引。索引從1開始,而不是0,這意味著第一個索引是1,然后是2……

為macOS構建自定義Mach-O內存加載器

如果索引值為0或253,則該項引用this-image(當前正在執行的二進制文件)。這就是我們之前構造符號字典的原因,因為現在我們可以簡單地將自己二進制文件中引用的符號名稱解析為其地址:

為macOS構建自定義Mach-O內存加載器

name_offset是從dyld_chained_fixups_header收集的symbols_offset字符串的偏移量。

使用這些信息,我們需要構建一個有序的導入數組,因為我們需要馬上引用這個有序數組。

構建了一個導入列表后,將開始鏈式啟動,這可以從dyld_chained_fixups_header結構的starts_offset標頭字段中找到。

鏈式啟動的結構是:

為macOS構建自定義Mach-O內存加載器

為了導航,我們需要遍歷seg_info_offset中的每個項,這為我們提供了指向dyld_chained_starts_in_segment的指針列表:

為macOS構建自定義Mach-O內存加載器

首先要注意這個結構,有時segment_offset是0,但不知道為什么,看起來dyld也識別了這個,只是忽略了它們。

為macOS構建自定義Mach-O內存加載器

我們需要找到每個reloc鏈的開始位置的字段如下:

pointer_format-鏈使用的DYLD_CHAINED_PTR_結構的類型;

segment_offset-段起始地址在內存中的絕對偏移量;

page_count-page_start成員數組中的頁數;

page_start-從頁面到鏈開始的偏移量。

當我們在一個段中有一個有效的偏移量時,我們可以開始遵循reloc鏈。遍歷每個項,我們需要檢查第一位,以確定該項是一個rebase(設置為0)還是一個bind(設置為1):

在rebase的情況下,將該項轉換為dyld_chained_ptr_64_rebase,并使用目標偏移量更新該項到已分配內存的基數。

為macOS構建自定義Mach-O內存加載器

在綁定的情況下,我們使用dyld_chained_ptr_64_bind,序數字段是我們前面構建的導入數組的偏移量。

為macOS構建自定義Mach-O內存加載器

然后,我們需要移動到下一個bind或rebase,這是通過執行next*4(4字節是步長)來完成的。我們重復此操作,直到下一個字段為0,表示鏈已結束。

構建加載器

現在一切就緒,開始構建加載器。步驟如下:

1.分配內存區域;

2.根據LC_SEGMENT_64命令將每個段加載到虛擬內存中;

3.將每個節加載到每個段中;

4.從LC_LOAD_DYLIB命令構建dylib的有序集合;

5.從LC_SYMTAB命令構建一個符號集合。

6.遍歷LC_DYLD_CHAINED_FIXUPS鏈并對每個reloc進行bind或rebase。

一旦完成,我們就可以使用LC_SYMTAB中的數據來引用我們想要輸入的符號并傳遞執行。如果一切順利,我們將看到Mach-O被加載到內存中并開始執行:

為macOS構建自定義Mach-O內存加載器

這個POC的所有代碼都已添加到Dyld-DeNeuralyzer項目。

雖然你可以使用其中的代碼加載C/ c++包,但如果你嘗試加載Objective-C包,你會看到如下的內容:

為macOS構建自定義Mach-O內存加載器

這是因為在加載Objective-C Mach-O時dyld中發生了一些事情,具體原因我們下一部分再講。

本文翻譯自:https://blog.xpnsec.com/building-a-mach-o-memory-loader-part-1/

責任編輯:武曉燕 來源: 嘶吼網
相關推薦

2022-08-11 16:47:32

Mach-OAPP

2022-06-24 07:08:24

OHOS自定義服務

2024-04-09 08:41:41

JVM類加載Java

2022-08-08 08:17:43

類隔離加載器自定義類

2022-09-30 13:40:23

masOS 系統執行命令行工具

2019-09-06 14:51:40

Python數據庫腳本語言

2023-10-19 09:14:34

Java開發

2015-02-12 15:33:43

微信SDK

2011-05-04 10:40:02

網頁加載進度標題欄lephone

2011-03-17 09:45:01

Spring

2022-07-12 16:56:48

自定義組件鴻蒙

2022-06-23 07:23:34

自定義組件計時器

2024-01-08 08:30:05

光標圖形編輯器開發游標

2024-11-18 09:18:21

Gin框架驗證器

2016-11-16 21:55:55

源碼分析自定義view androi

2015-02-12 15:38:26

微信SDK

2024-12-04 09:01:55

引導類加載器C++

2011-06-23 10:49:13

Qt 自定義信號

2009-07-22 15:27:39

ASP.NET MVC自定義路由

2009-11-23 20:13:33

ibmdwLotus
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产成人福利在线观看 | 久久久.com| 福利视频一二区 | 成人欧美一区二区 | 日韩精品在线网站 | 欧美日韩综合一区 | 日本精品视频一区二区三区四区 | 日本在线看片 | 亚洲精品中文字幕 | 日日干夜夜操天天操 | 亚洲丝袜天堂 | 天天综合永久 | 成人免费大片黄在线播放 | 亚洲精品久久久蜜桃 | 久久久久久久国产精品视频 | 欧美www在线观看 | 久久亚洲经典 | 老司机久久 | 这里只有精品999 | 在线观看www | 欧美日韩国产一区二区 | 久久久精品| 精品欧美乱码久久久久久1区2区 | 日本久久精 | 91色啪 | 婷婷开心激情综合五月天 | 欧美xxxx色视频在线观看免费 | 中文字幕乱码一区二区三区 | 日本激情视频中文字幕 | 日韩视频a | 国产三区四区 | 中文字幕在线播放不卡 | 99视频久 | 81精品国产乱码久久久久久 | av在线一区二区三区 | 欧洲精品一区 | 99国内精品久久久久久久 | 国产精品亚洲综合 | 国产免费一区 | 国产色片 | 精品免费视频一区二区 |