LongingForLife

导航

 

作者: 陈飞. 

加个前提:本文对应Windows下编程环境。

简而言之:一般情况,如初始化内存块的时候,用ZeroMemory。销毁内存块中储敏感数据时或者释放存有敏感数据(比如密码,密钥等)的内存块前应使用使用SecurZeroMemory。如无特殊原因不使用“={ 0 }”。

使用memset函数将内存块置0是完全没有问题。memset的好处是跨平台比较容易,可是C/C++跨平台就是梦魇。在使用memset的时候有个小地方需要注意,W.Richard Stevens在《UNIX网络编程》中提到void *memset(void *dest, int c, size_t count)的后两个参数容易写反,而且在编译时无法发现。

 

ZeroMemory宏,在底层就是由memset实现的。只是ZeroMemory易读性更好,更加健壮。或者说看起来更cool、更professional。在微软平台下的程序,推荐使用ZeroMemory。

 

SecurZeroMemory函数,可以看作是在安全方面加强版的ZeroMemory。细心的读者是否注意到ZeroMemory是宏,而SecurZeroMemory是函数?ZeroMemory在一定的编译优化条件下,使用ZeroMemory置0以后的内存块如果再也不被引用,ZeroMemory有可能会被“优化”掉而不执行。如果这块内存里存储的是用户的密码、加解密算法的密钥等敏感信息,就存在被黑客偷窥的可能。而SecurZeroMemory在任何条件下都不会被“优化”掉,所以在销毁内存块中储敏感数据时或者释放存有敏感数据的内存块前应使用SecurZeroMemory,而不是ZeroMemory。

 

至于"={ 0 }"的形式,尽量不要使用,不够直观。而且在内存对齐方面也存在一定问题。有兴趣的朋友可以参考Raymond Chen的《Why do Microsoft code samples tend to use ZeroMemory instead of { 0 }?》

顺便提一句,Raymond Chen可不是一般的人物,他是Windows组元老级人物,著有The old new thing一书,对Windows的技术历史和原理感兴趣的朋友可以一读。他的Blog: http://blogs.msdn.com/b/oldnewthing/ 到现在依然非常活跃

 

posted on 2013-09-24 14:26  hbyang  阅读(4162)  评论(0编辑  收藏  举报