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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

GPS 校验和 代码_Linux recovery 移除签名校验

發布時間:2024/8/23 linux 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 GPS 校验和 代码_Linux recovery 移除签名校验 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

原創作者:王銳,多年 Linux 系統、龍芯平臺移植與優化研發經驗,Linux Contributor、Mozillian。

背景

某個設備配套的刷機程序是個 Linux recovery kernel,刷機過程會先從U盤加載刷機腳本,僅在簽名校驗通過后才執行腳本。本文記錄了分析和移除簽名校驗的方法。

分析

刷機程序是一個 bzImage 文件,從啟動的輸出來看,內部包含了一個 initrd,在 initrd 中實現了讀取U盤中的腳本和簽名校驗過程。

查看initrd內容

通過增加啟動參數(cmdline)rdinit=/bin/sh,可以使 Kernel 啟動后執行 /bin/sh,而不是默認的 /init 程序,有了命令行接口后,就可以查看 initrd 的內容。

#?busybox?find?/#?cat?/init

從 initrd 的內容來看,由 /init 調用 gpg2 對 U 盤中的刷機腳本執行簽名校驗,只有公鑰集成在 initrd 中,沒有私鑰。

到這一步,我們已經清楚了簽名校驗的實現方法,并且也能使啟動過程進入受控的命令行交互狀態,其實已經可以手工操作跳過簽名過程來刷機。

修改

每次手工操作的確太麻煩,那就來移除 initrd 中的簽名校驗過程吧。

從 bzImage 的結構來看,要想修改 initrd,先要從 bzImage 中提取出 vmlinux,再從 vmlinux 中提取出 initrd。

1. 提取 vmlinux

從 bzImage 中提取 vmlinux 比較簡單,有現成的工具,位于 Linux 源代碼中 scripts/extract-vmlinux

./scripts/extract-vmlinux?bzImage?>?vmlinux

2. 提取 initrd

initrd 的格式可以是 cpio archive,也可以是 gzip、bzip2、lzma、xz 或 lzo 壓縮的,先用 binwalk 掃描一遍。

