wordpress mip教程,WordPress博客程序优化,cms类型网站开发,网站开发人员负责方面说说栈保护指令 在分析反汇编代码时#xff0c;经常会看到一些特殊的指令序列。这些指令不是程序的功能逻辑#xff0c;而是编译器插入的安全保护代码#xff0c;专门用来防御栈溢出攻击。理解这些指令的作用#xff0c;对逆向分析很有帮助。基本工作原理 栈溢出攻击利用的…说说栈保护指令在分析反汇编代码时经常会看到一些特殊的指令序列。这些指令不是程序的功能逻辑而是编译器插入的安全保护代码专门用来防御栈溢出攻击。理解这些指令的作用对逆向分析很有帮助。基本工作原理栈溢出攻击利用的是程序的内存管理漏洞。函数调用时会在栈上分配局部变量空间。如果向局部变量写入数据时没有检查长度就可能写超出分配的空间覆盖栈上的其他数据比如函数返回地址。攻击者可以精心构造输入数据让溢出的数据中包含恶意代码的地址从而控制程序执行流程。这是很经典的一种攻击方式。编译器的防护思路很简单在函数开始时在栈上放一个“金丝雀”值函数返回前检查这个值是否被修改。如果被修改了说明栈可能被破坏了程序就主动崩溃不让攻击者得逞。这个“金丝雀”在Windows里叫__security_cookieLinux里叫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_cookie4 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中可以写脚本自动识别这些模式标记出有栈保护的函数。动态调试时可以在检查函数设条件断点监控哪些函数频繁触发检查这可能提示有问题的代码区域。总结栈保护指令是编译器安全加固的一部分。虽然增加了一点性能开销但大大提高了攻击门槛。在逆向分析中这些指令提供了额外的信息有助于理解程序结构和安全特性。