傻孩子(GorgonMeducer) · 2020年10月13日

【嵌入式秘术】手把手教你如何劫持RTOS(上)

作者:GorgonMeducer 傻孩子
首发:裸机思维
前言:

无论出于何种"学习"目的,作为用户,有时候我们总难免需要在“运行时刻”对RTOS所使用的关键系统资源"检视一番",比如 SysTick,PendSV,SVCall之类中断发生的时候,操作系统的用户可以在RTOS之前“神不知鬼不觉”的先获得执行自己指定的小程序的机会——哪怕是写个“到此一游”也好——这种操作当然不能去修改RTOS的源代码;尤其是RTOS以库的形式提供时特别有意义。那么具体如何去实现呢?

【说在前面的话】

作为一篇严肃的技术文章,我们首先要以最大的善意来看待读者打开这篇文章的动机——肯定是学习目的啦——并在此基础上精确定义“所要实现的功能、目的”、以及“所使用的环境”是怎样的:

环境

  • Cortex-M 微控制器
  • 任意的RTOS——无论其是以源代码形式还是以库的形式参与工程编译
  • 裸机环境
  • 使用 Arm Compiler 作为编译环境
  • 其它编译环境需要阅读对应的用户手册找到类似的解决方案
  • RTOS 或者某些库 占用了关键的系统资源,比如 SysTick、PendSV以及SVCall
  • RTOS 可能将用户任务限制在非特权模式下运行,且受到MPU的监管而无法访问任务权限以外的资源

我们要实现的功能

  • 劫持SysTick、PendSV、SVCall 之类关键的被 RTOS 占用的中断处理,即:
  • 当这些中断被触发时,首先执行我们指定的代码
  • 劫持的过程不能影响RTOS已有的正常功能
  • 由于我们所劫持的系统资源具有非常高的系统权限,理论上我们可以:
  • 对RTOS 的行为进行额外的追踪和调试
  • 重新配置MPU

限制要素

  • 不能修改 RTOS的源代码、或者说对于RTOS以库提供的形式实际上我们也无法修改对应的中断处理程序

【先从劫持SysTick开始】


大部分 RTOS 会使用由 SysTick、PendSV 或是 SVCall 产生的异常(Exception)来完成系统的上下文切换,因此只要劫持了这些关键异常的中断处理程序就能轻松实现对 RTOS 的劫持。

这里,“劫持”(Hijack)虽然是一个听起来特别酷的信息安全词汇,但翻译成人话并不复杂,即:当对应的异常被触发时,在执行原先由RTOS 所提供的异常处理程序之前,首先执行由第三方(也就是我们)所“插入”的特定小程序;并在“事成之后”重新回到原本RTOS的处理程序中去执行,从而掩盖了我们所作的“小动作”

640.png

要理解这一过程以及具体的操作方法,我们不妨以劫持SysTick为例,对于PendSV以及SVCall来说,完全可以如法炮制,本文也不再赘述。为了将问题简化,我们不妨假设某一个已经编译成Library的算法库,它在内部提供了一个SysTick的异常处理程序:

//! 某一个算法库占用了SysTick,并实现了一个对应的异常处理程序

假设,作为用户,我们有一系列操作希望加入到SysTick\_Handler中:

__attribute__((used))       /* Linker不要开枪,自己人!*/

由于该函数已经固化在算法的库文件里了,我们实际上没法像修改源代码那样向SysTick\_Handler中添加对函数 user\_code\_insert\_to\_systick\_handler() 的调用。怎么办呢?

专栏推荐文章


如果你喜欢我的思维,欢迎订阅裸机思维
版权归裸机思维(傻孩子图书工作室旗下公众号)所有,
所有内容原创,严禁任何形式的转载。
推荐阅读
关注数
1466
内容数
108
探讨嵌入式系统开发的相关思维、方法、技巧。
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息