APEX 檔案格式

Android Pony EXpress (APEX) 容器格式是在 Android 中導入 10 分 這類憑證會用於低階系統的安裝流程 模組。這種格式可更新不相容的系統元件 嵌入到標準 Android 應用程式模型中有些是原生元件 服務和程式庫、硬體抽象層 (HAL)、執行階段 (ART) 和類別程式庫。

「APEX」一詞也參照 APEX 檔案

背景

雖然 Android 支援符合標準應用程式的模組更新 透過套件安裝程式應用程式 (例如 Google Play 商店應用程式) 能對較低層級的 OS 元件使用類似的模型 具有下列缺點:

  • APK 型模組無法在啟動序列中使用,包裹 管理員是應用程式資訊的集中存放區, 從活動管理員開始著手,後者在之後的 啟動程序
  • APK 格式 (尤其是資訊清單) 是專為 Android 應用程式和 系統模組並非隨時都適用

設計

本節將說明 APEX 檔案格式的概要設計,以及 APEX 管理員,這是管理 APEX 檔案的服務。

如需進一步瞭解為何選擇此 APEX 設計,請參閱 開發 APEX 時考慮的替代方案

APEX 格式

此為 APEX 檔案格式。

APEX 檔案格式

圖 1. APEX 檔案格式

在頂層,APEX 檔案是儲存檔案的 ZIP 檔案 且位於 4 KB 的邊界。

APEX 檔案中的四個檔案如下:

  • apex_manifest.json
  • AndroidManifest.xml
  • apex_payload.img
  • apex_pubkey

apex_manifest.json 檔案內含套件名稱和版本, 識別 APEX 檔案。這是 ApexManifest敬上 通訊協定緩衝區。

AndroidManifest.xml 檔案可讓 APEX 檔案使用 APK 相關工具和 包括 ADB、PackageManager 和套件安裝程式應用程式 Play 商店)。舉例來說,APEX 檔案可以使用 aapt 等現有工具。 檢查檔案的基本中繼資料。這個檔案包含套件名稱和 版本資訊。通常你也可以在 apex_manifest.json

建議以 apex_manifest.json 取代 AndroidManifest.xml,以用於新程式碼和 以及支援 APEX 的系統AndroidManifest.xml可能包含額外的 現有的應用程式發布工具可用的指定目標資訊

apex_payload.img 是 dm-verity 支援的 ext4 檔案系統映像檔。圖片 是透過回送裝置在執行階段掛接。具體來說,雜湊樹狀結構 中繼資料區塊是使用 libavb 程式庫建立。檔案系統酬載 因此系統不會剖析 (因為映像檔必須可掛接在正確位置)。一般檔案為 包含在 apex_payload.img 檔案中。

apex_pubkey 是用於簽署檔案系統映像檔的公開金鑰。在執行階段 確保下載的 APEX 由同一個實體簽署 會在內建分區中簽署相同的 APEX。

APEX 命名規範

隨著平台不斷進化,為了避免新的 APEX 之間命名衝突, 請使用下列命名規則:

  • com.android.*
    • 預留給 Android 開放原始碼計畫 APEXs 使用。不是所有公司或裝置獨有的。
  • com.<companyname>.*
    • 為公司保留。可能由這些裝置供多部裝置使用 公司。
  • com.<companyname>.<devicename>.*
    • 為特定裝置 (或部分裝置) 專屬的 APEX 保留。

APEX 管理員

APEX 管理員 (或 apexd) 是獨立的原生程序, 驗證、安裝及解除安裝 APEX 檔案。系統會啟動這項程序 就在啟動序列中初期準備就緒APEX 檔案通常會預先安裝 「/system/apex」下的裝置。根據預設,APEX 管理員會使用這些 如果沒有可用更新,套件就會停止接收更新。

