修复缓冲区溢出问题
2009-03-07 20:02:33 来源:WEB开发网然而,您不能想当然地信任 cbName 。攻击者可以设置该名称和缓冲区大小,因此必须进行检查!
探测内存
如何判别 szName 和 cbName 是有效的?您相信用户会提供有效的值吗?一般来说,答案是否定的。验证缓冲区大小是否有效的一个简单方法是探测内存。以下代码段显示了如何在代码的调试版中完成这一验证过程:
void Function(char *szName, DWORD cbName) {
char szBuff[MAX_NAME];
#ifdef _DEBUG
// 探测
memset(szBuff, 0x42, cbName);
#endif
// 复制并使用 szName
if (cbName < MAX_NAME)
strncpy(szBuff,szName,MAX_NAME-1);
}
此代码将尝试向目标缓冲区写入值 0x42。您可能会想,为什么要这样做而不是直接复制缓冲区呢?通过向目标缓冲区的末尾写入一个固定的已知值,可以在源缓冲区太大时,强制代码失败。同时这样也可以在开发过程中及早发现开发错误。与其运行攻击者的恶意有效代码,还不如让程序失败。这就是不复制攻击者的缓冲区的原因。
注意:您只能在调试版中这样做,以便在测试过程中捕获缓冲区溢出。
采取防范措施
说实话,探测虽然很有用,但它并不能使您免遭攻击。真正安全的办法是编写防范性的代码。您会注意到代码已经具有防范性了。它将检查进入函数的数据是否不超过内部缓冲区 szBuff 。然而,有些函数在处理或复制不可靠的数据时,如果使用不当,则会存在潜在的严重安全问题。这里的关键是不可靠的数据。在检查代码的缓冲区溢出错误时,应跟踪数据在代码中的流向,并检查各种数据假设。当您意识到有些假设不正确时,您也许会惊异于所发现的错误。
更多精彩
赞助商链接