ReactOS  0.4.13-dev-73-gcfe54aa
dbgkutil.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Kernel
3  * LICENSE: GPL - See COPYING in the top level directory
4  * FILE: ntoskrnl/dbgk/dbgkutil.c
5  * PURPOSE: User-Mode Debugging Support, Internal Debug Functions.
6  * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7  */
8 
9 /* INCLUDES ******************************************************************/
10 
11 #include <ntoskrnl.h>
12 #define NDEBUG
13 #include <debug.h>
14 
15 /* FUNCTIONS *****************************************************************/
16 
17 HANDLE
18 NTAPI
20 {
25  HANDLE Handle;
26  PAGED_CODE();
27 
28  /* Get the filename of the section */
30  if (!NT_SUCCESS(Status)) return NULL;
31 
32  /* Initialize object attributes */
34  &FileName->Name,
38  NULL,
39  NULL);
40 
41  /* Open the file */
48 
49  /* Free the name and return the handle if we succeeded */
51  if (!NT_SUCCESS(Status)) return NULL;
52  return Handle;
53 }
54 
55 BOOLEAN
56 NTAPI
58 {
59  PAGED_CODE();
60 
61  /* Make sure this isn't a deleted process */
62  if (!PsGetCurrentProcess()->ProcessDelete)
63  {
64  /* Freeze all the threads */
66  return TRUE;
67  }
68  else
69  {
70  /* No suspend was done */
71  return FALSE;
72  }
73 }
74 
75 VOID
76 NTAPI
78 {
79  PAGED_CODE();
80 
81  /* Thaw all the threads */
83 }
84 
85 VOID
86 NTAPI
88  IN PVOID StartAddress)
89 {
91  ULONG ProcessFlags;
92  IMAGE_INFO ImageInfo;
93  PIMAGE_NT_HEADERS NtHeader;
95  UNICODE_STRING NtDllName;
97  PVOID DebugPort;
98  DBGKM_MSG ApiMessage;
101  PDBGKM_LOAD_DLL LoadDll = &ApiMessage.LoadDll;
104  PTEB Teb;
105  PAGED_CODE();
106 
107  /* Sanity check */
109 
110  /* Try ORing in the create reported and image notify flags */
111  ProcessFlags = PspSetProcessFlag(Process,
114 
115  /* Check if we were the first to set them or if another thread raced us */
116  if (!(ProcessFlags & PSF_IMAGE_NOTIFY_DONE_BIT) && (PsImageNotifyEnabled))
117  {
118  /* It hasn't.. set up the image info for the process */
119  ImageInfo.Properties = 0;
121  ImageInfo.ImageBase = Process->SectionBaseAddress;
122  ImageInfo.ImageSize = 0;
123  ImageInfo.ImageSelector = 0;
124  ImageInfo.ImageSectionNumber = 0;
125 
126  /* Get the NT Headers */
127  NtHeader = RtlImageNtHeader(Process->SectionBaseAddress);
128  if (NtHeader)
129  {
130  /* Set image size */
131  ImageInfo.ImageSize = NtHeader->OptionalHeader.SizeOfImage;
132  }
133 
134  /* Get the image name */
135  Status = MmGetFileNameForSection(Process->SectionObject, &ModuleName);
136  if (NT_SUCCESS(Status))
137  {
138  /* Call the notify routines and free the name */
140  Process->UniqueProcessId,
141  &ImageInfo);
143  }
144  else
145  {
146  /* Call the notify routines */
148  Process->UniqueProcessId,
149  &ImageInfo);
150  }
151 
152  /* Setup the info for ntdll.dll */
153  ImageInfo.Properties = 0;
155  ImageInfo.ImageBase = PspSystemDllBase;
156  ImageInfo.ImageSize = 0;
157  ImageInfo.ImageSelector = 0;
158  ImageInfo.ImageSectionNumber = 0;
159 
160  /* Get the NT Headers */
162  if (NtHeader)
163  {
164  /* Set image size */
165  ImageInfo.ImageSize = NtHeader->OptionalHeader.SizeOfImage;
166  }
167 
168  /* Call the notify routines */
169  RtlInitUnicodeString(&NtDllName,
170  L"\\SystemRoot\\System32\\ntdll.dll");
172  Process->UniqueProcessId,
173  &ImageInfo);
174  }
175 
176  /* Fail if we have no port */
177  DebugPort = Process->DebugPort;
178  if (!DebugPort) return;
179 
180  /* Check if create was not already reported */
181  if (!(ProcessFlags & PSF_CREATE_REPORTED_BIT))
182  {
183  /* Setup the information structure for the new thread */
184  CreateProcess->InitialThread.SubSystemKey = 0;
185  CreateProcess->InitialThread.StartAddress = NULL;
186 
187  /* And for the new process */
188  CreateProcess->SubSystemKey = 0;
190  SectionObject);
191  CreateProcess->BaseOfImage = Process->SectionBaseAddress;
192  CreateProcess->DebugInfoFileOffset = 0;
193  CreateProcess->DebugInfoSize = 0;
194 
195  /* Get the NT Header */
196  NtHeader = RtlImageNtHeader(Process->SectionBaseAddress);
197  if (NtHeader)
198  {
199  /* Fill out data from the header */
200  CreateProcess->InitialThread.StartAddress =
201  (PVOID)((ULONG_PTR)NtHeader->OptionalHeader.ImageBase +
203  CreateProcess->DebugInfoFileOffset = NtHeader->FileHeader.
204  PointerToSymbolTable;
205  CreateProcess->DebugInfoSize = NtHeader->FileHeader.
206  NumberOfSymbols;
207  }
208 
209  /* Setup the API Message */
210  ApiMessage.h.u1.Length = sizeof(DBGKM_MSG) << 16 |
211  (8 + sizeof(DBGKM_CREATE_PROCESS));
212  ApiMessage.h.u2.ZeroInit = 0;
213  ApiMessage.h.u2.s2.Type = LPC_DEBUG_EVENT;
214  ApiMessage.ApiNumber = DbgKmCreateProcessApi;
215 
216  /* Send the message */
217  DbgkpSendApiMessage(&ApiMessage, FALSE);
218 
219  /* Close the handle */
220  ObCloseHandle(CreateProcess->FileHandle, KernelMode);
221 
222  /* Setup the parameters */
223  LoadDll->BaseOfDll = PspSystemDllBase;
224  LoadDll->DebugInfoFileOffset = 0;
225  LoadDll->DebugInfoSize = 0;
226  LoadDll->NamePointer = NULL;
227 
228  /* Get the NT Headers */
230  if (NtHeader)
231  {
232  /* Fill out debug information */
233  LoadDll->DebugInfoFileOffset = NtHeader->
234  FileHeader.PointerToSymbolTable;
235  LoadDll->DebugInfoSize = NtHeader->FileHeader.NumberOfSymbols;
236  }
237 
238  /* Get the TEB */
239  Teb = Thread->Tcb.Teb;
240  if (Teb)
241  {
242  /* Copy the system library name and link to it */
244  L"ntdll.dll",
245  sizeof(Teb->StaticUnicodeBuffer) / sizeof(WCHAR));
247 
248  /* Return it in the debug event as well */
249  LoadDll->NamePointer = &Teb->NtTib.ArbitraryUserPointer;
250  }
251 
252  /* Get a handle */
258  NULL,
259  NULL);
260  Status = ZwOpenFile(&LoadDll->FileHandle,
263  &IoStatusBlock,
268  if (NT_SUCCESS(Status))
269  {
270  /* Setup the API Message */
271  ApiMessage.h.u1.Length = sizeof(DBGKM_MSG) << 16 |
272  (8 + sizeof(DBGKM_LOAD_DLL));
273  ApiMessage.h.u2.ZeroInit = 0;
274  ApiMessage.h.u2.s2.Type = LPC_DEBUG_EVENT;
275  ApiMessage.ApiNumber = DbgKmLoadDllApi;
276 
277  /* Send the message */
278  DbgkpSendApiMessage(&ApiMessage, TRUE);
279 
280  /* Close the handle */
282  }
283  }
284  else
285  {
286  /* Otherwise, do it just for the thread */
287  CreateThread->SubSystemKey = 0;
288  CreateThread->StartAddress = StartAddress;
289 
290  /* Setup the API Message */
291  ApiMessage.h.u1.Length = sizeof(DBGKM_MSG) << 16 |
292  (8 + sizeof(DBGKM_CREATE_THREAD));
293  ApiMessage.h.u2.ZeroInit = 0;
294  ApiMessage.h.u2.s2.Type = LPC_DEBUG_EVENT;
295  ApiMessage.ApiNumber = DbgKmCreateThreadApi;
296 
297  /* Send the message */
298  DbgkpSendApiMessage(&ApiMessage, TRUE);
299  }
300 }
301 
302 VOID
303 NTAPI
305 {
306  DBGKM_MSG ApiMessage;
310  PAGED_CODE();
311 
312  /* Check if this thread is hidden, doesn't have a debug port, or died */
313  if ((Thread->HideFromDebugger) ||
314  !(Process->DebugPort) ||
315  (Thread->DeadThread))
316  {
317  /* Don't notify the debugger */
318  return;
319  }
320 
321  /* Set the exit status */
322  ExitProcess->ExitStatus = ExitStatus;
323 
324  /* Setup the API Message */
325  ApiMessage.h.u1.Length = sizeof(DBGKM_MSG) << 16 |
326  (8 + sizeof(DBGKM_EXIT_PROCESS));
327  ApiMessage.h.u2.ZeroInit = 0;
328  ApiMessage.h.u2.s2.Type = LPC_DEBUG_EVENT;
329  ApiMessage.ApiNumber = DbgKmExitProcessApi;
330 
331  /* Set the current exit time */
332  KeQuerySystemTime(&Process->ExitTime);
333 
334  /* Send the message */
335  DbgkpSendApiMessage(&ApiMessage, FALSE);
336 }
337 
338 VOID
339 NTAPI
341 {
342  DBGKM_MSG ApiMessage;
347  PAGED_CODE();
348 
349  /* Check if this thread is hidden, doesn't have a debug port, or died */
350  if ((Thread->HideFromDebugger) ||
351  !(Process->DebugPort) ||
352  (Thread->DeadThread))
353  {
354  /* Don't notify the debugger */
355  return;
356  }
357 
358  /* Set the exit status */
359  ExitThread->ExitStatus = ExitStatus;
360 
361  /* Setup the API Message */
362  ApiMessage.h.u1.Length = sizeof(DBGKM_MSG) << 16 |
363  (8 + sizeof(DBGKM_EXIT_THREAD));
364  ApiMessage.h.u2.ZeroInit = 0;
365  ApiMessage.h.u2.s2.Type = LPC_DEBUG_EVENT;
366  ApiMessage.ApiNumber = DbgKmExitThreadApi;
367 
368  /* Suspend the process */
370 
371  /* Send the message */
372  DbgkpSendApiMessage(&ApiMessage, FALSE);
373 
374  /* Resume the process if needed */
376 }
377 
378 VOID
379 NTAPI
384 {
385  DBGKM_MSG ApiMessage;
386  PDBGKM_LOAD_DLL LoadDll = &ApiMessage.LoadDll;
389  PIMAGE_NT_HEADERS NtHeader;
390  PAGED_CODE();
392  "Section: %p. Base: %p\n", Section, BaseAddress);
393 
394  /* Check if this thread is kernel, hidden or doesn't have a debug port */
395  if ((ExGetPreviousMode() == KernelMode) ||
397  !(Process->DebugPort))
398  {
399  /* Don't notify the debugger */
400  return;
401  }
402 
403  /* Setup the parameters */
404  LoadDll->FileHandle = DbgkpSectionToFileHandle(Section);
405  LoadDll->BaseOfDll = BaseAddress;
406  LoadDll->DebugInfoFileOffset = 0;
407  LoadDll->DebugInfoSize = 0;
408  LoadDll->NamePointer = &NtCurrentTeb()->NtTib.ArbitraryUserPointer;
409 
410  /* Get the NT Headers */
411  NtHeader = RtlImageNtHeader(BaseAddress);
412  if (NtHeader)
413  {
414  /* Fill out debug information */
415  LoadDll->DebugInfoFileOffset = NtHeader->FileHeader.
416  PointerToSymbolTable;
417  LoadDll->DebugInfoSize = NtHeader->FileHeader.NumberOfSymbols;
418  }
419 
420  /* Setup the API Message */
421  ApiMessage.h.u1.Length = sizeof(DBGKM_MSG) << 16 |
422  (8 + sizeof(DBGKM_LOAD_DLL));
423  ApiMessage.h.u2.ZeroInit = 0;
424  ApiMessage.h.u2.s2.Type = LPC_DEBUG_EVENT;
425  ApiMessage.ApiNumber = DbgKmLoadDllApi;
426 
427  /* Send the message */
428  DbgkpSendApiMessage(&ApiMessage, TRUE);
429 
430  /* Close the handle */
432 }
433 
434 VOID
435 NTAPI
437 {
438  DBGKM_MSG ApiMessage;
439  PDBGKM_UNLOAD_DLL UnloadDll = &ApiMessage.UnloadDll;
442  PAGED_CODE();
443 
444  /* Check if this thread is kernel, hidden or doesn't have a debug port */
445  if ((ExGetPreviousMode() == KernelMode) ||
447  !(Process->DebugPort))
448  {
449  /* Don't notify the debugger */
450  return;
451  }
452 
453  /* Set the DLL Base */
454  UnloadDll->BaseAddress = BaseAddress;
455 
456  /* Setup the API Message */
457  ApiMessage.h.u1.Length = sizeof(DBGKM_MSG) << 16 |
458  (8 + sizeof(DBGKM_UNLOAD_DLL));
459  ApiMessage.h.u2.ZeroInit = 0;
460  ApiMessage.h.u2.s2.Type = LPC_DEBUG_EVENT;
461  ApiMessage.ApiNumber = DbgKmUnloadDllApi;
462 
463  /* Send the message */
464  DbgkpSendApiMessage(&ApiMessage, TRUE);
465 }
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
_Must_inspect_result_ _Outptr_ PVOID * SectionObject
Definition: fsrtlfuncs.h:860
ULONG DebugInfoSize
Definition: dbgktypes.h:166
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define IN
Definition: typedefs.h:38
VOID NTAPI KeThawAllThreads(VOID)
Definition: thrdobj.c:669
WCHAR StaticUnicodeBuffer[261]
Definition: compat.h:526
#define TRUE
Definition: types.h:120
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
ULONG ImageAddressingMode
Definition: pstypes.h:200
HANDLE FileHandle
Definition: dbgktypes.h:163
NTSTATUS NTAPI MmGetFileNameForSection(IN PVOID Section, OUT POBJECT_NAME_INFORMATION *ModuleName)
Definition: section.c:1801
ULONG ImageSelector
Definition: pstypes.h:208
PVOID ImageBase
Definition: pstypes.h:207
#define PSF_CREATE_REPORTED_BIT
Definition: pstypes.h:257
SIZE_T ImageSize
Definition: pstypes.h:209
LONG NTSTATUS
Definition: precomp.h:26
KTHREAD Tcb
Definition: pstypes.h:1034
UNICODE_STRING PsNtDllPathName
Definition: psmgr.c:45
VOID NTAPI DbgkMapViewOfSection(IN PVOID Section, IN PVOID BaseAddress, IN ULONG SectionOffset, IN ULONG_PTR ViewSize)
Definition: dbgkutil.c:380
VOID WINAPI ExitProcess(IN UINT uExitCode)
Definition: proc.c:1517
KPROCESSOR_MODE NTAPI ExGetPreviousMode(VOID)
Definition: sysinfo.c:2966
ACPI_BUFFER *RetBuffer ACPI_BUFFER *RetBuffer char ACPI_WALK_RESOURCE_CALLBACK void *Context ACPI_BUFFER *RetBuffer UINT16 ACPI_RESOURCE **ResourcePtr ACPI_GENERIC_ADDRESS *Reg UINT32 *ReturnValue UINT8 UINT8 *Slp_TypB ACPI_PHYSICAL_ADDRESS PhysicalAddress64 UINT32 UINT32 *TimeElapsed UINT32 ACPI_STATUS const char UINT32 ACPI_STATUS const char UINT32 const char const char * ModuleName
Definition: acpixf.h:1252
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
DBGKM_CREATE_PROCESS CreateProcess
Definition: dbgktypes.h:215
HANDLE NTAPI DbgkpSectionToFileHandle(IN PVOID Section)
Definition: dbgkutil.c:19
PVOID ArbitraryUserPointer
Definition: compat.h:379
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
#define PAGED_CODE()
Definition: video.h:57
#define FILE_SHARE_READ
Definition: compat.h:125
VOID NTAPI DbgkCreateThread(IN PETHREAD Thread, IN PVOID StartAddress)
Definition: dbgkutil.c:87
uint32_t ULONG_PTR
Definition: typedefs.h:63
DBGKM_EXIT_THREAD ExitThread
Definition: dbgktypes.h:216
#define OBJ_FORCE_ACCESS_CHECK
Definition: winternl.h:232
DBGKM_LOAD_DLL LoadDll
Definition: dbgktypes.h:218
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
PORT_MESSAGE h
Definition: dbgktypes.h:208
#define PsGetCurrentProcess
Definition: psfuncs.h:17
unsigned char BOOLEAN
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:112
smooth NULL
Definition: ftsmooth.c:416
#define PSF_IMAGE_NOTIFY_DONE_BIT
Definition: pstypes.h:278
VOID WINAPI ExitThread(IN DWORD uExitCode)
Definition: thread.c:327
void * PVOID
Definition: retypes.h:9
IMAGE_FILE_HEADER FileHeader
Definition: ntddk_ex.h:183
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER SectionOffset
Definition: mmfuncs.h:404
BOOLEAN NTAPI DbgkpSuspendProcess(VOID)
Definition: dbgkutil.c:57
_In_ HANDLE Handle
Definition: extypes.h:390
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
TCHAR Name[MAX_PATH]
Definition: filecomp.c:349
DWORD NumberOfSymbols
Definition: ntddk_ex.h:126
__wchar_t WCHAR
Definition: xmlstorage.h:180
BOOLEAN PsImageNotifyEnabled
Definition: psnotify.c:18
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define IMAGE_ADDRESSING_MODE_32BIT
Definition: pstypes.h:194
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
VOID NTAPI DbgkpResumeProcess(VOID)
Definition: dbgkutil.c:77
PVOID PspSystemDllBase
Definition: psmgr.c:41
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
FORCEINLINE VOID PspRunLoadImageNotifyRoutines(PUNICODE_STRING FullImageName, HANDLE ProcessId, PIMAGE_INFO ImageInfo)
Definition: ps_x.h:84
NTSYSAPI NTSTATUS NTAPI ZwOpenFile(_Out_ PHANDLE FileHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes, _Out_ PIO_STATUS_BLOCK IoStatusBlock, _In_ ULONG ShareAccess, _In_ ULONG OpenOptions)
VOID NTAPI DbgkUnMapViewOfSection(IN PVOID BaseAddress)
Definition: dbgkutil.c:436
VOID NTAPI DbgkExitProcess(IN NTSTATUS ExitStatus)
Definition: dbgkutil.c:304
NTSTATUS NTAPI ObCloseHandle(IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
Definition: obhandle.c:3376
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
static const WCHAR L[]
Definition: oid.c:1250
NTSTATUS NTAPI DbgkpSendApiMessage(IN OUT PDBGKM_MSG ApiMsg, IN BOOLEAN SuspendProcess)
Definition: dbgkobj.c:242
PVOID NamePointer
Definition: dbgktypes.h:167
ULONG ImageSectionNumber
Definition: pstypes.h:210
#define GENERIC_READ
Definition: compat.h:124
#define SYNCHRONIZE
Definition: nt_native.h:61
#define CreateProcess
Definition: winbase.h:3572
Status
Definition: gdiplustypes.h:24
Definition: compat.h:484
struct _FileName FileName
Definition: fatprocs.h:884
FORCEINLINE struct _TEB * NtCurrentTeb(VOID)
Definition: psfuncs.h:420
_CRTIMP wchar_t *__cdecl wcsncpy(wchar_t *_Dest, const wchar_t *_Source, size_t _Count)
DBGKM_EXIT_PROCESS ExitProcess
Definition: dbgktypes.h:217
DBGKM_APINUMBER ApiNumber
Definition: dbgktypes.h:209
_In_ NTSTATUS ExitStatus
Definition: psfuncs.h:861
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
struct _DBGKM_MSG DBGKM_MSG
#define DBGK_PROCESS_DEBUG
Definition: dbgk.h:18
PVOID Teb
Definition: ketypes.h:1697
#define DBGKTRACE(x, fmt,...)
Definition: dbgk.h:46
#define RtlImageNtHeader
Definition: compat.h:457
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
#define PspSetProcessFlag(Process, Flag)
Definition: ps_x.h:33
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T ViewSize
Definition: mmfuncs.h:404
ULONG DebugInfoFileOffset
Definition: dbgktypes.h:165
VOID NTAPI KeFreezeAllThreads(VOID)
Definition: thrdobj.c:315
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
ULONG HideFromDebugger
Definition: pstypes.h:1111
DBGKM_UNLOAD_DLL UnloadDll
Definition: dbgktypes.h:219
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
NT_TIB NtTib
Definition: ntddk_ex.h:332
VOID NTAPI DbgkExitThread(IN NTSTATUS ExitStatus)
Definition: dbgkutil.c:340
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
DBGKM_CREATE_THREAD CreateThread
Definition: dbgktypes.h:214
ULONG Properties
Definition: pstypes.h:198