# `pwnlib.windbg` — Working with WinDbg

During exploit development, it is frequently useful to debug the target binary under WinDbg. This module provides a simple interface to do so under Windows.

## Useful Functions

- `attach()` - Attach to an existing process

## Debugging Tips

The `attach()` and `debug()` functions will likely be your bread and butter for debugging.

Both allow you to provide a script to pass to WinDbg when it is started, so that it can automatically set your breakpoints.

### Attaching to Processes

To attach to an existing process, just use `attach()`. You can pass a PID, a process name (including file extension), or a `process`.

### Spawning New Processes

Attaching to processes with `attach()` is useful, but the state the process is in may vary. If you need to attach to a process very early, and debug it from the very first instruction (or even the start of `main`), you instead should use `debug()`.

When you use `debug()`, the return value is a `tube` object that you interact with exactly like normal.

## Tips and Troubleshooting

### `NOPTRACE` magic argument

It’s quite cumbersom to comment and un-comment lines containing attach.

You can cause these lines to be a no-op by running your script with the `NOPTRACE` argument appended, or with `PWNLIB_NOPTRACE=1` in the environment. (The name is borrowed from ptrace syscall on Linux.)

    $ python exploit.py NOPTRACE
    [+] Starting local process 'chall.exe': Done
    [!] Skipping debug attach since context.noptrace==True
    ...

#### Member Documentation

pwnlib.windbg.attach(target, windbgscript=None, windbg_args=[]) → int

  Attach to a running process with WinDbg.

  Parameters:

    - target (int, str, process) – Process to attach to.

    - windbgscript (str, list) – WinDbg script to run after attaching.

    - windbg_args (list) – Additional arguments to pass to WinDbg.

  Returns:

    int – PID of the WinDbg process.

  Notes

  The `target` argument is very robust, and can be any of the following:

  `int`

    PID of a process

  `str`

    Process name. The youngest process is selected.

  `process`

    Process to connect to

  Examples

  Attach to a process by PID

      >>> pid = windbg.attach(1234)

  Attach to the youngest process by name

      >>> pid = windbg.attach('cmd.exe')

  Attach a debugger to a `process` tube and automate interaction

      >>> io = process('cmd')
      >>> pid = windbg.attach(io, windbgscript='''
      ... bp kernelbase!WriteFile
      ... g
      ... ''')

pwnlib.windbg.binary() → str

  Returns the path to the WinDbg binary.

  Returns:

    str – Path to the appropriate `windbg` binary to use.

pwnlib.windbg.debug(args, windbgscript=None, exe=None, env=None, creationflags=0) → tube

  Launch a process in suspended state, attach debugger and resume process.

  Parameters:

    - args (list) – Arguments to the process, similar to `process`.

    - windbgscript (str) – windbg script to run.

    - exe (str) – Path to the executable on disk.

    - env (dict) – Environment to start the binary in.

    - creationflags (int) – Flags to pass to `process.process()`.

  Returns:

    `process` – A tube connected to the target process.

  Notes

  When WinDbg opens via `debug()`, it will initially be stopped on the very first instruction of the entry point.