夾帶 microcode 的 initrd 解法 [論壇 - Ubuntu 哈啦]


正在瀏覽:   1 名遊客


 到底部   前一個主題   下一個主題  [無發表權] 請登錄或者註冊



夾帶 microcode 的 initrd 解法
會員三級
註冊日期:
2017/3/23 10:15
所屬群組:
已註冊使用者
等級: 9
HP : 0 / 210
MP : 36 / 1664
EXP: 40
離線
有些 initrd.img 表面上是 cpio 的壓縮檔,打開後只看到 GenuineIntel.bin 或者 AuthenticAMD.bin

然後 file 之後顯示 ASCII cpio archive (SVR4 with no CRC)

google 一下全都是廢話, 到目前為止真的沒人解開過嗎?

要解 initrd 只有在非不得已修改別人發行版,或者自己除錯測試時才會用到

在沒資料參考的情況下只好用 HEX editor 打開來分析看看

分析的結果是... 這類型的壓縮檔有3到4層皮

最上層 microcode (GenuineIntel.bin 或者 AuthenticAMD.bin 或者兩個都有) 壓縮格式是 cpio

再來就是一般的 initrd 壓縮格式 gz 或 lzma、xz, 還一個 lz4

最後一層 cpio 解開之後就是 initrd 的根目錄

用壓縮工具只能解出第一層的 microcode 檔案

在每一層檔案結束都有一個 TRAILER!!! 的字串

microcode 如果夾帶2個 就會多出一個 TRAILER!!! 的字串

大致上相這樣
-----------------------
GenuineIntel.bin 第一層
----------------------- TRAILER!!!
AuthenticAMD.bin 第二層
----------------------- TRAILER!!!
gz 或 xz 或 lzma 或 lz4 第三層
----------------------- TRAILER!!!
cpio 第四層
----------------------- TRAILER!!!

需要提取出來的是第三層以後的內容

所以要找到第三層開始的偏移量,然後用 dd dump 出來。

如果用搜尋壓縮格式的特徵碼去找會出錯, 因為假如是 第三層是 gz 的壓縮格式,裡面可能也會包含 xz 的特徵碼。所以用 TRAILER!!! 字串去計算第三層開始偏移量比較保險

microcode 後面的 TRAILER!!!字串 前面有帶 0 所以比較好分辨


找到第三層開始的偏移量

INITRD=initrd.img

TRAILER=$(LC_ALL=C grep -a -b -o $'\x30\x54\x52\x41\x49\x4c\x45\x52\x21\x21\x21\x00\x00\x00\x00\x00\x00' $INITRD | awk 'END{print}' | cut -d ":" -f 1)

OFFSET=$(expr $TRAILER + 227)

然後用 dd dump 出來
dd if=$INITRD bs=1 skip=$OFFSET of=/tmp/initrd

檢查壓縮格式
file -b /tmp/initrd

解壓縮
# lz4
mv /tmp/initrd initrd.lz4
lz4 -d initrd.lz4 initrd

# gz
mv /tmp/initrd initrd.gz
gunzip -d initrd.gz

# lzma
mv /tmp/initrd initrd.lzma
lzma -d initrd.lzma

# xz
mv /tmp/initrd initrd.xz
xz -d initrd.xz

解開後還一層 cpio
mkdir -p rootfs && cd rootfs
cpio -i -F ../initrd
rm ../initrd

就醬

11/18 12:54:44
應用擴展 工具箱
回覆: 夾帶 microcode 的 initrd 解法
會員五級
註冊日期:
2012/4/22 10:50
所屬群組:
已註冊使用者
等級: 35
HP : 171 / 855
MP : 588 / 19065
EXP: 21
離線
感謝您提供您的心得,

我之前沒有花時間去研究這方面的議題,

所以剛剛先簡略探索了一下,

我使用「initrd arch wiki」當關鍵字查詢。

查到下面兩個頁面

* https://wiki.archlinux.org/index.php/Mkinitcpio_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)
* https://wiki.archlinux.org/index.php/Mkinitcpio

裡面有提到一個工具「lsinitcpio」,

於是我找「Ubuntu」看看有沒有這樣的工具。

在我的系統「Ubuntu 18.04」找了一下。

發現了「lsinitramfs」這個工具。

它來自於「initramfs-tools-core」。

================================================================================

執行


$ dpkg -S $(which lsinitramfs)



顯示


initramfs-tools-core: /usr/bin/lsinitramfs



================================================================================

執行


$ dpkg -L initramfs-tools-core | sort -u



顯示很多檔案,就不列了。

================================================================================

執行


$ dpkg -L initramfs-tools-core | grep bin



