WEB开发网
开发学院软件开发VC 修复缓冲区溢出问题 阅读

修复缓冲区溢出问题

 2009-03-07 20:02:33 来源:WEB开发网   
核心提示: 下面我们来看一个示例,以下代码有什么错误?voidCopyData(char*szData){charcDest[32];strcpy(cDest,szData);//使用cDest...}令人惊讶的是,修复缓冲区溢出问题(2),这段代码可能没有什么错误!这完全取决于 CopyData()

下面我们来看一个示例。

以下代码有什么错误?

void CopyData(char *szData) {
  char cDest[32];
  strcpy(cDest,szData);

  // 使用 cDest
  ...
} 

令人惊讶的是,这段代码可能没有什么错误!这完全取决于 CopyData() 的调用方式。例如,以下代码是安全的:

char *szNames[] = {"Michael","Cheryl","Blake"};
CopyData(szName[1]);

这段代码是安全的,因为名字是硬编码的,并且知道每个字符串在长度上不超过 32 个字符,因此调用 strcpy 永远是安全的。然而,如果 CopyData 和 szData 的唯一参数来自不可靠的源(如套接字或文件),则 strcpy 将复制该数据,直到碰到空字符为止;如果此数据的长度大于 32 个字符,则 cDest 缓冲区将溢出,并且在内存中该缓冲区以外的任何数据将遭到破坏。不幸的是,在这里,遭到破坏的数据是来自 CopyData 的返回地址,这意味着当 CopyData 完成时,它仍然在由攻击者指定的位置继续执行。这真糟糕!

其他数据结构也同样敏感。假设某个 C++ 类的 V 表遭到破坏,如下面这段代码:

void CopyData(char *szData) {
  char cDest[32];
  CFoo foo;
  strcpy(cDest,szData);

  foo.Init();
}

此示例假定 CFoo 类具有虚方法,以及一个 V 表或该类方法的地址列表(与所有 C++ 类一样)。如果由于 cDest 缓冲区被覆盖而破坏了 V 表,则该类的任何虚方法(在此例中是 Init() )都可能调用攻击者指定的地址,而不是 Init() 的地址。顺便说一句,如果认为您的代码不调用任何 C++ 方法就安全了,那就错了,因为有一个方法始终会被调用,即该类的虚析构函数!当然,如果某个类不调用任何方法,就应该想想它存在的必要了。

上一页  1 2 3 4 5 6  下一页

Tags:修复 缓冲区 溢出

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接