binfmt_misc是核心中的一個功能,它能將非本機的二進位制檔案與特定的解析器自動匹配起來,進行二進位制解析。
例如,在x86上解析arm64架構的二進位制。
通過binfmt_misc可以註冊解析器來處理指定二進位制檔案格式的請求。這些解析器可以是本地可執行檔案,也可以是跨平臺(ARM、MIPS)可執行檔案。
註冊解析器的目的是為了讓Linux在執行特定格式的二進位制時,能夠識別並自動選擇相應的解析器來處理。
1.掛載
首先需要掛載 binfmt_misc,並使用`mount`命令將`binfmt_misc`檔案掛載到/proc/sys/fs/binfmt_misc/。
mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc
2.建立解析器組態檔
在 /proc/sys/fs/binfmt_misc/
目錄下,可以建立一個組態檔,命名為 register,其中 register是要註冊的二進位制檔案格式的識別符號。
3.註冊
在直譯器組態檔中,可以使用 echo
命令將相應的設定資訊寫入。這些設定資訊指定了二進位制檔案格式的特徵、直譯器的路徑以及其他相關引數。例如,對於 Windows 可執行檔案的直譯器設定,可以指定其魔術數位、直譯器的路徑等。
使用`echo`命令向`/proc/sys/fs/binfmt_misc/
`目錄中的特定檔案寫入設定資訊,以註冊特定的二進位制檔案格式和直譯器。
註冊格式::name:type:offset:magic:mask:interpreter:flags
#/usr/bin/qemu-arm64為解析器程式的路徑
#magic為\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00
#mask為\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff
echo ':arm:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-arm64-static:' > register
以下是這些欄位的含義:
name:
是一個識別符號字串。指定解析器的名稱或標識。在這個例子中,解析器的名稱為"arm";
type:
是識別型別。給予M
魔法和E
擴充套件。offset:
是檔案中 magic/mask 的偏移量,以位元組計算。預設為 0 :name:type::magic...
。使用副檔名匹配時忽略。magic:
是 binfmt_misc 匹配的位元組序列。魔術字串可能包含十六進位制編碼的字元,mask:
是一個(可選,預設為所有 0xff)掩碼。interpreter:
是應該使用二進位制檔案作為第一個引數呼叫的程式(指定完整路徑)flags:
這些標誌控制解析器的行為和操作方式。下面是一些常見的 flags 標誌及其作用:在Linux中,核心通過魔術數位(Magic Nmuber)來識別特定的二進位制檔案格式。
具體的識別過程如下:
核心讀取二進位制檔案的開頭部分的位元組序列,通常是檔案的前幾個位元組。
核心將讀取到的位元組序列與已註冊直譯器的魔術數位進行比對。
如果找到與魔術數位匹配的直譯器,則選擇該直譯器來處理該二進位制檔案。
如果沒有找到匹配的直譯器,核心將無法執行該二進位制檔案,並可能會返回錯誤。
在 Linux 終端中,可以使用 hexdump -C <binary_file>或xxd <binary_file>等命令列工具來檢視二進位制檔案的內容。這些工具會顯示檔案的十六進位製表示,並可以幫助你找到檔案開頭部分的魔數。
案例如下:
除了magic還有一個mask這個怎麼理解?
mask的作用是遮蔽或過濾魔數中的某些位,將魔數與掩碼進行與運算,如果不想匹配魔數某些位,則再mask中將對應位設定為0即可。
掩碼的主要目的是允許對魔數進行更靈活的匹配。有時候,二進位制檔案的魔數中的某些位是可變的或不重要的,但其他位則必須匹配。通過定義一個掩碼來遮蔽那些不重要的位,可以提高匹配的靈活性。
與運算規則如下:
如果你想要通過按位元與運算得到0表示不匹配,可以將掩碼中需要匹配的位設定為1,不需要匹配的位設定為0。這樣,在按位元與運算時,如果魔數的對應位與掩碼的對應位都為1,結果位為1,否則為0。如果按位元與運算的結果為0,表示魔數與掩碼不匹配。
範例1:最終的按位元與運算結果與原始的魔數值相同,即沒有發生變化。
範例2:最終的按位元與運算結果後6位全部為0,則後6位不進行比較
1.取登入檔魔數
使用 cat
命令讀取 /proc/sys/fs/binfmt_misc/
目錄下的相關檔案。每個登入檔都以檔案的形式存在該目錄中,檔名代表了對應的架構。例如,/proc/sys/fs/binfmt_misc/arm_64,
表示 ARM 架構的登入檔。
2.對比
案例1:如下圖,因為與運算結果與登入檔魔數相同,則可以呼叫到對應登入檔中interpreter對應的解析器檔案。
案例2:如下圖,與運算結果的非0位與登入檔魔數結果相同, 則可以呼叫到對應登入檔中interpreter對應的解析器檔案。