顯示


/usr/bin
/usr/bin/lsinitramfs
/usr/bin/unmkinitramfs
/usr/sbin
/usr/sbin/mkinitramfs



================================================================================

執行


$ dpkg -L initramfs-tools-core | grep man



顯示


/usr/share/man
/usr/share/man/man5
/usr/share/man/man5/initramfs.conf.5.gz
/usr/share/man/man8
/usr/share/man/man8/initramfs-tools.8.gz
/usr/share/man/man8/lsinitramfs.8.gz
/usr/share/man/man8/mkinitramfs.8.gz
/usr/share/man/man8/unmkinitramfs.8.gz




* $ man initramfs.conf
* $ man initramfs-tools
* $ man lsinitramfs
* $ man mkinitramfs
* $ man unmkinitramfs

================================================================================

在「$ man unmkinitramfs」。

發現到下面的執行範例


$ unmkinitramfs /boot/initrd.img-$(uname -r) initramfs/



================================================================================

然後發現到「unmkinitramfs」是「shell script」,

所以有興趣深究的人,可以直接探索它裡面的作法。

執行


$ file $(which unmkinitramfs)



顯示


/usr/bin/unmkinitramfs: POSIX shell script, ASCII text executable



執行


$ file $(dpkg -L initramfs-tools-core | grep 'bin/')



顯示


/usr/bin/lsinitramfs: POSIX shell script, ASCII text executable
/usr/bin/unmkinitramfs: POSIX shell script, ASCII text executable
/usr/sbin/mkinitramfs: POSIX shell script, ASCII text executable



================================================================================

執行


$ apt-cache showsrc initramfs-tools-core | grep '^Binary:'



顯示


Binary: initramfs-tools, initramfs-tools-core, initramfs-tools-bin



* initramfs-tools
* initramfs-tools-core
* initramfs-tools-bin

================================================================================

* https://wiki.ubuntu.com/Initramfs
* https://wiki.debian.org/initramfs
* https://wiki.archlinux.org/index.php/Arch_boot_process#initramfs

================================================================================

* $ man 5 cpio ## <-- 可以找到「TRAILER!!!」的相關說明。
* $ man 1 cpio

================================================================================

目前先簡略探索到這,

先紀錄下來提供參考,

報告完畢


11/18 14:50:39
應用擴展 工具箱
回覆: 夾帶 microcode 的 initrd 解法
會員五級
註冊日期:
2012/4/22 10:50
所屬群組:
已註冊使用者
等級: 35
HP : 171 / 855
MP : 588 / 19065
EXP: 21
離線
================================================================================

延續「#2」。

* $ man 5 cpio ## <-- 可以找到「TRAILER!!!」的相關說明。
* $ man 1 cpio

================================================================================

使用「TRAILER!!! cpio」當關鍵字查詢,

可以找到下面兩篇文章

1. https://codeday.me/bug/20190808/1624182.html]https://codeday.me/bug/20190808/1624182.html (是翻譯下面一篇)
2. https://unix.stackexchange.com/questions/163346/why-is-it-that-my-initrd-only-has-one-directory-namely-kernel

================================================================================

參考「第二篇」裡其中一個回覆,有提供一個「function」名稱是「uncpio」,貼過來使用,

使用範例如下


#!/usr/bin/env bash


# https://codeday.me/bug/20190808/1624182.html
# https://unix.stackexchange.com/questions/163346/why-is-it-that-my-initrd-only-has-one-directory-namely-kernel


uncpio () {
	if [[ $(wc -c $1 | cut -d ' ' -f1) -eq 0 ]]; then
		return
	fi

	type=$(cat $1 | file -)
	local tmpfile=$(date +%s.%N)
	echo -e "\n$type"

	if [[ $type =~ .*cpio.* ]]; then
		cat $1 | (cpio -id; cat >$tmpfile)
	elif [[ $type =~ .*gzip.* ]]; then
		zcat $1 | (cpio -id; cat >$tmpfile)
	else
		return
	fi

	uncpio $tmpfile
	rm $tmpfile
}

INITRD="initrd.img"

cp "/boot/initrd.img-$(uname -r)" "./$INITRD"

mkdir -p rootfs
cd rootfs

uncpio "../$INITRD"




可以將上面內容,存成一個檔案「extract.sh」,並且「chmod u+x extract.sh」。

然後執行「./extract.sh」,就會產生一個資料夾「rootfs」。

會顯示


/dev/stdin: ASCII cpio archive (SVR4 with no CRC)
56 blocks

/dev/stdin: ASCII cpio archive (SVR4 with no CRC)
4712 blocks

