国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

修改嵌入式 ARM Linux 內(nèi)核映像中的文件系統(tǒng)

這篇具有很好參考價(jià)值的文章主要介紹了修改嵌入式 ARM Linux 內(nèi)核映像中的文件系統(tǒng)。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

zImage 是編譯內(nèi)核后在 arch/arm/boot 目錄下生成的一個(gè)已經(jīng)壓縮過的內(nèi)核映像。通常我們不會(huì)使用編譯生成的原始內(nèi)核映像 vmlinux,因其體積很大。因此,zImage 是我們最常見的內(nèi)核二進(jìn)制,可以直接嵌入到固件,也可以直接使用 qemu 進(jìn)行調(diào)試。當(dāng)然,在 32 位嵌入式領(lǐng)域還能見到 uImage,這是在 zImage 首位增加 64B 的頭,描述映像文件類型、加載位置、內(nèi)核大小等信息。

有些嵌入式設(shè)備的文件系統(tǒng)直接嵌入到內(nèi)核中,這種內(nèi)置文件系統(tǒng)的機(jī)制被稱為 ramdisk/initramfs,如果只是使用 extract-vmlinux/binwalk 解壓固件,釋放大量 shell 腳本和配置文件,是很容易做到的,但是如果想要修改這些文件,并進(jìn)行重新打包,生成實(shí)際設(shè)備可以運(yùn)行的 zImage 內(nèi)核映像可能不是那么簡單。

本文將演示如何在 32位 ARM zImage 中替換 piggy 中的文件系統(tǒng),我們以 openWRT 的某個(gè)版本固件為例進(jìn)行講解。

初始設(shè)置

下載 OpenWRT ARM zImage-initramfs 映像,這是一個(gè)基于 ramdisk 的典型內(nèi)核映像,不需要額外的文件系統(tǒng),實(shí)際上也無法使用 binwalk 直接提取我們想要修改的操作系統(tǒng)啟動(dòng)提示信息。

$ wget https://downloads.openwrt.org/releases/17.01.0/targets/armvirt/generic/lede-17.01.0-r3205-59508e3-armvirt-zImage-initramfs -O zImage-initramfs
$ openssl dgst zImage-initramfs
SHA256(zImage-initramfs)= 5ad269e95b2db16aea3794dd0e97dabb6f9712184d79b0764bb10a810f8d7639

使用 qemu 啟動(dòng)

$ qemu-system-arm -M virt -m 1024 -kernel zImage-initramfs -append "console=ttyAMA0" -nographic

最小 shell 控制臺(tái)

BusyBox v1.25.1 () built-in shell (ash)

     _________
    /        /\      _    ___ ___  ___
   /  LE    /  \    | |  | __|   \| __|
  /    DE  /    \   | |__| _|| |) | _|
 /________/  LE  \  |____|___|___/|___|                      lede-project.org
 \        \   DE /
  \    LE  \    /  -----------------------------------------------------------
   \  DE    \  /    Reboot (17.01.0, r3205-59508e3)
    \________\/    -----------------------------------------------------------

=== WARNING! =====================================
There is no root password defined on this device!
Use the "passwd" command to set up a new password
in order to prevent unauthorized SSH logins.
--------------------------------------------------
root@LEDE:/#

查看內(nèi)核版本,找到對應(yīng)的源碼,因?yàn)槲覀冇锌赡軙?huì)根據(jù)內(nèi)核解壓縮的源碼,調(diào)整重打包方式。

root@LEDE:/# uname -a
Linux LEDE 4.4.50 #0 SMP Mon Feb 20 17:13:44 2017 armv7l GNU/Linux

找到相應(yīng)版本的內(nèi)核,推薦在線瀏覽 https://elixir.bootlin.com/linux/v4.4.50/source/,版本匹配也沒有那么重要,因?yàn)閮?nèi)核解壓縮的核心代碼其實(shí)一直以來變化不大,位于源碼目錄 arch/arm/boot/compressed。

提取 Piggy

使用 binwalk 分析固件,就像我們在開始說的,binwalk 可能可以提取其中的配置文件,也有可能無法提取,即使提取,也都是歸在一個(gè)文件夾下,并沒有常見的 squashfs 文件系統(tǒng)

$ binwalk zImage-initramfs         

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
0             0x0             Linux kernel ARM boot executable zImage (little-endian)
15400         0x3C28          xz compressed data
15632         0x3D10          xz compressed data

