Automatic Break Points
The diagram from the previous section brings up an interesting point: the return address of a function call is in a known location at the time of the break point. You can display it or even set a break point on it automatically by using the command bp kernel32!CreateFileW "bp poi(esp);g".
Figure 2 demonstrates the debugging notepad and using a more complex break point. The break point on CreateFileW will display the file being opened and then automatically create a conditional break point on its return address and display "Handle Is Valid" if the handle returned is valid or "Handle Is Not Valid" if the handle returned is not valid. The output has been highlighted and you will notice that there was no interaction from the user.
![](http://twimgs.com/ddj/images/article/2007/0708/070828to01_f2.gif)
The break point used is the following: bp Kernel32!CreateFileW "du poi(esp+4); bp poi(esp) \"j eax == ffffffff ? '.echo Handle Is Not Valid;g' ; '.echo Handle Is Valid;g'\";g". You may want to notice the syntax: for example, to insert the quotes for the automatic break point's command string, you need to specify a backwards slash. A single quote was also used to group multiple commands together with the conditional break point as opposed to a double quote.
The insertion of automatic break points could be quite useful in avoiding modifying and recompiling your code to place debug output after every function call. This example only displayed a string, however it could stop at a failure and even display the GetLastError value. You can even generate log files of the output using the .logopen command.
There are alternative methods of creating similar functionality for certain types of events. These include using the application verifier to break on system event errors such as file open and create failure. These, however, most likely would not cover libraries or internal APIs that you may want to track. This is also a simple alternative to using tools like application verifier.