Win32 API (3) ZeroMemory,SecureZeroMemory
程序员文章站
2022-03-05 09:54:11
...
ZeroMemory
ZeroMemory
是一个宏,不是函数,它的定义如下:
#define ZeroMemory RtlZeroMemory
#define RtlZeroMemory(Destination,Length) memset((Destination),0,(Length))
我们发现,这个 ZeroMemory
是 RtlZeroMemory
的宏定义,而 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。
上一篇: redis-共享对象池