binwalk?vmlinux
DECIMAL???????HEXADECIMAL?????DESCRIPTION
--------------------------------------------------------------------------------
0?????????????0x0?????????????ELF,?32-bit?LSB?executable,?Intel?80386,?version?1?(SYSV)
3641536???????0x3790C0????????Linux?kernel?version?"2.6.39?(ubuntu@ubuntu)?(gcc?version?4.9.3?20150311?(prerelease)?(crosstool-NG?1.20.0)?)?#24?SMP?Fri?Jun?7?14:32:37?CST?2019"
3922304???????0x3BD980????????CRC32?polynomial?table,?little?endian
4318976???????0x41E700????????Unix?path:?/home/ubuntu/ce5300/barcelona_kernel/arch/x86/include/asm/desc.h
4321256???????0x41EFE8????????Unix?path:?/home/ubuntu/ce5300/barcelona_kernel/arch/x86/include/asm/i387.h
4322244???????0x41F3C4????????Unix?path:?/home/ubuntu/ce5300/barcelona_kernel/arch/x86/include/asm/processor.h
4323964???????0x41FA7C????????Unix?path:?/x86/kernel/cpu/perf_event_intel.c
4324152???????0x41FB38????????Unix?path:?/x86/kernel/cpu/perf_event_intel_ds.c
4325960???????0x420248????????Unix?path:?/x86/kernel/cpu/mcheck/mce.c
4326820???????0x4205A4????????Unix?path:?/x86/kernel/cpu/mcheck/mce_intel.c
4327124???????0x4206D4????????Unix?path:?/x86/kernel/cpu/mcheck/therm_throt.c
4328480???????0x420C20????????Unix?path:?/x86/kernel/cpu/mtrr/generic.c
4329752???????0x421118????????Unix?path:?/x86/kernel/cpu/mtrr/cleanup.c
4329832???????0x421168????????Unix?path:?/x86/kernel/cpu/perfctr-watchdog.c
4336148???????0x422A14????????Unix?path:?/x86/kernel/apic/apic_noop.c
4336572???????0x422BBC????????Unix?path:?/x86/kernel/apic/io_apic.c
4343276???????0x4245EC????????Unix?path:?/home/ubuntu/ce5300/barcelona_kernel/arch/x86/include/asm/fixmap.h
4347540???????0x425694????????Unix?path:?/x86/kernel/cpu/common.c
4347663???????0x42570F????????Unix?path:?/x86/kernel/cpu/vmware.c
4347911???????0x425807????????Unix?path:?/x86/kernel/cpu/intel.c
4350475???????0x42620B????????Unix?path:?/x86/kernel/acpi/boot.c
4352464???????0x4269D0????????Unix?path:?/x86/kernel/apic/apic.c
4352799???????0x426B1F????????Unix?path:?/x86/kernel/apic/ipi.c
4367224???????0x42A378????????Unix?path:?/home/ubuntu/ce5300/barcelona_kernel/arch/x86/include/asm/mmu_context.h
4374285???????0x42BF0D????????Unix?path:?/sys/kernel/debug/tracing/trace_clock
4383716???????0x42E3E4????????Unix?path:?/home/ubuntu/ce5300/barcelona_kernel/arch/x86/include/asm/pgalloc.h
4384752???????0x42E7F0????????Unix?path:?/home/ubuntu/ce5300/barcelona_kernel/arch/x86/include/asm/dma-mapping.h
4513864???????0x44E048????????xz?compressed?data
4514016???????0x44E0E0????????Unix?path:?/home/ubuntu/ce5300/barcelona_kernel/arch/x86/include/asm/syscall.h
4533558???????0x452D36????????Unix?path:?/Buffer/String/Package/Ref/Ddb],?found?[%s]?%p
4612622???????0x46620E????????Unix?path:?/sys/kernel/debug/dri
4614914???????0x466B02????????Unix?path:?/sys/kernel/debug/dri.
4618302???????0x46783E????????Unix?path:?/sys/kernel/debug/dri/%s/%s
4618366???????0x46787E????????Unix?path:?/sys/kernel/debug/dri/%s
4618509???????0x46790D????????Unix?path:?/sys/kernel/debug/dri.
4661219???????0x471FE3????????Unix?path:?/S70/S75/505V/F505/F707/F717/P8
4665828???????0x4731E4????????Unix?path:?/usr/include/asm/ioctls.h
4678778???????0x47647A????????Copyright?string:?"Copyright(c)?Pierre?Ossman"
4690408???????0x4791E8????????Unix?path:?/x86/oprofile/../../../drivers/oprofile/event_buffer.c
5242204???????0x4FFD5C????????ELF,?32-bit?LSB?shared?object,?Intel?80386,?version?1?(SYSV)
5243884???????0x5003EC????????ELF,?32-bit?LSB?shared?object,?Intel?80386,?version?1?(SYSV)

在 vmlinux 文件偏移 0x44E048 處,有一個疑似 xz 壓縮文檔,提取出來嘗試解壓。

if=vmlinux?

唯一的疑似壓縮文檔解壓出錯了,這個方法行不通,那就換另外一個方法吧。:)

2.1. 分析啟動過程中的 initrd 加載

從 bzImage 中提取出的 vmlinux 是 strip 掉 symbols 的,不便于反匯編后定位函數,我們先提取該內核的 /proc/kallsyms,直接在 rdinit=/bin/sh 啟動的命令行中 cat /proc/kallsyms 就可以了。

有了 symbols 后,首先我們要找 populate_rootfs 函數,從匯編代碼中獲得__initramfs_start 和 __initramfs_size。

c14d03b1?t?populate_rootfs
c14d0129?t?unpack_to_rootfs
c14d03b1:????55??????????????????????push???%ebp
c14d03b2:????b8?6c?59?51?c1??????????mov????$0xc151596c,%eax
c14d03b7:????57??????????????????????push???%edi
c14d03b8:????56??????????????????????push???%esi
c14d03b9:????53??????????????????????push???%ebx
c14d03ba:????8d?64?24?b8?????????????lea????-0x48(%esp),%esp
c14d03be:????8b?15?70?6f?8e?c1???????mov????0xc18e6f70,%edx
c14d03c4:????e8?60?fd?ff?ff??????????call???0xc14d0129

