欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Win32 API (3) ZeroMemory,SecureZeroMemory

程序员文章站 2022-03-05 09:54:11
...

ZeroMemory

ZeroMemory 是一个宏,不是函数,它的定义如下:

#define ZeroMemory RtlZeroMemory
#define RtlZeroMemory(Destination,Length) memset((Destination),0,(Length))

我们发现,这个 ZeroMemoryRtlZeroMemory 的宏定义,而 RtlZeroMemory 是一个有参宏,最终是通过调用C标准库函数 memset 来实现的。

下面为了方便,我们还是以函数原型的形式展示它的用法:

void ZeroMemory(
  [in] PVOID  Destination,
  [in] SIZE_T Length
);
参数说明:

Desitination:需要被填充0的内存块的起始地址

Length:需要被填充0的内存块以字节为单位计数的长度

注意事项:

不同语言可能提供了不同的语法用于将复杂变量初始化为0,他们的具体行为可能和 ZeroMemory 有所区别,因此在开发 Windows 应用程序最好总是使用 ZeroMemory 来清零内存块。对于 C/C++ 来说使用 memset 其实也是一样的,具体用什么看应用场合了,编写跨平台的应用程序应该使用标准库。

依赖信息:
名称
Header WinBase.h (include Windows.h)

某些编译器在开启优化的情况下,可能会忽略掉对 memset 或者是 ZeroMemory 的调用,此时应该使用另一个ZeroMemory 的安全版本 SecureZeroMemory

PVOID SecureZeroMemory(
  _In_ PVOID  ptr,
  _In_ SIZE_T cnt
);

参数和 ZeroMemory 都是完全一样的,区别在于 SecureZeroMemory 返回一个指向内存块的指针,下面是一个使用 SecureZeroMemory 代替 ZeroMemory 的例子,取自MSDN。

WCHAR szPassword[MAX_PATH];

// Retrieve the password
if (GetPasswordFromUser(szPassword, MAX_PATH))    
   UsePassword(szPassword);
// Clear the password from memory
SecureZeroMemory(szPassword, sizeof(szPassword));

在内存清0以后,该程序后面没有再引用 szPassword ,因此如果使用 ZeroMemory 就有可能会被编译器优化掉,但是该变量的原始值仍然保留在栈上,仍然可以通过其他途径被访问到,而这一块内存的内容是密码,出于安全考虑,我们无论如何都应该讲这段内存清0。

相关标签: Windows API