在分析固件、Bootloader或者裸机程序的时候,经常会遇到bin文件,这种文件没有PE或者ELF那样的结构头,所以IDA Pro没办法自己知道处理器类型、入口地址,还有ROM和RAM的映射关系,加载的时候就不能一路点“下一步”。如果基址填错了,后面看到的跳转地址、函数引用、字符串交叉引用,还有反编译出来的伪代码,都会乱掉。Hex-Rays的文档里也说过,加载Raw Binary文件的时候,需要分析的人自己去把处理器和装载的信息给补上。
一、IDA Pro反编译bin怎么加载基址
加载bin文件之前,先别急着按F5去看伪代码,基址这个东西,是后面反汇编和反编译能不能对得上的基础,应该先从芯片手册、链接脚本、map文件、烧录地址,或者启动日志里面找到依据。
1.先确认处理器架构
打开IDA Pro,选择新建然后把bin文件导进来,在加载的窗口里,要选对处理器类型,比如ARM、MIPS、PowerPC、RISC-V这些,它们不能混着用,就算是同一个架构下面,也要注意区分大小端和指令集的模式,要是架构选错了,就算基址填得再对,指令解析出来也还是一堆乱码。
2.确认bin文件实际的装载地址
基址一般是从链接脚本里的起始地址、map文件里的代码段起始地址,或者是烧录工具里面填的Flash地址来的,比如,固件是烧录到0x08000000这个地址的,就不要习惯性地填成0x00000000;如果这个bin文件只是从完整镜像里面截出来的一小段,那还要看它在原始镜像里的偏移位置,不能把文件自己的偏移直接当成运行地址来用。
3.在加载窗口填写地址
当IDA识别出这是一个Binary文件后,就会出现跟加载地址相关的设置,把装载地址或者叫加载地址那一栏,填成程序实际运行的基址,如果还有个加载偏移的选项,它通常是用来指文件第一个字节在段内的偏移位置的,Hex-Rays的文档说明,装载地址对可执行文件和二进制文件有意义,装载偏移则是用于二进制文件第一个字节相对于首段起点的位置。
4.加载后检查地址是否对齐
导进来之后,先看看左侧的地址是不是从我们预期的基址开始的,然后可以找一找复位向量、入口函数、跳转表或者常见的字符串引用,看它们跳转的目标是不是落在一个合理的地址范围里面,要是发现大量的跳转都跳到了不存在的区域,那一般就说明基址、偏移、大小端或者指令模式,这几项里面至少有一个是没搞对的。
二、IDA Pro反编译bin内存映射怎么填写
bin文件它只是一段文件里的内容,并不等于芯片运行时完整的那个内存,很多固件会去访问Flash、RAM、外设的寄存器、启动向量表这些,如果内存映射不补全,在IDA里面就会出现很多未知的地址。
1.先按芯片的地址空间来划分
根据芯片手册或者链接脚本,把Flash、SRAM、外设寄存器、中断向量这几个区域给分开,Flash那段一般放的是代码和常量,RAM段放的是全局变量、堆栈和未初始化的数据,外设区是用来做内存映射的I/O寄存器访问的,注意不要把所有地址都塞进一个代码段里,不然数据引用和外设引用会混在一起,看起来很乱。
2.创建或者调整段
在IDA里进入编辑→段→创建段的菜单,或者打开视图→子窗口→段来查看已有的段;代码段设置为可读可执行,数据段设置为可读可写,外设寄存器区通常只需要建立起地址范围和名字就行了,不一定非得有真实的文件内容,Hex-Rays也特别提过,分析固件时正确的内存布局很重要,默认给Raw Binary生成的那个单一代码段,很多时候是不够用的。
3.补充额外的bin片段
要是一个项目有好几个bin文件,比如引导、应用程序、校准参数各自一个文件,可以先加载主程序,再通过文件→加载文件→附加二进制文件,把其他的bin文件加载到它们对应的地址上,Hex-Rays说明过,附加二进制文件这个功能,会按照原始二进制内容把文件放到指定的位置。
4.把段的名字和权限写清楚
段名不要偷懒保留默认的,可以改成FLASH_TEXT、FLASH_CONST、SRAM_DATA、MMIO_REG这种能看懂的名字,权限也要按照用途来设,代码段就不要随便设成可写,RAM段也别随便设成可执行,这样后面看交叉引用、数据访问和函数边界的时候,会清楚很多。
三、IDA Pro反编译bin加载错了怎么校正
bin文件加载错了,不一定非得全部从头来一遍,但得先判断到底是基址错了、段映射错了,还是处理器模式错了,不同的问题,修正的方法也不一样。
1.基址整体偏移时,用Rebase功能
如果处理器和段划分都没问题,只是整体地址偏了,那可以进入编辑→段→程序重设基址的菜单来重新设置地址,Hex-Rays在关于重设基址的说明里提到,可以通过这个功能把当前文件移动到新的地址,也可以输入一个正向或者反向的偏移值。
2.局部地址不对的时候,直接改那个段
要是只有某一个段的映射不对,比如RAM段的起始地址填错了,就不要去整体Rebase了,应该到段的窗口里,调整那个段的起始和结束范围,或者直接把它删了重新建一个;局部的段错位会影响变量的识别和交叉引用,改完之后要记得重新触发一次分析。
3.反编译失败了,先手动创建函数
Raw bin导入之后,IDA不一定能自己把所有函数都认出来,可以在入口地址那里按C键先转成代码,再按P键创建函数,必要的时候,手动去指定一下是ARM模式还是Thumb模式,或者函数的边界在哪;等函数边界都搞对之后,再按F5看伪代码,这时候出来的结果通常会比直接反编译要稳定不少。
总结
总的来说,IDA Pro反编译bin怎么加载基址,还有内存映射怎么填,关键就是要先把程序的运行地址、处理器架构和内存布局给弄清楚。基址从map文件、链接脚本、烧录地址和芯片手册里面找,内存映射就按照Flash、RAM、外设区分别填进去。加载完之后,再检查一下跳转、入口、字符串和函数边界,发现整体有偏移就用重设基址,发现局部段有错就单独去调整它。这样处理完了之后,bin文件的反汇编和伪代码,才有继续往下分析的价值。
