欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

[原创]华为光猫固件结构逆向分析及编辑工具(一)

[原创]华为光猫固件结构逆向分析及编辑工具(一)

之前说打算写个拿华为光猫的root shell的文章来着,根据网上的资料,拿到root shell之后,发现不够玩的,想要玩的更深入点,还得实现固件的解包与打包,于是GG搜索相关资料,无意间找到一篇较冷门的但是很重要的资料:
PWN华为HG8120C光猫(三)
该文章对华为光猫固件的结构进行了粗略的猜解。但是已经具备了针对固件的解包与打包的基础功能。
不过源码是PY写的,本人对py不是很熟悉,加上原文对固件结构的解析不是很细致。
所以打算从头开始分析固件结构,一开始是瞄准了网上散播的华为ONT开telnet工具。
因为原文的upgrade.bin就是提取自该软件。
实际分析过后,发现该软件仅仅对固件文件做个校验,并不涉及解包打包的操作。
所以想从这软件里分析出固件的详细结构是不太可能的。
又开始搜索有关华为固件相关的工具,功夫不负有心人,终于在chinadsl上找到一个华为固件的重打包工具。
该工具的作用不是很清楚,实际测试时,我是用的一个老固件加一个xml来实现重打包操作的。

查了下发现没壳,还是VC++开发,IDA逆向过程也很顺利:

废话不多说,直接贴固件结构:

固件结构的C语言代码:

//基本文件头

typedef struct _HWNP_BasicFileHeader

{

  //魔法字

  uint32_t                  u32Magic;

  //文件大小 (计算公式为.bin的文件大小 - 76)  big-endian

  uint32_t                  beu32FileSize;

  //从HWNP_FILEHDR2开始到文件结束的CRC32值 (包含项目数据)

  uint32_t                  u32FileCRC32;

} HWNP_BASFILEHDR, *PHWNP_BASFILEHDR;

//文件头2

typedef struct _HWNP_FileHeader2

{

  //头部大小  

  //计算公式有2种:

  //1:  sizeof(HWNP_HEADER) + Header.u16ProductListSize + Header.u32ItemCount * Header.u16ItemInfoSize

  //2:  Header.u16ProductListSize + Header.u32ItemCount * Header.u16ItemInfoSize

  //前一种多了文件头大小

  //新版本固件一般是第一种公式,好像V100版本的固件是第二种计算公式

  //该数值不是计算头部CRC32时的大小

  uint32_t                  u32HeaderSize;

  //从HWNP_PAKHDR开始到N个HWNP_ITEMINFO结束的CRC32值 (不包含项目数据)

  uint32_t                  u32HeaderCRC32;

} HWNP_FILEHDR2, *PHWNP_FILEHDR2;

//包头

typedef struct _HWNP_PacketHeader

{

  uint32_t                  u32ItemCount;

  uint8_t                    u8PackTotal;

  uint8_t                    u8PackNum;

  uint16_t                  u16ProductListSize;

  union {

    uint16_t                u16ItemInfoSize;          //== sizeof(HWNP_ITEMINFO)

    uint32_t                _u32ItemInfoSize;          //== sizeof(HWNP_ITEMINFO)

  };

  

  uint32_t                  u32Reserved;

} HWNP_PAKHDR, *PHWNP_PAKHDR;

typedef struct _HWNP_Header

{

  HWNP_BASFILEHDR            BasicFileHeader;

  //file crc32 start comupte

  HWNP_FILEHDR2              FileHeader2;

  //header crc32 start comupte

  HWNP_PAKHDR                PacketHeader;

} HWNP_HEADER, *PHWNP_HEADER;

typedef struct _HWNP_ItemInfo

{

  uint32_t                  u32Id;                //原  Index

  uint32_t                  u32ItemCRC32;          

  uint32_t                  u32Offset;

  uint32_t                  u32Size;              //原  Len

  char                      chItemPath[256];      //原  Destination

  char                      chItemType[16];        //原  Name

  char                      chItemVersion[64];

  uint32_t                  u32Policy;

  uint32_t                  u32Reserved;

} HWNP_ITEMINFO, *PHWNP_ITEMINFO;


大致描述下固件结构,首先固件文件头是固定格式,可以被拆分为3个部分:
BasicFileHeader    //基本文件头
FileHeader2         //基本文件头2
PacketHeader       //包头
非要把文件头拆分成3个部分主要是为了好计算CRC32:
HeaderCRC32要从PacketHeader开始计算,包括了产品支持列表和项目信息部分。
FileCRC32则是从FileHeader2开始计算CRC32,一直到文件尾。
另外每一个项目都有自己的CRC32。
固件包也是包,类似于压缩文件包存放的是文件数据,而固件包存放的是各个项目,这些项目可以是文件,可以是kernel,uboot,rootfs,也可以是flash的配置信息。因为不是统一的类型,所以这里管固件包存放的东西称为项目。
每一个项目都有一个项目信息的结构来记录项目的相关属性,类似于PE文件的区段头记录区段的属性以及区段的文件偏移等。
项目信息除了记录项目数据的CRC,文件偏移,长度等信息,还包括项目的路径,类型,版本,策略(我觉得叫标志比较合适)等属性。
附件是我写的一个通过GUI对华为固件进行编辑的工具,暂时只完成了对项目的导入导出以及检查CRC校验的功能。以后会考虑开源。目前先放出测试版以供收集bug。
另外先挖一个坑,根据目前掌握的信息,或许可以根据dump出来的路由器mtd块,来实现重构路由器固件。这个以后如果研究成功了再来填坑。
已开源到github:https://github.com/csersoft/HWFW_GUI
附件已更新,修复bug(1.0.2 Alpha):
HWFW_GUI.7z
PS: 1.0.1以及1.0.0存在严重bug,不建议使用。

上传的附件 00.png
01.png
02.png
HWFW_GUI.7z

注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功