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[source]
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
targetargument is very robust, and can be any of the following:intPID of a process
strProcess name. The youngest process is selected.
processProcess 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
processtube 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.
- Returns:
str – Path to the appropriate
windbgbinary 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.
- 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.