블로그 이미지
fiadot_old

칼퇴근을 위한 게임 서버 개발 방법론에 대한 심도있는 고찰 및 성찰을 위한 블로그!

Rss feed Tistory
Technical Article 2007. 8. 23. 11:58

_tcscpy, _tcsncpy, _tcsncpy_s 비교 및 올바른 사용법

TCHAR pszMsg[256];

 _tcscpy(pktSend.pszMsg, _T("Hello~ Everyone~"));// , sizeof(pktSend.pszMsg));

 _tcsncpy(pktSend.pszMsg, _T("5555555555555555"), sizeof(pktSend.pszMsg)); // it's wrong

 _tcsncpy(pktSend.pszMsg, _T("5555555555555555"), _countof(pktSend.pszMsg)); // it's right


_tcsncpy의 count인자는 ( Number of characters to be copied.)

 복사될 글자수를 의미하는데,

 UNICODE나 _UNICODE가 define되어있을때는 wchar가 아닐때는 char가 들어가게 되는데

 sizeof를 사용하게 되면 wchar일때 TCHAR pszMsg[256]이

 wchar pszMSg[256]이 되어 실질적인 사이즈가 516바이트가 된다.
 
 즉 ,다른부분의 스택 영역에 오버런이 발생하게 되는것이다.

 VS2005로 오면서 _countof키워드가 추가되었는데 이 키워드를 이용하게 되면,
 
 Compute the number of elements in a statically-allocated array.
 
 MSDN에 있는 설명대로 배열의 갯수를 반환하게 되는것이다.

  single byte나 multi byte나 신경안쓰고 배열의갯수 = 글자의 갯수로 보게 되면
 
 UNICODE선언 유무에 따라 유니코드인지 안시코드인지 결정하게 되는 스트링 관련
 
 함수들(_tcs 접두어가 붙는 CRT String macro functions)은 sizeof대신에 _countof를
 
 사용하면 된다.

 
 좀더 깊이 있게 살펴보자면 Security Enhanced 함수들도 찾아볼수 있는데,
 
 
  • Parameter Validation. Parameters passed to CRT functions are validated, in both secure functions and in many preexisting versions of functions. These validations include:
    • Checking for NULL values passed to the functions,
    • Checking enumerated values for validity,
    • 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 errno type 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.

     
    이런 기능들을 해준다.

    어렵게 생각할것없이 strcpy_s( ... ) ; 이런식으로, 일반 CRT스트링 함수에 _s 접미사를 붙여주면 된다.

    다만 dest영역의 크기를 지정해줘야 하는데, 이부분이 귀찮다면

    #define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1

    이걸 헤더에 선언해줌으로써 전처리 과정에서 strcpy를 strcpy_s로 바꿔주게 된다.



    마지막으로, _tcsncpy와 _tcsncpy_s의 count부분에 sizeof를 사용해서 두 결과의 차이를 비교해보면

    _tcsncpy(pktSend.pszMsg, _T("5555555555555555"), sizeof(pktSend.pszMsg));

    _tcsncpy_s(pktSend.pszMsg, sizeof(pktSend.pszMsg), _T("5555555555555555"), sizeof(pktSend.pszMsg));

    _tcsncpy는 오버런 됐을때 0x00으로 채우게 되지만,

    _tcsncpy_s는 0xFD로 채워줌으로 바로 access viloation을 발생시켜준다.


  • ,
    TOTAL TODAY