
LD_PRELOAD-Magie für den AssetManager von Android
(A)AssetHook ist eine auf LD_PRELOAD basierende Hooking-Bibliothek, die das dynamische Ersetzen von APK-Asset-Dateien ermöglicht, ohne eine APK zu modifizieren. Sie ist ebenfalls in rust geschrieben. Sie leitet das Laden von Asset-Dateien auf einen Dateipfad auf einem Android-Gerät unter /data/local/tmp/assethook/com.pkg.name um. Es versteht sich von selbst, dass AssetHook aufgrund dessen (bzw. SEAndroids lächerlichem DRM-Schema, das Apps nun den Zugriff auf /data/local/tmp blockiert) derzeit erfordert, dass der SELinux-Modus auf permissiv gesetzt ist. Wenn der rohe Asset-Pfad (typischerweise assets/path/to/file.name) unter dem jeweiligen AssetHook-Pfad des Pakets existiert, wird stattdessen der Ersatz geladen. AssetHook besteht aus zwei separaten LD_PRELOAD-Hook-Implementierungen, eine für die "öffentliche" C-API und eine für die interne C++-API. Verwenden Sie im Allgemeinen den C++-Hook, aber wenn er bei einer neuen Android-Version bricht, versuchen Sie den C-Hook (beachten Sie dabei die unten beschriebenen Einschränkungen).
Da Dinge wie React Native die native Asset-Manager-API verwenden, die nicht über Dinge wie Xposed gehooked werden kann.
cppapi_assethook)Ein "relativ stabiler" auf LD_PRELOAD basierender Hook, der die zugrunde liegende C++-Asset-Implementierung hookt, die unter anderem von der öffentlichen C-API und den Java-APIs aufgerufen wird. Da diese API auf niedrigerer Ebene gelegentlich von anderem internen Android-Code verwendet wird, um andere statische Ressourcen aus APKs zu laden/zu prüfen, kann sie auch verwendet werden, um diese Dateien (sofern über diese API gelesen) zu ersetzen, indem Ersatzdateien unter Nicht-assets/-APK-Pfaden abgelegt werden.
Hinweis: Während Dateien wie res/layout/activity_main.xml zumindest über diese API geöffnet werden, werden sie nicht darüber gelesen und können zur Laufzeit nicht mit AssetHook ersetzt werden.
capi_aassethook)(Beachte die beiden 'a' in "aasset")
Ein "konservativer" auf LD_PRELOAD basierender Hook, der nicht die Java-Ebene android.content.res.AssetManager hookt. Da die C-API, die er hookt (AAsset*), öffentlich ist, ist dies ein stabiler Hook, der verwendet werden kann, wenn neue Änderungen in der internen C++-Implementierung den C++-API-Hook brechen. Mit diesem Hook können nur Dateien unter /data/local/tmp/assethook/com.example.name/assets/ gehooked werden.
Installieren Sie AAssetHook und aktivieren Sie es für ein bestimmtes App-Paket
Übertragen Sie (als shell, um sicherzustellen, dass die Datei weltweit lesbar ist) Ersatzdateien:
adb push index.android.bundle.mod /data/local/tmp/assethook/com.pkg.name/assets/index.android.bundle
Starten Sie die gehookte App neu
Hinweis: Shared Objects für 32-Bit- und 64-Bit-arm sind im Repository enthalten.
Hinweis: Der C-API-Hook AAssetHook verwendet einige rust-Syntaxerweiterungen, um eine enorme Menge an Boilerplate zu reduzieren, und muss daher mit rust nightly kompiliert werden. Es ist bekannt, dass er mit rust bei Commit daf8c1dfc vom 2016-12-05 gebaut werden kann (falls interne Änderungen im rust-Compiler den Build brechen).
Installieren Sie das Android NDK
Installieren Sie rust über rustup (https://github.com/rust-lang-nursery/rustup.rs)
Führen Sie die folgenden Befehle aus:
rustup install nightly # C API hook only
rustup default nightly # C API hook only
rustup target add aarch64-linux-android
rustup target add arm-linux-androideabi
rustup target add i686-linux-android # AVD/HAXM
mkdir ~/.cargo/toolchains
cd ~/.cargo/toolchains
/path/to/ndk/build/tools/make-standalone-toolchain.sh \
--platform=android-22 --toolchain=arm-linux-android-4.9 \
--install-dir=android-22-arm-toolchain`
/path/to/ndk/build/tools/make-standalone-toolchain.sh \
--platform=android-22 --toolchain=aarch64-linux-android-4.9 \
--install-dir=android-22-aarch64-toolchain`
/path/to/ndk/build/tools/make-standalone-toolchain.sh \
--platform=android-22 --toolchain=x86-linux-android-4.9 \
--install-dir=android-22-x86-toolchain`
Fügen Sie Folgendes zu ~/.cargo/config hinzu
[target.arm-linux-androideabi]
linker = "/path/to/home/.cargo/toolchains/android-22-arm-toolchain/bin/clang"
[target.aarch64-linux-android]
linker = "/path/to/home/.cargo/toolchains/android-22-aarch64-toolchain/bin/clang"
[target.i686-linux-android]
linker = "/path/to/home/.cargo/toolchains/android-22-x86-toolchain/bin/clang"
Hinweis: Das Skript build.sh im Verzeichnis cppapi führt die letzten drei Befehle aus.
Hinweis: Wenn auf die capi-Implementierung zurückgegriffen wird, ersetzen Sie alle Vorkommen von cppapi durch capi.
Installieren Sie zuerst SELinuxModeChanger von F-Droid oder MrBIMC/SELinuxModeChanger und setzen Sie ihn in den permissiven Modus.
Hinweis: Sie können auch einfach /system/bin/setenforce 0 nach jedem Boot ausführen.
cd cppapi
./install.sh
Hinweis: Wenn auf die capi-Implementierung zurückgegriffen wird, ersetzen Sie alle Vorkommen von cppapi durch capi.
cd cppapi
./hook.sh <pkg.name> <32|64|unhook>
cd /path/to/aassethook/cppapi
cargo build --target=arm-linux-androideabi --release
cargo build --target=aarch64-linux-android --release
cargo build --target=i686-linux-android --release