0x02 TP-Link wr886nv7-V1.1.0 路由器分析 - 导出BSS区辅助IDA分析

在之前一篇文章中通过焊接串口调试的方式已经成功的获取到VxWorks的cmd命令行,并且能够执行一些基础的系统命令。这篇文章将会对如何使用cmd命令行工具来辅助IDA进行静态分析。

通过阅读Vxworks 5.5的mips官方文档可以找得到如下所示的一张图,图中对VxWorks在MIPS架构下的内存布局进行了描述,其中bss(Block Started by Symbol)区在VxWorks系统中主要用于存储一些当前未赋值的变量。

由于bss段的数据在固件中是没有进行赋值的未初始化数据,因此我们可以尝试从路由器实际运行的内存中dump出bss段信息,并将其还原到IDA中。

为了dump bss段的信息,首先我们需要知道bss段的起始地址及大小,这部分的信息我们可以通过分析VxWorks系统的初始化代码进行实现。由于bss段存储的是未初始化的变量数据,因此在每次VxWorks系统加载过程中都会使用bzero函数对bss段的数据使用进行一次清除。

在IDA中我们可以通过追踪VxWorks的启动函数usrInit->sysStart来找到这段初始化bss段的代码。

此时我们就可以使用串口通讯dump处0x8024BB000x802A07B0的数据了。

dump完成后即可编写idapython脚本还原bss数据,还原代码如下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import idc
import idaapi
import idautils


bss_dump_path = 'path of bss_dump'
bss_dump_data = open(bss_dump_path, 'rb').read()
bss_start_address = 0x8024BB00
bss_end_address = 0x802A07B0

# Add segment
idc.AddSeg(bss_start_address, bss_end_address, 0, 1, 4, 0)
idc.RenameSeg(bss_start_address, ".bss")
idc.SetSegClass(bss_start_address, ".bss")

for offset in range(len(bss_dump_data)):
idc.PatchByte(bss_start_address + offset, ord(bss_dump_data[offset]))

还原bss区的变量数据对使用IDA进行静态分析还是有很大的帮助的,例如在还原bss段数据前所有对bss段的引用数据都为空无法辅助判断该地址的用途。

在还原bss段数据后,bss段的变量引用就可以通过变量的数据来辅助判断程序的处理逻辑。

同样的有些函数的地址是保存在BSS区的,如果我们不修复BSS区的数据那么在分析例如下图所示的一些函数时将会造成不少的困难。

通过导出路由器的BSS区数据可以更方便的辅助我们使用IDA等工具对设备的固件进行静态分析,此外如果遇到了未导出的地址也可以通过串口读取对应地址段的数据在IDA中使用类似的方法进行扩充。