ReactOS  0.4.14-dev-845-g8381e29
dbgui.c File Reference
#include <ntdll.h>
#include <ndk/dbgkfuncs.h>
#include <debug.h>
Include dependency graph for dbgui.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

NTSTATUS NTAPI DbgUiConnectToDbg (VOID)
 
NTSTATUS NTAPI DbgUiContinue (IN PCLIENT_ID ClientId, IN NTSTATUS ContinueStatus)
 
NTSTATUS NTAPI DbgUiConvertStateChangeStructure (IN PDBGUI_WAIT_STATE_CHANGE WaitStateChange, OUT PVOID Win32DebugEvent)
 
NTSTATUS NTAPI DbgUiWaitStateChange (OUT PDBGUI_WAIT_STATE_CHANGE WaitStateChange, IN PLARGE_INTEGER TimeOut OPTIONAL)
 
VOID NTAPI DbgUiRemoteBreakin (VOID)
 
NTSTATUS NTAPI DbgUiIssueRemoteBreakin (IN HANDLE Process)
 
HANDLE NTAPI DbgUiGetThreadDebugObject (VOID)
 
VOID NTAPI DbgUiSetThreadDebugObject (HANDLE DebugObject)
 
NTSTATUS NTAPI DbgUiDebugActiveProcess (IN HANDLE Process)
 
NTSTATUS NTAPI DbgUiStopDebugging (IN HANDLE Process)
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 15 of file dbgui.c.

Function Documentation

◆ DbgUiConnectToDbg()

NTSTATUS NTAPI DbgUiConnectToDbg ( VOID  )

Definition at line 25 of file dbgui.c.

