winappdbg.debug

Main debugger class. Most applications will want to start with this one.

class winappdbg.debug.Debug(eventHandler=None, bKillOnExit=False, bHostileCode=False)

The main debugger class.

Variables:

system – A System snapshot that is automatically updated for processes being debugged. Processes not being debugged in this snapshot may be outdated.

add_existing_session(dwProcessId, bStarted=False)

Use this method only when for some reason the debugger’s been attached to the target outside of WinAppDbg (for example when integrating with other tools).

You don’t normally need to call this method. Most users should call attach(), execv() or execl() instead.

Parameters:
  • dwProcessId (int) – Global process ID.

  • bStarted (bool) – True if the process was started by the debugger, or False if the process was attached to instead.

Raises:

WindowsError – The target process does not exist, is not attached to the debugger anymore.

attach(dwProcessId, bScan=True)

Attaches to an existing process for debugging.

See also

detach(), execv(), execl()

Parameters:
  • dwProcessId (int) – Global ID of a process to attach to.

  • bScan (bool) –

    True to perform a scan of threads and modules once attached to the process, False to let the debug events provide that information.

    It is generally best to do a scan instead of relying on the debug events, since they may be missing some information that we can obtain by scanning. However, there are some situations when scanning may fail - in particular, attaching to a suspended process and then trying to scan it will fail.

Return type:

Process

Returns:

A new Process object. Normally you don’t need to use it now, it’s best to interact with the process from the event handler.

Raises:

WindowsError – Raises an exception on error. Depending on the circumstances, the debugger may or may not have attached to the target process.

cont(event=None)

Resumes execution after processing a debug event.

See also

dispatch(), loop(), wait()

Parameters:

event (Event) – (Optional) Event object returned by wait().

Raises:

WindowsError – Raises an exception on error.

detach(dwProcessId, bIgnoreExceptions=False)

Detaches from a process currently being debugged.

Note

On Windows 2000 and below the process is killed.

Parameters:
  • dwProcessId (int) – Global ID of a process to detach from.

  • bIgnoreExceptions (bool) – True to ignore any exceptions that may be raised when detaching. False to stop and raise an exception when encountering an error.

Raises:

WindowsError – Raises an exception on error, unless bIgnoreExceptions is True.

detach_from_all(bIgnoreExceptions=False)

Detaches from all processes currently being debugged.

Note

To better handle last debugging event, call stop() instead.

Parameters:

bIgnoreExceptions (bool) – True to ignore any exceptions that may be raised when detaching.

Raises:

WindowsError – Raises an exception on error, unless bIgnoreExceptions is True.

dispatch(event=None)

Calls the debug event notify callbacks.

See also

cont(), loop(), wait()

Parameters:

event (Event) – (Optional) Event object returned by wait().

Raises:

WindowsError – Raises an exception on error.

execl(lpCmdLine, **kwargs)

Starts a new process for debugging.

This method uses a command line string. To use a list of arguments instead, use execv().

See also

attach(), detach()