APEX 的更新序列會使用 PackageManager 類別 如下所示。

  1. 系統會透過套件安裝程式應用程式、ADB 或其他應用程式,下載 APEX 檔案 來源。
  2. 套件管理員會啟動安裝程序。現在, 檔案是 APEX,套件管理員會將控制權轉移到 APEX 聯絡。
  3. APEX 管理員會驗證 APEX 檔案。
  4. 如果 APEX 檔案已通過驗證,APEX 管理員的內部資料庫就會 更新 APEX 檔案,以在下次啟動時啟用 APEX 檔案。
  5. 安裝要求者在成功套件時接收廣播訊息 驗證。
  6. 如要繼續安裝,必須重新啟動系統。
  7. APEX 管理員會在下次啟動時啟動、讀取內部資料庫,然後 將下列各項 APEX 檔案載入:

    1. 驗證 APEX 檔案。
    2. 從 APEX 檔案建立回送裝置。
    3. 在回送裝置上方建立裝置對應工具區塊裝置。
    4. 將裝置對應工具區塊裝置掛接至不重複的路徑 (例如 /apex/name@ver)。

當內部資料庫列出的所有 APEX 檔案皆已掛接時,APEX 管理員提供的繫結器服務,可讓其他系統元件查詢 已安裝 APEX 檔案的相關資訊。例如其他系統 元件可以查詢裝置安裝的 APEX 檔案清單,或查詢 掛接特定 APEX 的確切路徑,以便存取檔案。

APEX 檔案是 APK 檔案

APEX 檔案為有效的 APK 檔案,因為這類檔案的簽署 ZIP 封存檔 (使用 APK 簽署配置) 內含 AndroidManifest.xml 檔案。這會允許 APEX 檔案,使用 APK 檔案 (例如套件安裝程式應用程式) 包括簽署公用程式和套件管理員

APEX 檔案中的 AndroidManifest.xml 檔案相當精簡,其中包含 nameversionCode 和選用的 targetSdkVersionminSdkVersion 套件, 和 maxSdkVersion,用於精細指定目標這項資訊允許 APEX 並透過套件安裝程式應用程式等現有管道 ADB。

支援的檔案類型

APEX 格式支援下列檔案類型:

  • 原生共用程式庫
  • 原生執行檔
  • JAR 檔案
  • 資料檔案
  • 設定檔

但這不表示 APEX 可以更新所有檔案類型。檔案是否為 更新的頻率取決於平台以及 各檔案類型的介面

簽署選項

APEX 檔案以兩種方式簽署。首先,apex_payload.img (具體來說 附加至 apex_payload.img 的 vbmeta 描述元) 檔案是以金鑰簽署。 接著,系統會使用 APK 簽署配置 v3。使用兩個不同的金鑰 。

裝置端會有一個與用於簽署的私密金鑰相對應的公開金鑰 是否已安裝 vbmeta 描述元。APEX 管理員會使用公開金鑰 驗證請求安裝的 APEX。每個 APEX 都必須與 並在建構和執行階段強制執行。

內建分區中的 APEX

APEX 檔案可位於內建分區,例如 /system。 分區已經超過 dm-verity,因此 APEX 檔案已直接掛接 經由回送裝置

如果內建分區中有 APEX,您可以透過以下方式更新 APEX: 提供具有相同套件名稱的 APEX 套件,且大於或等於 並轉換為版本代碼新的 APEX 會儲存在 /data 中,與 APK 類似, 新安裝的版本覆蓋了內建中現有的版本 但與 APK 不同的是,最新安裝的 APEX 版本 會在重新啟動後啟用。

核心需求

如要在 Android 裝置上支援 APEX 主系列模組,請使用下列 Linux 需要核心功能:回送驅動程式和 dm-verity。回送 驅動程式會將檔案系統映像檔掛接在 APEX 模組中,然後 dm-verity 會驗證 APEX 模組。

回送驅動程式和 dm-verity 的效能十分重要 確保使用 APEX 模組時的系統效能良好。

支援的核心版本

