现在的位置: 首页 > 综合 > 正文

strcpy_s与strcpy安全性的比较(转载)

2013年03月07日 ⁄ 综合 ⁄ 共 6345字 ⁄ 字号 评论关闭

在VC2005的CRT中,增加了一些具有更强安全性的CRT函数,例如strcpy_s, strncat_s等。

MSDN:

Significant enhancements have been made to make the CRT more secure. Many CRT functions now have more secure versions. If a new secure function exists, the older, less secure version is marked as deprecated and the new version has the _s ("secure") suffix.

中文翻译:CRT比以前的版本更安全。很多CRT中的功能函数有了更安全的版本。如果更安全的函数版本存在于CRT中,那么旧的函数会被标注为不推荐使用,同时新的版本会以旧的函数名加上_s后缀出现。

deprecate ['deprikeit]  v. 声明不赞成,抨击,反对

It should be noted that in this context, "deprecated" just means that a function's use is not recommended; it does not indicate that the function is scheduled to be removed from the CRT.

中文翻译:要注意"deprecated"是指在CRT中这个函数不被推荐使用,而不是说它从CRT中剔除了。

It should also be noted that the secure functions do not prevent or correct security errors; rather, they catch errors when they occur. They perform additional checks for error conditions, and in the case of an error, they invoke an error handler (see Parameter Validation).

中文翻译:更安全的功能函数并不能阻止错误的发生,或者修改错误,他们只能更准确和更全面的Catch错误。

For example, the strcpy function has no way of telling if the string that it's copying is too big for its destination buffer. However, its secure counterpart, strcpy_s, takes the size of the buffer as a parameter, so it can determine if a buffer overrun will occur. If you use strcpy_s to copy eleven characters into a ten-character buffer, that is an error on your part; strcpy_s cannot correct your mistake, but it can detect your error and inform you by invoking the invalid parameter handler.

以下下是使用strcpy_s与strcpy的安全性比较

char szBuf[2] = {0};

strcpy_s(szBuf, 2, "12131");  //新的CRT函数
strcpy(szBuf,  "12131");    //老的CRT函数

上述代码,明显有缓冲区溢出的问题。 使用strcpy_s函数则会抛出一个异常。而使用strcpy函数的结果则未定,因为它错误地改变了程序中其他部分的内存的数据,可能不会抛出异常但导致程序数据错误,也可能由于非法内存访问抛出异常。

使用新的增强安全的CRT函数有什么好处呢?简单地说,新的函数加强了对参数合法性的检查以及缓冲区边界的检查,如果发现错误,会返回errno或抛出异常。老版本的这些CRT函数则没有那么严格的检查与校验,如果错误地传输了参数或者缓冲区溢出,那么错误并不能被立刻发现,对于定位程序错误也带来更大困难。

以下是MSDN关于CRT安全增强的说明。

-------------------------------------------------------------------------------------------------------------

【MSDN】:

Some of the security enhancements are:

  • Parameter Validation. Parameters passed to CRT functions are validated, in both secure functions and in many preexisting versions of functions. These validations include:
  1.  
    1. Checking for NULL values passed to the functions,
    2. Checking enumerated values for validity,
    3. Checking that integral values are in valid ranges.

For more information, see Parameter Validation.

There is also a handler for invalid parameters which is accessible to the developer. When an invalid parameter is encountered, instead of asserting and exiting the application, the CRT provides a way to check these problems with the _set_invalid_parameter_handler function.

  • Sized Buffers. The secure functions require that the buffer size be passed to any function that writes to a buffer. The secure versions validate that the buffer is large enough before writing to it, helping to avoid dangerous buffer overrun errors which could allow malicious code to execute. These functions will usually return an errnotype of error code and invoke the invalid parameter handler if the size of the buffer is too small. Functions which read from input buffers, such as gets, have secure versions that require you to specify a maximum size.
  • Null termination. Some functions which left potentially non terminated strings have secure versions which ensure that strings are properly null terminated.
  • Enhanced error reporting. The secure functions return error codes with more error information than was available with the preexisting functions. The secure functions and many of the preexisting functions now set errno and often return an errno code type as well, to provide better error reporting.
  • Filesystem security. Secure file I/O APIs support secure file access in the default case.
  • Windows security. Secure process APIs enforce security policies and allow ACLs to be specified.
  • Format string syntax checking. Invalid strings are now detected, for example using incorrect type field characters in printf format strings.

Additional security enhancements are described in the documentation for each function.

-------------------------------------------------------------------------------------------------------------

在我的项目中也有这样的问题,譬如说编译器会警告说wcscpy是被否决的,不安全的,推荐使用wcscpy_s. wfopen也是被否决的。

为微软公司对C/C++语言的扩展,其中的一部分已于2003年提交给ISO作为C/C++标准下一版本的修改建议。

安全CRT函数,在原来函数名后添加了“_s”后缀;一般返回出错代码;并将原来的返回值,作为一个参数,添加到函数输入参数列表的最后;对带缓冲区参数的函数,还添加了表示缓冲区大小的输入参数,以防止溢出。

有关的帮助文档参见URL:

ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.VisualStudio.v80.chs/dv_vccrt/html/f87e5a01-4cb2-4379-9e8f-d4693828c55a.htm

1.类型定义

下面是若干安全函数原型用到的类型定义:

#include

typedef int errno_t;

typedef unsigned short wchar_t;

#ifdef _WIN64

typedef unsigned __int64    size_t;

#else

typedef _W64 unsigned int   size_t;

#endif

2.常用安全CRT函数

下面是若干最常用的安全CRT函数原型:

(说明:部分为函数名;函数原型后面是其所在的头文件)

char *gets_s( char *buffer, size_t sizeInCharacters); //

wchar_t *_getws_s( wchar_t *buffer, size_t sizeInCharacters); // or

errno_t _itoa_s( int value, char *buffer, size_t sizeInCharacters, int radix ); //

errno_t _itow_s( int value, wchar_t *buffer, size_t sizeInCharacters, int radix ); //

errno_t _ultoa_s( unsigned long value, char *str, size_t sizeOfstr, int radix ); //

errno_t _ultow_s( unsigned long value, wchar_t *str, size_t sizeOfstr, int radix ); //

int printf_s( const char *format [, argument]... ); //

int wprintf_s( const wchar_t *format [, argument]... ); // or

int scanf_s( const char *format [, argument]... ); //

int wscanf_s( const wchar_t *format [, argument]... ); // or

int sprintf_s( char *buffer, size_t sizeOfBuffer, const char *format [, argument] ... ); //

int swprintf_s( wchar_t *buffer, size_t sizeOfBuffer, const wchar_t *format [, argument]...); // or

int sscanf_s( const char *buffer, const char *format [, argument ] ...); //

int swscanf_s( const wchar_t *buffer, const wchar_t *format [, argument ] ...); // or

int fprintf_s( FILE *stream, const char *format [, argument ]...); //

int fwscanf_s( FILE *stream, const wchar_t *format [, argument ]... ); // or

int fscanf_s( FILE *stream, const char *format [, argument ]... ); //

int fwscanf_s( FILE *stream, const wchar_t *format [, argument ]... ); // or

errno_t strcpy_s( char *strDestination, size_t sizeInBytes, const char *strSource ); //

errno_t wcscpy_s( wchar_t *strDestination, size_t sizeInWords, const wchar_t *strSource ); // or

errno_t fopen_s( FILE** pFile, const char *filename, const char *mode ); //

errno_t _wfopen_s( FILE** pFile, const wchar_t *filename, const wchar_t *mode ); // or

errno_t mbstowcs_s( size_t *pConvertedChars, wchar_t *wcstr, size_t sizeInWords, const char *mbstr, size_t count ); //

errno_t wcstombs_s( size_t *pConvertedChars, char *mbstr, size_t sizeInBytes, const wchar_t *wcstr, size_t count ); //

errno_t rand_s( unsigned int* randomValue); //

 

看到这样一段话。

《 C++中Unicode与MBCS版函数对应表

因为项目碰到了国际化的问题,自己整理了一下, 主要是从tchar.h里面导出的。包括类型和各类字符相关的处理函数,大部分都应该是用不到的。如果有想用自动化工具替换字符升级到unicode版本的,这个列表就比较全了。》

Generic SBCS UNICODE
TCHAR char wchar_t
_TEOF EOF WEOF
_TINT int wint_t
_TSCHAR signed char wchar_t
_TUCHAR unsigned char wchar_t
__T(x) x L
... ... ...

哎,怎么没有想到用工具自动转换呢,都是手动修改,从SBCS到UNICODE。

来源http://blog.csdn.net/waterathena/archive/2008/12/01/3422468.aspx

抱歉!评论已关闭.