Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygendbgkutil.c
Go to the documentation of this file.
00001 /* 00002 * PROJECT: ReactOS Kernel 00003 * LICENSE: GPL - See COPYING in the top level directory 00004 * FILE: ntoskrnl/dbgk/dbgkutil.c 00005 * PURPOSE: User-Mode Debugging Support, Internal Debug Functions. 00006 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) 00007 */ 00008 00009 /* INCLUDES ******************************************************************/ 00010 00011 #include <ntoskrnl.h> 00012 #define NDEBUG 00013 #include <debug.h> 00014 00015 /* FUNCTIONS *****************************************************************/ 00016 00017 HANDLE 00018 NTAPI 00019 DbgkpSectionToFileHandle(IN PVOID Section) 00020 { 00021 NTSTATUS Status; 00022 POBJECT_NAME_INFORMATION FileName; 00023 OBJECT_ATTRIBUTES ObjectAttributes; 00024 IO_STATUS_BLOCK IoStatusBlock; 00025 HANDLE Handle; 00026 PAGED_CODE(); 00027 00028 /* Get the filename of the section */ 00029 Status = MmGetFileNameForSection(Section, &FileName); 00030 if (!NT_SUCCESS(Status)) return NULL; 00031 00032 /* Initialize object attributes */ 00033 InitializeObjectAttributes(&ObjectAttributes, 00034 &FileName->Name, 00035 OBJ_CASE_INSENSITIVE | 00036 OBJ_FORCE_ACCESS_CHECK | 00037 OBJ_KERNEL_HANDLE, 00038 NULL, 00039 NULL); 00040 00041 /* Open the file */ 00042 Status = ZwOpenFile(&Handle, 00043 GENERIC_READ | SYNCHRONIZE, 00044 &ObjectAttributes, 00045 &IoStatusBlock, 00046 FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, 00047 FILE_SYNCHRONOUS_IO_NONALERT); 00048 00049 /* Free the name and return the handle if we succeeded */ 00050 ExFreePool(FileName); 00051 if (!NT_SUCCESS(Status)) return NULL; 00052 return Handle; 00053 } 00054 00055 BOOLEAN 00056 NTAPI 00057 DbgkpSuspendProcess(VOID) 00058 { 00059 PAGED_CODE(); 00060 00061 /* Make sure this isn't a deleted process */ 00062 if (!PsGetCurrentProcess()->ProcessDelete) 00063 { 00064 /* Freeze all the threads */ 00065 KeFreezeAllThreads(); 00066 return TRUE; 00067 } 00068 else 00069 { 00070 /* No suspend was done */ 00071 return FALSE; 00072 } 00073 } 00074 00075 VOID 00076 NTAPI 00077 DbgkpResumeProcess(VOID) 00078 { 00079 PAGED_CODE(); 00080 00081 /* Thaw all the threads */ 00082 KeThawAllThreads(); 00083 } 00084 00085 VOID 00086 NTAPI 00087 DbgkCreateThread(IN PETHREAD Thread, 00088 IN PVOID StartAddress) 00089 { 00090 PEPROCESS Process = PsGetCurrentProcess(); 00091 ULONG ProcessFlags; 00092 IMAGE_INFO ImageInfo; 00093 PIMAGE_NT_HEADERS NtHeader; 00094 POBJECT_NAME_INFORMATION ModuleName; 00095 UNICODE_STRING NtDllName; 00096 NTSTATUS Status; 00097 PVOID DebugPort; 00098 DBGKM_MSG ApiMessage; 00099 PDBGKM_CREATE_THREAD CreateThread = &ApiMessage.CreateThread; 00100 PDBGKM_CREATE_PROCESS CreateProcess = &ApiMessage.CreateProcess; 00101 PDBGKM_LOAD_DLL LoadDll = &ApiMessage.LoadDll; 00102 OBJECT_ATTRIBUTES ObjectAttributes; 00103 IO_STATUS_BLOCK IoStatusBlock; 00104 PTEB Teb; 00105 PAGED_CODE(); 00106 00107 /* Sanity check */ 00108 ASSERT(Thread == PsGetCurrentThread()); 00109 00110 /* Try ORing in the create reported and image notify flags */ 00111 ProcessFlags = PspSetProcessFlag(Process, 00112 PSF_CREATE_REPORTED_BIT | 00113 PSF_IMAGE_NOTIFY_DONE_BIT); 00114 00115 /* Check if we were the first to set them or if another thread raced us */ 00116 if (!(ProcessFlags & PSF_IMAGE_NOTIFY_DONE_BIT) && (PsImageNotifyEnabled)) 00117 { 00118 /* It hasn't.. set up the image info for the process */ 00119 ImageInfo.Properties = 0; 00120 ImageInfo.ImageAddressingMode = IMAGE_ADDRESSING_MODE_32BIT; 00121 ImageInfo.ImageBase = Process->SectionBaseAddress; 00122 ImageInfo.ImageSize = 0; 00123 ImageInfo.ImageSelector = 0; 00124 ImageInfo.ImageSectionNumber = 0; 00125 00126 /* Get the NT Headers */ 00127 NtHeader = RtlImageNtHeader(Process->SectionBaseAddress); 00128 if (NtHeader) 00129 { 00130 /* Set image size */ 00131 ImageInfo.ImageSize = NtHeader->OptionalHeader.SizeOfImage; 00132 } 00133 00134 /* Get the image name */ 00135 Status = MmGetFileNameForSection(Process->SectionObject, &ModuleName); 00136 if (NT_SUCCESS(Status)) 00137 { 00138 /* Call the notify routines and free the name */ 00139 PspRunLoadImageNotifyRoutines(&ModuleName->Name, 00140 Process->UniqueProcessId, 00141 &ImageInfo); 00142 ExFreePool(ModuleName); 00143 } 00144 else 00145 { 00146 /* Call the notify routines */ 00147 PspRunLoadImageNotifyRoutines(NULL, 00148 Process->UniqueProcessId, 00149 &ImageInfo); 00150 } 00151 00152 /* Setup the info for ntdll.dll */ 00153 ImageInfo.Properties = 0; 00154 ImageInfo.ImageAddressingMode = IMAGE_ADDRESSING_MODE_32BIT; 00155 ImageInfo.ImageBase = PspSystemDllBase; 00156 ImageInfo.ImageSize = 0; 00157 ImageInfo.ImageSelector = 0; 00158 ImageInfo.ImageSectionNumber = 0; 00159 00160 /* Get the NT Headers */ 00161 NtHeader = RtlImageNtHeader(PspSystemDllBase); 00162 if (NtHeader) 00163 { 00164 /* Set image size */ 00165 ImageInfo.ImageSize = NtHeader->OptionalHeader.SizeOfImage; 00166 } 00167 00168 /* Call the notify routines */ 00169 RtlInitUnicodeString(&NtDllName, 00170 L"\\SystemRoot\\System32\\ntdll.dll"); 00171 PspRunLoadImageNotifyRoutines(&NtDllName, 00172 Process->UniqueProcessId, 00173 &ImageInfo); 00174 } 00175 00176 /* Fail if we have no port */ 00177 DebugPort = Process->DebugPort; 00178 if (!DebugPort) return; 00179 00180 /* Check if create was not already reported */ 00181 if (!(ProcessFlags & PSF_CREATE_REPORTED_BIT)) 00182 { 00183 /* Setup the information structure for the new thread */ 00184 CreateProcess->InitialThread.SubSystemKey = 0; 00185 CreateProcess->InitialThread.StartAddress = NULL; 00186 00187 /* And for the new process */ 00188 CreateProcess->SubSystemKey = 0; 00189 CreateProcess->FileHandle = DbgkpSectionToFileHandle(Process-> 00190 SectionObject); 00191 CreateProcess->BaseOfImage = Process->SectionBaseAddress; 00192 CreateProcess->DebugInfoFileOffset = 0; 00193 CreateProcess->DebugInfoSize = 0; 00194 00195 /* Get the NT Header */ 00196 NtHeader = RtlImageNtHeader(Process->SectionBaseAddress); 00197 if (NtHeader) 00198 { 00199 /* Fill out data from the header */ 00200 CreateProcess->InitialThread.StartAddress = 00201 (PVOID)((ULONG_PTR)NtHeader->OptionalHeader.ImageBase + 00202 NtHeader->OptionalHeader.AddressOfEntryPoint); 00203 CreateProcess->DebugInfoFileOffset = NtHeader->FileHeader. 00204 PointerToSymbolTable; 00205 CreateProcess->DebugInfoSize = NtHeader->FileHeader. 00206 NumberOfSymbols; 00207 } 00208 00209 /* Setup the API Message */ 00210 ApiMessage.h.u1.Length = sizeof(DBGKM_MSG) << 16 | 00211 (8 + sizeof(DBGKM_CREATE_PROCESS)); 00212 ApiMessage.h.u2.ZeroInit = 0; 00213 ApiMessage.h.u2.s2.Type = LPC_DEBUG_EVENT; 00214 ApiMessage.ApiNumber = DbgKmCreateProcessApi; 00215 00216 /* Send the message */ 00217 DbgkpSendApiMessage(&ApiMessage, FALSE); 00218 00219 /* Close the handle */ 00220 ObCloseHandle(CreateProcess->FileHandle, KernelMode); 00221 00222 /* Setup the parameters */ 00223 LoadDll->BaseOfDll = PspSystemDllBase; 00224 LoadDll->DebugInfoFileOffset = 0; 00225 LoadDll->DebugInfoSize = 0; 00226 LoadDll->NamePointer = NULL; 00227 00228 /* Get the NT Headers */ 00229 NtHeader = RtlImageNtHeader(PspSystemDllBase); 00230 if (NtHeader) 00231 { 00232 /* Fill out debug information */ 00233 LoadDll->DebugInfoFileOffset = NtHeader-> 00234 FileHeader.PointerToSymbolTable; 00235 LoadDll->DebugInfoSize = NtHeader->FileHeader.NumberOfSymbols; 00236 } 00237 00238 /* Get the TEB */ 00239 Teb = Thread->Tcb.Teb; 00240 if (Teb) 00241 { 00242 /* Copy the system library name and link to it */ 00243 wcsncpy(Teb->StaticUnicodeBuffer, 00244 L"ntdll.dll", 00245 sizeof(Teb->StaticUnicodeBuffer) / sizeof(WCHAR)); 00246 Teb->NtTib.ArbitraryUserPointer = Teb->StaticUnicodeBuffer; 00247 00248 /* Return it in the debug event as well */ 00249 LoadDll->NamePointer = &Teb->NtTib.ArbitraryUserPointer; 00250 } 00251 00252 /* Get a handle */ 00253 InitializeObjectAttributes(&ObjectAttributes, 00254 &PsNtDllPathName, 00255 OBJ_CASE_INSENSITIVE | 00256 OBJ_KERNEL_HANDLE | 00257 OBJ_FORCE_ACCESS_CHECK, 00258 NULL, 00259 NULL); 00260 Status = ZwOpenFile(&LoadDll->FileHandle, 00261 GENERIC_READ | SYNCHRONIZE, 00262 &ObjectAttributes, 00263 &IoStatusBlock, 00264 FILE_SHARE_DELETE | 00265 FILE_SHARE_READ | 00266 FILE_SHARE_WRITE, 00267 FILE_SYNCHRONOUS_IO_NONALERT); 00268 if (NT_SUCCESS(Status)) 00269 { 00270 /* Setup the API Message */ 00271 ApiMessage.h.u1.Length = sizeof(DBGKM_MSG) << 16 | 00272 (8 + sizeof(DBGKM_LOAD_DLL)); 00273 ApiMessage.h.u2.ZeroInit = 0; 00274 ApiMessage.h.u2.s2.Type = LPC_DEBUG_EVENT; 00275 ApiMessage.ApiNumber = DbgKmLoadDllApi; 00276 00277 /* Send the message */ 00278 DbgkpSendApiMessage(&ApiMessage, TRUE); 00279 00280 /* Close the handle */ 00281 ObCloseHandle(LoadDll->FileHandle, KernelMode); 00282 } 00283 } 00284 else 00285 { 00286 /* Otherwise, do it just for the thread */ 00287 CreateThread->SubSystemKey = 0; 00288 CreateThread->StartAddress = StartAddress; 00289 00290 /* Setup the API Message */ 00291 ApiMessage.h.u1.Length = sizeof(DBGKM_MSG) << 16 | 00292 (8 + sizeof(DBGKM_CREATE_THREAD)); 00293 ApiMessage.h.u2.ZeroInit = 0; 00294 ApiMessage.h.u2.s2.Type = LPC_DEBUG_EVENT; 00295 ApiMessage.ApiNumber = DbgKmCreateThreadApi; 00296 00297 /* Send the message */ 00298 DbgkpSendApiMessage(&ApiMessage, TRUE); 00299 } 00300 } 00301 00302 VOID 00303 NTAPI 00304 DbgkExitProcess(IN NTSTATUS ExitStatus) 00305 { 00306 DBGKM_MSG ApiMessage; 00307 PDBGKM_EXIT_PROCESS ExitProcess = &ApiMessage.ExitProcess; 00308 PEPROCESS Process = PsGetCurrentProcess(); 00309 PETHREAD Thread = PsGetCurrentThread(); 00310 PAGED_CODE(); 00311 00312 /* Check if this thread is hidden, doesn't have a debug port, or died */ 00313 if ((Thread->HideFromDebugger) || 00314 !(Process->DebugPort) || 00315 (Thread->DeadThread)) 00316 { 00317 /* Don't notify the debugger */ 00318 return; 00319 } 00320 00321 /* Set the exit status */ 00322 ExitProcess->ExitStatus = ExitStatus; 00323 00324 /* Setup the API Message */ 00325 ApiMessage.h.u1.Length = sizeof(DBGKM_MSG) << 16 | 00326 (8 + sizeof(DBGKM_EXIT_PROCESS)); 00327 ApiMessage.h.u2.ZeroInit = 0; 00328 ApiMessage.h.u2.s2.Type = LPC_DEBUG_EVENT; 00329 ApiMessage.ApiNumber = DbgKmExitProcessApi; 00330 00331 /* Set the current exit time */ 00332 KeQuerySystemTime(&Process->ExitTime); 00333 00334 /* Send the message */ 00335 DbgkpSendApiMessage(&ApiMessage, FALSE); 00336 } 00337 00338 VOID 00339 NTAPI 00340 DbgkExitThread(IN NTSTATUS ExitStatus) 00341 { 00342 DBGKM_MSG ApiMessage; 00343 PDBGKM_EXIT_THREAD ExitThread = &ApiMessage.ExitThread; 00344 PEPROCESS Process = PsGetCurrentProcess(); 00345 PETHREAD Thread = PsGetCurrentThread(); 00346 BOOLEAN Suspended; 00347 PAGED_CODE(); 00348 00349 /* Check if this thread is hidden, doesn't have a debug port, or died */ 00350 if ((Thread->HideFromDebugger) || 00351 !(Process->DebugPort) || 00352 (Thread->DeadThread)) 00353 { 00354 /* Don't notify the debugger */ 00355 return; 00356 } 00357 00358 /* Set the exit status */ 00359 ExitThread->ExitStatus = ExitStatus; 00360 00361 /* Setup the API Message */ 00362 ApiMessage.h.u1.Length = sizeof(DBGKM_MSG) << 16 | 00363 (8 + sizeof(DBGKM_EXIT_THREAD)); 00364 ApiMessage.h.u2.ZeroInit = 0; 00365 ApiMessage.h.u2.s2.Type = LPC_DEBUG_EVENT; 00366 ApiMessage.ApiNumber = DbgKmExitThreadApi; 00367 00368 /* Suspend the process */ 00369 Suspended = DbgkpSuspendProcess(); 00370 00371 /* Send the message */ 00372 DbgkpSendApiMessage(&ApiMessage, FALSE); 00373 00374 /* Resume the process if needed */ 00375 if (Suspended) DbgkpResumeProcess(); 00376 } 00377 00378 VOID 00379 NTAPI 00380 DbgkMapViewOfSection(IN PVOID Section, 00381 IN PVOID BaseAddress, 00382 IN ULONG SectionOffset, 00383 IN ULONG_PTR ViewSize) 00384 { 00385 DBGKM_MSG ApiMessage; 00386 PDBGKM_LOAD_DLL LoadDll = &ApiMessage.LoadDll; 00387 PEPROCESS Process = PsGetCurrentProcess(); 00388 PETHREAD Thread = PsGetCurrentThread(); 00389 PIMAGE_NT_HEADERS NtHeader; 00390 PAGED_CODE(); 00391 DBGKTRACE(DBGK_PROCESS_DEBUG, 00392 "Section: %p. Base: %p\n", Section, BaseAddress); 00393 00394 /* Check if this thread is kernel, hidden or doesn't have a debug port */ 00395 if ((ExGetPreviousMode() == KernelMode) || 00396 (Thread->HideFromDebugger) || 00397 !(Process->DebugPort)) 00398 { 00399 /* Don't notify the debugger */ 00400 return; 00401 } 00402 00403 /* Setup the parameters */ 00404 LoadDll->FileHandle = DbgkpSectionToFileHandle(Section); 00405 LoadDll->BaseOfDll = BaseAddress; 00406 LoadDll->DebugInfoFileOffset = 0; 00407 LoadDll->DebugInfoSize = 0; 00408 00409 /* Get the NT Headers */ 00410 NtHeader = RtlImageNtHeader(BaseAddress); 00411 if (NtHeader) 00412 { 00413 /* Fill out debug information */ 00414 LoadDll->DebugInfoFileOffset = NtHeader->FileHeader. 00415 PointerToSymbolTable; 00416 LoadDll->DebugInfoSize = NtHeader->FileHeader.NumberOfSymbols; 00417 } 00418 00419 /* Setup the API Message */ 00420 ApiMessage.h.u1.Length = sizeof(DBGKM_MSG) << 16 | 00421 (8 + sizeof(DBGKM_LOAD_DLL)); 00422 ApiMessage.h.u2.ZeroInit = 0; 00423 ApiMessage.h.u2.s2.Type = LPC_DEBUG_EVENT; 00424 ApiMessage.ApiNumber = DbgKmLoadDllApi; 00425 00426 /* Send the message */ 00427 DbgkpSendApiMessage(&ApiMessage, TRUE); 00428 00429 /* Close the handle */ 00430 ObCloseHandle(LoadDll->FileHandle, KernelMode); 00431 } 00432 00433 VOID 00434 NTAPI 00435 DbgkUnMapViewOfSection(IN PVOID BaseAddress) 00436 { 00437 DBGKM_MSG ApiMessage; 00438 PDBGKM_UNLOAD_DLL UnloadDll = &ApiMessage.UnloadDll; 00439 PEPROCESS Process = PsGetCurrentProcess(); 00440 PETHREAD Thread = PsGetCurrentThread(); 00441 PAGED_CODE(); 00442 00443 /* Check if this thread is kernel, hidden or doesn't have a debug port */ 00444 if ((ExGetPreviousMode() == KernelMode) || 00445 (Thread->HideFromDebugger) || 00446 !(Process->DebugPort)) 00447 { 00448 /* Don't notify the debugger */ 00449 return; 00450 } 00451 00452 /* Set the DLL Base */ 00453 UnloadDll->BaseAddress = BaseAddress; 00454 00455 /* Setup the API Message */ 00456 ApiMessage.h.u1.Length = sizeof(DBGKM_MSG) << 16 | 00457 (8 + sizeof(DBGKM_UNLOAD_DLL)); 00458 ApiMessage.h.u2.ZeroInit = 0; 00459 ApiMessage.h.u2.s2.Type = LPC_DEBUG_EVENT; 00460 ApiMessage.ApiNumber = DbgKmUnloadDllApi; 00461 00462 /* Send the message */ 00463 DbgkpSendApiMessage(&ApiMessage, TRUE); 00464 } Generated on Sun May 27 2012 04:37:09 for ReactOS by
1.7.6.1
|