毫無疑問,固件開始部分是可以直接運(yùn)行的未經(jīng)壓縮的用于解壓內(nèi)核的 head.omisc.o,使用 dd 命令提取該部分進(jìn)行分析,或者直接將整個(gè)固件拖入 IDA,選擇 arm,并只反匯編固件頭部部分。
修改嵌入式 ARM Linux 內(nèi)核映像中的文件系統(tǒng)
運(yùn)行上述 IDC 腳本,即可得到解壓內(nèi)核代碼部分??梢詫Ρ葍?nèi)核源碼,我們需要找到固件中,內(nèi)核壓縮映像文件的起始地址和結(jié)束地址。piggy.S 使用 incbin 關(guān)鍵字引入 piggy.gz。其中全局變量 input_datainput_data_end 分別是 piggy 的起始地址和結(jié)束地址。

	.section .piggydata,#alloc
	.globl	input_data
input_data:
	.incbin	"arch/arm/boot/compressed/piggy.gz"
	.globl	input_data_end
input_data_end:

毫無疑問,內(nèi)核解壓代碼需要這些全局變量,這樣才能夠解壓真正壓縮的內(nèi)核。

putstr("Uncompressing Linux...");
ret = do_decompress(input_data, input_data_end - input_data,
    output_data, error);
if (ret)
    error("decompressor returned an error");
else
    putstr(" done, booting the kernel.\n");

IDA 反編譯的固件頭部,尋找 Uncompressing Linux...,對比源碼很容易知道 piggy 的實(shí)際偏移。
修改嵌入式 ARM Linux 內(nèi)核映像中的文件系統(tǒng)
繼續(xù)分析匯編,找到全局變量存放的位置
修改嵌入式 ARM Linux 內(nèi)核映像中的文件系統(tǒng)
對比原始固件二進(jìn)制時(shí),發(fā)現(xiàn)壓縮結(jié)束 magic YZ 后面多出了 4B 數(shù)據(jù),這 4B 其實(shí)是原始未經(jīng)壓縮的xz大小。實(shí)際上 YZ 才是壓縮文件的結(jié)尾。因此使用 xz 解壓時(shí),估計(jì)會(huì)出現(xiàn) Unexpected end of input 錯(cuò)誤,只需要添加參數(shù)即可。
修改嵌入式 ARM Linux 內(nèi)核映像中的文件系統(tǒng)
dd 截取 piggy

$ dd if=zImage-initramfs of=vmlinux.xz bs=1 skip=$[0x3d10] count=$[0x2bb404]                     
2864132+0 records in
2864132+0 records out
2864132 bytes (2.9 MB, 2.7 MiB) copied, 13.595 s, 211 kB/s

解壓 piggy

$ unxz --verbose --single-stream < vmlinux.xz > /tmp/vmlinux
  100 %   2,797.0 KiB / 8,883.5 KiB = 0.315 

我們發(fā)現(xiàn)解壓后的 vmlinux 內(nèi)核映像大小果然是 28 c3 8a 00

$ ls -l /tmp/vmlinux                
-rw-r--r-- 1 kali kali 9096744 Dec 20 04:04 /tmp/vmlinux

$ python -c "print(0x8ace28)"
9096744

重打包

修改 vmlinux,例如修改啟動(dòng)界面字符串,找到需要修改信息的地址。這些信息顯示 initramfs 嵌入在解壓后的 vmlinux 中,該部分由一個(gè)沒有校驗(yàn)和的未經(jīng)壓縮的 CPIO 文檔組成(binwalk 可以識(shí)別)。

$ strings -t x /tmp/vmlinux | grep "WARNING\!" 
 76ac3a === WARNING! =====================================

使用 hexedit 編輯,回車鍵可快速定位此地址,tab 可切換 16 進(jìn)制 / ASCII 碼,ctrl+x 保存并退出。

0076AC3C   3D 20 57 41  52 4E 49 4E  47 21 20 4D  6F 64 69 66  69 63 61 74  = WARNING! Modificat
0076AC50   69 6F 6E 20  73 75 63 63  65 65 64 65  64 21 21 21  3D 3D 3D 3D  ion succeeded!!!====

如果直接使用 xz 壓縮,我們會(huì)發(fā)現(xiàn)壓縮后大小大于原始?jí)嚎s文件 0x2bb404(2864132),通過 Linux 源碼可以找到壓縮命令位于 xz_wrap.sh

xz --check=crc32 --arm --lzma2=$LZMA2OPTS,dict=32MiB