搭載核心 4.4 或以下版本的裝置支援 APEX 主系列模組 更高。搭載 Android 10 以上版本的新裝置 必須使用核心 4.9 以上版本支援 APEX 模組。

必要的核心修補程式

支援 APEX 模組所需的核心修補程式列於 Android 常用樹狀結構。如要取得支援 APEX 的修補程式,請使用最新版本 「Android 常用樹狀圖」部分

核心 4.4 版

此版本僅支援從 Android 9 升級至 Android 9 的裝置 Android 10 並且想要支援 APEX 模組。若要取得 需要修補程式,因此 android-4.4 分支版本執行向下合併作業 建議以下列出所需的個別修補程式 核心版本 4.4

  • UPSTREAM:迴圈:新增 ioctl 來變更邏輯區塊大小 (4.4)。
  • BACKPORT:區塊/迴圈:設定 hw_sectors (4.4)。
  • UPSTREAM:迴圈:在相容性 ioctl 中新增 LOOP_SET_BLOCK_SIZE (4.4)。
  • ANDROID:mnt:修正 next_descendent (4.4)。
  • ANDROID:mnt:remount 應傳播至奴隸 (4.4)。
  • ANDROID:mnt:正確傳播重新掛載 (4.4)。
  • 還原「ANDROID:dm verity:新增預先擷取大小下限」 (4.4)。
  • UPSTREAM:迴圈:如果 offset 或 block_size 變更,則會捨棄快取 (4.4)。

核心版本 4.9/4.14/4.19

如要取得核心版本 4.9/4.14/4.19 的必要修補程式,請從以下函式中向下合併: android-common 分支版本。

必要的核心設定選項

以下列出支援支援的基本設定需求 Android 10 所引進的 APEX 模組。有星號 (*) 的項目 是 Android 9 以下版本的現有需求條件。

(*) CONFIG_AIO=Y # AIO support (for direct I/O on loop devices)
CONFIG_BLK_DEV_LOOP=Y # for loop device support
CONFIG_BLK_DEV_LOOP_MIN_COUNT=16 # pre-create 16 loop devices
(*) CONFIG_CRYPTO_SHA1=Y # SHA1 hash for DM-verity
(*) CONFIG_CRYPTO_SHA256=Y # SHA256 hash for DM-verity
CONFIG_DM_VERITY=Y # DM-verity support

核心指令列參數需求

如要支援 APEX,請確認核心指令列參數符合下列各項規定 規定:

  • 不得設定「loop.max_loop
  • loop.max_part 必須小於 8

建立 APEX

本節說明如何使用 Android 建構系統建構 APEX。 以下是名為 apex.test 的 APEX 的 Android.bp 範例。

apex {
    name: "apex.test",
    manifest: "apex_manifest.json",
    file_contexts: "file_contexts",
    // libc.so and libcutils.so are included in the apex
    native_shared_libs: ["libc", "libcutils"],
    binaries: ["vold"],
    java_libs: ["core-all"],
    prebuilts: ["my_prebuilt"],
    compile_multilib: "both",
    key: "apex.test.key",
    certificate: "platform",
}

apex_manifest.json 範例:

{
  "name": "com.android.example.apex",
  "version": 1
}

file_contexts 範例:

(/.*)?           u:object_r:system_file:s0
/sub(/.*)?       u:object_r:sub_file:s0
/sub/file3       u:object_r:file3_file:s0

APEX 中的檔案類型和位置

檔案類型 APEX 的位置資訊
共享相片庫 /lib/lib64 (/lib/arm 的 x86 版的實驗組)
執行檔 /bin
Java 程式庫 /javalib
預建 /etc

遞移依附元件

APEX 檔案自動包含原生共用程式庫的遞移依附元件 或執行檔舉例來說,如果 libFoo 依附 libBar,則兩個程式庫都會是 如果 native_shared_libs 屬性中只列出 libFoo,就會納入這個值。

處理多個 ABI

