找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
广告投放联系QQ68610888
查看: 9205|回复: 28

[k2p] 博通 CFE 数据压缩与解压

[复制链接]
用过博通芯片路由器的都知道,博通的 bootloader(简称 CFE)里包含了一些参数信息,比如 MAC 地址、无线参数、序列号型号名称等等,可以通过一些工具可以进行修改,比如 https://www.linksysinfo.org/index.php?threads/asuswrt-merlin-on-netgear-r7000.71108/ 或者 https://cfeditor.pipeline.sh/,还有论坛里一些易语言工具,不过这些工具的应用范围有限,只适合参数数据是明文存储的 CFE 文件,其实不用工具用十六进制编辑器也可以编辑:



而对于非明文存储的参数数据,它们就无能为力了,比如 K2P B1 版本的 CFE,它的数据并非是明文保存的:



但是仔细观察其数据存储结构,可以发现:
  • 无论是明文形式还是非明文形式,数据前的固定位置都有 ZSIB 和 FLSH 标志。
  • FLSH 标志之后有 16 个字节的数据区,然后再是参数数据区。
  • 参数数据区之后会有一个 AMZL 标志,这也很容易让人想到 LZMA 压缩算法。


我们可以通过这些标记的字符串和字节序列在源码(我用的是 ASUS RT-AC1200G+ GPL 源码)里找到一些相关的信息:

1、在 asuswrt/release/src-rt-9.x/src/include/hndsoc.h 中,可以看到 BISZ 数据区的描述信息:
/* A boot/binary may have an embedded block that describes its size  */
#define        BISZ_OFFSET                0x3e0                /* At this offset into the binary */
#define        BISZ_MAGIC                0x4249535a        /* Marked with this value: 'BISZ' */
#define        BISZ_MAGIC_IDX                0                /* Word 0: magic */
#define        BISZ_TXTST_IDX                1                /*        1: text start */
#define        BISZ_TXTEND_IDX                2                /*        2: text end */
#define        BISZ_DATAST_IDX                3                /*        3: data start */
#define        BISZ_DATAEND_IDX        4                /*        4: data end */
#define        BISZ_BSSST_IDX                5                /*        5: bss start */
#define        BISZ_BSSEND_IDX                6                /*        6: bss end */
#define        BISZ_SIZE                7                /* descriptor size in 32-bit integers */


正好是 sizeof(BISZ_MAGIC)+sizeof(int32)xBISZ_SIZE=32 个字节大小,和我们在 CFE 文件中看到的一致。

2、在 asuswrt/release/src-rt-9.x/src/linux/linux-2.6.36/arch/mips/include/asm/mach-bcm47xx/nvram.h 中可以看到 FLSH 数据区的结构信息:
struct nvram_header {
        u32 magic;
        u32 len;
        u32 crc_ver_init;        /* 0:7 crc, 8:15 ver, 16:31 sdram_init */
        u32 config_refresh;        /* 0:15 sdram_config, 16:31 sdram_refresh */
        u32 config_ncdl;        /* ncdl values for memc */
};

#define NVRAM_HEADER                0x48534C46        /* 'FLSH' */
#define NVRAM_VERSION                1
#define NVRAM_HEADER_SIZE        20


同时结合 asuswrt/release/src-rt-9.x/src/shared/startarm-ca9.S 的部分代码:
/* Embedded NVRAM */
        .global        embedded_nvram
embedded_nvram:
        .fill        0x400,4,~0x48534C46        /* 'FLSH' */
        .long   0x4c5a4d41              /* LZMA NVRAM Supported */


可以知道,博通把 CFE 中存储参数信息的数据区叫做 embedded nvram,也就是嵌入的 NVRAM,这个 NVRAM 的 HEADER 占 20 字节。

3、另外简单看下 asuswrt/release/src-rt-9.x/src/shared/startarm-ca9.S,从 /* Entry point */ 开始看:
/* Entry point */
        .section .text.startup

        .globl startup

startup:
        b        tr_rst        /* 0 - reset */
        ldr        pc,_tr_und        /* 4 - undefined instruction */
        ldr        pc,_tr_swi        /* 8 - software interrupt */
        ldr        pc,_tr_iab        /* 0xc - prefetch abort */
        ldr        pc,_tr_dab        /* 0x10 - data abort */
        ldr        pc,_tr_bad        /* 0x14 - reserved */
        ldr        pc,_tr_irq        /* 0x18 - external interrupt */
        ldr        pc,_tr_fiq        /* 0x1c - fast interrupt */

