如何利用MCU单片机嵌入式开发工具中的堆栈保护功能

文章图片

在开发以MCU单片机为核心的嵌入式系统时,当软件程序将数据写入预设数据结构(通常为固定长度的缓冲区)以外的程序调用堆栈的存储地址范围时,就会产生堆栈。缓冲区溢出。这几乎肯定会破坏附近的数据,甚至改变返回函数。如果是故意的,这就是我们所知的堆栈粉碎。防止堆栈缓冲区溢出的一种方法是使用堆栈金丝雀,它的命名是因为它与在煤矿中使用金丝雀检测有毒气体相似。目前,在所有以IAR Embedded Workbench为代表的领先开发工具的最新版本中,都已经支持堆栈保护功能。

堆栈保护已经成为最新的嵌入式开发工具的一个必要特性,但是为了在工业标准工具(如IAR Embedded Workbench for ARM)中实现堆栈保护,使用了一种启发式算法来确定函数是否需要堆栈保护。如果在函数中定义的任何局部变量是数组类型或包含数组类型成员的结构类型,则该函数需要堆栈保护。此外,如果任何局部变量的地址在函数外部传播,则该函数也需要堆栈保护。

嵌入式开发工具.png

如果一个函数需要堆栈保护,那么函数的局部变量将按顺序排列,数组类型的变量将放在函数堆栈中可能的最高地址。在这些变量之后,放置一个加那利元素。在函数入口处,将初始化Canary。初始化值是从全局变量__stack_chk_guard。在函数退出时,代码验证Canary元素是否仍然包含初始化值。如果值被改变,函数__stack_chk_fail将被调用。


以广泛使用的IAR Embedded Workbench for Arm嵌入式开发工具为例,使用Project>选项>C/C编译器>代码>堆栈保护选项,则可以对标识为需要保护的函数启用堆栈保护。


或者,您也可以使用Project>选项>C/C编译器>在“额外选项”页上,指定--stack_protection命令行以启用堆栈保护。


栈保护在实际应用中的实现。


要使用堆栈保护,开发人员必须在其应用程序中定义以下对象。


外部单位堆栈_chk_guard全局变量__stack_chk_guard必须在第一次使用前初始化。如果初始化值是随机的,则更安全。


互通无风无回栈校验失败&#40第41名。stack_chk_fail函数的功能是通知发生了错误,然后终止应用程序。 

注意,这个函数的返回地址将指向失效函数。

arm\src\lib\runtime目录中的文件stack_protection.c为_stack_chk_guard提供了一个参考模板和__堆栈_chk_fail函数。


发表评论

评论

    暂无评论

©Copyright 2013-2025 亿配芯城(深圳)电子科技有限公司 粤ICP备17008354号

Scroll