在 0xc14d03c4 處調用了0xc14d0129 這個函數,也就是 unpack_to_rootfs,傳遞了兩個參數,%eax 就是 __initramfs_start,值是 0xc151596c,%edx 就是 __initramfs_size,%edx 的值是存儲在地址 0xc18e6f70 處的。

有了 __initramfs_start 的程序地址后,只需要轉換為 vmlinux 文件的偏移地址后,就可以提取出 initrd 的內容了。映射關系可以通過 readelf 獲得。

readelf?

程序地址 0xc151596c 和 0xc18e6f70 都隸屬于 .init.data section,文件偏移計算:

Offset?=?Addr?-?Section?Base?Addr?+?Section?Base?Offset

0xc151596c:?0xc151596c?-?0xc14f3b40?+?0x4f4b40?=?0x51696c
0xc18e6f70:?0xc18e6f70?-?0xc14f3b40?+?0x4f4b40?=?0x8e7f70
2.2. 提取 initrd

提取 initrd,首先需要知道 __initramfs_size,該值位于 vmlinux 文件的 0x8e7f70 偏移處,類型是 unsigned long。

08e7f70?if=vmlinux?
2.3. 分析 initrd 格式

雖然提取出了 initrd,但不是已知的格式,內核支持的格式都有確定的 magic number:

static?hexdump?initrd

0000000?6fde?40fe?2ee2?5fbf?27e3?e8fe?fb88?6a72
0000010?b649?904e?378a?49f4?057f?69b4?f9d9?4d43
0000020?7a8a?fe5b?1ba5?2442?3ea5?365e?7945?fd49
0000030?9afb?fca6?143c?b30d?eff8?a715?0982?424c
...

既然這個內核能執行,說明它有一種未知的加載方法,那就看看它是怎么做的吧,我們需要找到 unpack_to_rootfs 函數。

c14d0129?t?unpack_to_rootfs
c1001410?T?aes_key_schedule_128
c10017c0?T?aes_decrypt_128
c14d0129:????55??????????????????????push???%ebp
c14d012a:????b9?11?00?00?00??????????mov????$0x11,%ecx
c14d012f:????89?d5???????????????????mov????%edx,%ebp
c14d0131:????57??????????????????????push???%edi
c14d0132:????56??????????????????????push???%esi
c14d0133:????be?ce?c6?41?c1??????????mov????$0xc141c6ce,%esi
c14d0138:????53??????????????????????push???%ebx
c14d0139:????89?c3???????????????????mov????%eax,%ebx
c14d013b:????8d?a4?24?30?ff?ff?ff????lea????-0xd0(%esp),%esp
c14d0142:????8d?7c?24?0f?????????????lea????0xf(%esp),%edi
c14d0146:????8d?54?24?20?????????????lea????0x20(%esp),%edx
c14d014a:????8d?44?24?0f?????????????lea????0xf(%esp),%eax
c14d014e:????f3?a4???????????????????rep?movsb?%ds:(%esi),%es:(%edi)
c14d0150:????e8?bb?12?b3?ff??????????call???0xc1001410?//?aes_key_schedule_128
c14d0155:????31?f6???????????????????xor????%esi,%esi
c14d0157:????39?ee???????????????????cmp????%ebp,%esi
c14d0159:????73?13???????????????????jae????0xc14d016e
c14d015b:????8d?14?33????????????????lea????(%ebx,%esi,1),%edx
c14d015e:????8d?44?24?20?????????????lea????0x20(%esp),%eax
c14d0162:????89?d1???????????????????mov????%edx,%ecx
c14d0164:????83?c6?10????????????????add????$0x10,%esi
c14d0167:????e8?54?16?b3?ff??????????call???0xc10017c0?//?aes_decrypt_128
c14d016c:????eb?e9???????????????????jmp????0xc14d0157
c14d016e:????a1?7c?74?93?c1??????????mov????0xc193747c,%eax

