ReactOS 0.4.15-dev-7788-g1ad9096
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
20{
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
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
75VOID
78{
79 PAGED_CODE();
80
81 /* Thaw all the threads */
83}
84
85VOID
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 */
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;
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 =
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 */
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,
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
302VOID
303NTAPI
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
338VOID
339NTAPI
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
378VOID
379NTAPI
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
434VOID
435NTAPI
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 PAGED_CODE()
unsigned char BOOLEAN
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:1280
LONG NTSTATUS
Definition: precomp.h:26
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define DBGK_PROCESS_DEBUG
Definition: dbgk.h:18
#define DBGKTRACE(x, fmt,...)
Definition: dbgk.h:46
NTSTATUS NTAPI DbgkpSendApiMessage(IN OUT PDBGKM_MSG ApiMsg, IN BOOLEAN SuspendProcess)
Definition: dbgkobj.c:242
struct _DBGKM_MSG DBGKM_MSG
@ DbgKmCreateProcessApi
Definition: dbgktypes.h:68
@ DbgKmCreateThreadApi
Definition: dbgktypes.h:67
@ DbgKmExitProcessApi
Definition: dbgktypes.h:70
@ DbgKmUnloadDllApi
Definition: dbgktypes.h:72
@ DbgKmExitThreadApi
Definition: dbgktypes.h:69
@ DbgKmLoadDllApi
Definition: dbgktypes.h:71
VOID NTAPI DbgkUnMapViewOfSection(IN PVOID BaseAddress)
Definition: dbgkutil.c:436
VOID NTAPI DbgkMapViewOfSection(IN PVOID Section, IN PVOID BaseAddress, IN ULONG SectionOffset, IN ULONG_PTR ViewSize)
Definition: dbgkutil.c:380
VOID NTAPI DbgkCreateThread(IN PETHREAD Thread, IN PVOID StartAddress)
Definition: dbgkutil.c:87
VOID NTAPI DbgkExitThread(IN NTSTATUS ExitStatus)
Definition: dbgkutil.c:340
HANDLE NTAPI DbgkpSectionToFileHandle(IN PVOID Section)
Definition: dbgkutil.c:19
VOID NTAPI DbgkpResumeProcess(VOID)
Definition: dbgkutil.c:77
BOOLEAN NTAPI DbgkpSuspendProcess(VOID)
Definition: dbgkutil.c:57
VOID NTAPI DbgkExitProcess(IN NTSTATUS ExitStatus)
Definition: dbgkutil.c:304
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define GENERIC_READ
Definition: compat.h:135
#define RtlImageNtHeader
Definition: compat.h:806
#define FILE_SHARE_READ
Definition: compat.h:136
VOID WINAPI ExitProcess(IN UINT uExitCode)
Definition: proc.c:1487
VOID WINAPI ExitThread(IN DWORD uExitCode)
Definition: thread.c:365
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:137
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define ExGetPreviousMode
Definition: ex.h:140
struct _FileName FileName
Definition: fatprocs.h:896
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
#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:223
_Must_inspect_result_ _Outptr_ PVOID * SectionObject
Definition: fsrtlfuncs.h:860
ULONG Handle
Definition: gdb_input.c:15
Status
Definition: gdiplustypes.h:25
#define PSF_CREATE_REPORTED_BIT
Definition: pstypes.h:273
#define PSF_IMAGE_NOTIFY_DONE_BIT
Definition: pstypes.h:294
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define OBJ_FORCE_ACCESS_CHECK
Definition: winternl.h:232
#define IMAGE_ADDRESSING_MODE_32BIT
Definition: pstypes.h:194
#define NtCurrentTeb
#define ASSERT(a)
Definition: mode.c:44
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define LPC_DEBUG_EVENT
Definition: port.c:100
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define KernelMode
Definition: asm.h:34
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)
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER SectionOffset
Definition: mmfuncs.h:407
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T ViewSize
Definition: mmfuncs.h:408
_In_ NTSTATUS ExitStatus
Definition: psfuncs.h:867
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define SYNCHRONIZE
Definition: nt_native.h:61
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
VOID NTAPI KeFreezeAllThreads(VOID)
Definition: thrdobj.c:306
VOID NTAPI KeThawAllThreads(VOID)
Definition: thrdobj.c:660
NTSTATUS NTAPI MmGetFileNameForSection(IN PVOID Section, OUT POBJECT_NAME_INFORMATION *ModuleName)
Definition: section.c:1864
#define L(x)
Definition: ntvdm.h:50
NTSTATUS NTAPI ObCloseHandle(IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
Definition: obhandle.c:3379
UNICODE_STRING PsNtDllPathName
Definition: psmgr.c:45
BOOLEAN PsImageNotifyEnabled
Definition: psnotify.c:18
PVOID PspSystemDllBase
Definition: psmgr.c:41
FORCEINLINE VOID PspRunLoadImageNotifyRoutines(PUNICODE_STRING FullImageName, HANDLE ProcessId, PIMAGE_INFO ImageInfo)
Definition: ps_x.h:84
#define PspSetProcessFlag(Process, Flag)
Definition: ps_x.h:33
_CRTIMP wchar_t *__cdecl wcsncpy(wchar_t *_Dest, const wchar_t *_Source, size_t _Count)
HANDLE FileHandle
Definition: dbgktypes.h:163
PVOID NamePointer
Definition: dbgktypes.h:167
ULONG DebugInfoFileOffset
Definition: dbgktypes.h:165
ULONG DebugInfoSize
Definition: dbgktypes.h:166
PORT_MESSAGE h
Definition: dbgktypes.h:208
DBGKM_CREATE_THREAD CreateThread
Definition: dbgktypes.h:214
DBGKM_CREATE_PROCESS CreateProcess
Definition: dbgktypes.h:215
DBGKM_UNLOAD_DLL UnloadDll
Definition: dbgktypes.h:219
DBGKM_LOAD_DLL LoadDll
Definition: dbgktypes.h:218
DBGKM_APINUMBER ApiNumber
Definition: dbgktypes.h:209
DBGKM_EXIT_PROCESS ExitProcess
Definition: dbgktypes.h:217
DBGKM_EXIT_THREAD ExitThread
Definition: dbgktypes.h:216
KTHREAD Tcb
Definition: pstypes.h:1103
ULONG HideFromDebugger
Definition: pstypes.h:1180
TCHAR Name[MAX_PATH]
Definition: filecomp.c:349
DWORD NumberOfSymbols
Definition: ntddk_ex.h:126
SIZE_T ImageSize
Definition: pstypes.h:209
ULONG ImageSectionNumber
Definition: pstypes.h:210
PVOID ImageBase
Definition: pstypes.h:207
ULONG Properties
Definition: pstypes.h:198
ULONG ImageAddressingMode
Definition: pstypes.h:200
ULONG ImageSelector
Definition: pstypes.h:208
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
IMAGE_FILE_HEADER FileHeader
Definition: ntddk_ex.h:183
PVOID Teb
Definition: ketypes.h:1807
PVOID ArbitraryUserPointer
Definition: compat.h:719
Definition: compat.h:836
WCHAR StaticUnicodeBuffer[261]
Definition: compat.h:877
NT_TIB NtTib
Definition: ntddk_ex.h:332
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
#define CreateProcess
Definition: winbase.h:3693
@ Suspended
Definition: ketypes.h:420
#define PsGetCurrentProcess
Definition: psfuncs.h:17
__wchar_t WCHAR
Definition: xmlstorage.h:180