為主要和次要分別安裝 native_shared_libs 屬性 應用程式二進位檔介面 (ABI)。如果 APEX 指定裝置 只有含有單一 ABI (僅限 32 位元或僅限 64 位元) 的程式庫,只有含有 並安裝對應的 ABI。

請僅針對裝置的主要 ABI 安裝 binaries 屬性,如 說明:

  • 如果裝置只有 32 位元,則只有二進位檔的 32 位元變化版本為 已安裝。
  • 如果裝置只有 64 位元,那麼只有二進位檔的 64 位元變化版本為 已安裝。

如要微調原生資料庫和二進位檔的 ABI, 請使用 multilib.[first|lib32|lib64|prefer32|both].[native_shared_libs|binaries] 資源。

  • first:比對裝置的主要 ABI。這是 二進位檔。
  • lib32:比對裝置的 32 位元 ABI (如果支援的話)。
  • lib64:與裝置的 64 位元 ABI 相符 (支援)。
  • prefer32:比對裝置的 32 位元 ABI (如果支援的話)。如果 系統不支援 32 位元 ABI,且與 64 位元 ABI 相符。
  • both:比對兩個 ABI。這是 native_shared_libraries

javalibrariesprebuilts 屬性適用於跨 ABI。

以下範例適用於支援 32/64 但並非 32 版本的裝置:

apex {
    // other properties are omitted
    native_shared_libs: ["libFoo"], // installed for 32 and 64
    binaries: ["exec1"], // installed for 64, but not for 32
    multilib: {
        first: {
            native_shared_libs: ["libBar"], // installed for 64, but not for 32
            binaries: ["exec2"], // same as binaries without multilib.first
        },
        both: {
            native_shared_libs: ["libBaz"], // same as native_shared_libs without multilib
            binaries: ["exec3"], // installed for 32 and 64
        },
        prefer32: {
            native_shared_libs: ["libX"], // installed for 32, but not for 64
        },
        lib64: {
            native_shared_libs: ["libY"], // installed for 64, but not for 32
        },
    },
}

vbmeta 簽署

請使用不同金鑰簽署各個 APEX。需要新的金鑰時,請建立一個 公開/私密金鑰組,並建立 apex_key 模組。使用 key 屬性: 簽署 APEX。公開金鑰會自動包含在 名為 avb_pubkey 的 APEX。

# create an rsa key pair
openssl genrsa -out foo.pem 4096

# extract the public key from the key pair
avbtool extract_public_key --key foo.pem --output foo.avbpubkey

# in Android.bp
apex_key {
    name: "apex.test.key",
    public_key: "foo.avbpubkey",
    private_key: "foo.pem",
}

在上述範例中,公開金鑰的名稱 (foo) 會成為 鍵。用於簽署 APEX 的金鑰 ID 會寫入 APEX。在執行階段 apexd 會使用裝置上 ID 相同的公開金鑰驗證 APEX。

APEX 簽署

簽署 APEX 的方式與簽署 APK 的方式相同。兩次簽署 APEX。同樣是 迷你檔案系統 (apex_payload.img 檔案),一次收錄整個檔案。

如要在檔案層級簽署 APEX,請在其中一個檔案層級設定 certificate 屬性: 這三種方式

  • 未設定:如未設定任何值,APEX 會使用找到的憑證簽署 通知時間:PRODUCT_DEFAULT_DEV_CERTIFICATE。如未設定任何旗標,路徑預設值就會 至 build/target/product/security/testkey
  • <name>:APEX 使用了相同的 <name> 憑證簽署 PRODUCT_DEFAULT_DEV_CERTIFICATE 格式的檔案。
  • :<name>:此 APEX 使用由 名為 <name> 的 Soong 模組。憑證模組可定義為 後面。
,瞭解如何調查及移除這項存取權。
android_app_certificate {
    name: "my_key_name",
    certificate: "dir/cert",
    // this will use dir/cert.x509.pem (the cert) and dir/cert.pk8 (the private key)
}

