VxWorks固件分析方法总结

VxWorks固件分析方法总结

最近研究基于VxWorks系统的iot设备的固件分析方法,将学习心得记录于此,以备未来的查询须要。linux

1.VxWorks是什么?

VxWorks是美国WindRiverSystem公司(风河公司)推出的一个RTOS(实时操做系统),凭借良好的持续发展能力、高性能的内核以及友好的用户开发环境,在嵌入式实时操做系统领域占据一席之地。自从1987年首次问世以来,VxWorks系统版本经历了5.x,6.x到现在的7版本。VxWorks系统凭借其优秀的实时性占据着不小的市场份额,包括NASA的火星探测器、波音787客机、网络路由器等,市场范围跨越各类安全领域。
VxWorks版本更替安全

按照所运行的操做系统区分,嵌入式iot设备能够大体上分为基于linux和基于VxWorks的两类。VxWorks支持几乎全部现代市场上的嵌入式CPU架构,包括x86系列、MIPS、PowerPC、Freescale ColdFire、Intel i960、SPARC、SH-四、ARM、StrongARM以及xScale CPU。网络

2.如何定位VxWorks固件的加载地址

使用ida pro、ghidra等反汇编工具进行分析时,须要了解固件的加载地址,不然没法正确的分析固件。下图所示为填写固件加载地址先后的函数识别状况的对比,能够看出肯定了固件加载地址以后函数的识别度更高。
before
after架构

2.1经过ELF文件头读取

一般固件文件会使用ELF格式进行封装,所以可使用readelf等工具对头部文件进行分析,进而获得固件的加载地址。IDA pro已经集成了这个功能,能够直接分析出常见的固件的加载地址。
elf函数

2.2经过分析内存中的相邻位置

mips
如图所示为VxWorks固件在mips架构中的内存分布图,可知固件加载地址与栈初始化地址相邻,能够经过定位栈初始化地址肯定固件的加载地址。工具

initialstack
那么如何定位栈初始化地址呢?那就是寻找栈指针寄存器sp的位置。根据VxWorks官网给出的Initial Stack的说明,可知Initial Stack是usrInit()函数的初始化栈。性能

usrinit
又由于UsrInit()是VxWorks系统引导后的运行的第一个函数,所以能够经过在ida中寻找sp寄存器首次出现的位置(此时的ida并无指定固件加载地址),经过sp的值肯定栈初始化的值,从而肯定固件的加载地址。学习

sp
若是所示,sp寄存器中保存0x80000FF0,所以固件的加载地址应该是0x80001000。操作系统

2.3经过定位bss在内存中的地址

usrinit2
这个方法在原理上同2.2的方法同样,可是须要必定的计算。根据UsrInit()的描述,第一个跳转的函数就是负责初始化BBS区的函数,所以能够寻找第一个跳转的指令的位置;还有另一个方法肯定初始化BBS区的位置,因为在系统启动过程当中VxWorks会使用bzero函数对bss区的数据进行清零,因此能够在固件中用命令grep -r bzero查找bzero字符串出现的位置,此方法能够做为验证。3d

2.4其余方法

经过焊接UART接口查看系统引导过程的串口输出;经过查阅开发者手册等。

3.使用符号表修复函数名

3.1寻找符号表的位置

若是固件自己已经编入了符号表,那么可使用binwalk肯定符号表的位置。
binwalk-fuhaobiao

VxWorks系统的符号表按照每16个字节一组,前四个字节用0x00进行填充,第二个四字节表示符号名字符串在内存中的位置,第三个四字节表示符号在内存中的位置,最后四个字节表明符号的类型,如0x0500表示函数名。
fuhaobiao

可是若是分析固件没有获得符号表,可能存在两种可能:一种是固件自己就没有编入符号表,这种状况使得函数分析变得比较困难;另外一种是符号表被开发者隐藏了起来,防止固件被顺利逆向。

如何寻找隐藏了的符号表还在学习中,以后会另开一篇专门介绍。

3.2修复函数名

在ida pro中,函数名的修复须要编写脚本,用符号表中的函数名替换当前无心义的函数名。在ghidra中,加载完固件以后能够运行vxhunter脚本,将函数名替换为符号表中的函数名。

ghidra修复完函数名以后的效果,能够很明显的看出施耐德PLC以太网模块固件NOE77101.bin固件中所存在的后门帐户漏洞CVE-2011-4859
ghidra