当前位置: 首页 > news >正文

说说栈保护指令

说说栈保护指令

在分析反汇编代码时,经常会看到一些特殊的指令序列。这些指令不是程序的功能逻辑,而是编译器插入的安全保护代码,专门用来防御栈溢出攻击。理解这些指令的作用,对逆向分析很有帮助。

基本工作原理

栈溢出攻击利用的是程序的内存管理漏洞。函数调用时,会在栈上分配局部变量空间。如果向局部变量写入数据时没有检查长度,就可能写超出分配的空间,覆盖栈上的其他数据,比如函数返回地址。

攻击者可以精心构造输入数据,让溢出的数据中包含恶意代码的地址,从而控制程序执行流程。这是很经典的一种攻击方式。

编译器的防护思路很简单:在函数开始时,在栈上放一个“金丝雀”值,函数返回前检查这个值是否被修改。如果被修改了,说明栈可能被破坏了,程序就主动崩溃,不让攻击者得逞。

这个“金丝雀”在Windows里叫__security_cookie,Linux里叫canary,原理都差不多。

反汇编中的识别

在反汇编代码里,这些保护指令有固定的模式。一般出现在函数开头和结尾。

函数开头常见这样的指令:

push ebp mov ebp, esp sub esp, 栈空间大小 mov eax, __security_cookie xor eax, ebp mov [ebp-4], eax

这几行代码做了几件事。先是标准函数序言,保存ebp,设置新栈帧。然后分配局部变量空间。关键在最后三行:从全局变量获取安全cookie,和ebp做异或运算,然后把结果保存到栈上特定位置(通常是[ebp-4])。

这个异或操作是为了让cookie值更随机。单纯用固定值不够安全,和栈地址异或后,每个函数的cookie值都不同,更难预测。

函数结尾的检查代码:

mov ecx, [ebp-4] xor ecx, ebp call @__security_check_cookie@4 mov esp, ebp pop ebp retn

先取出之前保存的值,同样和ebp异或。然后调用检查函数,这个函数内部会比较计算出的值和全局cookie是否一致。如果不一致,就触发异常处理。

检查通过后,才是正常的函数返回流程。

编译器的实现细节

不同版本的编译器,实现有细微差别。VC++ 2003开始引入这个功能,当时叫Buffer Security Check。后来不断改进。

cookie的生成有讲究。程序启动时,系统会生成一个随机数作为全局cookie。在启用了ASLR(地址空间布局随机化)的系统上,这个值更难预测。

保存位置也经过考虑。通常放在局部变量区和返回地址之间。这样,如果局部缓冲区溢出,要覆盖返回地址,必须先覆盖cookie。这就起到了预警作用。

检查函数__security_check_cookie内部实现很简单:

cmp ecx, ___security_cookie jnz short failure retn failure: jmp ___report_gsfailure

比较,相等就返回,不等就跳转到错误处理。错误处理函数会记录崩溃信息,然后终止程序。

逆向分析的意义

看到这些指令,能知道几件事:

第一,程序是用VC++编译的,而且开了/GS编译选项。这个选项默认是开启的,但有些追求性能的程序可能会关掉。

第二,函数有局部缓冲区。没有局部变量的小函数,编译器可能不插入保护代码。有缓冲区操作的函数,保护代码出现的概率大。

第三,可以辅助识别函数边界。保护代码通常紧挨着函数序言和结语,找到它们有助于划分函数范围。

第四,在漏洞分析中,如果攻击要成功,必须绕过这个保护。现代漏洞利用技术,有些会先泄露cookie值,或者用其他方法绕过检查。

局限性

这个保护机制不是万能的。有几个弱点:

如果溢出不覆盖返回地址,而是修改函数指针、异常处理结构等其他控制流,可能绕过检查。

如果攻击者能获取cookie值,就可以在溢出数据中包含正确的cookie,让检查通过。这需要信息泄露漏洞配合。

有些溢出是堆溢出,不是栈溢出,这个机制就无效了。

所以现在都是组合防御,除了栈cookie,还有ASLR、DEP、CFG等各种技术一起用。

调试中的表现

