
Android के AssetManager के लिए LD_PRELOAD जादू
(A)AssetHook एक LD_PRELOAD-आधारित हुकिंग लाइब्रेरी है जो APK को संशोधित किए बिना APK एसेट फ़ाइलों को गतिशील रूप से बदलने की सुविधा देती है। इसे रस्ट में भी लिखा गया है। यह एसेट फ़ाइल लोड को Android डिवाइस पर /data/local/tmp/assethook/com.pkg.name के तहत एक फ़ाइलपाथ पर रीडायरेक्ट करता है। कहने की ज़रूरत नहीं, इसके कारण (वास्तव में SEAndroid की बेतुकी DRM योजना जो अब ऐप्स की /data/local/tmp तक पहुंच को ब्लॉक करती है), AssetHook को वर्तमान में SELinux मोड को permissive पर सेट करने की आवश्यकता होती है। यदि कच्चा एसेट पाथ (आमतौर पर assets/path/to/file.name) संबंधित पैकेज के AssetHook पाथ के अंतर्गत मौजूद है, तो उसके स्थान पर प्रतिस्थापन (replacement) लोड किया जाएगा। AssetHook में दो अलग-अलग LD_PRELOAD हुक इम्प्लीमेंटेशन शामिल हैं, एक "public" C API के लिए और एक आंतरिक C++ API के लिए। सामान्य तौर पर, C++ हुक का उपयोग करें, लेकिन यदि यह Android के नए संस्करण पर टूट जाता है, तो C वाला आज़माएँ (बस नीचे वर्णित इसकी सीमाओं पर ध्यान दें)।
क्योंकि React Native जैसी चीज़ें नेटिव एसेट मैनेजर API का उपयोग करती हैं, जिसे Xposed जैसी चीज़ों से हुक नहीं किया जा सकता।
cppapi_assethook) हुकएक "अपेक्षाकृत स्थिर" LD_PRELOAD-आधारित हुक जो अंतर्निहित C++ एसेट इम्प्लीमेंटेशन को हुक करता है, जिसे public C API और अन्य चीज़ों के अलावा Java APIs भी कॉल करते हैं। चूँकि यह निम्न-स्तरीय API कभी-कभी Android के अन्य आंतरिक कोड द्वारा APK से अन्य स्थैतिक संसाधनों को लोड/जाँचने के लिए उपयोग की जाती है, इसका उपयोग उन फ़ाइलों को बदलने के लिए भी किया जा सकता है (यदि वे इस API के माध्यम से पढ़ी जाती हैं) गैर-assets/ APK पाथ के तहत प्रतिस्थापन रखकर।
नोट: हालाँकि res/layout/activity_main.xml जैसी फ़ाइलें कम से कम इस API के माध्यम से खोली जाती हैं, वे इसके साथ पढ़ी नहीं जाती हैं और AssetHook के साथ रनटाइम पर प्रतिस्थापित नहीं की जा सकतीं।
capi_aassethook) हुक("aasset" में दो 'a' पर ध्यान दें)
एक "रूढ़िवादी" LD_PRELOAD-आधारित हुक जो Java-स्तरीय android.content.res.AssetManager को हुक नहीं करेगा। चूँकि यह जिस C API को हुक करता है (AAsset*) public है, यह एक स्थिर हुक है जिसका उपयोग तब किया जा सकता है जब आंतरिक C++ इम्प्लीमेंटेशन में नए बदलाव C++ API हुक को तोड़ दें। इस हुक का उपयोग करके, केवल /data/local/tmp/assethook/com.example.name/assets/ के अंतर्गत फ़ाइलों को हुक किया जा सकता है।
AAssetHook इंस्टॉल करें और इसे किसी विशेष ऐप पैकेज के लिए सक्षम करें
प्रतिस्थापन फ़ाइलों को (सुनिश्चित करने के लिए shell के रूप में पुश करें कि फ़ाइल world-readable है):
adb push index.android.bundle.mod /data/local/tmp/assethook/com.pkg.name/assets/index.android.bundle
हुक किए गए ऐप को पुनः आरंभ करें
नोट: 32-बिट और 64-बिट arm के लिए शेयर्ड ऑब्जेक्ट रिपॉज़िटरी में एम्बेडेड हैं।
नोट: AAssetHook को हुक करने वाला C API बॉयलरप्लेट की भारी मात्रा को कम करने के लिए कुछ रस्ट सिंटैक्स एक्सटेंशन का उपयोग करता है, और इसलिए इसे रस्ट नाइटली का उपयोग करके कंपाइल करने की आवश्यकता होती है। यह रस्ट कमिट daf8c1dfc (दिनांक 2016-12-05) पर बिल्ड होने के लिए जाना जाता है (यदि रस्ट कंपाइलर में आंतरिक परिवर्तन बिल्ड को तोड़ते हैं)।
Android NDK इंस्टॉल करें
rustup के माध्यम से रस्ट इंस्टॉल करें (https://github.com/rust-lang-nursery/rustup.rs)
निम्नलिखित कमांड चलाएँ:
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`
~/.cargo/config में निम्नलिखित जोड़ें
[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"
नोट: cppapi निर्देशिका में build.sh स्क्रिप्ट अंतिम तीन कमांड निष्पादित करती है।
नोट: यदि capi इम्प्लीमेंटेशन पर फॉलबैक कर रहे हैं, तो cppapi के सभी उदाहरणों को capi से बदल दें।
पहले F-Droid या MrBIMC/SELinuxModeChanger से SELinuxModeChanger इंस्टॉल करें, और इसे permissive मोड पर सेट करें।
नोट: आप प्रत्येक बूट के बाद बस /system/bin/setenforce 0 भी चला सकते हैं।
cd cppapi
./install.sh
नोट: यदि capi इम्प्लीमेंटेशन पर फॉलबैक कर रहे हैं, तो cppapi के सभी उदाहरणों को 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