介绍一个ARM固件加载基址定位器
注:本文出自复眼小组的magpie
一、 前言
最近入坑 iot ,涉及很多芯片固件的逆向。但是这些固件很多时候都不是标准二进制格式,也就是说丢进 ida ,识别不出架构和指令集。架构和指令集可以查芯片的文档,但是加载基址还没法确定,这个靠自己去定位,再配置 ida 。人工做这个工作太累,而我又是懒狗,所以自动化这一过程不香吗?
这里推荐一篇很优秀的论文,北京理工大学朱瑞瑾博士学位论文《 ARM 设备固件装载基址定位的研究》,在第三章提到了一个基于函数入口表的基址定位方法。具体原理原文写的非常清楚,建议直接阅读原文,我就不再赘述。本文要聊的就是把文中提到的这个方法给具体实现出来,做成工具。
文末我会附上 GitHub 地址,我完成这个工具的开发后,测试的固件样本毕竟不多,肯定会遗留一些问题,希望师傅们能试一下帮我发现问题,能帮到师傅们最好了。
二、 工具的开发、改进和优化
工具的原理直接去看论文原文就可以,源码我都公开在 GitHub 了,这里就不贴了。下面就主要聊一下对原文的算法做的改进和优化。
1、 扫描模式的优化
原文中扫描寻找入口表时,找到一个入口表后就会停止 gap 值的遍历,且直接跳过入口表覆盖的偏移。跳过这些 gap 和偏移其实并不是很合理,会不够精确。
起初我是改成了不跳过,但是扫描时间变长了,于是我设置了一个开关参数,可以选择精确模式和粗糙模式。
2、 函数紧凑间隔值的优化
匹配规则一中的间隔值,原文建议为 0x10000 ,本人实测建议为 0x1000.
3、 简洁模式
实际情况中,加载基址第三位 hex 一般为 000 ,原文中不考虑这一点,全部输出,其实不够准确。因此增加了简洁模式开关参数,可以开启后只输出第三位 hex 为 000 的地址。
4、boot 模式
笔者新增的一个模式,也叫上电模式。 Arm Cortex-M/R 核心的固件的 4 偏移为 pc 寄存器上电值,代表第一条指令地址,因此能确定时加载基址不会大于此值。这时可以将 boot 参数设为此值来提高扫描效率。否则 boot 参数设为 0.
三、 其他说明
iAudio固件测试图:
sony固件测试图:
项目GitHub地址 :
https://github.com/MagpieRYL/arm32_base_loc
关于工具的用法,下载后详见项目内的文档。 Exmaple 目录下有几个测试用例固件,其中 sony 和 iAudio 固件为原论文中用到的,可以去对照加载基址。 Sony 固件满足 boot 模式。