【问题标题】:Issue with new/delete with SecureZeroMemorySecureZeroMemory 的新建/删除问题
【发布时间】:2018-03-09 21:06:21
【问题描述】:

谁能帮我理解为什么我的代码在第一个代码块中的 delete[] szPassword 上失败了?我知道szPassword只是复制“a”,st2等于8:

TCHAR *szPassword = new TCHAR[2]();
StringCchCopy(szPassword, 2, L"ab");
SIZE_T st2 = sizeof(szPassword);
SecureZeroMemory(szPassword, st2);
delete[] szPassword;

但是,当它运行时,没有得到 sizeof() 值,它工作正常:

TCHAR *szPassword = new TCHAR[2]();
StringCchCopy(szPassword, 2, L"ab");
SecureZeroMemory(szPassword, 2);
delete[] szPassword;

【问题讨论】:

  • 你检查过sizeof(szPassword);给你的价值吗? (提示:极不可能是 2)
  • 很明显,您对SecureZeroMemory 的调用最终会超出数组的边界,调用未定义的行为
  • 不是“可以”,但可以。你知道未定义的行为是什么意思吗?
  • 未定义的行为意味着任何事情都可能发生。在你的情况下,你似乎很幸运,编译器在delete[] 捕获它(这让我相信你在调试模式下运行它)
  • @JeffR,例如使用std::vector

标签: c++ winapi new-operator delete-operator securezeromemory


【解决方案1】:

szPassword 是一个指针,而不是一个数组,因此sizeof(szPassword) 将是 4 或 8。在 64 位应用程序中这太多了,您将尝试将 8 个字节写入 4 字节缓冲区。

C++ 运行时允许分配比您要求的更多,并且它经常这样做,因此它可以将特殊数据添加到缓冲区的末尾,以便检测缓冲区溢出。

改为这样做:

const UINT charcount = 2;
TCHAR *szPassword = new TCHAR[charcount];
...
SecureZeroMemory(szPassword, charcount * sizeof(TCHAR));
delete[] szPassword;

如果缓冲区总是很小,你可以在堆栈上使用一个数组:

TCHAR szPassword[200];
...
SecureZeroMemory(szPassword, sizeof(szPassword));

【讨论】:

  • 所以在这个例子中,使用 szPassword[200],你是说只要缓冲区大于 8,那么 sizeof() 就可以工作?如果是这样,那不就是将前 4 或 8 个字节的内存清零吗?
  • 不,在第二个示例中,szPassword 在数组中,而不是指针。如果您正在编译 Unicode 应用程序,则在第二个示例中它将是 400 字节。这是基本的 C 内容,您需要了解指针和数组之间的区别。
  • TCHAR a[20], *b = new TCHAR[20]; 并在这两个上尝试sizeof
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-09
  • 1970-01-01
  • 2018-01-31
  • 1970-01-01
相关资源
最近更新 更多