安裝 APEX

如要安裝 APEX,請使用 ADB。

adb install apex_file_name
adb reboot

如果 apex_manifest.json 中的 supportsRebootlessUpdate 設為 true,且 目前安裝的 APEX 未使用過 (例如其中所含任何服務 ),那麼安裝新的 APEX 時,無需重新啟動, --force-non-staged 標記。

adb install --force-non-staged apex_file_name

使用 APEX

重新啟動後,APEX 會掛接在 /apex/<apex_name>@<version> 目錄。同一個 APEX 可以同時掛接多個版本。 在掛接路徑中,對應最新版本的路徑為 掛接位置:/apex/<apex_name>

用戶端可以使用繫結掛接的路徑,從 APEX 讀取或執行檔案。

APEX 通常用於以下用途:

  1. 當裝置由原始設備製造商 (OEM) 或 ODM 預先載入 APEX 時,/system/apex 已出貨。
  2. 你可以透過 /apex/<apex_name>/ 路徑存取 APEX 中的檔案。
  3. /data/apex 中安裝新版 APEX 時,路徑 重新啟動後指向新的 APEX。

使用 APEX 更新服務

如何使用 APEX 更新服務:

  1. 將系統分區中的服務標示為可更新。新增選項 updatable 改為服務定義。

    /system/etc/init/myservice.rc:
    
    service myservice /system/bin/myservice
        class core
        user system
        ...
        updatable
    
  2. 為更新後的服務建立新的 .rc 檔案。使用 override 選項 重新定義現有服務

    /apex/my.apex/etc/init.rc:
    
    service myservice /apex/my.apex/bin/myservice
        class core
        user system
        ...
        override
    

服務定義只能在 APEX 的 .rc 檔案中定義。動作 APEX 不支援觸發條件。

如果標示為可更新的服務在啟用 APEX 前啟動, 會延遲到 APEXs 啟用為止。

設定支援 APEX 更新

將下列系統屬性設為 true,以支援 APEX 檔案更新。

<device.mk>:

PRODUCT_PROPERTY_OVERRIDES += ro.apex.updatable=true

BoardConfig.mk:
TARGET_FLATTEN_APEX := false

或只需要

<device.mk>:

$(call inherit-product, $(SRC_TARGET_DIR)/product/updatable_apex.mk)

壓平合併 APEX

對於舊版裝置,有時無法或無法更新舊裝置 才能完整支援 APEX。舉例來說,核心可能已建立 如果不使用 CONFIG_BLK_DEV_LOOP=Y,這對掛接檔案系統非常重要 在 APEX 中定義映像檔

壓平合併的 APEX 是特別建構的 APEX,可在搭載以下硬體的裝置上啟用: 會是舊版核心扁平化 APEX 中的檔案會直接安裝至目錄 內建分區下例如,在整併 APEX 中 lib/libFoo.somy.apex」已安裝至「/system/apex/my.apex/lib/libFoo.so」。

啟用扁平的 APEX 不會涉及迴圈裝置。整個 目錄 /system/apex/my.apex 直接繫結至 /apex/name@ver

無法透過下載更新版本來更新壓平合併的 APEX 的 APEXs 數量,因為下載的 APEX 無法壓平合併。 扁平的 APEX 只能透過一般 OTA 更新。

壓平合併的 APEX 為預設設定。也就是說 除非您已明確設定裝置,否則 APEX 預設為扁平化 建構非整併的 APEX 來支援 APEX 更新 (如上所述)。

在單一裝置上混合整併及不整併的 APEX 元件並「不」 。裝置上的 APEX 必須全部不拆除或全部壓平合併。 預先簽署的 APEX 預先簽署 例如 Mainline未預先簽署的 APEX 來源) 也應不要整併,並使用適當的金鑰簽署。 裝置應沿用自 updatable_apex.mk,詳情請參閱: 使用 APEX 更新服務

