mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 06:22:58 +00:00
- 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:
parent
024e1d9725
commit
756da82c2f
4 changed files with 229 additions and 9 deletions
|
@ -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 */
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue