- Implement helper routine DbgkpSectionToFileHandle and stub MmGetFileNameForSection (easy ObQueryNameString-based implementation to do later).

- Implement helpers DbgkpSuspendProcess and DbgkpResumeProcess based on KeFreeze/ThawAllThreads.
- Implement DbgkExitProcess, DbgkExitThread, DbgkMapViewOfSection, DbgkUnmapViewOfSection. Apart from DbgkCreateThread, these are the main notification APIs that Dbgk uses for user-mode debug events. (Mm code needs to be changed to call the map/unmap notifications. Ps already calls the exit/create ones).

svn path=/trunk/; revision=24614
This commit is contained in:
Alex Ionescu 2006-10-22 20:56:24 +00:00
parent 024e1d9725
commit 756da82c2f
4 changed files with 229 additions and 9 deletions

View file

@ -14,6 +14,72 @@
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
HANDLE
NTAPI
DbgkpSectionToFileHandle(IN PVOID Section)
{
NTSTATUS Status;
UNICODE_STRING FileName;
OBJECT_ATTRIBUTES ObjectAttributes;
IO_STATUS_BLOCK IoStatusBlock;
HANDLE Handle;
PAGED_CODE();
/* Get the filename of the section */
Status = MmGetFileNameForSection(Section, &FileName);
if (!NT_SUCCESS(Status)) return NULL;
/* Initialize object attributes */
InitializeObjectAttributes(&ObjectAttributes,
&FileName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
/* Open the file */
Status = ZwOpenFile(&Handle,
GENERIC_READ | SYNCHRONIZE,
&ObjectAttributes,
&IoStatusBlock,
FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
FILE_SYNCHRONOUS_IO_NONALERT);
/* Free the name and return the handle if we succeeded */
ExFreePool(FileName.Buffer);
if (!NT_SUCCESS(Status)) return NULL;
return Handle;
}
BOOLEAN
NTAPI
DbgkpSuspendProcess(VOID)
{
PAGED_CODE();
/* Make sure this isn't a deleted process */
if (PsGetCurrentProcess()->ProcessDelete)
{
/* Freeze all the threads */
KeFreezeAllThreads();
return TRUE;
}
else
{
/* No suspend was done */
return FALSE;
}
}
VOID
NTAPI
DbgkpResumeProcess(VOID)
{
PAGED_CODE();
/* Thaw all the threads */
KeThawAllThreads();
}
VOID VOID
NTAPI NTAPI
DbgkCreateThread(PVOID StartAddress) DbgkCreateThread(PVOID StartAddress)
@ -25,28 +91,160 @@ VOID
NTAPI NTAPI
DbgkExitProcess(IN NTSTATUS ExitStatus) DbgkExitProcess(IN NTSTATUS ExitStatus)
{ {
/* FIXME */ DBGKM_MSG ApiMessage;
PDBGKM_EXIT_PROCESS ExitProcess = &ApiMessage.ExitProcess;
PEPROCESS Process = PsGetCurrentProcess();
PETHREAD Thread = PsGetCurrentThread();
PAGED_CODE();
/* Check if this thread is hidden, doesn't have a debug port, or died */
if ((Thread->HideFromDebugger) ||
!(Process->DebugPort) ||
(Thread->DeadThread))
{
/* Don't notify the debugger */
return;
}
/* Set the exit status */
ExitProcess->ExitStatus = ExitStatus;
/* Setup the API Message */
ApiMessage.h.u1.Length = sizeof(DBGKM_MSG) << 16 |
(8 + sizeof(DBGKM_EXIT_PROCESS));
ApiMessage.h.u2.ZeroInit = LPC_DEBUG_EVENT;
ApiMessage.ApiNumber = DbgKmExitProcessApi;
/* Set the current exit time */
KeQuerySystemTime(&Process->ExitTime);
/* Send the message */
DbgkpSendApiMessage(&ApiMessage, FALSE);
} }
VOID VOID
NTAPI NTAPI
DbgkExitThread(IN NTSTATUS ExitStatus) DbgkExitThread(IN NTSTATUS ExitStatus)
{ {
/* FIXME */ DBGKM_MSG ApiMessage;
PDBGKM_EXIT_THREAD ExitThread = &ApiMessage.ExitThread;
PEPROCESS Process = PsGetCurrentProcess();
PETHREAD Thread = PsGetCurrentThread();
BOOLEAN Suspended;
PAGED_CODE();
/* Check if this thread is hidden, doesn't have a debug port, or died */
if ((Thread->HideFromDebugger) ||
!(Process->DebugPort) ||
(Thread->DeadThread))
{
/* Don't notify the debugger */
return;
}
/* Set the exit status */
ExitThread->ExitStatus = ExitStatus;
/* Setup the API Message */
ApiMessage.h.u1.Length = sizeof(DBGKM_MSG) << 16 |
(8 + sizeof(DBGKM_EXIT_THREAD));
ApiMessage.h.u2.ZeroInit = LPC_DEBUG_EVENT;
ApiMessage.ApiNumber = DbgKmExitThreadApi;
/* Suspend the process */
Suspended = DbgkpSuspendProcess();
/* Send the message */
DbgkpSendApiMessage(&ApiMessage, FALSE);
/* Resume the process if needed */
if (Suspended) DbgkpResumeProcess();
} }
VOID VOID
NTAPI NTAPI
DbgkpSuspendProcess(VOID) DbgkMapViewOfSection(IN HANDLE SectionHandle,
IN PVOID BaseAddress,
IN ULONG SectionOffset,
IN ULONG_PTR ViewSize)
{ {
DBGKM_MSG ApiMessage;
PDBGKM_LOAD_DLL LoadDll = &ApiMessage.LoadDll;
PEPROCESS Process = PsGetCurrentProcess();
PETHREAD Thread = PsGetCurrentThread();
PIMAGE_NT_HEADERS NtHeader;
PAGED_CODE();
/* Check if this thread is hidden, doesn't have a debug port, or died */
if ((Thread->HideFromDebugger) ||
!(Process->DebugPort) ||
(Thread->DeadThread) ||
(KeGetPreviousMode() == KernelMode))
{
/* Don't notify the debugger */
return;
}
/* Setup the parameters */
LoadDll->FileHandle = DbgkpSectionToFileHandle(SectionHandle);
LoadDll->BaseOfDll = BaseAddress;
LoadDll->DebugInfoFileOffset = 0;
LoadDll->DebugInfoSize = 0;
/* Get the NT Headers */
NtHeader = RtlImageNtHeader(BaseAddress);
if (NtHeader)
{
/* Fill out debug information */
LoadDll->DebugInfoFileOffset = NtHeader->FileHeader.
PointerToSymbolTable;
LoadDll->DebugInfoSize = NtHeader->FileHeader.NumberOfSymbols;
}
/* Setup the API Message */
ApiMessage.h.u1.Length = sizeof(DBGKM_MSG) << 16 |
(8 + sizeof(DBGKM_LOAD_DLL));
ApiMessage.h.u2.ZeroInit = LPC_DEBUG_EVENT;
ApiMessage.ApiNumber = DbgKmLoadDllApi;
/* Send the message */
DbgkpSendApiMessage(&ApiMessage, TRUE);
/* Close the handle */
ObCloseHandle(LoadDll->FileHandle, KernelMode);
} }
VOID VOID
NTAPI NTAPI
DbgkpResumeProcess(VOID) DbgkUnMapViewOfSection(IN PVOID BaseAddress)
{ {
DBGKM_MSG ApiMessage;
PDBGKM_UNLOAD_DLL UnloadDll = &ApiMessage.UnloadDll;
PEPROCESS Process = PsGetCurrentProcess();
PETHREAD Thread = PsGetCurrentThread();
PAGED_CODE();
/* Check if this thread is hidden, doesn't have a debug port, or died */
if ((Thread->HideFromDebugger) ||
!(Process->DebugPort) ||
(Thread->DeadThread) ||
(KeGetPreviousMode() == KernelMode))
{
/* Don't notify the debugger */
return;
}
/* Set the DLL Base */
UnloadDll->BaseAddress = BaseAddress;
/* Setup the API Message */
ApiMessage.h.u1.Length = sizeof(DBGKM_MSG) << 16 |
(8 + sizeof(DBGKM_UNLOAD_DLL));
ApiMessage.h.u2.ZeroInit = LPC_DEBUG_EVENT;
ApiMessage.ApiNumber = DbgKmUnloadDllApi;
/* Send the message */
DbgkpSendApiMessage(&ApiMessage, TRUE);
} }
/* EOF */ /* EOF */

View file

@ -19,7 +19,7 @@ DbgkExitThread(
IN NTSTATUS ExitStatus IN NTSTATUS ExitStatus
); );
VOID BOOLEAN
NTAPI NTAPI
DbgkpSuspendProcess( DbgkpSuspendProcess(
VOID VOID
@ -31,6 +31,13 @@ DbgkpResumeProcess(
VOID VOID
); );
NTSTATUS
NTAPI
DbgkpSendApiMessage(
IN OUT PDBGKM_MSG ApiMsg,
IN ULONG Flags
);
VOID VOID
NTAPI NTAPI
DbgkCopyProcessDebugPort( DbgkCopyProcessDebugPort(

View file

@ -1322,6 +1322,13 @@ MmGetFileNameForAddress(
OUT PUNICODE_STRING ModuleName OUT PUNICODE_STRING ModuleName
); );
NTSTATUS
NTAPI
MmGetFileNameForSection(
IN PROS_SECTION_OBJECT Section,
OUT PUNICODE_STRING ModuleName
);
PVOID PVOID
NTAPI NTAPI
MmAllocateSection( MmAllocateSection(

View file

@ -106,6 +106,16 @@ MmGetFileObjectForSection(IN PROS_SECTION_OBJECT Section)
return Section->FileObject; // Section->ControlArea->FileObject on NT return Section->FileObject; // Section->ControlArea->FileObject on NT
} }
NTSTATUS
NTAPI
MmGetFileNameForSection(IN PROS_SECTION_OBJECT Section,
OUT PUNICODE_STRING ModuleName)
{
/* FIXME: TODO. ObQueryNameString on the FileObject */
RtlCreateUnicodeString(ModuleName, L"C:\\ReactOS\\system32\\ntdll.dll");
return STATUS_SUCCESS;
}
NTSTATUS NTSTATUS
NTAPI NTAPI
MmGetFileNameForAddress(IN PVOID Address, MmGetFileNameForAddress(IN PVOID Address,
@ -118,10 +128,8 @@ MmGetFileNameForAddress(IN PVOID Address,
* corresponds to the address. Then make sure it's a section * corresponds to the address. Then make sure it's a section
* view type (MEMORY_AREA_SECTION_VIEW) and use the marea's * view type (MEMORY_AREA_SECTION_VIEW) and use the marea's
* per-type union to get the .u.SectionView.Section pointer to * per-type union to get the .u.SectionView.Section pointer to
* the SECTION_OBJECT. Then we can use MmGetFileObjectForSection * the SECTION_OBJECT. Then we can use MmGetFileNameForSection
* to get the FILE_OBJECT, from which we can then query the name * to get the full filename.
* to get the full filename (much like we do for creating the
* SeAuditName in EPROCESS.
*/ */
RtlCreateUnicodeString(ModuleName, L"C:\\ReactOS\\system32\\ntdll.dll"); RtlCreateUnicodeString(ModuleName, L"C:\\ReactOS\\system32\\ntdll.dll");
return STATUS_SUCCESS; return STATUS_SUCCESS;