壓縮 APEX

Android 12 以上版本中的 APEX 壓縮功能,適用於 並降低可更新的 APEX 套件對儲存空間的影響更新至 已安裝 APEX,但預先安裝的版本已未使用 仍會使用相同大小的空間佔用的空間仍為無法使用。

APEX 壓縮使用高壓縮集,將對儲存空間的影響降至最低 此為唯讀分區 (例如 /system 分區) 上的 APEX 檔案。Android 版 12 以上版本會使用 DEFLATE ZIP 壓縮演算法。

壓縮功能不會針對下列項目提供最佳成效:

  • 必須在啟動時提早掛接的啟動 APEX 序列

  • 不可更新的 APEX。 安裝 APEX 的更新版本時,壓縮功能才有助益 /data 分區。 如需可更新的完整 APEX 清單,請前往 模組化系統元件 頁面。

  • 動態共用程式庫 APEXs。由於 apexd 一律會啟用兩個版本的 已預先安裝及升級的 APEX 這類 APEX,壓縮得比較無益。

壓縮後的 APEX 檔案格式

這是 APEX 壓縮檔的格式。

圖表顯示 APEX 壓縮檔的格式

圖 2. 壓縮後的 APEX 檔案格式

在頂層,壓縮的 APEX 檔案是 ZIP 檔案,內含原始檔案 壓縮等級為 9 的 Apex 檔案,和其他檔案 儲存。

APEX 檔案是由四個檔案組成:

  • original_apex:以 9 的壓縮等級定義 這是未經壓縮的原始 APEX 檔案
  • apex_manifest.pb:僅儲存
  • AndroidManifest.xml:僅儲存
  • apex_pubkey:僅儲存

apex_manifest.pbAndroidManifest.xmlapex_pubkey 檔案是 「original_apex」中對應的檔案副本。

建立壓縮的 APEX

您可以使用位於下列位置的 apex_compression_tool.py 工具建構已壓縮的 APEX system/apex/tools

建構系統提供多個與 APEX 壓縮相關的參數。

Android.bp 中,檢查 APEX 檔案是否由 compressible 屬性:

apex {
    name: "apex.test",
    manifest: "apex_manifest.json",
    file_contexts: "file_contexts",
    compressible: true,
}

PRODUCT_COMPRESSED_APEX 產品旗標可控管系統是否建構系統映像檔 來源必須包含壓縮的 APEX 檔案。

進行區域實驗時,您可以透過設定 讓版本強制壓縮 APEX OVERRIDE_PRODUCT_COMPRESSED_APEX=true

建構系統產生的壓縮 APEX 檔案具有 .capex 副檔名。 您可以利用這個擴充功能,輕鬆區分壓縮及未壓縮 多個版本。

支援的壓縮演算法

Android 12 僅支援延遲壓縮壓縮。

在開機時啟用壓縮的 APEX 檔案

壓縮後的 APEX 可以啟用之前,該檔案內含的 original_apex 檔案 解壓縮到 /data/apex/decompressed 目錄。最終產生的 解壓縮後的 APEX 檔案已硬連結至 /data/apex/active 目錄。

請參考以下範例,瞭解上述程序。

請將 /system/apex/com.android.foo.capex 視為壓縮的 APEX 啟動,且 versionCode 37。

  1. /system/apex/com.android.foo.capex 中的 original_apex 檔案是 解壓縮成 /data/apex/decompressed/com.android.foo@37.apex
  2. 已對「restorecon /data/apex/decompressed/com.android.foo@37.apex」執行以下動作: 確認其 SELinux 標籤正確無誤。
  3. 驗證檢查執行的時間如下: /data/apex/decompressed/com.android.foo@37.apex以確保有效性: apexd 會檢查以下項目隨附的公開金鑰: /data/apex/decompressed/com.android.foo@37.apex,確認兩者相等 繫結至 /system/apex/com.android.foo.capex 的套裝組合中。
  4. /data/apex/decompressed/com.android.foo@37.apex 檔案已硬連結至 /data/apex/active/com.android.foo@37.apex 目錄。
  5. 未壓縮 APEX 檔案的一般啟用邏輯 /data/apex/active/com.android.foo@37.apex

