code 39 font c# Check lock usage Detect invalid handle usage in Visual C#

Print Code 39 Extended in Visual C# Check lock usage Detect invalid handle usage

Check lock usage Detect invalid handle usage
Making Code39 In Visual C#.NET
Using Barcode generation for VS .NET Control to generate, create Code 39 Extended image in .NET applications.
Decoding USS Code 39 In C#.NET
Using Barcode recognizer for Visual Studio .NET Control to read, scan read, scan image in .NET applications.
Check for adequate stack Log start and stop
Printing Bar Code In Visual C#
Using Barcode maker for VS .NET Control to generate, create bar code image in VS .NET applications.
Scan Barcode In C#.NET
Using Barcode decoder for .NET Control to read, scan read, scan image in Visual Studio .NET applications.
Checks system path usage
Code39 Printer In Visual Studio .NET
Using Barcode maker for ASP.NET Control to generate, create USS Code 39 image in ASP.NET applications.
Generate ANSI/AIM Code 39 In VS .NET
Using Barcode printer for .NET framework Control to generate, create Code39 image in VS .NET applications.
Table 17-4: The AppVerifier Test Descriptions Test Checks version handling Description of gathering the information. In the past, many applications have been written to run on a single version of Windows. This test will return a very high version number when the application attempts to determine which version of Windows it's running in. This test monitors the application's use of the system registry for any inappropriate or dangerous calls. Any problems detected will be logged. This test helps to ensure future compatibility for applications because it checks for the usage of specific registry keys that might be dropped or changed in future versions of the Windows operating system. This test logs changes to Windows File Protection files. This test logs any attempts that an application makes to perform a version check on DirectX libraries. This test logs to an XML file all changes that an application makes to the registry. This test logs to an XML file all changes that an application makes to the file system. You'll receive a warning if the application attempts to write files to the %windir% or Program Files folders. This test logs calls made to APIs that have been marked as obsolete in the Microsoft Platform SDK. When using this test, only look for log entries with your binaries in the log. The operating system itself makes quite a few obsolete calls. This test logs any attempt made by an application to install a kernel-mode driver. This test detects and logs potential security issues when using NULL DACL security descriptors and process creation API calls. This test checks for incorrect RPC usage. This test applies only to Windows Server 2003. You'll probably never need to turn this test on.
USS Code 39 Maker In VB.NET
Using Barcode drawer for .NET Control to generate, create Code-39 image in .NET framework applications.
PDF417 Creator In C#.NET
Using Barcode drawer for VS .NET Control to generate, create PDF 417 image in Visual Studio .NET applications.
Checks registry usage
EAN 128 Drawer In C#.NET
Using Barcode drawer for VS .NET Control to generate, create UCC-128 image in .NET framework applications.
UPC - 13 Generator In C#
Using Barcode generation for Visual Studio .NET Control to generate, create EAN13 image in Visual Studio .NET applications.
Logs changes to Windows File Protection files Logs DirectX file checks
Matrix Barcode Drawer In Visual C#
Using Barcode encoder for .NET framework Control to generate, create 2D Barcode image in VS .NET applications.
Print MSI Plessey In Visual C#.NET
Using Barcode printer for .NET framework Control to generate, create MSI Plessey image in VS .NET applications.
Logs registry changes Logs file system changes
Generate Code 128 Code Set A In Java
Using Barcode encoder for Android Control to generate, create Code 128 image in Android applications.
Making Data Matrix ECC200 In Objective-C
Using Barcode creator for iPhone Control to generate, create DataMatrix image in iPhone applications.
Logs calls made to obsolete APIs
UCC - 12 Printer In .NET Framework
Using Barcode drawer for .NET framework Control to generate, create GTIN - 128 image in VS .NET applications.
UPC A Encoder In Java
Using Barcode drawer for Java Control to generate, create UPC-A Supplement 5 image in Java applications.
Logs installations of kernelmode drivers Logs issues potential security
Creating PDF417 In Java
Using Barcode creation for Java Control to generate, create PDF417 image in Java applications.
Code-128 Scanner In Java
Using Barcode decoder for Java Control to read, scan read, scan image in Java applications.
RPC Checks
Barcode Creator In Java
Using Barcode maker for Java Control to generate, create bar code image in Java applications.
Barcode Recognizer In Java
Using Barcode recognizer for Java Control to read, scan read, scan image in Java applications.
Figure 17-5: AppVerifier Test Settings dialog box Turning on the AppVerifier add-in for your application is as simple as clicking the Enable Verification button. As you'll notice, you'll need to define your tests and options before you click Enable Verification because the Tests and Options buttons are disabled after clicking it. ACT does come with a demo program, but what it does isn't clear and it doesn't come with source code, so I wrote a quick demo program, AppVerifierDemo, that you can use to see many of the errors that the AppVerifier add-in catches. Simply open the AppVerifierDemo project (which is included with this book's sample files) to see the errors in action. Some of the buttons don't cause errors for example, the double critical section initialization. ACT 2.6 documented the error but doesn't actually generate it. The important section to play with is the PageHeap Errors section so that you can see how excellent PageHeap is at detecting those tough overruns and other nasty memory errors. After you've executed your application a time or two, you can look at the logs of the runs and the output saved by the AppVerifier add-in. Although most of the errors the AppVerifier add-in detects result in an immediate access violation, some, such as obsolete function calls, appear only in the log, which you can access by clicking the Log Files button on the Debug toolbar. When looking at the logs, make sure to set the view option to Show All so that you'll see everything. Killer Switches As I mentioned in 2, there are some new compiler switches in Microsoft Visual C++ .NET that you should always have turned on. In this section, I'll introduce the /RTCx and /GS switches and explain why they're so important. The Run-Time Check Switches If the only feature added to the Visual C++ .NET compiler were the /RTCx (Run-Time Error Checks) switches, I would still tell everyone that it's a mandatory upgrade. As the name implies, the four RTC switches watch your code, and when you have certain errors at run 655
time, the debugger pops up and tells you about them. Figure 17-6 shows an error in which some code overwrote past the end of a local variable. As you can see in the message box, the particular local that was blown is shown as well. The part you can't see is that this message box pops up at the end of the function where the error occurred, so it's trivial to find and fix the problem! The RTC switches, by the way, are allowed only in debug builds.
Figure 17-6: The /RTCs error report The first switch, /RTCs, whose error report is shown in Figure 17-6, does all sorts of runtime stack checking. It starts by initializing all local variables to nonzero values. This helps you find those pesky release build problems that don't show up in debug builds specifically the case in which you have an uninitialized pointer variable on the stack. All local variables are filled with 0xCC, the INT 3 (breakpoint) opcode. The second helpful stack-checking feature is that /RTCs does stack pointer verification around every function call you make to combat against calling convention mismatches. For example, if you declare a function as __cdecl, but it's exported as __stdcall, the stack will be corrupted upon returning from the __stdcall function. If you've been paying attention to compiler switches over the years, you might have guessed that the first two stack-checking options for /RTCs do the same thing as the /GZ switch in Microsoft Visual C++ 6. Fortunately for us, Microsoft extended the /RTCs switch to also do overrun and underrun checking of all multibyte local variables such as arrays. It does this by adding four bytes to the front and end of those arrays and checking them at the end of the function to ensure those extra bytes are still set to 0xCC. The local checking works with all multibyte locals except those that require the compiler to add padding bytes. In almost all cases, padding is added only when you use the __declspec(align) directive, the /Zp structure member alignment switch, or the #pragma pack(n) directive. The second switch, /RTCu, checks your variable usage and will pop the warning if you use any without initializing them first. If you've been a loyal Bugslayer over the years, you might be wondering why this switch is important. Since all loyal readers (like you) are already compiling their code with warning level 4 (/W4) and treating all warnings as errors (/WX), you know that compiler warnings C4700 and C4701 will always tell you at compile time where you are definitely using and where you might be using variables without initialization, respectively. With the /RTCu switch, those who aren't will still be told they have bugs in their code. What's interesting about the /RTCu switch is the code to check for uninitialized variables is inserted if the compiler detects a C4700 or C4701 condition. The third switch, /RTC1, is just shorthand for combining /RTCu and /RTCs. The final switch, /RTCc, checks for data truncation assignments for example, if you try to assign 0x101 to a char variable. Like the /RTCu, if you're compiling with /W4 and /WX, data truncation will produce a C4244 error at compilation time. If you get an /RTCc error, you 656
have to either mask off the bits you need or cast to the appropriate value. The project Property Pages dialog box, shown in Figure 17-7, allows you to only set /RTCu, /RTCs, or /RTC1 in the Basic Runtime Checks option. In order to turn on /RTCc, you'll need to select the Smaller Type Check option above the Basic Runtime Checks option, as shown in Figure 17-7.
Figure 17-7: Setting the /RTCx switches At first, I couldn't see why the /RTCc switch was not turned on by the /RTC1. A little thinking showed that /RTCc can show errors on legal C code such as the following: char LoByte(int a) { return ((char)a) ; } If /RTCc were included in /RTC1, people might think that all the Run-Time Error Checks switches are reporting false positives. However, I vote for always turning on /RTCc because I want to know about any potential problems whenever I run my code. With the switch descriptions out of the way, I want to turn to the notification you get when you do have an error. When running your programs outside the debugger, the run-time checking code uses the standard C run-time assertion message box. For those of you writing services or code that can't have a user interface, you'll need to redirect the message box using the _CrtSetReportMode function with the _CRT_ASSERT report type parameter. You might think there would be a single, standard way for the /RTCx switches to notify the user, but that's not the case. When running under the debugger, there's a completely different way to do the notifications. If you happen to look at the Exceptions dialog box in the Visual Studio .NET IDE, you might notice several new classes of exceptions added. The interesting new exception class is 657
Native Run-Time Checks. As you look at it in the Exceptions dialog box, you'll recognize the four different exceptions as matching up with the /RTCx switches. That's your hint that when your program encounters a run-time check while running under the debugger, your program will throw a special exception so that the debugger can handle it. Controlling Run-Time Check Output While the default method of output will suffice for many situations, you might want to handle the error output yourself. Listing 17-6 shows a sample custom error handler. The parameter list for run-time check error handlers is a little different in that it takes variable parameters. Evidently, Microsoft is planning to add quite a few different run-time error checks in the future to account for this flexibility. Since your custom handler gets the same parameters as the default version, you can show the errors with variable information and everything else. As you can see from Listing 17-6, it's up to you how you choose to inform the user. The code from Listing 17-6 is with this book's sample files in the RTCHandling sample, so you can play with the error handling all you want. Listing 17-6: /RTCx custom error reporting /*///////////////////////////////////////////////////////////////// //// FUNCTION DESCRIPTION : : HandleRTCFailure
The Run Time Checking (RTC) handler function when NOT running under the debugger. When running under a debugger, this function is ignored. Consequently, you can't debug this puppy at all! PARAMETERS : The type of error as reported through iError _RTC_SetErrorType. szFile iLine
Note that I don't use this parameter. - The source filename where the error occurred. - The line where the error occurred.
szModule - The module where the error occurred. szFormat - The printf-style format string for the variable parameters. Note that I don't use this parameter except to get the values out of the variables parameters. ... - The "variable" length parameter list. There are only two values passed here. The first is the RTC Error number. 1 = /RTCc 2 = /RTCs 3 = /RTCu The debugger 658 second is the string that appears when the
shows the message. This is only important for /RTCs and /RTCu as those show the variable where the problem happened. RETURN VALUES TRUE : - Cause a _DebugBreak to be called after this function returns. FALSE - Continue execution. /////////////////////////////////////////////////////////////////// //*/ // Turn off recursive // on myself. #pragma runtime_checks("", off) // The critical section to protect against reentrancy in the // HandleRTCFailure function. CRITICAL_SECTION g_csRTCLock ; int HandleRTCFailure ( int int /*iError*/ iLine , , , , , ) run time checks for this function so I don't go
const char * szFile const char * szModule const char * szFormat ... { // Just say no to reentrant code! EnterCriticalSection ( &g_csRTCLock ) ;
// Get the two variable length parameters. I guess they plan on // adding a ton of these RTC checks in the future. va_list vl ; va_start ( vl , szFormat ) ; // The first one is the number of the error that occured. _RTC_ErrorNumber RTCErrNum = va_arg ( vl , _RTC_ErrorNumber ) ; // The second is the additional description of the error. char * szErrorVariableDesc = va_arg ( vl , char * ) ; va_end ( vl ) ; 659
TCHAR szBuff [ 512 ] ; // Get the error description text based off the error number. const char *szErr = _RTC_GetErrDesc ( RTCErrNum ) ; // Make sure szFile and szModule have something in them. if ( NULL == szFile ) { szFile = "Unknown File" ; } if ( NULL == szModule ) { szModule = "Unknown Module" ; } // If it's any error other than /RTCc, I can show some cool info // that includes the variable in question! if ( 1 != RTCErrNum ) { _stprintf ( szBuff szErr szErrorVariableDesc iLine szFile szModule ) ; } else { // Build the string. _stprintf ( szBuff szErr iLine szFile szModule } , , , , ) ; _T ( "%S\nLine #%d\nFile:%S\nModule:%S" ) , , , , , , _T ( "%S\n%S\nLine #%d\nFile:%S\nModule:%S" ) ,
int iRes = TRUE ; if ( IDYES == MessageBox ( GetForegroundWindow ( ) szBuff _T ( "Run Time Check Failure" ) MB_YESNO | MB_ICONQUESTION ) { // Returning 1 means DebugBreak will happen when this // function returns. iRes = 1 ; } else { iRes = 0 ; } // Pop out of the lock. LeaveCriticalSection ( &g_csRTCLock ) ; return ( iRes ) ; } #pragma runtime_checks("", restore) , , , )
Setting your custom error handler function is trivial; just pass it as the parameter to _RTC_SetErrorFunc. There are a few other functions to assist you when handling runtime check errors. The first, _RTC_GetErrDesc, retrieves the description string for a particular error. _RTC_NumErrors returns the total number of errors supported by the current version of the compiler and run time. One function, which I find a little dangerous, is _RTC_SetErrorType. You can use this function to turn off error handling for any or all of the specific run-time checks. Since the run-time checks rely on the C run time, if your program doesn't use the C run time, you might think you would completely lose the benefits of the RTC switches. If you are wondering why you would ever have a program without the C run time, think about ATL and building with _ATL_MIN_CRT. Without the C run time, you need to call _RTC_Initialize if you've used __MSVC_RUNTIME_CHECKS. You must also provide a function named _CRT_RTC_INIT, which returns your custom error handler. When I first started playing with a custom output handler, I immediately ran into a small problem. I couldn't debug my handler! If you think about it, you can see why it happens. As I've already discussed, the run-time checking code can determine whether you are running under a debugger and display the output either in the debugger or through the normal C run-time assertion dialog box. When you're running under a debugger, the run-time checking code sees that it's under a debugger and just generates the special exception code to talk to the debugger, completely bypassing your custom output handler. 661
Common Debugging Question: How can I make sure I don't screw up my string processing Probably the most common security error as well as an inflection point for bugs is related to handling good old null terminated strings. The problem lies in the original definition of the C run time string handling functions: there's no way to indicate how long a string buffer is. For example, strcpy takes an input buffer and an output buffer and blindly copies the date from the input buffer into the output buffer no matter that the output buffer might be only half the size. Not only is that a memory overrun but one of the key security holes that virus writers take advantage of to overwrite the return value on the stack in order to get code executing. You could code review yourself to death looking for these errors, but you'll still miss them. Fortunately, some very bright people at Microsoft realized it was time to make a change. A new library, STRSAFE, rides to the rescue to save your string processing from yourself. STRSAFE is part of the July 2002 Platform SDK and is included with Visual Studio .NET 2003. The whole idea is to include STRSAFE.H in your precompiled header so that you'll have access to a whole slew of functions that take output buffer lengths and ensure those functions don't copy any more than the specified number of characters. When you first compile after including STRSAFE.H, you'll find that all the error-prone string functions are now deprecated and your builds will stop until you fix them. Unfortunately, STRSAFE came out after I had written nearly all the code for this book. As you'll find with your projects, retrofitting STRSAFE on your code is much like taking the ride to convert ANSI code to Unicode. It takes quite a bit of time, but it's worth it. If the code is not fully converted by the time the book ships, I'll have it moved over soon and posted on Wintellect's Web site.
The Buffer Security Check Switch The run-time checks are very cool, but another switch that you should always turn on is /GS, the Buffer Security Check switch. Unlike the /RTCx switches, /GS should be turned on for both debug and release builds. The purpose of /GS is to monitor the return address for a function to see whether it's overwritten, which is a common technique used by viruses and Trojan horse programs to take over your application. /GS works by reserving space on the stack before the return address. At the function entry, the function prolog fills in that spot with a security cookie XOR'd with the return address. That security cookie is computed as part of the module load so it's unique to each module. When the function exits, a special function, _security_check_cookie, checks to see whether the value stored at the special spot is the same as it was when entering the function. If the values are different, the code pops up a message box and terminates the program. If you want to see the security code in action, read the source files SECCINIT.C, SECCOOK.C, and SECFAIL.C in the C run-time source code. As if the security-checking capability of the /GS switch weren't enough, the switch is also a wonderful debugging aid. Even though the /RTCx switches will track numerous errors, a random write to the return address will still sneak through. With the /GS, you get that checking in your debug builds as well. Of course, the Redmondtonians were thinking of us when they wrote the /GS switch, so you can replace the default message box function with your own handler by calling _set_security_error_handler. If you do whack the stack, your handler should call ExitProcess after logging the error. 662
Summary The debug C run-time library has many wonderful features provided you turn them on in your application. Because using memory is a fact of life in our C and C++ programs, we need all the help we can get solving the problems we invariably have with memory. This chapter covered the high points of the DCRT library and presented two utilities I wrote, MemDumperValidator and MemStress, that will help you get more information about the memory your application uses and allow you to better test your application under stressful conditions. The extensibility of the DCRT library is pretty amazing. If you've been in this business for more than a year or two, you've probably written something like it in the past. I hope I was able to give you some sense of the power of the DCRT library. I encourage you to devise other utilities and helper code that will ease your memory debugging chores. I also discussed the techniques and tools necessary to handle the nastiest of memory problems in production applications: uninitialized writes and memory overruns. Although the brute force approach might not seem elegant for solving those uninitialized writes, it's the only technique that actually gives you a chance. When it comes to memory overruns, the PageHeap tool accessible from AppVerifier, part of the Application Compatibility Toolkit, makes tracking them down easier. Although AppVerifier has some lumps, I'm sure Microsoft will continue to improve it in the future. Finally, the new Run-Time Error Checks and Buffer Security Check compiler switches are some of the most important advances we've had in compiler tools to help eradicate errors.
Copyright © . All rights reserved.