VxWorks固件分析方法总结

摘要:
VxWorks固件分析方法总结最近研究基于VxWorks系统的iot设备的固件分析方法,将学习心得记录于此,以备将来的查询需要。自从1987年首次问世以来,VxWorks系统版本经历了5.x,6.x到如今的7版本。VxWorks系统凭借其优秀的实时性占据着不小的市场份额,包括NASA的火星探测器、波音787客机、网络路由器等,市场范围跨越各种安全领域。
VxWorks固件分析方法总结

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

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-4、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字符串出现的位置,此方法可以作为验证。

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

免责声明:文章转载自《VxWorks固件分析方法总结》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇关于微服务(三)PHP基础封装简单的MysqliHelper类下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

StringBuilder 以及 StringBuffer默认大小与扩容

默认值初始化: 1.  首先明确 StringBuffer类与 StringBuilder类均继承了抽象类 AbstractStringBuilder类 无参构造方法 2. 源码中StringBuffer类和StringBuilder类初始化均调用父类的构造方法: 父类初始化: 子类默认传入值16 给父类初始化字符数组   有参构造方法:   扩容...

STM32F1库函数初始化系列:DMA—ADC采集

1 void ADC_Configure(void) 2 { 3 ADC_InitTypeDef ADC_InitStructure; 4   GPIO_InitTypeDef GPIO_InitStructure; 5 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE); 6   RCC_AHBPer...

CentOS中如何安装7ZIP

7-zip以高压缩率著称,并且是一款免费开源的压缩软件。在常规的Linux发行版中,无法通过简单的yum命令来安装该软件。那么在CentOS中,如何安装7ZIP呢?有以下3种方法: 第一种,源码编译安装官网下载地址:http://www.7-zip.org/download.html源文件项目地址:http://sourceforge.net/projec...

Windows启动过程详解

Windows启动过程详解   我们每天都在和Windows打交道,很多人可能每天都要面对多次Windows的启动过程,可是您知道在Windows的启动过程背后,隐藏着什么秘密吗?在这一系列过程中都用到了哪些重要的系统文件?系统的启动分为几个步骤?在这些步骤中计算机中发生了什么事情?这些就是本文试图告诉您的。 本文的适用范围 随着技术的发展,我们能够见到的...

uboot完全手册---14

1. u-boot介绍 本次移植采用的是U-Boot-1.2.0版本。 3. U-Boot源码分析 3.1 源码入口的解释 可能大多数的同学上网查资料后都了解到,stage1阶段的启动代码,主要就在start.s文件里。此start.s也是系统上电后执行的第一个代码。它全部由汇编编写。在讲述start.s之前,我们先来了解一下,系统怎么知道它要先去star...

bss段为什么需要初始化?

    我们都知道bss段需要初始化,但是这是为什么呢?        通过浏览资料,我们都会发现,bss段是不会出现在程序下载文件(*.bin *.hex)中的,因为全都是0。如果把它们出现在程序下载文件中,会增加程序下载文件的大小。实际应用中,通常只需要把bss段的起始地址和结束地址保存起来,而不需要将程序下载文件中出现bss段(一堆0)将来真正运行程...