zoukankan      html  css  js  c++  java
  • (转) 遭遇sprintf导致的堆栈崩溃。不使用sprintf_s()的代价

    问题描述:

    一直以来,引擎都运行的很稳定。而且在所有电脑上都很稳定。

    但是,唯独一个笔记本不行。引擎在其上一运行就崩掉。

    问题分析:
    根据生成的dump文件,windbg的分析结果为:
    The stored exception information can be accessed via .ecxr.
    (c98.da0): Stack buffer overflow - code c0000409 (first/second chance not available)

    还有 frame IP 被破坏, (IP是什么来着? 指令地址?忘了,权当作当前frame的基地址吧)可见, 可能是堆栈的基地址被破坏了


    查看调用堆栈:
    。。。一些系统的dll内部函数
    xeyez!funxEyeLoadAllDll( ),

    。。。。

    问题应该出在funxEyeLoadAllDll这里,
    根据windbg提示的出错行,定位到该函数的最后一行!! 可见就是函数返回时,返回失败!

    查看该函数的实现:

    int funxEyeLoadAllDll( )
    {
     char * strOldEnv;
     strOldEnv = getenv("Path");
     // 把插件目录加入到环境变量,以便可以让系统载入DLL时找到插件间依赖的DLL
     char newEnv[1024] = {0};
     sprintf(newEnv,"Path=%s;.\\External;.\\USB",strOldEnv);


     TCHAR buf[MAX_PATH] = {0};
     TCHAR *psz;
     GetModuleFileName(NULL, buf, MAX_PATH);
     

     。。。。。。

     。。。。。。
    }  // windbg提示该行出错           <-------------

    经分析,可能问题出在 下面代码处,下面代码的意思是,把当前系统的PATH环境变量读入到newEnv中。
    由于使用sprintf非安全版,就可能破坏堆栈!
    char newEnv[1024] = {0};
     sprintf(newEnv,"Path=%s;.\\External;.\\USB",strOldEnv);

    果然, 查看那个笔记本的path变量,居然有10几行,每行有100多个字母!

    看来,防御性编程是很有必要的!
    不要假设客户的电脑的情况!
    还好,现在可以使用windbg+pdb文件调试,要是不能,这样的bug不知会调到什么时候!更要命的是,可能会被黑客攻击

    本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/zdl1016/archive/2009/04/15/4076796.aspx

  • 相关阅读:
    面向对象编程——设计模式之一
    mysql死锁——mysql之四
    Mysql基本类型(字符串类型)——mysql之二
    Mysql基本类型(五种年日期时间类型)——mysql之二
    Mysql基础教程——mysql之一
    JVM启动参数手册——JVM之八
    Thinkphp 框架2
    Thinkphp 框架
    流程(下)
    流程(上)
  • 原文地址:https://www.cnblogs.com/lancidie/p/1895644.html
Copyright © 2011-2022 走看看