审计模式下的循环影子堆栈的制作方法

文档序号:36964949发布日期:2024-02-07 13:11阅读:25来源:国知局
审计模式下的循环影子堆栈的制作方法


背景技术:

1、在大多数现代计算架构中,操作系统将系统存储器的针对每个线程的部分分配给调用堆栈(有时被称为机器堆栈或执行堆栈)。该调用堆栈被用于促进应用代码内的程序调用(例如,函数、例程等)。通常,每当程序在线程的执行期间被调用时,新的堆栈帧被添加或“推送”到针对该线程的调用堆栈。该堆栈帧通常由程序的“序言”创建,“序言”可以保存返回到调用上下文所需的状态信息(例如,要在程序退出之后被执行的下一指令的返回地址、所保存的寄存器值等),为传递给程序的任何参数分配存储器,为程序的局部变量分配存储器等。堆栈帧中包括的特定数据以及该数据的布局根据处理器架构、操作系统等而异。当程序退出时,其堆栈帧被从针对线程的调用堆栈中去除或“弹出”。该堆栈帧通常通过程序的“尾声”被去除,尾声可以恢复调用上下文所需的已保存的信息(例如,通过将所保存的返回地址放置在程序计数器或指令计数器中,恢复所保存的寄存器值等),并且解除分配由堆栈帧占用的任何调用堆栈存储器。

2、最近,一些操作系统和/或处理器已包括对影子堆栈(shadow stack)的支持。影子堆栈是这样的机制,该机制用于诸如在调用堆栈“缓冲区溢出”引起程序在完成时返回到除了其正确的返回地址以外的地址(例如,在恶意代码内,而不是在调用上下文中)时,保护程序的所存储的返回地址免受恶意或无意的修改。例如,恶意的参与者可能能够通过利用程序边界检查中的缺陷写入超出被分配给程序的堆栈帧中的参数和/或局部变量的存储器的量并且写入到程序的堆栈帧中的被用于存储程序的返回地址的堆栈存储器,完成堆栈缓冲区溢出攻击。因此,恶意的参与者可以使用堆栈缓冲区溢出来将程序的所存储的存储器地址替换为新的存储器地址(例如,在恶意的参与者自己的代码内、或者在从程序返回时不打算被执行的代码内)。针对线程的影子堆栈是第二、单独的堆栈,该堆栈将线程的正常调用堆栈消隐。当影子堆栈针对应用的线程被启用时,执行该应用的程序序言中的每个程序序言会引起要在线程的调用堆栈和线程的影子堆栈两者中存储返回地址。另一方面,执行该应用的程序尾声中的每个程序尾声会引起要从线程的调用堆栈和线程的影子堆栈两者加载返回地址,然后将它们进行比较。如果在调用堆栈与影子堆栈之间返回地址的两个记录不同,则影子堆栈违规(violation)被检测并且线程(或线程所属的进程)被终止。


技术实现思路

1、当影子堆栈强制执行(enforcement)特征在生态系统内被启用时,需要以预期方式利用其调用堆栈来执行代码;否则,该代码可能会引起致命的系统错误,诸如“蓝屏”、内核崩溃等。但是,并非所有代码当前都符合影子堆栈功能。为了确保生态系统和/或驱动程序符合影子堆栈功能,审计模式可以被启用以获取与影子堆栈强制执行被启用时哪些代码中断有关的遥测数据(telemetry)。在实施例中,当影子堆栈不匹配发生时,cpu发布异常(例如,控制保护异常)。在审计模式下,当异常被发布时,不会强制执行任何策略,而是影子堆栈中的不匹配条目被替换为调用堆栈中的条目,并且报告遥测数据可以被生成(例如,包括应用二进制文件名称、回溯跟踪信息等)。开发人员然后可以利用该遥测数据来改进影子堆栈兼容性,以将应用二进制文件添加到影子堆栈阻止列表等。因此,与影子堆栈的不兼容可以在审计模式下被捕获。

