
汇编是一种与机器码密切相关的低级编程语言,它使用符号和助记符来表示机器码指令。
每种计算机架构都有其特定的汇编指令集,如ARMv7-M架构,支持Thumb-2指令集,Thumb-2结合了16位和32位指令,以实现最佳的性能与代码大小比;大多数指令可单周期执行,并通过向量表支持确定性硬件中断。
反汇编是一种将机器码转换为可读的汇编代码的过程,其目的是能够读取目标设备内存中的二进制数据,并通过反汇编器执行这些代码。通过已知的目标设备的指令集以及它启动时所处的模式,我们可以逆向工程出由编译器生成的原始汇编代码,示例见图1。
如果反汇编器拥有二进制文件的源代码信息,还可以将源代码与反汇编指令进行关联。这些附加信息可通过调试符号引用。
让我们再来看一下SEGGER Embedded Studio开发环境中的一个小型加法函数调试示例。
_AddTwoNumbers函数代码实现了Num1和_Num2两个变量相加的操作。Num1是函数内的局部变量,_Num2是可在文件作用域内访问的静态变量。
图3 _AddTwoNumbers函数的ARM反汇编
我们有C语言源代码工程,调试器可以在反汇编视图中引用相应的源码行,以获得更好的上下文信息。应用程序在C源码级别时停止在加法函数处。但在汇编级别,我们可以看到,一条C语言的代码行会扩展为从地址0x12000094开始的六条指令。
第一条指令将堆栈中的第一个操作数变量(Num1)加载到寄存器R0中。接下来的两条指令加载第二个操作数所在的地址。之后,从该地址加载_Num2变量值,并将其存储到寄存器R1中。最后,将两个寄存器的值相加,结果存储在寄存器R0中,然后压入堆栈。
如果我们将此过程与CPU寄存器结合使用,就能获得非常详细的系统信息,精确跟踪应用程序以及MCU执行的每一步操作。通过验证每一条被执行的指令,我们可以找出潜在的错误。
另一个应用场景是连接未知的应用程序。大多数调试器都提供连接已运行系统的选项。我们只需连接到目标设备,即可控制正在运行的黑盒应用程序。
图4展示了连接设备执行被停止时的反汇编结果。
目前应用已暂停在地址0x08002DE6处。通过简单地查看芯片并手动查找其参考信息,我们便能确定正在调试的目标设备。这样,我们就能立即判断该代码段是在Flash还是RAM中运行。此外,我们还能访问CPU寄存器,从而无需查看原始源码,即可尝试理解并逆向工程运行在芯片上的目标应用程序。
如图所示,只要能够控制目标系统并拥有反汇编器,我们就能获得非常详细的系统洞察,了解目标设备上究竟发生了什么。
示例代码工程可以访问链接:https://pan.baidu.com/s/1bbcmlZdxGPEmrVY4iH1O7g?pwd=nxfk下载或阅读原文,工程基于Embedded Studio simulator运行。
SEGGER Embedded Studio是管理、构建、测试和部署嵌入式应用程序的IDE,无缝集成J-Link工具,提供强大的应用调试功能。麦克泰技术作为SEGGER代理商,秉承“让嵌入式软件开发更容易”的理念,致力于推广嵌入式软件开发工具、测试软件和嵌入式操作系统及中间件。更多SEGGER产品信息,欢迎联系info@bmrtech.com。
欢迎关注微信公众号【麦克泰技术】,回复 “加群” 按提示可加入技术交流群
产品咨询:
北京:010-62975900
上海:021-62127690
深圳:0755-82977971
分享、在看与点赞,至少我要拥有一个吧
关于科技区角:国内科技展会垂直内容策划服务商,提供从论坛内容全案策划、会展市场化IP打造到精准专业观众一站式邀约服务,以产业内容吸引高质量B端人群,打通展会从议题设计、演讲嘉宾邀约、宣传预热、精准邀观到供需对接全链路。