_tr_und:
        .word tr_und
_tr_swi:
        .word tr_swi
_tr_iab:
        .word tr_iab
_tr_dab:
        .word tr_dab
_tr_bad:
        .word tr_bad
_tr_irq:
        .word tr_irq
_tr_fiq:
        .word tr_fiq
_pad:
        .word 0x12345678 /* now 16*4=64 */

        .org        (BISZ_OFFSET-4)
_ddrclk:
        .word        0x0
        /* Record the size of the binary */
        .org        BISZ_OFFSET

        .word        BISZ_MAGIC
        .word        text_start
        .word        text_end
        .word        data_start
        .word        data_end
        .word        bss_start
        .word        bss_end
        .word        _end

        .balign envram_ofs
        /* Embedded NVRAM */
        .global        embedded_nvram
embedded_nvram:
        .fill        0x400,4,~0x48534C46        /* 'FLSH' */
        .long   0x4c5a4d41              /* LZMA NVRAM Supported */


结合 CFE 的二进制数据:

一个 word 占 4 个字节,第 60 字节处正好有个 0x12345678 (小端)。

很容易发现,CFE 就是由这种(是这种,不一定就是这个)汇编文件编译而来,还可以在 http://armconverter.com/hextoarm/ 上验证一下:

结果和猜测一致。

当然,我们想找出 embedded nvram 数据区的压缩和解压方法,并不需要去研究这个汇编代码,这个文件就到此为止,我们再来看另外一个东西:

在 asuswrt/release/src-rt-9.x/src/ctools 下有一个 nvserial 工具,这个工具的作用就是把一些 NVRAM 数据写入 CFE 文件中:

这一点我是从 https://blog.csdn.net/weixin_42353331/article/details/86060895 了解到的,在他博文的文末。

nvserial 的帮助信息里有这么一条:


可以简单找个一些源码里的文件测试一下:
./nvserial -z -i cfez.bin -o cfez_out_compress.bin -s 10 bcm94702ap.txt

加 -z 时:


不加 -z 时:


!!!

那这个 -z 的压缩算法到底是什么呢?看看 nvserial 的反编译代码:


使用的是一个名为 LzmaCompress 的函数,if 在有 -z 是就调用压缩,没有时直接 memcpy。

我们可以在 asuswrt/release/src-rt-9.x/src/tools/misc/lzma_src/C 找到 LzmaCompress 的 C 源码,其函数定义在 LzmaLib.h 中,虽然并不一定就是 nvserial 用到的代码,但是从反编译结果看,代码基本是一样的,可作为参考。我们看看这个函数的定义:

MY_STDAPI LzmaCompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t srcLen,
        unsigned char *outProps, size_t *outPropsSize, /* *outPropsSize must be = 5 */
        int level,      /* 0 <= level <= 9, default = 5 */
        unsigned dictSize,  /* default = (1 << 24) */
        int lc,        /* 0 <= lc <= 8, default = 3  */
        int lp,        /* 0 <= lp <= 4, default = 0  */
        int pb,        /* 0 <= pb <= 4, default = 2  */
        int fb,        /* 5 <= fb <= 273, default = 32 */
        int numThreads /* 1 or 2, default = 2 */
);


大致看过一圈之后,可以了解到,这是一个 Lzma1 算法压缩函数,压缩数据没有包装容器。其次,结合反编译的代码可知,LzmaCompress 会将 nvram 第 20 个字节开始到 v66 的数据压缩到 output_nvram 中,从 output_nvram 第 25 个字节的位置开始写。另外 LzmaCompress 还会将 props 信息写入到 output_nvram 中,从第 20 字节处开始写,占 5 字节。

对照上面 nvserial 加 -z 和不加 -z 的输出结果图,很容易了解到,加了 -z 就是把不加 -z 时 nvram_header 后面的数据压缩一下再存进来,props 存在 0x414 - 0x418,压缩数据从 0x419 处开始存储。