果然是 unpack_to_rootfs 被修改了,里面調用了 aes_key_schedule_128 和 aes_decrypt_128 兩個函數,加入了 AES128 解密過程,這說明我們提取出來的 initrd 是被加密的。
AES128 是對稱加密,如果沒有使用加硬件密鑰不管,極有可能是硬編碼在程序中的,試試提出它。從匯編代碼中看,在棧上構建了一個 crypto 上下文,部分內容是從地址 0xc141c6ce 復制過來的,這會不會就是密鑰呢?

041d6b2?

一個 16 字節的數據,與字符串混編在一起,極有可能是 128 位的密鑰。

2.4. 解密 initrd
-128-ecb?-

經常一些嘗試,使用 AES-128-ECB 解密成功,還原出了 initrd.img,實際為 cpio 格式。

2.5. 修改 initrd
cd?rootfs
2.6. 寫回 initrd

從 unpack_to_rootfs 匯編代碼可以看出,aes_decrypt 將明文寫到了對應密文的相同內存空間,我們可以修改代碼來跳過解密過程,這樣就可以直接把 initrd-noverify.img 寫回到 vmlinux 中,而不需要再加密來找麻煩了。

55??????????????????????

程序地址 0xc14d0155 處的代碼修改為 jmp 0xc14d016e,這樣就可以直接跳過 aes_decrypt 過程了。如果不懂 x86 的 instruction encoding 方法,有個簡單的方法可以產生正確的 jmp 0xc14d016e 編碼。

????.text
????.globl?_start
_start:
????jmp????0xc14d016e
gcc?-m32?-o?jmp?-nostdlib?-Wl,-Ttext=0xc14d0155?jmp.S
objdump?-d?jmp
c14d0155?<_start>:c14d0155:????e9?14?00?00?00??????????jmp????c14d016e?<_start>

現在可以寫回 initrd-noverify.img 了

if=initrd-noverify.img?

還需要編輯 vmlinux 文件 0x8e7f70 偏移處的 __initramfs_size,改為 initrd-noverify.img 的長度。

2.7. 寫回 vmlinux

extract-vmlinux 腳本也是通過搜索 magic number 和嘗試解壓來提取 vmlinux 的,以此就可以獲得 vmlinux 在 bzImage 中的偏移,參考寫回 initrd 類似的方法,可以將 vmlinux 寫回至 bzImage 原來的偏移位置。

不幸的是,修改后的 bzImage 無法啟動,啟動參數加入 earlyprintk=ttyS0,115200 后,可以看到 LZMA data is corrupt 的錯誤。

bzImage 的解壓縮過程是從 input addr 讀取壓縮數據,解壓后寫到 output addr,而 output addr 與 input addr 之間的空間是不夠完整存放解壓后的數據的,之所以沒有問題是因為這個 input addr 與 output addr 之間的差值是經過精心計算的,能夠保證覆蓋發生時,被覆蓋的數據已完成解壓。

正是因為這個原因,我們修改后的 vmlinux 由于內容變化,壓縮比也發現了變化,已不能適應之前的比例計算出的差值,有兩種方法解決這個問題:1. 將 output addr 向低地址方向移動。2. 將 input addr 向高地址方向移動。

從反匯編 bzImage 的代碼來看,output addr 在之后還有校驗,相對修改 input addr更為復雜。

objdump?-D?-b?binary?-mi386?bzImage
...
??5d91d8:????8d?ab?00?10?bf?ff???????lea????-0x337000(%ebx),%ebp
??5d91de:????55??????????????????????push???%ebp????????????????//?output?address
??5d91df:????68?f5?d1?4f?00??????????push???$0x5d5747???????????//?input?length
??5d91e4:????8d?83?62?00?00?00???????lea????0x62(%ebx),%eax?????//?input?address
??5d91ea:????50??????????????????????push???%eax
??5d91eb:????8d?83?40?7b?5d?00???????lea????0x5d7b40(%ebx),%eax?//?heap
??5d91f1:????50??????????????????????push???%eax
??5d91f2:????56??????????????????????push???%esi????????????????//?rmode
??5d91f3:????e8?14?04?00?00??????????call???0x5d960c
??5d91f8:????83?c4?14????????????????add????$0x14,%esp
??5d91fb:????31?db???????????????????xor????%ebx,%ebx
??5d91fd:????ff?e5???????????????????jmp????*%ebp
...