26 {
28 
29  /* Don't connect twice */
30  if (NtCurrentTeb()->DbgSsReserved[1]) return STATUS_SUCCESS;
31 
32  /* Setup the Attributes */
34 
35  /* Create the object */
36  return ZwCreateDebugObject(&NtCurrentTeb()->DbgSsReserved[1],
40 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define DBGK_KILL_PROCESS_ON_EXIT
Definition: dbgktypes.h:49
smooth NULL
Definition: ftsmooth.c:416
FORCEINLINE struct _TEB * NtCurrentTeb(VOID)
Definition: psfuncs.h:420
NTSYSAPI NTSTATUS NTAPI ZwCreateDebugObject(_Out_ PHANDLE DebugHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes, _In_ ULONG Flags)
#define DEBUG_OBJECT_ALL_ACCESS
Definition: dbgktypes.h:34
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
return STATUS_SUCCESS
Definition: btrfs.c:2938

Referenced by CreateProcessInternalW(), DebugActiveProcess(), and Main().

◆ DbgUiContinue()

NTSTATUS NTAPI DbgUiContinue ( IN PCLIENT_ID  ClientId,
IN NTSTATUS  ContinueStatus 
)

Definition at line 47 of file dbgui.c.

49 {
50  /* Tell the kernel object to continue */
51  return ZwDebugContinue(NtCurrentTeb()->DbgSsReserved[1],
52  ClientId,
53  ContinueStatus);
54 }
NTSYSAPI NTSTATUS NTAPI ZwDebugContinue(_In_ HANDLE DebugObject, _In_ PCLIENT_ID AppClientId, _In_ NTSTATUS ContinueStatus)
_Out_ PCLIENT_ID ClientId
Definition: kefuncs.h:1163
FORCEINLINE struct _TEB * NtCurrentTeb(VOID)
Definition: psfuncs.h:420

Referenced by ContinueDebugEvent(), and Main().

◆ DbgUiConvertStateChangeStructure()

NTSTATUS NTAPI DbgUiConvertStateChangeStructure ( IN PDBGUI_WAIT_STATE_CHANGE  WaitStateChange,
OUT PVOID  Win32DebugEvent 
)

Definition at line 61 of file dbgui.c.

63 {
65  THREAD_BASIC_INFORMATION ThreadBasicInfo;
66  LPDEBUG_EVENT DebugEvent = Win32DebugEvent;
67 
68  /* Write common data */
69  DebugEvent->dwProcessId = PtrToUlong(WaitStateChange->AppClientId.UniqueProcess);
70  DebugEvent->dwThreadId = PtrToUlong(WaitStateChange->AppClientId.UniqueThread);
71 
72  /* Check what kind of even this is */
73  switch (WaitStateChange->NewState)
74  {
75  /* New thread */
77  {
78  /* Setup Win32 code */
79  DebugEvent->dwDebugEventCode = CREATE_THREAD_DEBUG_EVENT;
80 
81  /* Copy data over */
82  DebugEvent->u.CreateThread.hThread =
83  WaitStateChange->StateInfo.CreateThread.HandleToThread;
84  DebugEvent->u.CreateThread.lpStartAddress =
85  WaitStateChange->StateInfo.CreateThread.NewThread.StartAddress;
86 
87  /* Query the TEB */
88  Status = NtQueryInformationThread(WaitStateChange->StateInfo.
89  CreateThread.HandleToThread,
91  &ThreadBasicInfo,
92  sizeof(ThreadBasicInfo),
93  NULL);
94  if (!NT_SUCCESS(Status))
95  {
96  /* Failed to get PEB address */
97  DebugEvent->u.CreateThread.lpThreadLocalBase = NULL;
98  }
99  else
100  {
101  /* Write PEB Address */
102  DebugEvent->u.CreateThread.lpThreadLocalBase =
103  ThreadBasicInfo.TebBaseAddress;
104  }
105  break;
106  }
107 
108  /* New process */
110  {
111  /* Write Win32 debug code */
112  DebugEvent->dwDebugEventCode = CREATE_PROCESS_DEBUG_EVENT;
113 
114  /* Copy data over */
115  DebugEvent->u.CreateProcessInfo.hProcess =
116  WaitStateChange->StateInfo.CreateProcessInfo.HandleToProcess;
117  DebugEvent->u.CreateProcessInfo.hThread =
118  WaitStateChange->StateInfo.CreateProcessInfo.HandleToThread;
119  DebugEvent->u.CreateProcessInfo.hFile =
120  WaitStateChange->StateInfo.CreateProcessInfo.NewProcess.
121  FileHandle;
122  DebugEvent->u.CreateProcessInfo.lpBaseOfImage =
123  WaitStateChange->StateInfo.CreateProcessInfo.NewProcess.
124  BaseOfImage;
125  DebugEvent->u.CreateProcessInfo.dwDebugInfoFileOffset =
126  WaitStateChange->StateInfo.CreateProcessInfo.NewProcess.
127  DebugInfoFileOffset;
128  DebugEvent->u.CreateProcessInfo.nDebugInfoSize =
129  WaitStateChange->StateInfo.CreateProcessInfo.NewProcess.
130  DebugInfoSize;
131  DebugEvent->u.CreateProcessInfo.lpStartAddress =
132  WaitStateChange->StateInfo.CreateProcessInfo.NewProcess.
133  InitialThread.StartAddress;
134 
135  /* Query TEB address */
136  Status = NtQueryInformationThread(WaitStateChange->StateInfo.
137  CreateProcessInfo.HandleToThread,
139  &ThreadBasicInfo,
140  sizeof(ThreadBasicInfo),
141  NULL);
142  if (!NT_SUCCESS(Status))
143  {
144  /* Failed to get PEB address */
145  DebugEvent->u.CreateProcessInfo.lpThreadLocalBase = NULL;
146  }
147  else
148  {
149  /* Write PEB Address */
150  DebugEvent->u.CreateProcessInfo.lpThreadLocalBase =
151  ThreadBasicInfo.TebBaseAddress;
152  }
153 
154  /* Clear image name */
155  DebugEvent->u.CreateProcessInfo.lpImageName = NULL;
156  DebugEvent->u.CreateProcessInfo.fUnicode = TRUE;
157  break;
158  }
159 
160  /* Thread exited */
162  {
163  /* Write the Win32 debug code and the exit status */
164  DebugEvent->dwDebugEventCode = EXIT_THREAD_DEBUG_EVENT;
165  DebugEvent->u.ExitThread.dwExitCode =
166  WaitStateChange->StateInfo.ExitThread.ExitStatus;
167  break;
168  }
169 
170  /* Process exited */
172  {
173  /* Write the Win32 debug code and the exit status */
174  DebugEvent->dwDebugEventCode = EXIT_PROCESS_DEBUG_EVENT;
175  DebugEvent->u.ExitProcess.dwExitCode =
176  WaitStateChange->StateInfo.ExitProcess.ExitStatus;
177  break;
178  }
179 
180  /* Any sort of exception */
184  {
185  /* Check if this was a debug print */
186  if (WaitStateChange->StateInfo.Exception.ExceptionRecord.
188  {
189  /* Set the Win32 code */
190  DebugEvent->dwDebugEventCode = OUTPUT_DEBUG_STRING_EVENT;
191 
192  /* Copy debug string information */
193  DebugEvent->u.DebugString.lpDebugStringData =
194  (PVOID)WaitStateChange->
195  StateInfo.Exception.ExceptionRecord.
196  ExceptionInformation[1];
197  DebugEvent->u.DebugString.nDebugStringLength =
198  WaitStateChange->StateInfo.Exception.ExceptionRecord.
199  ExceptionInformation[0];
200  DebugEvent->u.DebugString.fUnicode = FALSE;
201  }
202  else if (WaitStateChange->StateInfo.Exception.ExceptionRecord.
204  {
205  /* Set the Win32 code */
206  DebugEvent->dwDebugEventCode = RIP_EVENT;
207 
208  /* Set exception information */
209  DebugEvent->u.RipInfo.dwType =
210  WaitStateChange->StateInfo.Exception.ExceptionRecord.
211  ExceptionInformation[1];
212  DebugEvent->u.RipInfo.dwError =
213  WaitStateChange->StateInfo.Exception.ExceptionRecord.
214  ExceptionInformation[0];
215  }
216  else
217  {
218  /* Otherwise, this is a debug event, copy info over */
219  DebugEvent->dwDebugEventCode = EXCEPTION_DEBUG_EVENT;
220  DebugEvent->u.Exception.ExceptionRecord =
221  WaitStateChange->StateInfo.Exception.ExceptionRecord;
222  DebugEvent->u.Exception.dwFirstChance =
223  WaitStateChange->StateInfo.Exception.FirstChance;
224  }
225  break;
226  }
227 
228  /* DLL Load */
230  {
231  /* Set the Win32 debug code */
232  DebugEvent->dwDebugEventCode = LOAD_DLL_DEBUG_EVENT;
233 
234  /* Copy the rest of the data */
235  DebugEvent->u.LoadDll.hFile =
236  WaitStateChange->StateInfo.LoadDll.FileHandle;
237  DebugEvent->u.LoadDll.lpBaseOfDll =
238  WaitStateChange->StateInfo.LoadDll.BaseOfDll;
239  DebugEvent->u.LoadDll.dwDebugInfoFileOffset =
240  WaitStateChange->StateInfo.LoadDll.DebugInfoFileOffset;
241  DebugEvent->u.LoadDll.nDebugInfoSize =
242  WaitStateChange->StateInfo.LoadDll.DebugInfoSize;
243  DebugEvent->u.LoadDll.lpImageName =
244  WaitStateChange->StateInfo.LoadDll.NamePointer;
245 
246  /* It's Unicode */
247  DebugEvent->u.LoadDll.fUnicode = TRUE;
248  break;
249  }
250 
251  /* DLL Unload */
253  {
254  /* Set Win32 code and DLL Base */
255  DebugEvent->dwDebugEventCode = UNLOAD_DLL_DEBUG_EVENT;
256  DebugEvent->u.UnloadDll.lpBaseOfDll =
257  WaitStateChange->StateInfo.UnloadDll.BaseAddress;
258  break;
259  }
260 
261  /* Anything else, fail */
262  default: return STATUS_UNSUCCESSFUL;
263  }
264 
265  /* Return success */
266  return STATUS_SUCCESS;
267 }
_Inout_ PIRP _In_ NTSTATUS ExceptionCode
Definition: cdprocs.h:1782
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
#define DebugEvent(tess)
Definition: sweep.c:59
#define LOAD_DLL_DEBUG_EVENT
Definition: winbase.h:107
HANDLE FileHandle
Definition: stats.c:38
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:136
smooth NULL
Definition: ftsmooth.c:416
#define UNLOAD_DLL_DEBUG_EVENT
Definition: winbase.h:108
SIZE_T LPDEBUG_EVENT
Definition: cordebug.idl:83
void * PVOID
Definition: retypes.h:9
#define PtrToUlong(u)
Definition: config.h:107
#define EXIT_PROCESS_DEBUG_EVENT
Definition: winbase.h:106
#define CREATE_THREAD_DEBUG_EVENT
Definition: winbase.h:103
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS NTAPI NtQueryInformationThread(IN HANDLE ThreadHandle, IN THREADINFOCLASS ThreadInformationClass, OUT PVOID ThreadInformation, IN ULONG ThreadInformationLength, OUT PULONG ReturnLength OPTIONAL)
Definition: query.c:2497
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define DBG_PRINTEXCEPTION_C
Definition: ntstatus.h:53
Status
Definition: gdiplustypes.h:24
#define EXCEPTION_DEBUG_EVENT
Definition: winbase.h:102
#define DBG_RIPEXCEPTION
Definition: ntstatus.h:54
#define EXIT_THREAD_DEBUG_EVENT
Definition: winbase.h:105
#define OUTPUT_DEBUG_STRING_EVENT
Definition: winbase.h:109
#define CREATE_PROCESS_DEBUG_EVENT
Definition: winbase.h:104
return STATUS_SUCCESS
Definition: btrfs.c:2938
#define RIP_EVENT
Definition: winbase.h:110

Referenced by WaitForDebugEvent().

◆ DbgUiDebugActiveProcess()

NTSTATUS NTAPI DbgUiDebugActiveProcess ( IN HANDLE  Process)

Definition at line 355 of file dbgui.c.

356 {
358 
359  /* Tell the kernel to start debugging */
360  Status = NtDebugActiveProcess(Process, NtCurrentTeb()->DbgSsReserved[1]);
361  if (NT_SUCCESS(Status))
362  {
363  /* Now break-in the process */
365  if (!NT_SUCCESS(Status))
366  {
367  /* We couldn't break-in, cancel debugging */
369  }
370  }
371 
372  /* Return status */
373  return Status;
374 }
NTSTATUS NTAPI DbgUiStopDebugging(IN HANDLE Process)
Definition: dbgui.c:381
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS NTAPI NtDebugActiveProcess(IN HANDLE ProcessHandle, IN HANDLE DebugHandle)
Definition: dbgkobj.c:1797
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS NTAPI DbgUiIssueRemoteBreakin(IN HANDLE Process)
Definition: dbgui.c:303
Status
Definition: gdiplustypes.h:24
FORCEINLINE struct _TEB * NtCurrentTeb(VOID)
Definition: psfuncs.h:420
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219

Referenced by DebugActiveProcess(), and Main().

◆ DbgUiGetThreadDebugObject()

HANDLE NTAPI DbgUiGetThreadDebugObject ( VOID  )

Definition at line 333 of file dbgui.c.

334 {
335  /* Just return the handle from the TEB */
336  return NtCurrentTeb()->DbgSsReserved[1];
337 }
FORCEINLINE struct _TEB * NtCurrentTeb(VOID)
Definition: psfuncs.h:420

Referenced by CreateProcessInternalW(), and DebugSetProcessKillOnExit().

◆ DbgUiIssueRemoteBreakin()

NTSTATUS NTAPI DbgUiIssueRemoteBreakin ( IN HANDLE  Process)

Definition at line 303 of file dbgui.c.

304 {
305  HANDLE hThread;
308 
309  /* Create the thread that will do the breakin */
311  NULL,
312  FALSE,
313  0,
314  0,
315  PAGE_SIZE,
317  NULL,
318  &hThread,
319  &ClientId);
320 
321  /* Close the handle on success */
323 
324  /* Return status */
325  return Status;
326 }
VOID NTAPI DbgUiRemoteBreakin(VOID)
Definition: dbgui.c:289
LONG NTSTATUS
Definition: precomp.h:26
smooth NULL
Definition: ftsmooth.c:416
_Out_ PCLIENT_ID ClientId
Definition: kefuncs.h:1163
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
#define PAGE_SIZE
Definition: env_spec_w32.h:49
NTSYSAPI NTSTATUS NTAPI RtlCreateUserThread(_In_ PVOID ThreadContext, _Out_ HANDLE *OutThreadHandle, _Reserved_ PVOID Reserved1, _Reserved_ PVOID Reserved2, _Reserved_ PVOID Reserved3, _Reserved_ PVOID Reserved4, _Reserved_ PVOID Reserved5, _Reserved_ PVOID Reserved6, _Reserved_ PVOID Reserved7, _Reserved_ PVOID Reserved8)
Status
Definition: gdiplustypes.h:24
HANDLE hThread
Definition: wizard.c:27
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219

Referenced by DbgUiDebugActiveProcess(), and DebugBreakProcess().

◆ DbgUiRemoteBreakin()

VOID NTAPI DbgUiRemoteBreakin ( VOID  )

Definition at line 289 of file dbgui.c.

290 {
291  /* Make sure a debugger is enabled; if so, breakpoint */
292  if (NtCurrentPeb()->BeingDebugged) DbgBreakPoint();
293 
294  /* Exit the thread */
296 }
NTSYSAPI VOID NTAPI RtlExitUserThread(_In_ NTSTATUS Status)
void DbgBreakPoint()
Definition: mach.c:553
#define NtCurrentPeb()
Definition: FLS.c:20
return STATUS_SUCCESS
Definition: btrfs.c:2938

Referenced by DbgUiIssueRemoteBreakin().

◆ DbgUiSetThreadDebugObject()

VOID NTAPI DbgUiSetThreadDebugObject ( HANDLE  DebugObject)

Definition at line 344 of file dbgui.c.

345 {
346  /* Just set the handle in the TEB */
347  NtCurrentTeb()->DbgSsReserved[1] = DebugObject;
348 }
FORCEINLINE struct _TEB * NtCurrentTeb(VOID)
Definition: psfuncs.h:420

◆ DbgUiStopDebugging()

NTSTATUS NTAPI DbgUiStopDebugging ( IN HANDLE  Process)

Definition at line 381 of file dbgui.c.

382 {
383  /* Call the kernel to remove the debug object */
384  return NtRemoveProcessDebug(Process, NtCurrentTeb()->DbgSsReserved[1]);
385 }
NTSTATUS NTAPI NtRemoveProcessDebug(IN HANDLE ProcessHandle, IN HANDLE DebugHandle)
Definition: dbgkobj.c:1873
FORCEINLINE struct _TEB * NtCurrentTeb(VOID)
Definition: psfuncs.h:420
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219

Referenced by DbgUiDebugActiveProcess(), and DebugActiveProcessStop().

◆ DbgUiWaitStateChange()

NTSTATUS NTAPI DbgUiWaitStateChange ( OUT PDBGUI_WAIT_STATE_CHANGE  WaitStateChange,
IN PLARGE_INTEGER TimeOut  OPTIONAL 
)

Definition at line 274 of file dbgui.c.

276 {
277  /* Tell the kernel to wait */
278  return NtWaitForDebugEvent(NtCurrentTeb()->DbgSsReserved[1],
279  TRUE,
280  TimeOut,
281  WaitStateChange);
282 }
#define TRUE
Definition: types.h:120
NTSTATUS NTAPI NtWaitForDebugEvent(IN HANDLE DebugHandle, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL, OUT PDBGUI_WAIT_STATE_CHANGE StateChange)
Definition: dbgkobj.c:2001
FORCEINLINE struct _TEB * NtCurrentTeb(VOID)
Definition: psfuncs.h:420

Referenced by Main(), and WaitForDebugEvent().