调试时,如果触发了保护,会看到程序崩溃在__report_gsfailure。错误信息通常是"Stack cookie instrumentation code detected a stack-based buffer overrun"。

在OllyDbg或x64dbg里,可以在检查函数设断点,观察cookie值的变化。这对于分析漏洞利用很有帮助。

有时候攻击会故意触发这个保护,让程序崩溃,实现拒绝服务。这也是需要考虑的攻击面。

手动分析技巧

分析加了保护的程序,可以注意几点:

找到全局cookie变量,通常在.data或.rdata段。它的值在程序启动时确定,运行时不变。

注意函数序言中cookie的计算方式。老版本可能只是简单mov,新版本会做更多运算增加随机性。

在IDA中,可以写脚本自动识别这些模式,标记出有栈保护的函数。

动态调试时,可以在检查函数设条件断点,监控哪些函数频繁触发检查,这可能提示有问题的代码区域。

总结

栈保护指令是编译器安全加固的一部分。虽然增加了一点性能开销,但大大提高了攻击门槛。在逆向分析中,这些指令提供了额外的信息,有助于理解程序结构和安全特性。

http://www.jsqmd.com/news/451649/

相关文章:

  • 手把手教你配置WSL2与Neo4j:从安装到浏览器访问的全流程
  • 【免费开源】STM32F103C8T6移植DMP解算MPU9250 - 少年
  • KMS_VL_ALL_AIO:3大优势打造Windows与Office开源激活工具零基础操作指南
  • YOLOE镜像快速体验:无需训练,直接检测自定义类别(附示例图)
  • SenseVoice-small-onnx语音识别应用:法律庭审录音结构化提取实战
  • Qwen-Image-2512-Pixel-Art-LoRA镜像免配置:Gradio自动识别GPU+显存智能分配
  • PvZ Toolkit:突破游戏边界的植物大战僵尸修改工具创新指南
  • MedGemma X-Ray效果展示:胸椎侧弯与脊柱旋转AI评估
  • OFA-Image-Caption模型网络传输优化:减少延迟提升用户体验
  • 华为OD机考双机位C卷 - 二维伞的雨滴效应 (Java Python JS GO C++ C)
  • Flutter 三方库 iregexp 的鸿蒙化适配指南 - 掌控正则资产、精密 Case-insensitive 治理实战、鸿蒙级文本专家
  • 小白也能懂:Xinference-v1.17.1在Anaconda下的保姆级安装教程
  • DeepSeek推广服务联系哪家?DeepSeek推广服务联系方式 - 品牌2026
  • 怎么联系DeepSeek推广服务商?2026年服务商联系方式与能力指南 - 品牌2026
  • Qwen3-VL-4B Pro部署案例:K8s集群中水平扩展多实例图文问答服务
  • 华为OD机考双机位C卷 - 乘坐保密电梯 (Java Python JS GO C++ C)
  • DeepSeek推广怎么做?2026年DeepSeek推广服务商联系方式 - 品牌2026
  • DRG Save Editor实战指南:优化游戏体验的3个创新方案
  • 皮尔逊相关系数实战:用Excel和Python快速分析数据相关性(附完整代码)
  • Cosmos-Reason1-7B在软件测试领域的应用:自动化测试用例生成与代码分析
  • 提示工程架构师实战:未来AI应用从概念到落地的6步塑造流程
  • Java引入 Jedis 的 maven 依赖:
  • vLLM部署ERNIE-4.5-0.3B-PT性能评测:吞吐量/首token延迟/P99响应时间实测
  • nlp_structbert_sentence-similarity_chinese-large 开发入门:使用IDEA进行Java客户端SDK开发与调试
  • 3个核心优势的智能激活方案:面向办公用户的系统与软件授权管理指南
  • 基于GTE+SeqGPT的智能内容审核系统开发
  • Git-RSCLIP在Web开发中的应用:遥感图像在线检索系统
  • 别再用默认设置了!Kibana热力图高级配置指南(以机票价格分析为例)
  • Local AI MusicGen惊艳案例:AI生成音乐用于无障碍内容描述音效增强
  • nlp_structbert_sentence-similarity_chinese-large 部署效果对比:不同GPU配置下的性能基准测试