Win32 API (3) ZeroMemory,SecureZeroMemory

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。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章