編輯:關於android開發
在Android上使用qemu-user運行可執行文件
作者:尋禹@阿裡聚安全
QEMU簡要介紹:
QEMU可以解釋執行可執行程序。既然QEMU可以解釋執行可執行程序,那麼QEMU就能夠知道執行了哪些指令,從而可以跟蹤指令的執行。QEMU編譯出來的結果分為系統模式和用戶模式,QEMU用戶模式編譯出來的可執行文件名為:qemu-user。關於QEMU更多的介紹請浏覽官方網站:QEMU。
關於如何編譯QEMU用戶模式可執行文件,請參考這篇文章:編譯可在Android上運行的qemu user mode
qemu-user的main函數源碼在文件”linux-user/main.c”中。
本文研究的QEMU用戶模式的可執行文件運行在(Android & arm cpu)上,下文中說的“設備”一詞指的就是Android arm設備,設備的系統是CyanogenMod12.1 ROM,該ROM基於Android5.1.1。
將qemu-user拷貝到設備中,運行該可執行程序時會提示無法找到libglib-2.0.so.0和libgthread-2.0.so.0這兩個庫,如果讀者按照上文中引用的文章《編譯可在Android上運行的qemu user mode》編譯成功qemu-user,那麼這兩個庫就會存在於Android NDK目錄下,將這兩個目錄拷貝到設備的”/system/lib/”目錄下,然後就可以成功運行qemu-user程序。
我在設備上運行qemu-user的時候出現了標題上顯示的錯誤”FATAL: kernel did not supply AT_SECURE”。
解決辦法一
(解決辦法來源:https://gist.github.com/jserv/5019475)
找到”bionic/linker/linker_environ.cpp”文件,按照下面的代碼修改該文件:
如果讀者用過git再看上面的代碼就可以很清楚的知道,上面的代碼是運行”git diff”後所顯示內容,代碼做了哪些修改清楚的顯示了出來。如果讀者沒有見過”git diff”命令所顯示的內容,那麼這麼做:找到”-static void __init_AT_SECURE(KernelArgumentBlock& args) {“這一行,從這行開始(包括這一行)每一行以減號開頭的表示刪除該行。
文件修改完成後在Android源碼根目錄運行下面的命令:
. build/envsetup.sh
breakfast hammerhead
mmm <Android源碼根目錄>/bionic/linker/
mmm命令用於編譯”<Android源碼根目錄>/bionic/linker/”目錄下的源碼,這個目錄下的源碼編譯完成後會生成一個名為”linker”的可執行文件,這個可執行文件的生成目錄會在終端上顯示出來,將這個linker覆蓋設備上的”/system/bin/linker”文件。
覆蓋設備上的”/system/bin/linker”文件的實際操作中,覆蓋需要需要ROOT權限。”/system/bin/linker”文件覆蓋完成以後,它的文件權限是這樣的:
-rwxr-xr-x root root 91902 2016-05-01 21:50 linker
即linker屬於root用戶,並屬於root用戶組。但是linker原本的權限是下面這樣的:
-rwxr-xr-x root shell 91902 2016-05-01 21:50 linker
即linker屬於root用戶,並屬於shell用戶組。
所以linker覆蓋完成後需要執行”chgrp shell /system/bin/linker”命令設置linker的用戶組。
__init_AT_SECURE函數的被調路徑:__linker_init -> __linker_init_post_relocation -> linker_env_init -> __init_AT_SECURE
在qemu源碼目錄下找到”linux-user/elfload.c”文件,文件中有create_elf_tables函數,在該函數中找到這一行代碼:
在這行代碼下添加一行代碼:
在該文件中找到這一行:
將這一行改為:
[翻譯] getauxval() and the auxiliary vector這篇文章中說了,fs/binfmt_elf.c文件中有內核的ELF二進制加載器源碼,在該文件中也有一個create_elf_tables函數,fs/binfmt_elf.c文件create_elf_tables函數有下面一行代碼:
即在標准的create_elf_tables函數中會添加AT_SECURE這一項。通過閱讀“解決辦法一”可以推斷出,產生”FATAL: kernel did not supply AT_SECURE”錯誤是因為找不到AT_SECURE這一項,那麼“解決辦法二”的思路就是在qemu的create_elf_tables函數中添加這一項。
為什麼在qemu的create_elf_tables函數中添加的AT_SECURE項對應的值是0呢?這是因為我圖方便,標准代碼中AT_SECURE項對應的值是函數security_bprm_secureexec(bprm)的返回值,我發現理解security_bprm_secureexec函數比較麻煩。那麼為什麼是0而不是其他常量值?這是因為在linux系統的終端上輸入下面的命令:
LD_SHOW_AUXV=1 ps
最後顯示AT_SECURE對應的值是0。上面命令中的”ps”可以是其他命令,如:ls。關於LD_SHOW_AUXV這個環境變量在《[翻譯] getauxval() and the auxiliary vector》一文中有介紹。
- loader_exec -> linux-user/elfload.c - load_elf_binary -> linux-user/elfload.c - create_elf_tables
作者:尋禹@阿裡聚安全,更多安全技術、資訊文章,請訪問阿裡聚安全博客
Android事件分發機制源碼分析 小小感慨一下,做android有一段時間了,一直以來都是習慣整理筆記存到有道筆記上,沒有寫博客的習慣。以後逐步分類整理出來,也算&ld
Android AutoLayout全新的適配方式 堪稱適配終結者 一、概述 相信Android的開發者對於設配問題都比較苦惱,Google官方雖
Android學習二(電話拔號器),android拔號一、新建項目CallPhone 1.1、建立項目 二、設置界面與項目名稱 2.1、更改項目名稱 res/value
使用AIDL調用遠程服務設置系統時間,aidl調用系統 在實際工作中,經常遇到客戶需要用代碼設置系統時間的需求,但是Android非系統應用是無法設置系統時間