WinDbg: break if a function returns an error

This is probably best illustrated by example:

ad /q ${/v:path}; bp kernel32!LoadLibraryExW "as /mu path poi(@esp+4); gu; .if (@eax = 0) { .echo *** LoadLibrary failed for 'path' ***; !gle } .else { gc }"

I'll explain the purpose of the ad command later. The as command sets up an alias and is the WinDbg equivalent to assigning a variable, or more accurately a macro expansion. In particular, as /mu path poi(esp+4) assigns to the alias "path" the Unicode string located at esp+4 (which is the first argument to the function). gu executes until the function returns, at which point we check for failure (eax contains the return value, and LoadLibraryExW returns 0 on failure). If the function failed, we print a message using our alias and use !gle to get and decode the last error, if not, we simply continue running.

The purpose of the ad command is to delete the "path" alias if it is defined. Why? Because if we don't do this, executing the bp statement will fail as "path" will be expanded in the actual breakpoint definition. People who are familiar with aliases might suggest that the following fixes it:

bp kernel32!LoadLibraryExW "as /mu ${/v:path} poi(@esp+4); gu; .if (@eax = 0) { .echo *** LoadLibrary failed for 'path' ***; !gle } .else { gc }"

Because ${/v:path} always expands to "path", even if an alias "path" is defined, the as command now always works—but the "path" reference in the .echo command will still be replaced, and to the best of my knowledge there's no way to prevent this while still keeping it functional. In case you ever wondered why most contemporary programming languages don't use macros anymore, this sort of thing is why.


lee woo said...

The best argument against democracy is a five-minute conversation with the average voter. See the link below for more info.


Silvia Jacinto said...

The real necklace of a woman is not her looks but her heart. Visit my site for more interesting offer. Thank you and God bless!