最近家里的移动宽带到期了,闲置了一台H3-2S的光猫,原本我也有一台MIPS的友华光猫,固件修改后我自己也很满意了。但这台闲置的光猫是ARMv7l的,测试后发现性能更好一些(是MIPS的一倍多)。于是就想着也改改,加一些自启脚本,装frpc、alist、kms、aria2c、clash、甚至还能跑一点自己写的Java程序。通过分析一通之后,我发现这个光猫的rcS相关的自启内容里一点破绽都没有,原本的alipay的dns也注释了,要加自启脚本就必须改rootfs里的rcS。由于系统里没有dd,但有nandump,我给dump出来,使用binwalk分析了一下,果然从kernel里解出了文件系统。整个固件的文件结构大概是这样的:中兴文件结构,占480bytes,然后是uImage头64bytes,然后会执行一段程序,解压gzip。gzip解压出来之后,解压的字节中又有一段程序,然后再解压一个lzma块,这个lzma块解压出来就是rootfs.cpio了。这个cpio是没有任何压缩的。但我用python的cpio库libarchive的时候遇到了不小的挑战,就是cpio解压后什么都不改,再压回去,对比改动发现差异很大,里边有一些数据的大小写都发生了变化,小写全都变成了大写。我想探究里边的原因,耗费了一天时间也没找出来,于是我只好人肉修改cpio的16进制内容,找到rcS部分,把alipay.sh的注释打开,然后改一小段。剩下的就是还原回去并刷进去的工作了,这个还原工作异常艰难:首先是gzip解压的时候不知道gzip块的长度,不知道什么时候会结束,虽然不影响解压,但肯定影响还原啊。好在gzip解压的时候,异常信息里会提示无法解码的字节,那直接搜索这个字节就能找到结束的附近了。然后观察右侧的块特征,终于找到了结束位,顺带还发现了dtb的开始位置和整个分区的结束位置、还有crc32的偏移量。然后是lzma的结束位,这个就比gzip难多了,因为这个lzma解压的时候没有报任何异常,直接就解压出来了,再尝试压回去会发现大小完全对不上,大了1M多不止。尝试了好几个库和xz\tar等格式,发现也对不上,应该就是lzma的压缩格式。后来我开始怀疑是不是lzma的结束位置不对,可没有任何异常啊,应该不会不对吧。我带着这个怀疑,使用linux中的lzma去检查这个文件块,发现lzma竟然无法识别,而我压缩回去的lzma则能识别,而且完全没问题。我好奇它究竟用的什么lzma算法啊,难道老版本的不支持?于是我开始翻python的lzma库源代码,发现它果然捕获了异常,而且直接把异常吃掉了。真狗!我把那段代码拷贝出来。lzma则是非常难,因为lzma的那次压缩是在gzip解压之后,又执行了一段,那偏移量完全都不知道怎么对上,载入到IDA里也是一堆未识别的地址。好在它的库函数会有俩个不同的异常,一个是流未结束,一个是字节无法解析。流未结束就是截取少了,字节无法解析就是截取多了,然后写了一个二分查找的方法,找到了lzma解压的位置,位置结束后俩个字节处就是lzma的长度数值。然后我测试了一下,将截取的lzma解压出rootfs.cpio后再原封不动的压缩回去,大小竟然比原来的小了几十字节。这可不行,我又尝试了一下用linux自带的lzma压缩:果然还原了,和原文件md5值一字不差,看来linux的lzma算法还是和python的lzma有些小差异。至此,整个逆向过程告一段落。IDA可以直接载入uImage的文件去查看gzip的解压逻辑,来验证gzip的结束偏移的地址是否正确。经过一番验证,也找到了双固件切换的的方法,也完成了文件系统提取也压缩回去的程序工具,但改完的固件始终无法启动,查看gzip解压的出来的数据块,发现了大量证书内容:感觉要裹足不前了......,目前的水平对arm反汇编的能力严重不足。
所以把成果文件贡献出来,看有没有大神有兴趣挑战,如果成功,我将分享我开发的中兴固件拆包打包工具(现在不分享是因为打包的固件无法启动,有变砖风险)。c71K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6U0L8r3!0#2k6q4)9J5k6e0p5^5z5g2)9J5k6h3y4F1i4K6u0r3N6$3g2T1i4K6u0r3M7$3S2S2M7X3g2Q4x3@1k6U0L8$3c8W2i4K6y4p5j5g2W2h3g2V1&6*7e0i4k6m8y4%4A6W2i4@1g2r3i4@1u0o6i4K6R3^5i4@1f1^5i4@1q4q4i4@1u0r3i4@1f1&6i4K6V1%4i4@1q4q4i4@1f1%4i4@1p5H3i4K6R3I4i4@1g2r3i4@1u0o6i4K6W2m8y4X3S2&6P5q4!0q4c8W2!0n7b7#2)9^5z5b7`.`.文件说明:
该文件为吉比特,中兴芯片光猫固件:2023年5月8日 我已自己挑战成功,实现了通用工具:结帖啦:我的轩辕悠悠
---
来源: 看雪论坛
原文链接: https://bbs.kanxue.com/thread-276970.htm
[原创]中兴ZTE ZX279128S芯片固件解密
174 浏览
24 回复
给你上传一下这芯片的数据手册, 有这份资料的话可以知道针脚分布也可以自行画pcb板。
最后于 2023-4-28 00:16
被微启宇编辑
,原因:
最后于 2023-4-28 00:16
被微启宇编辑
,原因:
龙岱客
修改固件起不来应该是uboot对kernel的rsa签名校验过不了,如果只是crc就好弄 应该不是,我看是我处理掉了一个crc32的值,然后我又重新处理了,结果直接ttl显示start kernel...后就死机了,大概率是我动了kernel的内容,估计是我自己把kernel改坏了。我打算自己去编译一个kernel,然后在给里边内置一个lxc的openwrt,我目前的进展是进入到了kernel里去了,我已经感觉到我大概率成功了。
带着这些欣喜,我有尝试过了,昨晚又搞了大半夜,自己编译的内核刷进去后卡在start kernel的位置,而且rootfs编译的和原版固件差了0.4m多的体积,目前的猜测应该是uboot里做了手脚。
最后于 2023-4-29 09:37
被XYUU编辑
,原因:
修改固件起不来应该是uboot对kernel的rsa签名校验过不了,如果只是crc就好弄 应该不是,我看是我处理掉了一个crc32的值,然后我又重新处理了,结果直接ttl显示start kernel...后就死机了,大概率是我动了kernel的内容,估计是我自己把kernel改坏了。我打算自己去编译一个kernel,然后在给里边内置一个lxc的openwrt,我目前的进展是进入到了kernel里去了,我已经感觉到我大概率成功了。
带着这些欣喜,我有尝试过了,昨晚又搞了大半夜,自己编译的内核刷进去后卡在start kernel的位置,而且rootfs编译的和原版固件差了0.4m多的体积,目前的猜测应该是uboot里做了手脚。
最后于 2023-4-29 09:37
被XYUU编辑
,原因:
修改固件起不来应该是uboot对kernel的rsa签名校验过不了,如果只是crc就好弄
最后于 2023-4-27 17:06
被龙岱客编辑
,原因:
最后于 2023-4-27 17:06
被龙岱客编辑
,原因:
Q老Q
博主文中说修改完固件后重启失败,能上传一下启动过程中的完整串口log吗
焊油刚到,我处理好了再发出来。
博主文中说修改完固件后重启失败,能上传一下启动过程中的完整串口log吗
焊油刚到,我处理好了再发出来。
博主文中说修改完固件后重启失败,能上传一下启动过程中的完整串口log吗
XYUU
以我对GPL2.0协议的理解,凡是使用了uboot代码的项目就必须开源,否则就违反了协议,所以芯片厂商有不能公开的内容就不能使用uboot源码,而我从二进制代码中发现了大量uboot的常量字符串能证实 ...
那你可以试试去问光猫设备的生产商要源码。
以我对GPL2.0协议的理解,凡是使用了uboot代码的项目就必须开源,否则就违反了协议,所以芯片厂商有不能公开的内容就不能使用uboot源码,而我从二进制代码中发现了大量uboot的常量字符串能证实 ...
那你可以试试去问光猫设备的生产商要源码。
微启宇
给配置编译了也用不了, uboot里有芯片厂商独有的代码但这是不能公开的比如各个模块的初始化。不是芯片厂商给的代码属于公版编译了就算run起来也只是arm核心run而已。
以我对GPL2.0协议的理解,凡是使用了uboot代码的项目就必须开源,否则就违反了协议,所以芯片厂商有不能公开的内容就不能使用uboot源码,而我从二进制代码中发现了大量uboot的常量字符串能证实使用了uboot源码。
给配置编译了也用不了, uboot里有芯片厂商独有的代码但这是不能公开的比如各个模块的初始化。不是芯片厂商给的代码属于公版编译了就算run起来也只是arm核心run而已。
以我对GPL2.0协议的理解,凡是使用了uboot代码的项目就必须开源,否则就违反了协议,所以芯片厂商有不能公开的内容就不能使用uboot源码,而我从二进制代码中发现了大量uboot的常量字符串能证实使用了uboot源码。
XYUU
可我目前还是没有搞定[em_13],如果厂商能提供uboot编译的配置文件,也就能自己编译uboot了,这块我也没搞到,唉。
给配置编译了也用不了, uboot里有芯片厂商独有的代码但这是不能公开的比如各个模块的初始化。不是芯片厂商给的代码属于公版编译了就算run起来也只是arm核心run而已。
可我目前还是没有搞定[em_13],如果厂商能提供uboot编译的配置文件,也就能自己编译uboot了,这块我也没搞到,唉。
给配置编译了也用不了, uboot里有芯片厂商独有的代码但这是不能公开的比如各个模块的初始化。不是芯片厂商给的代码属于公版编译了就算run起来也只是arm核心run而已。
按照帖子的方法:
https://bbs.kanxue.com/thread-267719.htm
找了一下uboot的基址,大概是:0x47EE0000
先调出string窗口,找到
ROM:47F34BF7 00000012 C Bad Magic Number\n
搜字符串4BF7能看到:
ROM:47F0F128 sub_47F0F018 LDR R0, =0x47F34BF7
ROM:47F0F22C dword_47F0F22C DCD 0x47F34BF7 ; DATA XREF: sub_47F0F018+110↑r
和
ROM:00054BF7 aBadMagicNumber DCB "Bad Magic Number",0xA,0
然后0x47F34BF7-0x54BF7=0x47EE0000果然在字符串中发现了,x47ee0000接着下面有一行0x47f00000,这大概就是入口的地址了,跳过去按C,好激动。
最后于 2023-4-26 20:29
被XYUU编辑
,原因:
https://bbs.kanxue.com/thread-267719.htm
找了一下uboot的基址,大概是:0x47EE0000
先调出string窗口,找到
ROM:47F34BF7 00000012 C Bad Magic Number\n
搜字符串4BF7能看到:
ROM:47F0F128 sub_47F0F018 LDR R0, =0x47F34BF7
ROM:47F0F22C dword_47F0F22C DCD 0x47F34BF7 ; DATA XREF: sub_47F0F018+110↑r
和
ROM:00054BF7 aBadMagicNumber DCB "Bad Magic Number",0xA,0
然后0x47F34BF7-0x54BF7=0x47EE0000果然在字符串中发现了,x47ee0000接着下面有一行0x47f00000,这大概就是入口的地址了,跳过去按C,好激动。
最后于 2023-4-26 20:29
被XYUU编辑
,原因:
龙岱客
你的分析已经超过绝大部分人了[em_13]
可我目前还是没有搞定,如果厂商能提供uboot编译的配置文件,也就能自己编译uboot了,这块我也没搞到,唉。
你的分析已经超过绝大部分人了[em_13]
可我目前还是没有搞定,如果厂商能提供uboot编译的配置文件,也就能自己编译uboot了,这块我也没搞到,唉。
你的分析已经超过绝大部分人了
ChatGPT回答:
使用IDA pro打开uboot程序的bin文件,设置正确的处理器类型和加载地址,然后使用IDA pro的反汇编功能分析bin文件的结构和代码。
在IDA pro中,找到uboot程序的入口点,通常是.text段的开头,然后跟踪执行流程,找到第一个BL指令,该指令调用了main函数。
在IDA pro中,观察R2寄存器的值,该值就是main函数的地址,然后按g键输入R2的值,就可以跳转到main函数的位置。
我使用该方法没有找到基址。
最后于 2023-4-26 11:18
被XYUU编辑
,原因:
使用IDA pro打开uboot程序的bin文件,设置正确的处理器类型和加载地址,然后使用IDA pro的反汇编功能分析bin文件的结构和代码。
在IDA pro中,找到uboot程序的入口点,通常是.text段的开头,然后跟踪执行流程,找到第一个BL指令,该指令调用了main函数。
在IDA pro中,观察R2寄存器的值,该值就是main函数的地址,然后按g键输入R2的值,就可以跳转到main函数的位置。
我使用该方法没有找到基址。
最后于 2023-4-26 11:18
被XYUU编辑
,原因:
中兴和华为的光猫都自带基于lxc容器技术的OpenWRT子系统,能在里面折腾的就不要在宿主机上折腾,这个容器的权限和宿主系统同级没必要折腾宿主系统,进入openwrt是这个命令 `saf console` 华为的是`saf-huawei console`进入密码自己逆向 (镜像路径/opt/upt/framework/saf/rootfs 原则上最好不要修改这个路径里的文件但可以修改这个路径的文件/opt/upt/apps/apps 这个路径的文件会被bind挂载覆盖rootfs里的文件)进入这个openwrt系统后可以安装ipk的包。
最后于 2023-4-25 06:54
被微启宇编辑
,原因:
最后于 2023-4-25 06:54
被微启宇编辑
,原因:
先尝试patch一下uboot放到仿真环境测试一下效果,所以这一步就是找到uboot的基址,目前数据中大部分字符串我已手工恢复。接着就是找一个arm的uboot编译过去,然后IDA打开找找特征。
我又用自己编写的工具解了一个吉比特GM693-R的光猫固件,也是这个芯片的,固件除了最后rootfs.cpio的压缩格式是gzip的之外,解包工具基本可以通用,而且gzip解包找结束偏移的特征也很明显,就是gzip结束后的对齐字节紧跟着就是gzip的块长度值。lzma的特征则是块结束后的对齐字节的值就是结束位置的offset。
也就是rootfs和kernel组合生成zImage的特征基本是同一套编译器生成的。
最后于 2023-4-25 19:47
被XYUU编辑
,原因:
我又用自己编写的工具解了一个吉比特GM693-R的光猫固件,也是这个芯片的,固件除了最后rootfs.cpio的压缩格式是gzip的之外,解包工具基本可以通用,而且gzip解包找结束偏移的特征也很明显,就是gzip结束后的对齐字节紧跟着就是gzip的块长度值。lzma的特征则是块结束后的对齐字节的值就是结束位置的offset。
也就是rootfs和kernel组合生成zImage的特征基本是同一套编译器生成的。
最后于 2023-4-25 19:47
被XYUU编辑
,原因:
我全盘都备份过的,那些地方我不会去动它的。
所以理论思路就是,找到这款芯片的uboot相关的编译参数配置,然后将参数配置放到uboot源码中编译,编译完成后放入仿真环境测试,没问题后刷入uboot。然后就可以愉快的引导uImage的镜像固件了(uImage是由rootfs放入内核编译获得zImage然后与dtb合成)。此后的标准固件就都可以用了,对于官方原版固件则可以通过我的解包程序解出uImage,刷入即可使用。
另一种思路则是patch掉官方uboot的校验code hash校验内容,其他crc32的校验内容倒可以还原。
最后于 2023-5-3 10:13
被XYUU编辑
,原因:
所以理论思路就是,找到这款芯片的uboot相关的编译参数配置,然后将参数配置放到uboot源码中编译,编译完成后放入仿真环境测试,没问题后刷入uboot。然后就可以愉快的引导uImage的镜像固件了(uImage是由rootfs放入内核编译获得zImage然后与dtb合成)。此后的标准固件就都可以用了,对于官方原版固件则可以通过我的解包程序解出uImage,刷入即可使用。
另一种思路则是patch掉官方uboot的校验code hash校验内容,其他crc32的校验内容倒可以还原。
最后于 2023-5-3 10:13
被XYUU编辑
,原因: