在Android上使用qemu-user運行可執行檔,androidqemu-user

來源:互聯網
上載者:User

在Android上使用qemu-user運行可執行檔,androidqemu-user

在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

將qemu-user拷貝到裝置中,運行該可執行程式時會提示無法找到libglib-2.0.so.0和libgthread-2.0.so.0這兩個庫,如果讀者按照上文中引用的文章《編譯可在Android上啟動並執行qemu user mode》編譯成功qemu-user,那麼這兩個庫就會存在於Android NDK目錄下,將這兩個目錄拷貝到裝置的”/system/lib/”目錄下,然後就可以成功運行qemu-user程式。

 

運行錯誤解決:FATAL: kernel did not supply AT_SECURE

我在裝置上運行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

 

 

作者:尋禹@阿里聚安全,更多安全技術、資訊文章,請訪問阿里聚安全部落格

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.