原标題:IoT安全基本功系列——核心的編譯與qemu啟動
IoT安全基本功系列——核心的編譯與qemu啟動
搞IoT安全繞不開的知識
筆者想要完整的整理linux系統從核心的編譯,檔案系統的制作,bootloader引導核心啟動,最終至一個塊裝置,字元裝置,網卡驅動的編寫。做這件事的目的是,筆者發現對于IoT裝置的固件模拟,在開機時擷取root shell,以及驅動作為攻擊面的漏洞挖掘等方面的工作,都繞不開這塊内容。
為什麼要寫這個系列文章
本篇文章有可能是一個系列的開篇文章,市面上貌似對這塊内容的文章資料總讓我感覺是破碎不夠系統的,而且實操性或者準确性上都有些問題,筆者雖能力有限,将盡力能夠讓新手讀者看了本文就能夠實踐出來,本文也是筆者在實踐過程中的實錄,包括自己踩的坑,以及如何解決的這個的思路曆程也記錄了下來,是以本系列文章非常适合同學們實踐參考。
系列文章的最終目的
本系列文章的最終目的是能夠編寫一個真正的驅動程式,而驅動程式的編寫本文選擇參考ldd3即linux裝置驅動程式這本書,由于這本書的核心比較老,現在的核心都已經不再支援書上的例程,如果拿着書上的例程去在目前核心下做實驗的話,會出現很多莫名的坑,為了降低學習曲線,但又把一些基本linux啟動等流程說清楚,嘗試就在ldd3指定的核心linux 2.6.10版本上搭建學習開發環境。
本文的目标
由于上述的内容一篇文章是很難講完,本文先講第一部分,qemu上運作自己編譯的linux 2.6.10核心。其具體包括:
1.建構編譯ldd linx 2.6.10核心的環境
2.編譯核心,建構檔案系統
3.qemu運作系統
1. 建構編譯ldd linx 2.6.10核心的環境
1.linx 2.6.10核心非常老,我建議使用ubuntu5.0的鏡像 鏡像位址:http://old-releases.ubuntu.com/releases/5.04/
2.ubuntu5.0也非常老,我直接使用vmware安裝有問題,無法檢測到cd-rom 使用老版本的支援workstation
選擇workstation 5.x是可以安裝的
3.後來字ubuntu5.0啟動界面發現他使用的就是linux2.6.10
4.安裝完畢
2. 編譯核心,建構檔案系統
1.找到linux2.6.10核心代碼
連結核心代碼:https://mirrors.edge.kernel.org/pub/linux/kernel/v2.6/linux-2.6.10.tar.gz, 其大小為43.7MB, 可以嘗試使用ftp從host主控端上下載下傳代碼,因為安裝老版本的vmtools比較麻煩。
make的時候要用 make ARCH=i386 defconfig,因為menuconfig需要nurses那個庫,安裝這個庫挺麻煩的對于老版本,遂決定放棄好用的menuconfig,畢竟我們的目的是編譯成功。
2.initramfs根檔案系統
在挂載磁盤上的檔案系統之前,需要先挂載一個initramfs檔案系統,因為磁盤上的檔案系統需要驅動,而驅動的加載也需要檔案系統,這是一個雞蛋問題,是以不能一開始就加載磁盤上的檔案系統。 initramfs這個檔案系統的加載不需要驅動,可以在這個檔案系統裡啟動基本的挂載磁盤的驅動,initramfs是由bootload加載到核心中的。具體的,initramfs 就是一些檔案的 cpio壓縮包,由bootloader将其加載後供kernel使用,隻要你往initramfs中添加的檔案夠多,那麼你甚至不需要磁盤上的檔案系統這就是為什麼大家喜歡用busybox去建立initramfs,當加載driver的時候,喜歡把driver寫入到initramfs中,是以以後再更新module的時候,不用重新編譯核心,隻需要編譯一下module,然後把他放到核心中就行了。
3.使用busybox 建構initramfs根檔案系統
同樣的需要下載下傳busybox的源碼,我選擇的是2004年的busybox-1.00.tar.bz2 ,并且需要在ubuntu5.0上編譯,新版本的gcc都是不能用的。 需要注意的是在由于不能使用menuconfig,隻能使用config,要注意在後面可以選擇作為一個static 編譯然後正常編譯 makemake install得到這個檔案目錄 3. qemu運作系統
一開始參考的是這篇文章,https://consen.github.io/2018/01/17/debug-linux-kernel-with-qemu-and-gdb/
1.在搞這一塊的遇到了很多問題,現在羅列
qemu是否是起到了bootloader的作用?核心在和initrd 或者initramfs互動的時候是做了什麼?檔案系統是如何被初始化的?initrd和initramfs在本質上的差別?真實裝置的linux啟動的流程是什麼?vmlinux與最終zimage的差别?qemu運作一個vmlinux沒有任何反應,不知道是不是我的vmlinux有問題,還是qemu不能啟動vmlinux?上面那個文檔可以生成initramfs檔案系統,但是卻不能生成initrd, 這個busybox生成很少見我用qemu啟動的時候到底需要些什麼?dtb, dts 裝置樹又是啥?ttys0是幹啥的?
2.解決qemu運作vmlinux沒有任何反應的問題
參考: https://freemandealer.github.io/2015/10/04/debug-kernel-with-qemu-2/
嘗試用新的編譯好的bzimage和vmlinux.bin,就在arch i386目錄下的
結果新生成的bzimage和vmlinux 在qemu下運作同樣的沒有任何反應,運作的指令qemu-system-i386 -kernel ./bzImage -nographic
隻有在運作bziamge的時候才會出現這個界面,而且還是要運作下面這指令qemu-system-i386 -kernel ./bzImage -append "console=ttyS0"
從這個截圖可以看出,qemu貌似是使用了seabios這個bootloader去加載核心的
還是卡在啟動核心上,從這個圖看出核心貌似根本沒有任何輸出的,我想還是用一個别人編譯的例子
後來找到一個文章說之所出現核心太老不支援ramfs,并不是因為2.6太老,而是因為使用的是vmlinux作為核心啟動的,而不是使用的bzimage
直接使用vmlinux作為核心在qemu中啟動的結果就是下面這樣的
是以問題還是出現在為什麼我編譯的固件就一直卡在boot kernel上面
我決定按照他的建構initrd的方法再來一遍,以确定隻有可能是核心編譯的問題
按照這個文檔的方法是可以的沒有問題的,但是還是報出錯誤
顯示vfs unable to mount root fs on
這串輸出都是核心的代碼輸出,我在核心的源代碼中搜到了這句話
後來發現之前編譯的initramfs.cpio.gz也是可以啟動核心的,隻不過因為我加了一句console=ttyS0,導緻看不到輸出,我覺着實際上是由輸出的,我覺着console=ttyS0的意思就是把顯示放到了序列槽,導緻在目前這個console是看不到的,顯然在很多序列槽的地方就是把console給定位到了ttyS0,而由于我的qemu沒有這個序列槽,是以應該就不需要設定這個玩意
目前看來還是這個文檔最好用,我是通過搜linux 2.6和qemu關鍵詞搜到的,雖然是很久之前的文章,但是真的還挺有用的,起碼這個建構檔案系統的是可以的
目前已經發現核心的啟動是很随意的,不要檔案系統什麼東西的,直接qemu-system-i386 -kernel bzImage就可以啟動
有可能是編譯核心的時候沒有啟用支援ramdisk,根據這篇連結google 搜尋cannot open root device “ram”
The most obvious question is whether or not the kernel you built has
ramdisk support$ grep BLK_DEV_RAM .config CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=4096
我去看了一下發現我的linx 2.6.10版本并沒有啟用這個dev/ram這個裝置,我的一開始并沒有設定BLK_DEV_RAM,後來我才加上去了
initRamFS is a (compressed) CPIO archive, InitRD is a (compressed) ext2/3/4/jfs/xfs/whatever filesystem
參考自https://lists.nongnu.org/archive/html/qemu-devel/2013-10/msg01445.html
5.嘗試編譯新的核心,完全參照老文章
首先下載下傳 linux-2.6.32.60.tar.bz2 連結
用适配性高的核心啟動我編譯的各種檔案系統,觀察是否能起來
rootfs.img.gz這個是按照教程生成的gz格式的檔案系統,是可以起來的
rootfs.img 這個是沒有壓縮的檔案系統,也是可以起來的
6.嘗試各種建立initrd的辦法
7.最終解決了問題
發現是linux 2.6.10 缺少了對initrd的支援,并不是那個ram_dev設定就支援了,還有一個CONFIG_BLK_DEV_INITRD, 這個在i386defconfig預設配置中是根本沒有的,需要自己手動加上
CONFIG_BLK_DEV_INITRD=y
結語
本文是筆者在嘗試在qemu上運作linux 2.6.10版本核心的實錄包括自己在時間時候遇到的各種問題,最終完整編譯linux 2.6.10核心,并且通過很多嘗試最終發現i386的預設配置是缺少initrd支援的問題的,雖然不是按部就班的給出最優解,但是詳細的叙述解決過程,可能對大家更有參考性。
收藏
責任編輯: