Previous | Next |
STATUS_SERVICES_FAILED_AUTOSTART | DBG_UNABLE_TO_PROVIDE_HANDLE |
DBG_REPLY_LATER
ContinueDebugEvent function
This function enables a debugger to continue a thread that previously reported a debugging event.
BOOL ContinueDebugEvent([in] DWORD dwProcessId,[in] DWORD dwThreadId,[in] DWORD dwContinueStatus);
Parameters
[in] dwProcessId
The process identifier of the process to continue.
[in] dwThreadId
The thread identifier of the thread to continue. The combination of process identifier and thread identifier must identify a thread that has previously reported a debugging event.
[in] dwContinueStatus
The options to continue the thread that reported the debugging event.
Value | Meaning |
---|---|
|
If the thread specified by the dwThreadId parameter previously reported an EXCEPTION_DEBUG_EVENT debugging event, the function stops all exception processing and continues the thread and the exception is marked as handled. For any other debugging event, this flag simply continues the thread. |
|
If the thread specified by dwThreadId previously reported an EXCEPTION_DEBUG_EVENT debugging event, the function continues exception processing. If this is a first-chance exception event, the search and dispatch logic of the structured exception handler is used; otherwise, the process is terminated. For any other debugging event, this flag simply continues the thread. |
|
DBG_REPLY_LATER is supported in Windows 10, version 1507 or above, this flag causes dwThreadId to replay the existing breaking event after the target continues. By calling the SuspendThread API against dwThreadId, a debugger can resume other threads in the process and later return to the breaking. |
Return value
If the function succeeds, the return value is nonzero.
If the function fails, the return value is zero. To get extended error information, call GetLastError.
Windows Debugger API’s
Windows has a collection of API’s that allow for a process to attach to and debug another process. These are detailed in several short articles available on MSDN. For our purposes, we mainly care about the following API’s:
- DebugActiveProcess, which is used to attach to a target process
- WaitForDebugEvent, which is used to wait for debugging events, as described in MSDN articles
- ContinueDebugEvent, which is used to continue execution after a debug event is triggered
When using these API’s, we are attaching to a process and waiting for it to trigger one of several debug events, such as creating a thread or encountering an exception. However, when debugging a target we do not have the source code to, this will limit us to only breaking on thread and process creation events.
To be able to trigger a breakpoint on an address, we will need to use an interrupt instruction. Interrupt instructions are a special set of software instructions that invoke a special interrupt handler on the CPU. One of these instructions, int 3, will trigger a breakpoint when executed. Its opcode is 0xCC
.
We can utilize this behavior to set a breakpoint on any instruction. Before we attach a debugger to a process, we will use WriteProcessMemory to write 0xCC
to the instruction we wish to break on. We will then listen for debug events like normal. When we get a breakpoint event, we will restore the instruction to its original form and continue execution. By doing this, we can set breakpoints on any instruction in targets that we do not have the source control to.