僅僅使用上述命令壓縮還是不夠的,壓縮后的文件仍然較大,nice 可以達(dá)到最大壓縮比。最終壓縮命令如下

$ xz --check=crc32 --arm --lzma2=,dict=32MiB,nice=128 < /tmp/vmlinux > /tmp/vmlinux.xz             

$ ls -l /tmp/vmlinux.xz 
-rw-r--r-- 1 kali kali 2863832 Dec 20 04:26 /tmp/vmlinux.xz

顯然小于原始?jí)嚎s文件,符合要求。要記住,piggy 末尾 4 字節(jié)存放原始文件大小,而我們只是修改啟動(dòng)信息,并沒有改變原始 vmlinux 大小

$ echo -en "\x28\xce\x8a\x00" >> /tmp/vmlinux.xz # piggy.gz

替換 piggy

$ cp zImage-initramfs zImage-initramfs-warnmod
$ dd if=/tmp/vmlinux.xz of=zImage-initramfs-warnmod bs=1 seek=$[0x3d10] conv=notrunc
2863836+0 records in
2863836+0 records out
2863836 bytes (2.9 MB, 2.7 MiB) copied, 11.1713 s, 256 kB/s

修改內(nèi)核解壓代碼中的 piggy 結(jié)束地址,input_data_end = hex(0x3d10+2863836) = 0x2befec,原始大小為 0x2bf114

002BF124   EC EF 2B 00  68 F5 2B 00  10 3D 00 00  64 F5 2B 00  64 F1 2B 00  ..+.h.+..=..d.+.d.+.

嘗試啟動(dòng)內(nèi)核,修改成功!

BusyBox v1.25.1 () built-in shell (ash)

     _________
    /        /\      _    ___ ___  ___
   /  LE    /  \    | |  | __|   \| __|
  /    DE  /    \   | |__| _|| |) | _|
 /________/  LE  \  |____|___|___/|___|                      lede-project.org
 \        \   DE /
  \    LE  \    /  -----------------------------------------------------------
   \  DE    \  /    Reboot (17.01.0, r3205-59508e3)
    \________\/    -----------------------------------------------------------

=== WARNING! Modification succeeded!!!============
There is no root password defined on this device!
Use the "passwd" command to set up a new password
in order to prevent unauthorized SSH logins.
--------------------------------------------------
root@LEDE:/# 

小結(jié)

如果需要增加而不是修改 initramfs 的內(nèi)容,可能就沒那么簡單了。因?yàn)槟阈枰獪?zhǔn)確掌握固件的每一個(gè)部分,而且需要注意的是 piggy 的 inflated size 也就是 xz 實(shí)際大小其實(shí)是 input_data_end - 4,這一部分代碼位于 misc.cLC0 對象

LC0:	.word	LC0			@ r1
		.word	__bss_start		@ r2
		.word	_end			@ r3
		.word	_edata			@ r6
		.word	input_data_end - 4	@ r10 (inflated size location)
		.word	_got_start		@ r11
		.word	_got_end		@ ip
		.word	.L_user_stack_end	@ sp
		.word	_end - restart + 16384 + 1024*1024
		.size	LC0, . - LC0

以本文中的固件為例,piggy 實(shí)際大小 0x2bf110,位于固件偏移 0x258,因此如果修改了 piggy 的大小,還需要修改此處地址對應(yīng)的數(shù)據(jù)。

修改嵌入式 ARM Linux 內(nèi)核映像中的文件系統(tǒng)
當(dāng)然,實(shí)際還需要考慮各個(gè)部分的偏移,可參考 https://gist.github.com/jamchamb/243e6973aeb5c9a2e302a4d4f57f16e1

如果你需要增加內(nèi)核內(nèi)容并且改變了原有內(nèi)核大小,而不只是簡單修改,則需要掌握內(nèi)核解壓縮的詳細(xì)流程,在這里,我們只將內(nèi)核壓縮映像生成流程簡單呈現(xiàn)如下,詳細(xì)流程可參見

vmlinux
   │
   │ -R.note-R.comment
   │
   └─arch/arm/boot/Image
       │
       │ gzip -f -9 < Image > piggy.gz
       │
       └─arch/arm/boot/compressed/piggy.gz
           │
           │ piggy.S 直接引入piggy.gz
           │
           └─arch/arm/boot/compressed/piggy.o
               │
               │ +head.o
               │ +misc.o
               │
               └─arch/arm/boot/compressed/vmlinux
                   │
                   │ -debuginfo
                   │
                   └─arch/arm/boot/compressed/zImage

