Source: Strsafe. h: Safer String Handling in C
During Microsoft Windows Security Push held by Microsoft, a group of testers, Program Management Managers, and common programmers jointly decided to customize a set of string processing functions with high Security for the C language, in addition, we hope these functions can be used by Windows programmers and programmers in Microsoft.
To put it simply, the current C-language runtime functions are hard to stand in today's big environment where malicious attack attempts are everywhere. These functions either lack consistency between the returned values and parameters, or imply the so-called "truncation errors" error, or cannot provide adequate functionality. Frankly speaking, the code that calls these functions is too prone to "memory overflow.
We found that the class for C ++ programmers is sufficient to meet the programming needs of various security processing strings; they can select the Cstring class of MFC, The CComBSTR class of ATL or the string class of STL, and so on. However, classical C language programs are still widespread. Many people are using C ++ as a "Improved C Language", but they put a wide array of C ++ classes on the shelf.
In fact, you only need to add a line of code to call strsafe series functions with good security in the C language code. For details, see:
Using the Strsafe. h Functions
These new functions are included in a header file and a function library (optional), which can be found in the new Platform SDK. Yes, that's simple:
#include "strsafe.h"
What are you waiting!
Again, the reference to the strsafe function library is optional.
To implement strsafe functions, your code must meet the following conditions:
- Always ends the string with NULL characters.
- Always check the length of the target buffer.
- Always use the HRESULT statement to generate a unified return value.
- Both 32-bit and 64-bit runtime environments are supported.
- Flexibility.
We feel that the lack of uniformity is the root cause that many existing C-language string processing functions are prone to security vulnerabilities, the high degree of uniformity brought by strsafe functions is just a good medicine to solve this problem. However, strsafe is not a panacea. Relying solely on strsafe functions does not guarantee the security and robustness of the code-you must start your brain-but it is helpful to solve the problem!
The following code uses the Classic C Language Runtime function:
void UnsafeFunc(LPTSTR szPath,DWORD cchPath) {TCHAR szCWD[MAX_PATH];GetCurrentDirectory(ARRAYSIZE(szCWD), szCWD);strncpy(szPath, szCWD, cchPath);strncat(szPath, TEXT("\\"), cchPath);strncat(szPath, TEXT("desktop.ini"),cchPath);}
Bugs in the above Code are everywhere-it does not check any return value, in addition, cchPath is not correctly used in calls to the strncat function (because MAX_PATH stores the length of the remaining space in the target buffer, rather than the total length of the target buffer ). As a result, the "memory overflow" problem will be quickly found. However, code snippets like this have long been flooded. If you use strsafe functions, the above Code should be:
bool SaferFunc(LPTSTR szPath,DWORD cchPath) {TCHAR szCWD[MAX_PATH];if (GetCurrentDirectory(ARRAYSIZE(szCWD), szCWD) &&SUCCEEDED(StringCchCopy(szPath, cchPath, szCWD)) &&SUCCEEDED(StringCchCat(szPath, cchPath, TEXT("\\"))) &&SUCCEEDED(StringCchCat(szPath, cchPath, TEXT("desktop.ini")))) {return true;}return false;}
This Code not only checks every returned value, but also ensures the total length of the same target buffer zone in a timely manner. You can also use strsafe series functions of the Ex version to implement more advanced functions, such:
- Obtains the current pointer of the target buffer.
- Obtain the remaining space length of the target buffer.
- Fill the idle buffer with a specific character.
- Once the string processing function fails, it fills the string with a specific value.
- Once the string processing function fails, the target buffer is set to NULL.
What about the improved code performance? The good news is that it has almost no performance difference with the original code. I have tested the code of various string connection functions in the Classic C language on my 1.8 GHz computer, the code of various string connection functions in the mixed strsafe series, and the strsafe series of mixed Ex versions. code of various String concatenation functions. Each of them runs 1 million times independently (that is, 10,000,000 times) and consumes the following time:
- Typical C language-7.3 seconds
- Strsafe series-8.3 seconds
- Strsafe series (Ex)-11.1 seconds
During the test, the program that calls the strsafe series functions of the Ex version sets the buffer to NULL when the call fails and uses 0xFE as the padding byte. The Code is as follows:
DWORD dwFlags = STRSAFE_NULL_ON_FAILURE | STRSAFE_FILL_BYTE(0xFE);
It takes a lot of time to set the byte filling code. In fact, if we only set the buffer to NULL here, the code using the strsafe series functions of the Ex version will be the same as the code using the common strsafe series functions.
It can be seen that the performance of the above three solutions is very small. I believe that you will not repeatedly execute code containing a large number of string processing functions in a program for millions of times!
Note: When you reference strsafe functions, the original C-language string processing functions will be automatically processed by # undef. This is fine, because the error information during debugging will tell you which functions have been replaced by the corresponding strsafe series functions. Well, please feel free to use strsafe. h! For more information, see Using the Strsafe. h Functions.