Parameters:
  • lpCmdLine (str) – Command line string to execute. The first token must be the debugee executable filename. Tokens with spaces must be enclosed in double quotes. Tokens including double quote characters must be escaped with a backslash.

  • bBreakOnEntryPoint (bool) – True to automatically set a breakpoint at the program entry point. Defaults to False.

  • bConsole (bool) – True to inherit the console of the debugger. Defaults to False.

  • bFollow (bool) – True to automatically attach to child processes. Defaults to False.

  • bInheritHandles (bool) – True if the new process should inherit it’s parent process’ handles. Defaults to False.

  • bSuspended (bool) – True to suspend the main thread before any code is executed in the debugee. Defaults to False.

  • dwParentProcessId (int or None) –

    None or 0 if the debugger process should be the parent process (default), or a process ID to forcefully set as the debugee’s parent (only available for Windows Vista and above).

    In hostile mode, the default is not the debugger process but the process ID for “explorer.exe”.

  • iTrustLevel (int) –

    Trust level. Must be one of the following values:

    • 0: No trust. May not access certain resources, such as cryptographic keys and credentials. Only available since Windows XP and 2003, desktop editions. This is the default in hostile mode.

    • 1: Normal trust. Run with the same privileges as a normal user, that is, one that doesn’t have the Administrator or Power User user rights. Only available since Windows XP and 2003, desktop editions.

    • 2: Full trust. Run with the exact same privileges as the current user. This is the default in normal mode.

  • bAllowElevation (bool) –

    True to allow the child process to keep UAC elevation, if the debugger itself is running elevated. False to ensure the child process doesn’t run with elevation. Defaults to True in normal mode and False in hostile mode.

    This flag is only meaningful on Windows Vista and above, and if the debugger itself is running with elevation. It can be used to make sure the child processes don’t run elevated as well.

    This flag DOES NOT force an elevation prompt when the debugger is not running with elevation.

    Note that running the debugger with elevation (or the Python interpreter at all for that matter) is not normally required. You should only need to if the target program requires elevation to work properly (for example if you try to debug an installer).

Return type:

Process

Returns:

A new Process object. Normally you don’t need to use it now, it’s best to interact with the process from the event handler.

Raises:

WindowsError – Raises an exception on error.

execv(argv, **kwargs)

Starts a new process for debugging.

This method uses a list of arguments. To use a command line string instead, use execl().

See also

attach(), detach()

Parameters:
  • argv (list[str]) – List of command line arguments to pass to the debugee. The first element must be the debugee executable filename.

  • bBreakOnEntryPoint (bool) – True to automatically set a breakpoint at the program entry point.

  • bConsole (bool) – True to inherit the console of the debugger. Defaults to False.

  • bFollow (bool) – True to automatically attach to child processes. Defaults to False.

  • bInheritHandles (bool) – True if the new process should inherit it’s parent process’ handles. Defaults to False.

  • bSuspended (bool) – True to suspend the main thread before any code is executed in the debugee. Defaults to False.

  • dwParentProcessId

    None or 0 if the debugger process should be the parent process (default), or a process ID to forcefully set as the debugee’s parent (only available for Windows Vista and above).

    In hostile mode, the default is not the debugger process but the process ID for “explorer.exe”.

  • iTrustLevel (int or None) –

    Trust level. Must be one of the following values:

    • 0: No trust. May not access certain resources, such as cryptographic keys and credentials. Only available since Windows XP and 2003, desktop editions. This is the default in hostile mode.

    • 1: Normal trust. Run with the same privileges as a normal user, that is, one that doesn’t have the Administrator or Power User user rights. Only available since Windows XP and 2003, desktop editions.

    • 2: Full trust. Run with the exact same privileges as the current user. This is the default in normal mode.

  • bAllowElevation (bool) –

    True to allow the child process to keep UAC elevation, if the debugger itself is running elevated. False to ensure the child process doesn’t run with elevation. Defaults to True.

    This flag is only meaningful on Windows Vista and above, and if the debugger itself is running with elevation. It can be used to make sure the child processes don’t run elevated as well.

    This flag DOES NOT force an elevation prompt when the debugger is not running with elevation.

    Note that running the debugger with elevation (or the Python interpreter at all for that matter) is not normally required. You should only need to if the target program requires elevation to work properly (for example if you try to debug an installer).

Return type:

Process

Returns:

A new Process object. Normally you don’t need to use it now, it’s best to interact with the process from the event handler.

Raises:

WindowsError – Raises an exception on error.

static force_garbage_collection(bIgnoreExceptions=True)

Close all Win32 handles the Python garbage collector failed to close.

Parameters:

bIgnoreExceptions (bool) – True to ignore any exceptions that may be raised when detaching.

get_debugee_count()
Return type:

int

Returns:

Number of processes being debugged.

get_debugee_pids()
Return type:

list[int]

Returns:

Global IDs of processes being debugged.