與 OTA 互動

壓縮的 APEX 檔案會對 OTA 推送和應用程式造成影響。開始時間 OTA 更新可能包含版本更高的 APEX 壓縮檔 相較於裝置上的使用,必須保留一定的可用空間 以套用 OTA 更新。

為支援 OTA 系統,apexd 會公開下列兩個繫結器 API:

  • calculateSizeForCompressedApex - 計算解壓縮所需的大小 APEX 檔案。這可用來驗證裝置 有足夠的空間,才能下載 OTA。
  • reserveSpaceForCompressedApex - 保留磁碟空間,供日後使用 透過apexd解壓縮 OTA 套件中的壓縮 APEX 檔案。

如果是 A/B OTA 更新,apexd 會嘗試從 做為安裝後 OTA 常式的一部分如果解壓縮失敗 apexd 會在套用 OTA 的啟動期間執行解壓縮作業 更新。

開發 APEX 時考慮的替代方案

以下是 Android 開放原始碼計畫在設計 APEX 檔案時,考慮的一些選項 格式,以及被納入或排除的原因。

一般套件管理系統

Linux 發行版具有套件管理系統,例如 dpkgrpm、 且功能強大、成熟且完善但並未 被採用 APEX,因為 APEX 無法在 安裝。只有在安裝套件時才會進行驗證。 攻擊者可能會破壞已安裝套件的完整性,並且被察覺。這是 所有系統元件都以唯讀模式儲存的 Android 迴歸 完整性都受到 dm-verity 保護的檔案系統。不限 必須禁止竄改系統元件 ,如果裝置遭到入侵,可拒絕啟動。

完整性的 dm-crypt

APEX 容器中的檔案來自內建的分區 (例如, /system 分區) 受到 dmverity 保護,且該分區的任何修改 即使已掛接分區,仍無法存取這些檔案。為了提供 享有相同層級的檔案安全防護,APEX 中的所有檔案都會儲存在單一檔案中 與雜湊樹和 vbmeta 描述元配對的系統映像檔。不含 dm-verity,/data 分區中的 APEX 容易發生非預期的情況 已通過驗證並安裝後的修改內容。

事實上,/data 分區受到加密層 (例如 dm-crypt。儘管這樣可以提供一定程度的防竄改功能, 例如隱私權,而非完整性當攻擊者取得 /data 分區,無法提供進一步的保護,這同樣是 /system 分區中所有系統元件的迴歸差異 APEX 檔案中的雜湊樹和 dm-verity 也能提供相同的 所需的內容保護層級

將路徑從 /system 重新導向至 /apex

使用者可透過新路徑存取封裝在 APEX 中的系統元件檔案,例如 /apex/<name>/lib/libfoo.so。檔案屬於「/system」時 則可透過 /system/lib/libfoo.so 等路徑存取。A 罩杯 APEX 檔案的用戶端 (其他 APEX 檔案或平台) 必須使用新的 路徑。路徑有所變更時,您可能需要更新現有程式碼。

為了避免路徑變更,其中一種方法是將 將 APEX 檔案放到 /system 分區中,Android 團隊決定不重疊 檔案儲存在 /system 分區,因為這會影響 重疊的檔案數量 (甚至可能相互堆疊) 增加。

另一個方法則是綁架檔案存取函式,例如 openstat,以及 readlink,所以開頭為 /system 的路徑會重新導向至其 /apex 底下的對應路徑Android 團隊已捨棄這個選項 因為您無法變更所有接受路徑的函式。 舉例來說,某些應用程式會以靜態方式連結 Bionic,進而實作函式。 在這種情況下,系統不會重新導向這些應用程式。