既然有 LzmaCompress,那肯定有 LzmaUncompress,LzmaLib.h 就有定义,我们参考 nvserial 中的写法,写一段简单的 c 代码来解压:
if (LzmaUncompress(
                (unsigned char *)&output_buffer[0],
                &destLen,
                (const unsigned char *)&input_buffer[25],
                &lSize,
                (const unsigned char *)&input_buffer[20],
                outPropsSize)) {
        fputs("NVRAM uncompression error\n", stderr);
        // exit(-1);
} else {
        fwrite(output_nvram, sizeof(unsigned char), NVRAM_SIZE, outFile);
}


编译执行,得到解压之后的数据,把 0x00 替换成 0x0A,结果为:

下面还有很多参数,没截上来了。

至此,流传的 CFE 数据 “加密” 的问题已经解决了,其实并不是加密,只是压缩了而已。另外也解释了为什么在原厂分区被覆盖之后,会获得 00:90:4C:... 这种格式的 MAC 地址。
这个 00:90:4C 的地址查 OUI 是来自 Epigram, Inc. 的,但是源码里附带的 nvram*.txt 里都是这钟 MAC,也不知道两者有什么关系。

修改 CFE 的方法也很清楚了:
把这些解压出来的数据放在一个 txt 文件中,以 /n 作为换行符,修改你需要修改的部分,再使用 nvserial 工具压缩到 CFE 中:
./nvserial -z -b 0x400 -c 0x1000 -i mtd0.bin -o mtd0_new.bin nvram_embedded_uncompressed_phicomm.txt

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×

评分

参与人数 4恩山币 +6 收起 理由
燃*** + 1 一看就是觉得高端、大气、上档次!
gsy*** + 1 一看就是觉得高端、大气、上档次!
ikbsz*** + 2 一看就是觉得高端、大气、上档次!
ph*** + 2 率全体恩山路由党以及党魁向你学习!

查看全部评分

我的恩山、我的无线 The best wifi forum is right here.
 楼主| | 显示全部楼层
我命令里的 -b 0x400 -c 0x1000 是针对 K2P B1 的,其他博通机型比如 K3 请了解清楚后再操作,以免变砖。
我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

大佬,ac1200G+添加DualWan报错怎么解决

点评

没试过编译 DualWan,不清楚,从错误信息一步步往上查吧,或者问以前编译 DualWan 固件版本的人,  详情 回复 发表于 2019-5-11 13:48
我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

大神啊 如何做相对简单 找到为何这样做才麻烦 谢谢  学习了
我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

来自手机 | 显示全部楼层
不错,真大佬
我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

多谢老师无私分享
我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

学习一下谢谢
我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

学习一下谢谢
我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

 楼主| | 显示全部楼层
xiamo23 发表于 2019-5-11 04:54
大佬,ac1200G+添加DualWan报错怎么解决

没试过编译 DualWan,不清楚,从错误信息一步步往上查吧,或者问以前编译 DualWan 固件版本的人,
我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

好东西啊!我喜欢!谢谢!
我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

是这样的,一直是压缩的,你能写个工具出来吗

点评

见 https://www.right.com.cn/forum/thread-665232-1-1.html  详情 回复 发表于 2019-5-24 06:59
有空会写一个  详情 回复 发表于 2019-5-11 14:36
我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

 楼主| | 显示全部楼层
zhjook 发表于 2019-5-11 14:31
是这样的,一直是压缩的,你能写个工具出来吗

有空会写一个
我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

spoon 发表于 2019-5-11 13:48
没试过编译 DualWan,不清楚,从错误信息一步步往上查吧,或者问以前编译 DualWan 固件版本的人,

正在问,大神试一下编译一下?

点评

有点忙啊抱歉  详情 回复 发表于 2019-5-11 19:41
我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

 楼主| | 显示全部楼层
xiamo23 发表于 2019-5-11 18:24
正在问,大神试一下编译一下?

有点忙啊抱歉
我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

欢迎大家光临恩山无线论坛上一条 /1 下一条

有疑问请添加管理员QQ86788181|手机版|小黑屋|Archiver|恩山无线论坛(常州市恩山计算机开发有限公司版权所有) ( 苏ICP备05084872号 )

GMT+8, 2024-5-4 03:26

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

| 江苏省互联网有害信息举报中心 举报信箱:js12377 | @jischina.com.cn 举报电话:025-88802724 本站不良内容举报信箱:68610888@qq.com 举报电话:0519-86695797

快速回复 返回顶部 返回列表