8. windows.debug – Debugging

Note

See sample Debugging

8.1. Debugger

The Debugger is the base class to perform the debugging of a remote process. The Debugger have some functions called on given event that can be implemented by subclasses.

All Memory-breakpoint are disabled when callind a public callback or a breakpoint trigger() function.

This means that those methods see the original current_process memory access rights.

class windows.debug.Debugger(target)[source]

A debugger based on standard Win32 API. Handle :

  • Standard BP (int3)
  • Hardware-Exec BP (DrX)
  • Memory BP (virtual_protect)
__init__(target)[source]

target must be a debuggable WinProcess.

classmethod attach(target)[source]

attach to target (must be a WinProcess)

Return type:Debugger
detach(target=None)[source]

Detach from all debugged processes or process target

classmethod debug(path, args=None, dwCreationFlags=0, show_windows=False)[source]

Create a process and debug it.

Return type:Debugger
loop()[source]

Debugging loop: handle event / dispatch to breakpoint. Returns when all targets are dead/detached

add_bp(bp, addr=None, type=None, target=None)[source]

Add a breakpoint, bp can be:

  • a Breakpoint (addr and type must be None)
  • any callable (addr and type must NOT be None) (NON-TESTED)

If the bp type is STANDARD_BP or MEMORY_BREAKPOINT, target can be None (all targets) or a process.

If the bp type is HARDWARE_EXEC_BP, target can be None (all targets), a process or a thread.

del_bp(bp, targets=None)[source]

Delete a breakpoint, if targets is None: delete it from all targets

single_step()[source]

Make the current_thread single_step. Debugger.on_single_step will be called after that

get_memory_breakpoint_at(addr, process=None)[source]

Get the memory breakpoint that handle addr

Return values are:

  • False if the page has no memory breakpoint (real fault)
  • None if the page as memBP but None handle addr
  • bp the MemBP that handle addr
disable_all_memory_breakpoints(target=None)[source]

Restore all pages to their original access rights. If target is None, use current_process

Returns:a mapping of all disabled breakpoints that must be passed to restore_all_memory_breakpoints()
restore_all_memory_breakpoints(data, target=None)[source]

Re-setup all memory breakpoints, affecting pages access rights. If target is None, use current_process

data is the result of the corresponding call to disable_all_memory_breakpoints()

DisabledMemoryBreakpoint(**kwds)[source]

A context-manager that disable all memory breakpoints and restore them on exit

get_exception_bitness(exc)[source]

Return the bitness in which the exception occured. Useful when debugingg a 32b process from a 64bits one

Returns:int – 32 or 64
on_exception(exception)[source]

Called on exception event other that known breakpoint or requested single step. exception is one of the following type:

The default behaviour is to return DBG_CONTINUE for the known exception code and DBG_EXCEPTION_NOT_HANDLED else

on_single_step(exception)[source]

Called on requested single step exception is one of the following type:

There is no default implementation, if you use Debugger.single_step() you should implement on_single_step

on_create_process(create_process)[source]

Called on create_process event

Parameters:create_process (CREATE_PROCESS_DEBUG_INFO) –
on_exit_process(exit_process)[source]

Called on exit_process event

Parameters:exit_process (EXIT_PROCESS_DEBUG_INFO) –
on_create_thread(create_thread)[source]

Called on create_thread event

Parameters:create_thread (CREATE_THREAD_DEBUG_INFO) –
on_exit_thread(exit_thread)[source]

Called on exit_thread event

Parameters:exit_thread (EXIT_THREAD_DEBUG_INFO) –
on_load_dll(load_dll)[source]

Called on load_dll event

Parameters:load_dll (LOAD_DLL_DEBUG_INFO) –
on_unload_dll(unload_dll)[source]

Called on unload_dll event

Parameters:unload_dll (UNLOAD_DLL_DEBUG_INFO) –
on_output_debug_string(debug_string)[source]

Called on debug_string event

Parameters:debug_string (OUTPUT_DEBUG_STRING_INFO) –
on_rip(rip_info)[source]

Called on rip_info event

Parameters:rip_info (RIP_INFO) –

8.2. LocalDebugger

Note

See sample LocalDebugger

The Debugger is the base class to perform the debugging the current process. It is based on VectoredException() (see VectoredException())

There is not much documentation for now as the code might change soon.

class windows.debug.LocalDebugger[source]

A debugger interface around AddVectoredExceptionHandler().

Handle:

  • Standard BP (int3)
  • Hardware-Exec BP (DrX)
add_bp(bp, targets=None)[source]

Add a breakpoint, bp is a “class:Breakpoint

If the bp type is STANDARD_BP, target must be None.

If the bp type is HARDWARE_EXEC_BP, target can be None (all threads), or some threads of the process

del_bp(bp)[source]

Delete a breakpoint

get_exception_code()[source]

Return ExceptionCode of current exception

get_exception_context()[source]

Return context of current exception

on_exception(exc)[source]

Called on exception

single_step()[source]

Make the current thread to single step

8.3. Breakpoint

Standard breakpoints types expect an address as argument.

An address can be:

  • An int

  • A str of form (breakpoint will be put when DLL is loaded):

    • "DLL!ApiName"
    • "DLL!Offset" where offset is a int (“16”, “0x10”, ..)

When a breakpoint is hit, its trigger function is called with the debugger and a DEBUG_EXECEPTION_EVENT structure as argument.

class windows.debug.Breakpoint(addr)[source]

An standard (Int3) breakpoint (type == STANDARD_BP)

trigger(dbg, exception)[source]

Called when breakpoint is hit

class windows.debug.HXBreakpoint(addr)[source]

An hardware-execution breakpoint (type == HARDWARE_EXEC_BP)

trigger(dbg, exception)

Called when breakpoint is hit

class windows.debug.MemoryBreakpoint(addr, size=None, events=None)[source]

A memory breakpoint (type == MEMORY_BREAKPOINT)

__init__(addr, size=None, events=None)[source]

size: the size of the memory breakpoint.

events: a string representing the events that interest the BP (any of “RWX”)

trigger(dbg, exception)[source]

Called when breakpoint is hit

Note

MemoryBreakpoint are triggered based on the fault address only (as I don’t know a way to get the size of the read/write causing the fault without embedding a disassembler).

This means that a MEMBP at address X won’t be triggered by a write of size 4 at address X - 1. it’s sad I know.

class windows.debug.FunctionBP(addr=None, target=None)[source]

A breakpoint that accepts a function from windows.winproxy and able to:

  • Extract the arguments of the functions
  • Break at the return of the function
__init__(addr=None, target=None)

x.__init__(…) initializes x; see help(type(x)) for signature

break_on_ret(dbg, exception)

Setup a breakpoint at the return address of the function, this breakpoint will call ret_trigger()

extract_arguments(cproc, cthread)

Extracts the functions parameters in an OrderedDict

ret_trigger(dbg, exception)

Called at the return of the function if break_on_ret() was called

trigger(dbg, exception)

Called when breakpoint is hit