hook Android系統調用的樂趣和好處。Android的內核是逆向工程師的好伙伴。雖然常規的Android應用被限制和沙盒化,逆向工程師可以按自己希望自定義和改變操作系統和內核中行為。這給了你不可多得的優勢,因為大部分完整性校驗和防篡改功能都依賴內核的服務。部署這種可以濫用信任并自我欺騙的內核和環境,可以避免走很多歪路。
Android應用有幾種方式和系統環境交互。標準方法是通過安卓應用框架的API函數。然而在底層,很多重要的函數,例如分配內存和訪問文件,都是被轉化為linux的系統調用。在ARM linux中,系統調用的調用是通過SVC指令觸發軟件中斷實現的。中斷調用內核函數vector_swi(),用系統調用號作為一個函數指針表的偏移(如安卓上的sys_call_table)。
攔截系統調用最直接的方法是注入你的代碼到內核內存中,覆蓋系統調用表中的原始函數地址重定向執行。不幸的是,目前Android內核加強了內存限制阻止了這種操作。具體來說,內核是在啟用CONFIG_STRICT_MEMORY_RWX選項的情況下構建的。這阻止了向只讀內核內存區寫入,意味著任何試圖修改系統代碼或者系統調用表的操作都將導致崩潰和重啟。繞過這個的一個方法就是自己編譯內核:能夠禁用這種保護,做更多自定義的修改有利于逆向分析。如果你按常規方法逆向Android應用,構建你自己的逆向沙盒是不明智的。
注意:下面的步驟是最好在Ubuntu 14.04環境中用Android NDK 4.8完成。我個人在Mac上面失敗了很多次才完成。我推薦用Ubuntu虛擬機,除非你是個受虐狂。
0x01 構建內核
為了hack的目的,我推薦使用支持AOSP的設備。Google的Nexus智能手機和平板電腦是最合理的選擇,從AOSP構建的內核和系統組件在上面運行沒有問題。另外,索尼的Xperia也可以。為了構建AOSP內核,需要一系列工具(交叉編譯工具)和相應的內核源代碼。根據谷歌的指導,確定了正確的git倉庫和分支。
例如,獲取匹配Nexus 5的Lollipop的內核源碼,需要克隆“msm”倉庫并檢出一個分支“android-msm-hammerhead”。一旦源碼下載了,用make hammerhead_defconfig(或者whatever_defconfig,取決于你的設備)命令創建默認內核配置。
$ git clone https://android.googlesource.com/kernel/msm.git
$ cd msm
$ git checkout origin/android-msm-hammerhead-3.4-lollipop-mr1
$ export ARCH=arm
$ export SUBARCH=arm
$ make hammerhead_defconfig
$ vim .config
為了啟動系統調用掛鉤功能,我推薦增加可加載模塊的支持,由/dev/kmem接口支持,同時導出全局內核符號表。不要忘了禁用內存保護。這些選項的值在配置文件中已經存在,只需要簡單的設置以下值。
CONFIG_MODULES=Y
CONFIG_MODULE_UNLOAD=y
CONFIG_STRICT_MEMORY_RWX=N
CONFIG_DEVMEM=Y
CONFIG_DEVKMEM=Y
CONFIG_KALLSYMS=Y
CONFIG_KALLSYMS_ALL=Y
一旦你完成了編輯配置文件。或者,您現在可以創建一個獨立的工具鏈,用于交叉編譯內核和以后的任務。為了給Android 5.1創建一個工具鏈,運行Android NDK包的make-standalone_toolchain.sh:
$ cd android-ndk-rXXX
$ build/tools/make-standalone-toolchain.sh --arch=arm --platform=android-21 --install-dir=/tmp/my-android-toolchain
設置CROSS_COMPILE環境變量,指向NDK目錄,并運行make構建內核。
$ export CROSS_COMPILE=/tmp/my-android-toolchain/bin/arm-eabi-
$ make
當構建過程完成后,能在arch/arm/boot/zImage-dtb找到引導內核模塊。
0x02 啟動新內核
在啟動新內核前,備份一個你設備的原始引導映像。找到啟動分區的位置:
root@hammerhead:/dev # ls -al /dev/block/platform/msm_sdcc.1/by-name/
lrwxrwxrwx root root 1970-08-30 22:31 DDR -> /dev/block/mmcblk0p24
lrwxrwxrwx root root 1970-08-30 22:31 aboot -> /dev/block/mmcblk0p6
lrwxrwxrwx root root 1970-08-30 22:31 abootb -> /dev/block/mmcblk0p11
lrwxrwxrwx root root 1970-08-30 22:31 boot -> /dev/block/mmcblk0p19
(...)
lrwxrwxrwx root root 1970-08-30 22:31 userdata -> /dev/block/mmcblk0p28
然后,將所有的內容轉儲到一個文件中:
$ adb shell "su -c dd if=/dev/block/mmcblk0p19 of=/data/local/tmp/boot.img"
$ adb pull /data/local/tmp/boot.img
接下來,提取ramdisk以及有關引導映像結構的一些信息。有很多工具可以做到這個,我使用Gilles Grandou的abootimg工具。安裝工具并執行以下的命令:
$ abootimg -x boot.img
在本地目錄會創建bootimg.cfg、initrd.img和zImage(原始的內核)文件。
能用快速引導測試新內核。“fastboot boot”命令允許測試內核。在fastboot模式下用下面命令汗重啟設備:
$ adb reboot bootloader
然后,用“fastboot boot”命令引導Android的新內核。除了新建的內核和原始ramdisk,還需指定內核偏移量,ramdisk偏移量,標簽偏移量和命令行(使用在之前提取的bootimg.cfg中列出的值)。
$ fastboot boot zImage-dtb initrd.img --base 0 --kernel-offset 0x8000 --ramdisk-offset 0x2900000 --tags-offset 0x2700000 -c "console=ttyHSL0,115200,n8 androidboot.hardware=hammerhead user_debug=31 maxcpus=2 msm_watchdog_v2.enable=1"
現在應該手動重啟。為了快速驗證內核=正確運行了,通過校驗Settings->About phone中的“內核版本”的值。

如果一切運行良好,將顯示自定義構建的版本字符串。
0x03 用內核模塊hook系統調用
hook系統調用能讓我們繞過任何依賴內核提供的反逆向防御措施。在我們自定義的內核中,我們能用LKM加載例外的代碼到內核中。我們也可以訪問/dev/kmem接口,用來修改內核內存。這是個經典的linux rootkit技術。

首先需要的是sys_call_table的地址。幸運的是它被Android內核導出了符號(iOS沒這么幸運)。我們在/proc/kallsyms尋找地址:
$ adb shell "su -c echo 0 > /proc/sys/kernel/kptr_restrict"
$ adb shell cat /proc/kallsyms | grep sys_call_table
c000f984 T sys_call_table
這是我們僅需要寫入的內核地址,其他的可以通過便宜計算出來。
看文倉www.kanwencang.com網友整理上傳,為您提供最全的知識大全,期待您的分享,轉載請注明出處。
歡迎轉載:http://www.kanwencang.com/bangong/20170212/100587.html
文章列表