in_hostile_mode()

Determine if we’re in hostile mode (anti-anti-debug).

Return type:

bool

Returns:

True if this Debug instance was started in hostile mode, False otherwise.

interactive(bConfirmQuit=True, bShowBanner=True)

Start an interactive debugging session.

Parameters:
  • bConfirmQuit (bool) – Set to True to ask the user for confirmation before closing the session, False otherwise.

  • bShowBanner (bool) – Set to True to show a banner before entering the session and after leaving it, False otherwise.

Warning

This will temporarily disable the user-defined event handler!

This method returns when the user closes the session.

is_debugee(dwProcessId)

Determine if the debugger is debugging the given process.

Parameters:

dwProcessId (int) – Process global ID.

Return type:

bool

Returns:

True if the given process is being debugged by this Debug instance.

is_debugee_attached(dwProcessId)

Determine if the debugger is attached to the given process.

Parameters:

dwProcessId (int) – Process global ID.

Return type:

bool

Returns:

True if the given process is attached to this Debug instance.

is_debugee_started(dwProcessId)

Determine if the given process was started by the debugger.

Parameters:

dwProcessId (int) – Process global ID.

Return type:

bool

Returns:

True if the given process was started for debugging by this Debug instance.

kill(dwProcessId, bIgnoreExceptions=False)

Kills a process currently being debugged.

See also

detach()

Parameters:
  • dwProcessId (int) – Global ID of a process to kill.

  • bIgnoreExceptions (bool) – True to ignore any exceptions that may be raised when killing the process.

Raises:

WindowsError – Raises an exception on error, unless bIgnoreExceptions is True.

kill_all(bIgnoreExceptions=False)

Kills from all processes currently being debugged.

Parameters:

bIgnoreExceptions (bool) – True to ignore any exceptions that may be raised when killing each process. False to stop and raise an exception when encountering an error.

Raises:

WindowsError – Raises an exception on error, unless bIgnoreExceptions is True.

loop()

Simple debugging loop.

This debugging loop is meant to be useful for most simple scripts. It iterates as long as there is at least one debugee, or an exception is raised. Multiple calls are allowed.

This is a trivial example script:

import sys
debug = Debug()
try:
    debug.execv( sys.argv [ 1 : ] )
    debug.loop()
finally:
    debug.stop()
Raises:

WindowsError

Raises an exception on error.

If the wait operation causes an error, debugging is stopped (meaning all debugees are either killed or detached from).

If the event dispatching causes an error, the event is still continued before returning. This may happen, for example, if the event handler raises an exception nobody catches.

next()

Handles the next debug event.

Raises:

WindowsError

Raises an exception on error.

If the wait operation causes an error, debugging is stopped (meaning all debugees are either killed or detached from).

If the event dispatching causes an error, the event is still continued before returning. This may happen, for example, if the event handler raises an exception nobody catches.

stop(bIgnoreExceptions=True)

Stops debugging all processes.

If the kill on exit mode is on, debugged processes are killed when the debugger is stopped. Otherwise when the debugger stops it detaches from all debugged processes and leaves them running (default). For more details see: __init__()

Note

This method is better than detach_from_all() because it can gracefully handle the last debugging event before detaching.

Parameters:

bIgnoreExceptions (bool) – True to ignore any exceptions that may be raised when detaching.

wait(dwMilliseconds=None)

Waits for the next debug event.

See also

cont(), dispatch(), loop()

Parameters:

dwMilliseconds (int) – (Optional) Timeout in milliseconds. Use INFINITE or None for no timeout.

Return type:

Event

Returns:

An event that occured in one of the debugees.

Raises:

WindowsError – Raises an exception on error. If no target processes are left to debug, the error code is win32.ERROR_INVALID_HANDLE.

exception winappdbg.debug.MixedArchWarning

This warning is issued when mixing architectures.

exception winappdbg.debug.MixedBitsWarning

This warning is issued when mixing 32 and 64 bit processes.