freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

关于thumb2指令下函数运行地址对齐问题及验证固件分析
2022-10-28 11:24:34
所属地 北京

近期,在分析Thumb2指令的一个固件文件时,发现Thumb2指令集下执行函数的运行地址不对齐?

于是,为了分析一下原因,找了手头上现有的一款基于Cortex3内核的一块板子来实际执行看一下,结合编译后的Hex文件,通过IDA来进一步验证一下Thumb2运行地址不对其的现象。

操作示例:

  • 固件代码

找了一个FreeRTOS的示例工程,加入几行打印函数地址的日志:

1666926068_635b45f4e2399c170c40d.png!small

  • 通过hex2bin将编译后的Hex文件转成二进制bin文件

执行情况:

1666926085_635b4605be7806fe44221.png!small

  • 通过ue打开bin文件备用,如下1666926167_635b4657340201244067c.png!small
    • 通过Keil-IDE加载测试代码,如下:

    通过IDE debug调试后,板子reset之后在内部时序逻辑的控制下,将0x00000000地址的内容读取到SP;将0x00000004地址的内容读取到PC。此时SP中存放的是栈顶地址,PC中存放的是Reset_Handler复位处理函数地址。

    1666926217_635b46890b6a30a71df34.png!small1666926222_635b468ea62827b73f0d2.png!small
  • 通过IDA Pro加载上述第二步生成的bin文件,配置过程如下:1666926770_635b48b210ddf4314c2ee.png!small1666926776_635b48b8049b96d062afd.png!small

    通过在示例工程中的配置,来定义加载到IDA中的内存及存储映射地址,如下:

    1666926788_635b48c4943454a04b403.png!small1666926797_635b48cd0c686e801f0eb.png!small
  • ida加载后如下:1666926807_635b48d7dc6f496d42cf5.png!small
  • 顺利找到程序入口地址:1666926834_635b48f2676d50a25465c.png!small1666926848_635b49008ac77f67cd39c.png!small

    进而找到main函数的执行地址,发现通过ldr加载到寄存器时的地址为main函数真正地址+1;通过debug,也可以验证,如下:

    1666926860_635b490c36bee96286f3a.png!small1666926865_635b4911f36fe9c5942ca.png!small

    通过资料了解到ARM指令是4字节对齐的,Thumb-2指令是2字节对齐的,所以这里main函数和函数Delay_nS的地址应该是2字节对齐的,但是打印出来的值却是:08000BB1和080002D9。main函数的地址和test函数的地址都成了奇数地址了。

    这个问题在于有些ARM处理器即能使用ARM指令,又能兼容Thumb指令,同一个应用程序中可能同时存在ARM指令和Thumb指令,这两者的处理方式肯定是大不相同的,所以为了切换ARM状态和Thumb状态,在跳转到Thumb指令编写的代码块的时候,将程序地址的最低位置1(因为不管是ARM指令还是Thumb指令,都至少是2字节对齐的,所以最低位一定是0,所以最低位可以拿来用于区分ARM状态和Thumb状态),这样处理器识别到最低位为1的话就会切换到Thumb状态,否则则是ARM状态。Thumb2指令集也是为了兼容以前的ARM状态和Thumb状态所以这样做的。

    所以编译器编译STM32F1的程序的时候,会把函数的真实地址 加上1 作为常量放在ROM空间(如果这个函数的地址有被用到的话),获取函数的指针的时候就会获取到最低位被置1的一个地址。如下图,获取Delay_nS的地址的时候,到0x08000BC4地址处读取到了0x080002D9的值,这其实就是Delay_nS的真实地址0x080002D8 + 1得到的。

    1666926886_635b49268ca23acb2bddc.png!small

    程序debug,打印出的日志如下:

    1666926896_635b493079a44fe6cda3a.png!small

    最后,在ue中固件文件中也找到了相应的Delay_nS函数的入口地址,实际在flash中的地址也是+1的,如下图:

    1666926909_635b493d4ad9100306df5.png!small
# 渗透测试 # 黑客 # CTF # 灰产圈 # ARM汇编
本文为 独立观点,未经允许不得转载,授权请联系FreeBuf客服小蜜蜂,微信:freebee2022
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者