2、但是,特定不兼容影子堆栈的软件程序,诸如(但不限于)特定游戏,其行为不同,使得返回地址的不匹配无法简单地通过将影子堆栈中的返回地址替换为调用堆栈中的返回地址来缓解。例如,当一些不兼容的软件程序正在审计模式下运行时,它们不知道影子堆栈。当这样的软件程序连续地执行调用时,许多地址被不断推送到调用堆栈和影子堆栈两者上。由于这样的现象不会触发cpu发布传统的控制保护异常,因此影子堆栈可能会溢出其被分配的存储器缓冲区并且引起致命的系统错误。

3、本文中描述的至少一些实施例通过在审计模式下将影子堆栈的至少一部分启用为循环堆栈(circular stack)来解决上述问题,使得当影子堆栈的使用量(usage)达到所限定的使用量阈值时,影子堆栈的至少一部分中的内容被覆写。因此,在审计模式下,计算机系统能够在同时防止影子堆栈溢出以及引起致命的系统错误的同时获取当前与影子堆栈不兼容的特定应用二进制文件的数据。

4、一些实施例涉及在审计模式下将影子堆栈的至少一部分启用为循环堆栈的方法、系统和计算机程序产品。线程的执行在处理器处被发起。这包括发起应用二进制文件的可执行代码的执行作为线程的一部分。应用二进制文件在审计模式下针对影子堆栈功能被启用。至少基于在审计模式下在处理器处执行线程,影子堆栈的至少一部分被变为循环堆栈。将影子堆栈的至少一部分变为循环堆栈包括:确定影子堆栈的使用量是否已经达到所限定的使用量阈值。响应于确定影子堆栈的使用量已经达到所限定的使用量阈值,影子堆栈中的返回地址的一个或多个条目被覆写,从而防止影子堆栈溢出被分配给影子堆栈的存储器区域。

5、例如,软件程序(其不知道影子堆栈)可能会手动自行管理其调用堆栈(包括返回地址)以允许更深入的递归,从而引起影子堆栈耗尽被分配给影子堆栈的存储器区域。在一些情况下,软件程序可以在不干预类似“ret”的指令的情况下重复使用类似“调用(call)”的指令(例如,函数调用),类似“调用”的指令也使用影子堆栈。由于类似“ret”的指令被配置为弹出和验证影子堆栈中的条目,因此没有类似“ret”的指令的这样的类似“调用”的指令将引起影子堆栈继续增长。当这样的类似“调用”的指令或函数调用过多时,它们将值推送到影子堆栈上可能会引起影子堆栈耗尽(也被称为“影子堆栈溢出”)。当影子堆栈溢出发生时,可能会发生致命的cpu异常。本文中描述的实施例可以防止致命的cpu异常,即使这可能意味着损坏影子堆栈的至少一部分(通过使其循环)。再例如,软件程序不是使用“ret”指令,而是使用分支指令来返回。在这样的情况下,影子堆栈上的对应返回地址不会被弹出,并且影子堆栈溢出也可能最终发生。

6、在一些实施例中,响应于对影子堆栈的一个或多个当前被使用的条目进行覆写,与线程相关联的一个或多个遥测数据被记录。在一些实施例中,一个或多个遥测数据包括(但不限于)以下至少一项:(1)线程所属的进程的标识符,(2)线程的标识符,和/或(3)与线程相关联的应用二进制文件的标识符。在一些实施例中,应用二进制文件是设备驱动程序。应用二进制文件标识符的示例包括(但不限于)文件名、二进制文件的特定部分的哈希值、应用二进制文件的嵌入式版本元数据、和/或它们的组合。

7、在一些实施例中,影子堆栈功能也可以在强制执行模式下被启用。当强制执行模式被启用时,计算机系统不会将影子堆栈的任何部分启用为循环堆栈。在一些实施例中,将影子堆栈启用为循环堆栈还包括:确定审计模式在使影子堆栈成为循环堆栈之前被启用。

8、在一些实施例中,影子堆栈基于被分配给影子堆栈的存储器区域的大小包括针对返回地址的条目的最大数目的空间,并且返回地址的一个或多个条目被输入最大数目的空间当中的一个或多个顺序(sequential)空间中,直到影子堆栈的使用量已经达到所限定的使用量阈值。

9、本
技术实现要素:
旨在以简化的形式介绍一系列概念,这些概念将在以下的具体实施方式中被进一步描述。本发明内容不旨在标识所要求保护的主题的关键特征或基本特征,也不旨帮助确定所要求保护的主题的范围。

当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1