本文轉載自作者的博客,歡迎移步本文文末左下方點擊 “”。

掃 碼?關 注 我?們? ?

再 + 好 友 tinylab

進 泰 曉?技 術?群

泰? 曉? 科? 技


關注“泰曉科技”!點“在看”

總結

以上是生活随笔為你收集整理的GPS 校验和 代码_Linux recovery 移除签名校验的全部內容,希望文章能夠幫你解決所遇到的問題。

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

主站蜘蛛池模板: 免费一级黄色大片 | 国产99久一区二区三区a片 | 97视频在线观看免费 | 国产绿帽一区二区三区 | 中文字幕一二 | 无码日韩精品一区二区 | 国产精品jizz在线观看软件 | 国产亚洲欧美在线视频 | 欧美在线网址 | 九九视频这里只有精品 | 亚洲永久无码精品一区二区 | 国内免费毛片 | 中文字幕日产 | 国产精品二区一区二区aⅴ 一卡二卡三卡在线观看 | 蜜桃视频在线观看网站 | 樱空桃在线观看 | 亚洲天堂影院 | 中文字幕日韩一区二区三区不卡 | 99re热视频 | 欧美sm凌虐视频网站 | 高级毛片| 91在线精品秘密一区二区 | av在线第一页| 色综合天天射 | 欧美国产一级 | 中文字幕精品一区二区精品 | 亚洲成人精选 | 欧美日韩中文字幕视频 | 精品成人在线观看 | 国产做爰全免费的视频软件 | 久久这里只有精品9 | 亚洲乱码国产乱码精品精 | 精品动漫av| 国产原创91 | 麻豆传媒在线播放 | 女生张开腿让男生插 | 国产欧美精品一区二区三区app | 久久免费久久 | 日韩av综合网 | 深夜福利久久 | www天天操| 别揉我奶头一区二区三区 | 91超级碰| 亚洲综合在线一区 | 日韩有码视频在线 | 91免费在线播放 | 加勒比av在线播放 | 国产精品成人久久久 | 青青草国产在线视频 | 男人激情网 | 中文字幕黑人 | 久久精品视频网站 | 婷婷玖玖| 日日干日日射 | 人妻妺妺窝人体色www聚色窝 | 97在线国产 | 国产精品免费一区二区 | 午夜久久精品 | 好屌妞视频这里只有精品 | 女人高潮潮呻吟喷水 | 综合在线视频 | 久久99网 | 亚洲人一区| 色就色综合 | 日韩福利一区 | 日日爱99 | www.插插插.com| 天天爽夜夜春 | 精品午夜一区二区 | 日本在线免费播放 | 91麻豆精品一区二区三区 | 日本一区二区三区成人 | 色就是色欧美色图 | 精品国产xxx | 日本边添边摸边做边爱 | 可以看av的网站 | 水蜜桃亚洲精品 | 乱lun合集小可的奶水 | 婷婷丁香一区二区三区 | 午夜色综合 | 在线观看视频91 | 国产3页| 免费在线观看视频a | 欧美图片第一页 | 欧洲成人av | 色婷婷狠 | 欧美乱码精品 | 尤物视频在线观看视频 | 男女交性视频 | 天天躁日日躁狠狠躁喷水 | 久久久久久久久久福利 | 少妇久久久久久被弄高潮 | 国产 日韩 欧美 综合 | 新婚若妻侵犯中文字幕 | 亚洲久久久久久 | jizz国产视频 | 亚洲欧美日韩电影 | 日本一区二区三区在线播放 | 久久精品欧美日韩 |