/dev/stdin: gzip compressed data, last modified: Tue Nov 5 15:56:55 2019, from Unix
201265 blocks



執行


ls rootfs -1



顯示


bin
conf
etc
init
kernel
lib
lib64
run
sbin
scripts
usr
var



執行


tree rootfs/kernel/



顯示


rootfs/kernel/
└── x86
    └── microcode
        ├── AuthenticAMD.bin
        └── GenuineIntel.bin

2 directories, 2 files



================================================================================

以下簡單說明我理解到上面「uncpio」的原理。

關於「uncpio」的用法,是「uncpio initrd_filename」。

上面的範例,
是先將「/boot/initrd.img-$(uname -r)」複製到現在工作的資料夾,
並且改名為「initrd.img」。
所以上面的範例,也就是執行「uncpio initrd.img」。

================================================================================

而「uncpio」會跑遞迴。

以下拆解說明。

================================================================================

## 第一個操作步驟

執行下面指令,觀察「initrd.img」的檔案類型


file initrd.img



顯示


initrd.img: ASCII cpio archive (SVR4 with no CRC)



執行下面指令,觀察「initrd.img」,是否存在「TRAILER!!!」


grep 'TRAILER!!!' -a -b -o initrd.img



顯示


28182:TRAILER!!!
2440990:TRAILER!!!



以下是第一次執行「cpio」。


cat initrd.img | (cpio -id; cat > rest-1)



顯示


56 blocks



上面執行的結果,會產生一個資料夾「kernel/」,並且會產生一個檔案「rest-1」

執行


tree kernel/



顯示


kernel/
└── x86
    └── microcode
        └── AuthenticAMD.bin

2 directories, 1 file



我的理解,上面的指令,第一次執行「cpio」,
會將「AuthenticAMD.bin」解出來,
並且將剩下的部份儲存到「rest-1」這個檔案。

================================================================================

## 第二個操作步驟

執行下面指令,觀察「rest-1」的檔案類型


file rest-1



顯示


rest-1: ASCII cpio archive (SVR4 with no CRC)



執行下面指令,觀察「rest-1」,是否存在「TRAILER!!!」


grep 'TRAILER!!!' -a -b -o rest-1



顯示


2412318:TRAILER!!!



以下是第二次執行「cpio」。


cat rest-1 | (cpio -id; cat > rest-2)



顯示


4712 blocks



上面執行的結果,會解開一個檔案「kernel/x86/microcode/GenuineIntel.bin」,並且會產生一個檔案「rest-2」。

執行


tree kernel/



顯示


kernel/
└── x86
    └── microcode
        ├── AuthenticAMD.bin
        └── GenuineIntel.bin

2 directories, 2 files



我的理解,上面的指令,第二次執行「cpio」,
會將「GenuineIntel.bin」解出來,
並且將剩下的部份儲存到「rest-2」這個檔案。

================================================================================

## 第三個操作步驟

執行下面指令,觀察「rest-2」的檔案類型


file rest-2



顯示


rest-2: gzip compressed data, last modified: Tue Nov 5 15:56:55 2019, from Unix



執行下面指令,觀察「rest-2」,是否存在「TRAILER!!!」


grep 'TRAILER!!!' -a -b -o rest-2



沒有顯示

以下是第三次執行「cpio」。注意:這裡改成使用「zcat」


zcat rest-2 | (cpio -id; cat > rest-3)



顯示


201265 blocks



上面執行的結果,會解開很多個檔案和資料夾,並且會產生一個檔案「rest-3」。

執行


ls -1



顯示


bin
conf
etc
init
initrd.img
kernel
lib
lib64
rest-1
rest-2
rest-3
run
sbin
scripts
usr
var




我的理解,上面的指令,第三次執行「cpio」,
就會將「initrd」的「rootfs」結構解出來,
並且將剩下的部份儲存到「rest-3」這個檔案。

================================================================================

## 停止遞迴的關鍵

執行下面指令,觀察「rest-3」的檔案類型


file rest-3



顯示


rest-3: empty



執行


wc -c rest-3



顯示


0 rest-3



執行


wc -c rest-3 | cut -d ' ' -f1




顯示


0



可以對照上面的「uncpio」,開頭有一段程式碼如下,
也就是停止遞迴的檢核點。


	if [[ $(wc -c $1 | cut -d ' ' -f1) -eq 0 ]]; then
		return
	fi



================================================================================

請再搭配對照觀看「#1」提到的概念,

還有閱讀「man 5 cpio」和「man 1 cpio」。

================================================================================

上面一開始找到的參考文章,裡面有提到一個工具「binwalk」,

執行


