何时以及如何使用GCC的堆栈保护功能?

Gui*_*ume 59 c++ stack gcc protection

-Wstack-protector在编译正在进行的项目时启用了警告(商业多平台C++游戏引擎,使用GCC 4.2在Mac OS X 10.6上进行编译).此标志警告即使-fstack-protector启用了也不会防止堆栈粉碎的功能.GCC在构建项目时会发出一些警告:

不保护功能:没有缓冲区至少8个字节长
不保护局部变量:可变长度缓冲区

对于第一个警告,我发现可以调整缓冲区在函数中使用时必须具有的最小大小,以防止此函数发生堆栈粉碎:--param ssp-buffer-size=X可以使用,默认情况下X为8,可以为低至1.

对于第二次警告,除非我停止使用,否则无法抑制其发生-Wstack-protector.

  1. 什么时候应该-fstack-protector使用?(例如,在开发期间的所有时间,或者只是在跟踪错误时?)
  2. 什么时候应该-fstack-protector-all使用?
  3. 什么在-Wstack-protector告诉我?它是否暗示我减少缓冲区最小尺寸?
  4. 如果是这样,将尺寸设为1有什么缺点吗?
  5. -Wstack-protector如果您想要一个无警告的构建,它似乎不是您想要随时启用的那种标志.这是正确的吗?

小智 65

堆栈保护是一种强化策略,而不是调试策略.如果您的游戏具有网络感知能力,或者其他数据来自不受控制的来源,请将其打开.如果没有来自某处不受控制的数据,请不要打开它.

以下是它如何发挥作用:如果您有一个错误并根据攻击者可以控制的内容进行缓冲区更改,则该攻击者可以覆盖返回地址或堆栈的类似部分,以使其执行代码而不是代码.如果检测到这种情况,堆栈保护将中止您的程序.您的用户不会满意,但他们也不会被黑客攻击.这不是那种在游戏中作弊的黑客行为,而是一种黑客行为,即使用代码中的漏洞创建可能会感染用户的漏洞.

对于面向调试的解决方案,请查看mudflap等内容.

至于你的具体问题:

  1. 如果从不受控制的来源获取数据,请使用堆栈保护程序.答案可能是肯定的.所以使用它.即使您没有来自不受控制的来源的数据,您可能最终或已经做过而且没有意识到这一点.
  2. 如果您想要额外的保护以换取一些性能损失,可以使用所有缓冲区的堆栈保护.从gcc4.4.2手册:

    -fstack保护器

    发出额外的代码来检查缓冲区溢出,例如堆栈粉碎攻击.这是通过向具有易受攻击对象的函数添加保护变量来完成的.这包括调用alloca的函数,以及大于8字节的缓冲区的函数.输入功能时会初始化防护装置,然后在功能退出时进行检查.如果防护检查失败,则会打印错误消息并退出程序.

    -fstack保护器,所有

    与-fstack-protector类似,但所有功能都受到保护.

  3. 警告告诉您堆栈保护无法保护的缓冲区.

  4. 它不一定建议您减小最小缓冲区大小,并且在大小为0/1时,它与stack-protector-all相同.如果您决定重新设计代码以便缓冲区受到保护,那么它只是指向您,以便您可以.
  5. 不,这些警告不代表问题,他们只是向您指出信息.不要经常使用它们.

  • 堆栈保护的调试策略是可能的,有时也很有用:(1) 执行使用堆栈保护编译的二进制文件,并在调试器中禁用 ASLR(地址空间布局随机化)。(2) 等待一个内核。(3) 核心将指示被破坏的堆栈金丝雀的地址。(4) 在调试器中重新运行你的二进制文件,并在被破坏的堆栈金丝雀地址上设置一个硬件观察点。(5) 当位于罪魁祸首地址的内存被修改时,调试器将停止。 (3认同)