1、前言
之前我不常用反汇编,最近调试迫不得已,需要反汇编的技巧,所以特地试验了一下,结果流程跑通,特此记录。
本次反汇编的尝试,大体流程为,从 Flash 读取程序 -> 反汇编 BIN 文件 -> 与源程序对比。同时,编程环境是"我的往期文章",所以反汇编工具也会向环境靠拢。
为什么不使用keil的反汇编窗口呢。是因为即使魔术棒对debug设置了调试进行前不下载程序,开始debug后,keil依然会把工程源码重新覆盖到flash上,这样的话,整个工程肯定可以正常运行,但无法找出问题。
2、从 Flash 读取程序
代码和数据,最终都会存储到flash中,本质都是十六进制数据。这一步是为了将这些数据转换为.bin文件,方便后续处理。
stm32官方有STM32CubeProgrammer,可以从芯片flash直接读取一定量的数据,并自定义输出文件。注意硬件需要ST-Link工具。
准备好软件STM32CubeProgrammer和硬件ST-Link工具后,将芯片下载口连接到电脑,打开STM32CubeProgrammer。软件右上角选择ST-Link,点击connect。

上图的Address 0x08000000是起始地址,Size是读取大小。这两个是需要自定义的地方。
我习惯在工程设计过程中,随时更新Bootloader、用户区、flash用户数据区的区域划分,keil的魔术棒会随时与对应工程保持一致,这两个参数就直接按照下图填入参数0x08004000和0x19000。

修改完参数,点击下图read,得到下图。

read右侧下拉框选择save as,选择好文件保存路径即可输出.bin文件,比如文件名是V1_2_0.bin。
3、反汇编 BIN 文件的准备工作
下载安装好GNU Arm嵌入式工具链,下面简单讲解工具链与编程环境的适配。
找到windows环境变量,如下图,在系统变量中找到名称"Path",点击编辑。在弹出的对话框中添加工具链的路径,比如"D:\gcc-arm-none-eabi-10.3-2021.10-win32\gcc-arm-none-eabi-10.3-2021.10\bin"

路径"D:\gcc-arm-none-eabi-10.3-2021.10-win32\gcc-arm-none-eabi-10.3-2021.10\bin"下的文件如下,可参考:

最后,需要重启vscode,包括所有的vscode窗口。目的是vscode重新加载系统变量,从而读取到我们添加的工具链路径,从而才能使用相关命令。
4、反汇编 BIN 文件
这一步是将 小节2 生成的.bin文件转换为.asm文件,本质是工具命令行调用。所以电脑自带的命令行工具,或者vscode的终端都是可以的。我使用vscode终端。
我会将 小节2 生成的.bin文件输出到stm32工程的"xxx\xxx\MDK-ARM"路径下,vscode打开该工程,终端默认位置就在这个路径下,可以直接对文件进行操作,从"先cd文件夹,再执行反汇编命令"中省略了"cd文件夹"。
在vscode终端中输入如下命令,将V1_2_0.bin转换为V1_2_0.asm文件。

5、与源程序对比
vscode打开V1_2_0.asm文件,keil正常debug并查看反汇编窗口Disassembly,对比同一地址下的指令,发现地址范围 0x0800BF88 ~ 0x0800BFFC内数据都是0xFFFF FFFF,而且该范围正好位于串口通信函数,导致该函数没有完整的函数名和形参列表,以及前半段协议逻辑。因此,会进入HardFault_Handler中去。