日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

静态编译qemu_使用QEMU chroot进行固件本地调试

發布時間:2025/3/15 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 静态编译qemu_使用QEMU chroot进行固件本地调试 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

閱讀:

2,905

QEMU是開發者在調試一些不同架構的程序時經常使用的虛擬機軟件。它有兩種運行模式,全系統模擬(System mode)和單程序運行(User mode)。System mode和開發者平常用的VMWare一樣,模擬整個系統從加載器開始的啟動和運行。在設備逆向過程中,如果僅僅是為了運行開發者提取出文件系統中的某一個程序,那就可以使用QEMU的user mode來簡化整個操作流程,同時能夠方便的利用 QEMU 自帶的GDB服務來進行調試,免去搭建環境的煩惱。

但是,單單在命令行中調用“qemu-arm myprogram”往往沒有那么簡單,因為動態鏈接的程序都會依賴幾個動態鏈接庫。雖然可以傳入 -L 參數,或者通過指定環境變量QEMU_LD_PREFIX解決,但這種方式不但不優雅,還會造成重復性的工作——每個程序依賴的庫不同,因此每次都要選擇不同的目錄。而且使用這種方式啟動的程序,所運行的程序文件夾(CWD)與原來不同,很可能訪問不了程序中硬編碼的一些文件的絕對路徑,造成程序出錯。

因此最簡單直接的方法還是使用chroot配合QEMU,來完全模擬程序的文件系統環境,以固件的根目錄作為chroot的根目錄,程序也能夠自動加載到它所需要的libc與其他各種函數庫。綠盟的小伙伴在看雪上做過一次分享,我聽過后以為很容易上手,但是操作時踩到了一些坑。這里總結一下整個流程,順便講解一下其中的原理。

編譯安裝

Ubuntu自帶的 QEMU 版本有點老(我的18.04 LTS 附帶的 QEMU 2.11),在調試時會遇到類似下面的報錯:~ # ./gdbserver tcp:2333 /usr/bin/messagingagent

qemu: Unsupported syscall: 117

老版本QEMU不能夠很好的處理與調試相關的ptrace系統調用,我們需要從官方的最新版源代碼編譯安裝QEMU。

依賴的安裝可以參考官方教程。安裝好依賴后從git獲取最新的源碼,并使用以下參數指定編譯的QEMU采用靜態鏈接,最后進行編譯。我在這里指定prefix目錄為當前目錄下的 staging,自己操作時可以隨意更改。git clone git://git.qemu.org/qemu.git --recurse-submodules --depth 1

cd qemu

./configure --static --prefix="$PWD/staging/user-static" --disable-system --enable-linux-user

make –j8 && make install

然后 staging/user-static 目錄下就是我們編譯好的核武器了。

安裝binfmt

binfmt(Binary Format)是一個內核模塊,它的用處如它的名字,通過二進制文件頭來識別它的格式,從而指定用哪個解釋器去啟動——可以理解為二進制文件的hashbang(用處類似于在Python文件的第一行寫上“#!/usr/bin/env python”)。有了它我們就可以像啟動原生ELF一樣啟動一個ARM或其他任何QEMU支持的程序了。sudo apt install qemu-user-binfmt

update-binfmts --display

安裝這個包會依賴安裝系統軟件源中的qemu-user。我們用不到它,但裝這個包的意義在于它包含了幾個自動向內核注冊QEMU binfmt的腳本,這樣我們就不需要再手動指定我們的ARM可執行文件需要哪個路徑下的QEMU來執行,非常方便。安裝成功后在命令行中執行“update-binfmts –display”。

圖 1 update-binfmts輸出

我們此時可以測試一下,臨時將環境變量QEMU_LD_PREFIX設置為我們要chroot進去的根目錄,然后運行ARM設備中提取出的ELF可執行文件,如果不報錯就可以了。圖中a.out是我編譯的arm64的hello world,這個程序可在我的測試設備上正常運行。

圖 2 運行示例程序 Hello World

復制QEMU程序

hello world可以運行之后,我們還需要準備一下我們的rootfs目錄。

將第一步編譯目錄中的“staging/user-static/qemu-aarch64”復制到“update-binfmts”中顯示的對應位置(/usr/bin/qemu-aarch64),如果必要的話,將這里的aarch64替換成你所要運行的程序架構。注意必須是相同位置!當我們啟動為ARM或其他架構編譯的應用程序時,系統會調用binfmts識別它的類型并調用之前注冊的interpreter(如/usr/bin/qemu-aarch64)來“翻譯”啟動。在chroot下,依然會從這個路徑中尋找。因此如果chroot后這個路徑下找不到QEMU,啟動任何程序都會報錯No such file or directory。這個報錯會有很多歧義,因此一定要自己確認一下QEMU確實在rootfs的“/usr/bin”目錄中。

運行sudo chroot . /bin/sh

到這里,我們就可以像在虛擬機中一樣,通過shell運行這個chroot中的所有程序了!

總結 Xxx not found 相關的問題

當我運行一個命令時,# ./run_xxx_command

報一個錯——run_xxx_command :No such file or directory

我的第一反應肯定是懷疑自己。程序名稱輸錯了?但又不對,我怎么可能這么蠢呢?一路摸爬滾打下來,我發現最蠢的還是這句模糊的報錯信息。它會有很多歧義。

根據我的經驗,這個報錯會有以下四種原因。最容易想到的:要運行的命令不存在。

動態鏈接器不存在,如下例,運行IDA的遠程調試器。

運行objdump可以看到它需要哪個解釋器來讀取它。一般都是ld-xxxx.so

如果ld找不到的話,這程序能運行的概率就很小了。QEMU解釋器沒找到。如果我們注冊了binfmt卻沒有將qemu拷貝到“rootfs/usr/bin“中,chroot時也會報一樣的錯誤——文件沒找到。如果沒有踩過這個坑,大概會很久找不出原因吧。

動態鏈接庫沒找到。這種情況比較顯而易見,因為他會告訴你哪個庫沒找到。

以后拿到一個新的固件包,只需要解壓到一個文件夾里,把對應架構的qemu拷貝進去,直接運行命令chroot即可。遇到需要調試的程序,我們通過運行“qemu-aarch64 -g 2331 /path/to/binary”指定-g參數開啟調試選項,也可以聲明一個環境變量QEMU_GDB=2331,帶上這個環境變量所啟動的程序,都會自動開啟GDB端口并等待調試器attach,調試起來是不是很方便呢?

參考資料:

總結

以上是生活随笔為你收集整理的静态编译qemu_使用QEMU chroot进行固件本地调试的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。