內(nèi)核代碼中的 head.Smisc.c 用于內(nèi)核自解壓,所以,如果我們需要直接通過修改內(nèi)核二進(jìn)制的方式打 patch,則需要了解內(nèi)核壓縮和解壓的流程。從上圖也可以看出來,piggy 就是壓縮過的內(nèi)核的一部分,其實(shí)也是內(nèi)核的主體部分。

參考文獻(xiàn)

Modifying Embedded Filesystems in ARM Linux zImages
Linux內(nèi)核源碼分析–內(nèi)核啟動(dòng)之zImage自解壓過程
Linux2.6 內(nèi)核啟動(dòng)分析
initramfs 在內(nèi)核中的作用與實(shí)現(xiàn)文章來源地址http://www.zghlxwxcb.cn/news/detail-499523.html

到了這里,關(guān)于修改嵌入式 ARM Linux 內(nèi)核映像中的文件系統(tǒng)的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • ARM+LINUX嵌入式學(xué)習(xí)路線

    ARM+LINUX嵌入式學(xué)習(xí)路線

    嵌入式學(xué)習(xí)是一個(gè)循序漸進(jìn)的過程,如果是希望向嵌入式軟件方向發(fā)展的話,目前最常見的是嵌入式Linux方向,關(guān)注這個(gè)方向,大概分3個(gè)階段: 1、嵌入式linux上層應(yīng)用,包括QT的GUI開發(fā) 2、嵌入式linux系統(tǒng)開發(fā) 3、嵌入式linux驅(qū)動(dòng)開發(fā) 嵌入式目前主要面向的幾個(gè)操作系統(tǒng)是,

    2024年02月02日
    瀏覽(27)
  • 嵌入式中的MCU、ARM、DSP、FPGA

    嵌入式中的MCU、ARM、DSP、FPGA

    目錄 “角色扮演” MCU ARM 特點(diǎn) DSP 特點(diǎn) FPGA 特點(diǎn) 應(yīng)用 ? ????????MCU(Microcontroller?Unit)、ARM(Advanced?RISC?Machine)、DSP(Digital?Signal?Processor)和FPGA(Field-Programmable?Gate?Array)都是在嵌入式系統(tǒng)中常見的硬件組件,它們在嵌入式系統(tǒng)中扮演不同的角色。 ????????1.?

    2024年02月08日
    瀏覽(67)
  • 嵌入式Linux底層系統(tǒng)開發(fā) +系統(tǒng)移植+內(nèi)核文件系統(tǒng)(基礎(chǔ))

    嵌入式Linux底層系統(tǒng)開發(fā) +系統(tǒng)移植+內(nèi)核文件系統(tǒng)(基礎(chǔ))

    搭建交叉編譯開發(fā)環(huán)境 bootloader的選擇和移植 kernel的配置、編譯、移植和調(diào)試 根文件系統(tǒng)的制作 前兩個(gè)要點(diǎn)通常芯片廠家提供。后邊兩個(gè)要點(diǎn)是公司的工作重點(diǎn)。 學(xué)習(xí)方法:先整體后局部,層層推進(jìn) 如何編譯—如何添加命令和功能—如何定義自己的開發(fā)板。 移植的基本步

    2024年02月03日
    瀏覽(101)
  • 【嵌入式Linux內(nèi)核驅(qū)動(dòng)】SPI子系統(tǒng) | 硬件原理 | 應(yīng)用編程 | 內(nèi)核驅(qū)動(dòng) | 總體框架

    【嵌入式Linux內(nèi)核驅(qū)動(dòng)】SPI子系統(tǒng) | 硬件原理 | 應(yīng)用編程 | 內(nèi)核驅(qū)動(dòng) | 總體框架

    1.1 SPI通信協(xié)議 SPI(Serial Peripheral Interface)是由Motorola公司開發(fā)的一種通用數(shù)據(jù)總線 四根通信線:SCK(Serial Clock)、MOSI(Master Output Slave Input)、MISO(Master Input Slave Output)、SS(Slave Select) 同步,全雙工 支持總線掛載多設(shè)備(一主多從) 1.2 硬件連接 多NSS獨(dú)立片選方式 菊花

    2024年02月16日
    瀏覽(28)
  • Qt固件映像 Raspberry Pi 嵌入式C++(Qt)編程

    在我們的游戲中,我們有一個(gè)槳、一個(gè)球和三十塊磚。 計(jì)時(shí)器用于創(chuàng)建游戲周期。 我們不處理角度,我們只是改變方向:上、下、左、右。 Qt5 庫是為創(chuàng)建計(jì)算機(jī)應(yīng)用程序而開發(fā)的。盡管如此,它也可以用來創(chuàng)建游戲。開發(fā)計(jì)算機(jī)游戲是了解有關(guān) Qt5 的更多信息的好方法。

    2024年01月19日
    瀏覽(24)
  • 嵌入式Linux驅(qū)動(dòng)開發(fā) 02:將驅(qū)動(dòng)程序添加到內(nèi)核中

    嵌入式Linux驅(qū)動(dòng)開發(fā) 02:將驅(qū)動(dòng)程序添加到內(nèi)核中

    在上一篇文章 《嵌入式Linux驅(qū)動(dòng)開發(fā) 01:基礎(chǔ)開發(fā)與使用》 中我們已經(jīng)實(shí)現(xiàn)了最基礎(chǔ)的驅(qū)動(dòng)功能。在那篇文章中我們的驅(qū)動(dòng)代碼是獨(dú)立于內(nèi)核代碼存放的,并且我們的驅(qū)動(dòng)編譯后也是一個(gè)獨(dú)立的模塊。在實(shí)際使用中將驅(qū)動(dòng)代碼放在內(nèi)核代碼中,并將驅(qū)動(dòng)編譯到內(nèi)核中也是比較

    2023年04月09日
    瀏覽(51)
  • 【嵌入式Linux】編譯應(yīng)用和ko內(nèi)核模塊Makefile使用記錄

    【嵌入式Linux】編譯應(yīng)用和ko內(nèi)核模塊Makefile使用記錄

    在Makefile中,變量的賦值可以使用以下幾種方式: = :最基本的賦值符號(hào),表示簡單的延遲展開(lazy expansion)方式。變量的值將會(huì)在使用變量的時(shí)候進(jìn)行展開。 := :立即展開(immediate expansion)的賦值方式。變量的值在賦值的時(shí)候立即展開,并且在后續(xù)的使用中不再改變。

    2024年02月08日
    瀏覽(24)
  • ARM/Linux嵌入式面經(jīng)(二):芯片原廠

    UART(Universal Asynchronous Receiver/Transmitter,通用異步收發(fā)傳輸器)是一種用于串行通信的協(xié)議,它使用一對傳輸線(TX和RX)進(jìn)行雙向通信。 UART通信通過串行傳輸數(shù)據(jù),數(shù)據(jù)以字節(jié)為單位進(jìn)行傳輸。每個(gè)字節(jié)由起始位、數(shù)據(jù)位、校驗(yàn)位和停止位組成。 當(dāng)模塊向UART發(fā)送數(shù)據(jù)信息時(shí)

    2024年04月10日
    瀏覽(37)
  • 【ARM 嵌入式 編譯系列 3.6 -- 刪除lib中的某個(gè)文件】

    請閱讀 【嵌入式開發(fā)學(xué)習(xí)必備專欄 之 ARM GCC 編譯專欄】 比如,如果要?jiǎng)h除 libc.a 靜態(tài)庫中的特定對象文件并重新使用這個(gè)靜態(tài)庫,在終端中可以使用 ar 命令。 ar 是一個(gè)歸檔工具,它可以創(chuàng)建、修改、提取以及列出歸檔庫文件(如 .a 文件)的內(nèi)容。 下面是刪除 libc.a 中指定

    2024年01月25日
    瀏覽(50)
  • 使用VSCode clangd插件進(jìn)行l(wèi)inux內(nèi)核代碼閱讀和嵌入式開發(fā)

    使用VSCode clangd插件進(jìn)行l(wèi)inux內(nèi)核代碼閱讀和嵌入式開發(fā)

    在進(jìn)行 Linux 內(nèi)核代碼閱讀和嵌入式開發(fā)時(shí),選擇合適的開發(fā)工具至關(guān)重要。VSCode 是一個(gè)流行的跨平臺(tái)編輯器,并且它的擴(kuò)展生態(tài)系統(tǒng)非常強(qiáng)大。在這篇博客中,我們將介紹如何使用 VSCode Clangd 插件來提高 Linux 內(nèi)核代碼的閱讀和嵌入式開發(fā)效率。 Clangd 是一個(gè)基于 Clang 的語言

    2024年02月09日
    瀏覽(30)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包