找回密码
 立即注册

QQ登录

只需一步,快速开始

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

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

[复制链接]
发表于 2019-5-11 03:59 | 显示全部楼层 |阅读模式
用过博通芯片路由器的都知道,博通的 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 一看就是觉得高端、大气、上档次!
gsyzft + 1 一看就是觉得高端、大气、上档次!
ikbszj75089 + 2 一看就是觉得高端、大气、上档次!
php.c + 2 率全体恩山路由党以及党魁向你学习!

查看全部评分

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

使用道具 举报

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

点评

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

使用道具 举报

发表于 2019-5-11 07:34 | 显示全部楼层
大神啊 如何做相对简单 找到为何这样做才麻烦 谢谢  学习了
我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

发表于 2019-5-11 07:56 来自手机 | 显示全部楼层
不错,真大佬
我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

发表于 2019-5-11 07:58 | 显示全部楼层
多谢老师无私分享
我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

发表于 2019-5-11 08:43 | 显示全部楼层
我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

发表于 2019-5-11 09:38 | 显示全部楼层
学习一下谢谢
我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

发表于 2019-5-11 10:56 | 显示全部楼层
学习一下谢谢
我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

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

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

使用道具 举报

发表于 2019-5-11 14:25 | 显示全部楼层
好东西啊!我喜欢!谢谢!
我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

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

点评

见 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.
回复

使用道具 举报

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

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

使用道具 举报

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

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

点评

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

使用道具 举报

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

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

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-4-25 06:56

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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

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