binwalk "/boot/initrd.img-$(uname -r)"



或是執行


binwalk initrd.img



顯示


DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
0             0x0             ASCII cpio archive (SVR4 with no CRC), file name: ".", file name length: "0x00000002", file size: "0x00000000"
112           0x70            ASCII cpio archive (SVR4 with no CRC), file name: "kernel", file name length: "0x00000007", file size: "0x00000000"
232           0xE8            ASCII cpio archive (SVR4 with no CRC), file name: "kernel/x86", file name length: "0x0000000B", file size: "0x00000000"
356           0x164           ASCII cpio archive (SVR4 with no CRC), file name: "kernel/x86/microcode", file name length: "0x00000015", file size: "0x00000000"
488           0x1E8           ASCII cpio archive (SVR4 with no CRC), file name: "kernel/x86/microcode/AuthenticAMD.bin", file name length: "0x00000026", file size: "0x00006B2A"
28072         0x6DA8          ASCII cpio archive (SVR4 with no CRC), file name: "TRAILER!!!", file name length: "0x0000000B", file size: "0x00000000"
28672         0x7000          ASCII cpio archive (SVR4 with no CRC), file name: "kernel", file name length: "0x00000007", file size: "0x00000000"
28792         0x7078          ASCII cpio archive (SVR4 with no CRC), file name: "kernel/x86", file name length: "0x0000000B", file size: "0x00000000"
28916         0x70F4          ASCII cpio archive (SVR4 with no CRC), file name: "kernel/x86/microcode", file name length: "0x00000015", file size: "0x00000000"
29048         0x7178          ASCII cpio archive (SVR4 with no CRC), file name: "kernel/x86/microcode/.enuineIntel.align.0123456789abc", file name length: "0x00000036", file size: "0x00000000"
29212         0x721C          ASCII cpio archive (SVR4 with no CRC), file name: "kernel/x86/microcode/GenuineIntel.bin", file name length: "0x00000026", file size: "0x0024CC00"
2440880       0x253EB0        ASCII cpio archive (SVR4 with no CRC), file name: "TRAILER!!!", file name length: "0x0000000B", file size: "0x00000000"
2441216       0x254000        gzip compressed data, from Unix, last modified: 2019-11-05 15:56:55
3301160       0x325F28        MySQL ISAM compressed data file Version 10




================================================================================

另外發現到在「#2」提到的「unmkinitramfs」並沒有解出「kernel/x86/microcode/GenuineIntel.bin」。


================================================================================

## 相關工具


### 文字介面

* man hexer
* man hexedit


### 圖形介面

* Package: wxhexeditor
* Package: okteta
* man ghex

### 之前有紀錄過的工具

* man xxd
* man hexdump
* man od

### 查詢相關工具

* $ apt-cache search hex | grep viewer
* $ apt-cache search hex | grep editor
* $ apt-cache search 'hexeditor'
* $ apt-cache search 'hex editor'
* $ apt-cache search 'hex dump'

================================================================================

## 暫記

使用「microcode initrd」當關鍵字查詢。

可以找到下面這一頁

* https://kernel.googlesource.com/pub/scm/linux/kernel/git/cip/linux-cip/+/refs/tags/v4.19.72-cip10-rebase/Documentation/x86/microcode.txt

然後根據上面的線索,到下面這一頁

* https://github.com/torvalds/linux

找到

* https://github.com/torvalds/linux/blob/master/Documentation/x86/microcode.rst
* https://www.kernel.org/doc/html/latest/x86/microcode.html

================================================================================

以上提供參考

報告完畢


11/19 0:15:43
應用擴展 工具箱
回覆: 夾帶 microcode 的 initrd 解法
會員三級
註冊日期:
2017/3/23 10:15
所屬群組:
已註冊使用者
等級: 9
HP : 0 / 210
MP : 36 / 1664
EXP: 40
離線
說真的 Linux 底下 HEX 編輯器沒一款好用的

bless 視窗調大 視窗裡面的偏移量就走精了

HxD是windows的軟體,我用 Wine 跑的

習慣修改 HEX 的基本上應該對 Unix 下的 HEXEditor 很感冒。點擊要修改的地方觸感很差,自己試一下手感就知道 ˇˇ

HxD是免費的 還一款要註冊的 WinHEX 也很好用。

11/19 15:31:44
應用擴展 工具箱


 [無發表權] 請登錄或者註冊


可以查看帖子.
不可發帖.
不可回覆.
不可編輯自己的帖子.
不可刪除自己的帖子.
不可發起投票調查.
不可在投票調查中投票.
不可上傳附件.
不可不經審核直接發帖.