[PowerShell Script] PowerDbg v6.0 – Using PowerShell to Control WinDbg

Last October the latest version of the PowerDbg tool was released, version 6.0. This release has major changes. For example, it is now easier to write scripts or otherwise just hack around the debugger, and includes the PowerDbgConsole, a bootstrapper designed to make setting up an interactive PowerDbg debugging session a one-liner. In addition, this new version is faster, easier to use, and has full 64 bit support.

For those new to PowerDbg, with this tool you can easily create PowerShell scripts to automate a WinDbg/CDB debugging session. You can use PowerDbg for Kernel Mode or User Mode, Post-Mortem Debugging or Live Debugging, either for native or managed code.

PowerShell has several advantages over the WinDbg Scripting Language, like:

- Increased ease in creating scripts

- Leverage in the .NET Framework

- Debugging and tracing features

- Code reuse through functions and cmdlets

- Easier maintenance

- Increased ease in building large scripts

- Ease in formatting and displaying important information

PowerDbg is hosted in the CodePlex website and there you can find all the information you need about the new PowerDbg, so I’m just reusing the information from CodePlex here.

Download

Download PowerDbg.

Prerequisites

In order to use PowerDbg you will need:

* PowerShell 2

This comes ‘out of the box’ with Windows 7 and Windows 2008 R2 (though it may not be enabled by default). For other versions of Windows it can be obtained by installing the Windows Management Framework Core Package

* A recent version of the Debugging Tools for Windows.
Most of the testing has been done against the version that comes with the Windows SDK 7.1 and the previous stand-alone version 6.1.1.404 (x86 / x64).

You’ll also need to configure PowerShell to allow scripting, which is disabled by default. Typically you’d relax the execution policy to allow unsigned scripts to run from the local machine (only) [1]:

Set-ExecutionPolicy RemoteSigned

If UAC is enabled you’ll need to do this from a PowerShell prompt ‘run as administrator’.

If you’re running 64 bit Windows and plan on doing any 32 bit debugging, you’ll also need to do this in the 32 bit PowerShell console (Windows PowerShell (x86) in your Start menu).

Installation

After downloading, extract the PowerDbg.zip to a temporary directory somewhere, and use the Install_PowerDbg.ps1 script to install it: just right click on it and select ‘Run With PowerShell’.

Alternatively, you can manually drop the PowerDbg.psm1 module file into your PowerShell module directory, ensuring it gets placed in a ‘PowerDbg’ subfolder.

Establishing a PowerDbg Session

New-DbgSession

To use PowerDbg you must first establish a ‘session’. This establishes PowerDbg’s internal connection between a local debugger and either a memory dump, live process, or remote debugger.

Sessions are established using the New-DbgSession cmdlet and can be instantiated in one of four ways:

- attaching to a running process by name (-process)
- launching a process under the debugger (-command)
- opening a memory dump in the debugger (-dump)
- connecting to an existing debugger configured as a server (-remote)

Additionally, PowerDbg can be instructed to auto-load SOS (if possible), using the -sos parameter. This can only be performed if the process in question has already loaded the CLR, and so is not applicable to the -command method.

Example

The PowerDbg 'unhandled exception' demo can be run under the debugger as follows (note the quotes which allow us to pass an argument to the process being launched):

PS > New-DbgSession -command '.\blah\ManagedScenarios.exe UnhandledExceptionScenario'

PS > Send-DbgGo

...

(1104.730): CLR exception - code e0434f4d (first chance)

(1104.730): CLR exception - code e0434f4d (!!! second chance !!!)

KERNELBASE!RaiseException+0x39:

000007fe`fdedaa7d 4881c4c8000000 add rsp,0C8h

PS >

Since the debugger immediately breaks into the launched process, we have to use Send-DbgGo to allow the process to continue on (and subsequently fail). When creating a session to a memory dump or a remote debugger already halted at the point of interest, this would be unnecessary.

Once a PowerDbg session exists, you can interact with it using any of the Get-Dbg* cmdlets, or by using Invoke-DbgCommand to send commands directly.

Notes

* Each PowerShell window running PowerDbg can only support one such session at a time.

* The session is automatically terminated when the PowerDbg module is unloaded (Remove-Module PowerDbg).

* The debugger is attached invasively, and so the debuggee will terminate when the session is ended.

Some Commands

Session Management

New-DbgSession

Establishes a PowerDbg session with the debugger

Exit-DbgSession

Terminates the current PowerDbg session

Load-DbgExtension

Loads a debugger extension into the active session

Invoke-DbgCommand

Executes an arbitrary command against the debugger

Exploration

Get-DbgArray

Expands the contents of a managed array

Get-DbgClrHeap

Locates objects on the managed heap by type or MT

Get-DbgDictionaryContents

Enumerates Dictionary<T,T> collections

Get-DbgListContents

Enumerates List<T> collections

Get-DbgObject

Views the contents of a reference-type object

Get-DbgValueClass

Views the contents of a value-type object

Process State

Get-DbgClrThreads

Lists managed threads

Get-DbgComState

Views the COM apartment state associated with each thread

Get-DbgModules

Lists modules loaded into the process

Get-DbgRunaway

Views the kernel and user time associated with each thread

Analysis

Analyze-PowerDbgThreads

Sorts all threads by CPU (User Mode) and writes in red all threads which are using third-party components, an easy way to isolate threads consuming high CPU.

Misc

Start-DebuggerOnly

Launches a debugger without creating a PowerDbg session

Get-DbgHangDump

Takes an immediate full minidump of a given process


The new PowerDbg is the effort of a great team of people from different companies and different parts of the world. Particularly for me it’s always exciting to work with people from all over the world.

With that said, I want to thank everybody who worked in this project, especially:

I want to thank Lee Holmes (SDE from the PowerShell team) for all his support and valuable tips since the first versions of PowerDbg.

I also want to thank Augusto Pedroza (SDE from the Windows 8 FileSystem team) for using PowerShell in real Microsoft scenarios and for giving valuable feedback on how to improve the tool. (Obrigado Augusto! J)

Finally, I want to send a very special thanks to Piers Williams, who not only contributed with awesome ideas but added hundreds of lines of code to PowerDbg, worked on the documentation, and turned the PowerDbg project into one in which others can easily contribute.

We are looking for developers to join the PowerDbg project. If you’re interested, use the CodePlex site and join us!