Saturday, July 26, 2014

Customizing the WinDbg environment

Hi everyone,

In this post, I am going to discuss some of the customizations that I have come across in reading and videos from those such as Andrew Richards, etc, that I always make to my WinDbg environment to make it that much more comfortable/easier in the long run. In this post, I am using a fresh install of Windows 7 x64 on a VM so I can explain better and truly start from scratch. Do note that all of the customizations I make here also follow on Windows 8, etc, as well.

Disclaimer: This post will not teach you/show you how to install WinDbg! There are already plenty of posts and tutorials out there regarding that. This is strictly regarding its customization once it is installed.

Registering File Associations

On clean install of WinDbg with zero modifications and/or customizations done, this is what crash dumps look like:


We can see that the kernel-dump in the picture has no icon, etc, and is just a file. This is due to the fact that it has no known association. If we attempt to double click the crash dump in this state, Windows throw an error and say "Hey, we have no idea what type of file this is, so can you please perhaps tell us what program you'd like to associate all future crash dumps with?"

To properly circumvent this and set the file association, we're going to want to open an elevated command prompt. You can quickly do this by pressing Windows Key + R to open the run box, and then typing cmd and pressing Ctrl+Shift+Enter to execute an elevated command prompt.

Now that we have a window open, let's sidetrack to discuss something. If you navigate to the location in which you installed your WinDbg, and go into the Debuggers folder, we see the following:


We have an x86 and x64 debugger, and this is due to the fact that it's always best to debug a crash dump in its original architectural environment. With this said, if you're debugging a crash dump generated by an x64 box, you'll want to use the x64 debugger. At least 90% of all crash dumps you'll be debugging at this time in our life will be x64, therefore we want to obviously associate the x64 debugger as the main program for crash dumps. It just makes sense.

Now that we have navigated to the Debuggers folder, we can register associations by quickly going one folder higher (x64) and typing the following:

windbg -IA

Typing the above will do the following:



-- YOU MAY NEED TO RESTART AFTERWARDS TO HAVE IT FULLY APPLY.

Great! Now all future crash dumps are associated with the x64 debugger. This raises one problem though, what if we're assisting a user and they are on an x86 box? Surely we can just navigate to the WinDbg directory, go to the x86 folder and open the debugger, but this is too much work.

With the above said, let's have some fun by pressing the Windows Key + R to open the run box, and then typing regedit to execute the Registry Editor. The key we're interested in working within is HKEY_CLASSES_ROOT. It's important to note that this is the key that controls all of the file name extension associations and COM class registration information. With that said, programs start how they're supposed to thanks to this key!

Now we want to take a peek at the extension .dmp (scroll down until you see it, or actually type .dmp until you get there):


The above is essentially a shortcut which implies in the default key, jump to WinDbg.DumpFile.1.

Now that we know this, let's go ahead and do as we did above, but instead type windbg until we get to WinDbg.DumpFile.1. You can alternatively scroll as well if you're cautious of screwing anything up, although it'll take you awhile:


WinDbg.DumpFile.1 is where the .dmp extension is housed.

If we click DefaultIcon:


The familiar little computer WinDbg icon is what resource -3002 is from windbg.exe.

If we go into shell, we see Open:


If we double-click the string itself:


&Open actually creates the underscore under the O in the Open command in the context menu for right-clicking a crash dump. We want to change this from &Open to Open x&64, for example:


and then click OK.

Now that we've done this, as said above, on the context menu for crash dumps, instead of saying Open, it will say Open x64. For example:


Great! We're making progress, but we also want an Open x86 option on the context menu as well. In order to do this, bring regedit back up and right-click shell, select new, and then select key. Once you've done this, name the new key Open_x86. After we've done all that, this is what regedit should look like:


With all of the above done, now we need to go ahead and set that value by double-clicking where it says (Default), and typing Open x&86 this time as opposed to Open x&64 as we did earlier above. Now we need to right-click our Open_x86 key, select new, and then select key. Once you've done this, name the new key command. After we've done all that, this is what regedit should look like:


Once we have the above, to save ourselves some time, let's navigate to Open's command key, double-click (Default), and then copy the string's Value data. For example:


With the above Value data copied, let's navigate back to our created Open_x86's command key, double-click (Default), and then paste into Value data's empty box. DO NOT PRESS OK YET!

We need to make an adjustment to the path, which is extremely simple.

Here was my pasted Value data:

"C:\Program Files (x86)\Windows Kits\8.1\Debuggers\x64\windbg.exe" -z "%1"

Here is what it needed to be changed to:

"C:\Program Files (x86)\Windows Kits\8.1\Debuggers\x86\windbg.exe" -z "%1"

Extremely simple as I noted, and all I had to do was change x64 to x86.

With all of the above said and done, now if we once again right-click a crash dump to bring up its context menu, here's what we now see:


Fantastic, so now we no longer need to spend time traversing through folders and such to open the x86 debugger if we need to. You may be saying to yourself "This was a bit of a pain, I really don't want to do this every time I have to reinstall Windows...". You're in luck, you don't have to!

If you now right-click WinDbg.DumpFile.1 in regedit, select Export, and save it as WinDbg_IA.reg, you're now exporting that registry key from the registry to be saved. This is extremely handy because you can throw it on your trusty USB that you use for absolutely everything debugging related, and when you're on a brand new system/different system that doesn't have file associations set that you need to debug, you can just quickly install the key, and you're good to go. This also of course saves you from having to do this process on your own system.

-- Do note that you will have to do the windbg -IA command before installing the registry key or it will not work. Once you've done the windbg -IA command, you can then simply install the registry key and all the work is done.

Symbols

So now that we have file associations registered for crash dumps, and have successfully modified our crash dump context menu to contain an option to either execute the x64 or x86 debugger, let's go one step further and automate the creation, download, etc, of symbols.

One thing to note is that everything we're doing here in this post could be done manually, but will take twice the actual effort, and will in the end waste time. When we're debugging, etc, and looking to get a box back up and running that we're debugging on, time is of the essence. With that said, all of these steps are to make our lives as debuggers much easier.

First off, it's important to understand what symbols are! Symbols (also known as PDB files -- program database) hold a variety of data which are not actually needed when running the binaries, but contain very useful debugging information. The fact that they are not needed when running the binaries themselves is the reason why PDB files exist! PDB files exist to separate the symbols from the binary, which ultimately helps limit the size of the executable, saving disk storage space and reducing the time it takes to load the data.

Symbol files contain:
  • Global varibles
  • Local Variables
  • Function names and the addresses of their entry points
  • Frame pointer omission (FPO) records
  • Source-line numbers
Each of these items is individually a symbol. For example, a single symbol file called Myprogram.pdb might contain several hundred symbols, including global variables and function names and hundreds of local variables.

Unfortunately, as debuggers who aren't internally within a company (Microsoft for example), we are only provided with what is known as public symbols (as opposed to private). The differences are listed here.

With all of the above said, if a debugger attempts to load a crash dump without symbols, we won't be able to successfully resolve functions, etc, and it'll instead be junk. This is why symbols are very important to have. Normally, when you first install WinDbg, you'd have to navigate to File>Symbol File Path and manually set the path. However, since time is of the essence and we love to do things automatically, we're going to make a one-time script that will set everything for us.

Let's get to work!

1. Create a next .txt file on your Desktop.

2. Within the new .txt file, paste the following code:
md c:\Symbols
md c:\Symbols\Src
md c:\Symbols\Sym
md c:\Symbols\SymCache
setx /M _NT_SOURCE_PATH SRV*C:\Symbols\Src
setx /M _NT_SYMBOL_PATH SRV*C:\Symbols\Sym*http://msdl.microsoft.com/download/symbols
setx /M _NT_SYMCACHE_PATH C:\Symbols\SymCache
You can change Symbols to whatever you want. I just find naming it Symbols is easy to remember and obvious on what's being stored there.

So, what is this script doing?

- Creating the Symbols directory in C:\.

- Inside of the Symbols directory, it's also creating three subfolders: Src, Sym, SymCache.

Src - Source code.

Sym - Symbol path.

SymCache - Symbol cache.

This ultimately creates an environment variable which sets it all for us, therefore we have to do nothing manually.

To expand a little, the reason we're using * in the script is to essentially say:

"Hey, look at C:\Symbols for the symbols. Are they there?"

If the answer is yes, then the symbols are loaded locally.

If the answer is no, then here's what it instead says:

"Hey, look at C:\Symbols for the symbols. Are they there? Oh wow, they're not?! Okay, let's grab them from http://msdl.microsoft.com/download/symbols instead!"

This is done that in the event your local symbols aren't available for some reason, it'll download them from the MSFT symbol server.

3. After pasting the code and changing anything about it to your liking (such as the directory name itself), navigate to File>Save As, change the Save as type: to All Files, and finally give it the File name: Symbols.bat or Symbols.cmd, etc.

4. Once you've done that, run it.

5. After it runs, you're all done setting up symbols and never have to worry about them ever again.

Extensions

Extensions are a really brilliant part of WinDbg that I actually didn't use for awhile, but once I looked into them more, it really has made my life a lot easier. First off, one of the extensions I really can't live without now even using it for such a short period of time is SwishDbgExt.

Some of its features, etc, are listed on that page, as well as the download link. Once you've downloaded it, installing it is really easy. When you extract it, it has a few items, but only two folders you're interested in (x64 and x86). Inside both of these folders is the extension itself, but for its specific architecture.

Now that you know the existence of the extension files, do the following:

1. Navigate to your WinDbg directory. For example, mine is C:\Program Files (x86)\Windows Kits\8.1\Debuggers

2. Once inside the Debuggers folder, double-click the x64 folder, and then the winext folder.

3. Now that you're in the winext folder, this is where you will simply drag n' drop the extension itself from the x64 extension folder. Once you've done that, you're all done for x64. Do the same for x86.

4. Now that you have both the extension files in their respectable directories, load up a crash dump as an example and type !load swishdbgext to load the extension. For example:



Once it's loaded, you can then use any of the various commands that this extension holds. For example, we could run !ms_drivers to display a list of drivers loaded:



We can get in-depth IRP information this way on a driver, such as myfault.sys:



Workspace



Here's what you can get your workspace to look like with some time and some messing around. This was done based off of Tess Ferrandez's workspace. I personally prefer the all stock white/black WinDbg, but if The Matrix is your thing, go for it.

You can make all of these edits by opening up WinDbg on its own and not with a dump file, navigating to View>Options, and changing the Colors how you want. You can also change Fonts through the View menu. Ensure that after you get yours all set, you manually save your workspace by going to File>Save Workspace As..., and then creating one. This will save your workspace and make it the default for the future.

That's it for now, thanks for reading!

References/LinksPimp up your debugger: Creating a custom workspace for windbg debugging.
Channel9.

No comments:

Post a Comment