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 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[source]

Attach to a running process with WinDbg.

  • 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.


int – PID of the WinDbg process.


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


PID of a process


Process name. The youngest process is selected.


Process to connect to


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[source]

Returns the path to the WinDbg binary.


str – Path to the appropriate windbg binary to use.

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

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

  • 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().


process – A tube connected to the target process.


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