mirror of
https://github.com/reactos/reactos.git
synced 2025-07-31 10:01:43 +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 *****************************************************************/
|
||||
|
||||
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
|
||||
NTAPI
|
||||
DbgkCreateThread(PVOID StartAddress)
|
||||
|
@ -25,28 +91,160 @@ VOID
|
|||
NTAPI
|
||||
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
|
||||
NTAPI
|
||||
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
|
||||
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
|
||||
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 */
|
||||
|
|
|
@ -19,7 +19,7 @@ DbgkExitThread(
|
|||
IN NTSTATUS ExitStatus
|
||||
);
|
||||
|
||||
VOID
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
DbgkpSuspendProcess(
|
||||
VOID
|
||||
|
@ -31,6 +31,13 @@ DbgkpResumeProcess(
|
|||
VOID
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
DbgkpSendApiMessage(
|
||||
IN OUT PDBGKM_MSG ApiMsg,
|
||||
IN ULONG Flags
|
||||
);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
DbgkCopyProcessDebugPort(
|
||||
|
|
|
@ -1322,6 +1322,13 @@ MmGetFileNameForAddress(
|
|||
OUT PUNICODE_STRING ModuleName
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
MmGetFileNameForSection(
|
||||
IN PROS_SECTION_OBJECT Section,
|
||||
OUT PUNICODE_STRING ModuleName
|
||||
);
|
||||
|
||||
PVOID
|
||||
NTAPI
|
||||
MmAllocateSection(
|
||||
|
|
|
@ -106,6 +106,16 @@ MmGetFileObjectForSection(IN PROS_SECTION_OBJECT Section)
|
|||
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
|
||||
NTAPI
|
||||
MmGetFileNameForAddress(IN PVOID Address,
|
||||
|
@ -118,10 +128,8 @@ MmGetFileNameForAddress(IN PVOID Address,
|
|||
* corresponds to the address. Then make sure it's a section
|
||||
* view type (MEMORY_AREA_SECTION_VIEW) and use the marea's
|
||||
* per-type union to get the .u.SectionView.Section pointer to
|
||||
* the SECTION_OBJECT. Then we can use MmGetFileObjectForSection
|
||||
* to get the FILE_OBJECT, from which we can then query the name
|
||||
* to get the full filename (much like we do for creating the
|
||||
* SeAuditName in EPROCESS.
|
||||
* the SECTION_OBJECT. Then we can use MmGetFileNameForSection
|
||||
* to get the full filename.
|
||||
*/
|
||||
RtlCreateUnicodeString(ModuleName, L"C:\\ReactOS\\system32\\ntdll.dll");
|
||||
return STATUS_SUCCESS;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue