mirror of
https://github.com/reactos/reactos.git
synced 2025-02-22 16:36:33 +00:00
- Implement DbgkPostFakeThreadMessages.
- Add Dbgk-calls to NtMap/UnmapViewOfSection to nodify debugging services of new DLL image load. - Dbgk support is now skeletally complete, I will write a simple test app to test some functionality and start finding/fixing bugs. svn path=/trunk/; revision=24980
This commit is contained in:
parent
9ceed92dda
commit
2a4049fdfc
4 changed files with 207 additions and 3 deletions
|
@ -551,8 +551,168 @@ DbgkpPostFakeThreadMessages(IN PEPROCESS Process,
|
||||||
OUT PETHREAD *FirstThread,
|
OUT PETHREAD *FirstThread,
|
||||||
OUT PETHREAD *LastThread)
|
OUT PETHREAD *LastThread)
|
||||||
{
|
{
|
||||||
/* FIXME: TODO */
|
PETHREAD pFirstThread = NULL, ThisThread, OldThread = NULL, pLastThread;
|
||||||
return STATUS_UNSUCCESSFUL;
|
NTSTATUS Status = STATUS_UNSUCCESSFUL;
|
||||||
|
BOOLEAN IsFirstThread;
|
||||||
|
ULONG Flags;
|
||||||
|
DBGKM_MSG ApiMessage;
|
||||||
|
PDBGKM_CREATE_THREAD CreateThread = &ApiMessage.CreateThread;
|
||||||
|
PDBGKM_CREATE_PROCESS CreateProcess = &ApiMessage.CreateProcess;
|
||||||
|
BOOLEAN First;
|
||||||
|
PIMAGE_NT_HEADERS NtHeader;
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
/* Check if we have a start thread */
|
||||||
|
if (StartThread)
|
||||||
|
{
|
||||||
|
/* Then the one we'll find won't be the first one */
|
||||||
|
IsFirstThread = FALSE;
|
||||||
|
pFirstThread = StartThread;
|
||||||
|
ThisThread = StartThread;
|
||||||
|
|
||||||
|
/* Reference it */
|
||||||
|
ObReferenceObject(StartThread);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Get the first thread ourselves */
|
||||||
|
ThisThread = PsGetNextProcessThread(Process, OldThread);
|
||||||
|
IsFirstThread = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Start thread loop */
|
||||||
|
do
|
||||||
|
{
|
||||||
|
/* Dereference the previous thread if we had one */
|
||||||
|
if (OldThread) ObDereferenceObject(OldThread);
|
||||||
|
|
||||||
|
/* Set this as the last thread and lock it */
|
||||||
|
pLastThread = ThisThread;
|
||||||
|
ObReferenceObject(ThisThread);
|
||||||
|
if (ExAcquireRundownProtection(&ThisThread->RundownProtect))
|
||||||
|
{
|
||||||
|
/* Acquire worked, set flags */
|
||||||
|
Flags = 0x8 | 0x2;
|
||||||
|
|
||||||
|
/* Check if this is a user thread */
|
||||||
|
if (!ThisThread->SystemThread)
|
||||||
|
{
|
||||||
|
/* Suspend it */
|
||||||
|
if (NT_SUCCESS(PsSuspendThread(ThisThread, NULL)))
|
||||||
|
{
|
||||||
|
/* Remember this */
|
||||||
|
Flags = 0x8 | 0x2 | 0x20;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Couldn't acquire rundown */
|
||||||
|
Flags = 0x10 | 0x2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clear the API Message */
|
||||||
|
RtlZeroMemory(&ApiMessage, sizeof(ApiMessage));
|
||||||
|
|
||||||
|
/* Check if this is the first thread */
|
||||||
|
if ((IsFirstThread) &&
|
||||||
|
!(Flags & 0x10) &&
|
||||||
|
!(ThisThread->SystemThread) &&
|
||||||
|
(ThisThread->GrantedAccess))
|
||||||
|
{
|
||||||
|
/* It is, save the flag */
|
||||||
|
First = TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* It isn't, save the flag */
|
||||||
|
First = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if this is the first */
|
||||||
|
if (First)
|
||||||
|
{
|
||||||
|
/* So we'll start with the create process message */
|
||||||
|
ApiMessage.ApiNumber = DbgKmCreateProcessApi;
|
||||||
|
|
||||||
|
/* Get the file handle */
|
||||||
|
if (Process->SectionObject)
|
||||||
|
{
|
||||||
|
/* Use the section object */
|
||||||
|
CreateProcess->FileHandle =
|
||||||
|
DbgkpSectionToFileHandle(Process->SectionObject);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Don't return any handle */
|
||||||
|
CreateProcess->FileHandle = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the base address */
|
||||||
|
CreateProcess->BaseOfImage = Process->SectionBaseAddress;
|
||||||
|
|
||||||
|
/* Get the NT Header */
|
||||||
|
NtHeader = RtlImageNtHeader(Process->SectionBaseAddress);
|
||||||
|
if (NtHeader)
|
||||||
|
{
|
||||||
|
/* Fill out data from the header */
|
||||||
|
CreateProcess->DebugInfoFileOffset = NtHeader->FileHeader.
|
||||||
|
PointerToSymbolTable;
|
||||||
|
CreateProcess->DebugInfoSize = NtHeader->FileHeader.
|
||||||
|
NumberOfSymbols;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Otherwise it's a thread message */
|
||||||
|
ApiMessage.ApiNumber = DbgKmCreateThreadApi;
|
||||||
|
CreateThread->StartAddress = ThisThread->StartAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Queue the message */
|
||||||
|
Status = DbgkpQueueMessage(Process,
|
||||||
|
ThisThread,
|
||||||
|
&ApiMessage,
|
||||||
|
Flags,
|
||||||
|
DebugObject);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* We failed. FIXME: Handle this */
|
||||||
|
DPRINT1("Unhandled Dbgk codepath!\n");
|
||||||
|
KEBUGCHECK(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if this was the first message */
|
||||||
|
if (First)
|
||||||
|
{
|
||||||
|
/* It isn't the first thread anymore */
|
||||||
|
IsFirstThread = FALSE;
|
||||||
|
|
||||||
|
/* Reference this thread and set it as first */
|
||||||
|
ObDereferenceObject(ThisThread);
|
||||||
|
pFirstThread = ThisThread;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the next thread */
|
||||||
|
ThisThread = PsGetNextProcessThread(Process, ThisThread);
|
||||||
|
OldThread = pLastThread;
|
||||||
|
} while(ThisThread);
|
||||||
|
|
||||||
|
/* Check the API status */
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* We failed. FIXME: Handle this */
|
||||||
|
DPRINT1("Unhandled Dbgk codepath!\n");
|
||||||
|
KEBUGCHECK(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make sure we have a first thread */
|
||||||
|
if (!pFirstThread) return STATUS_UNSUCCESSFUL;
|
||||||
|
|
||||||
|
/* Return thread pointers */
|
||||||
|
*FirstThread = pFirstThread;
|
||||||
|
*LastThread = pLastThread;
|
||||||
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
|
|
@ -19,6 +19,21 @@ DbgkExitThread(
|
||||||
IN NTSTATUS ExitStatus
|
IN NTSTATUS ExitStatus
|
||||||
);
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
DbgkMapViewOfSection(
|
||||||
|
IN HANDLE SectionHandle,
|
||||||
|
IN PVOID BaseAddress,
|
||||||
|
IN ULONG SectionOffset,
|
||||||
|
IN ULONG_PTR ViewSize
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
DbgkUnMapViewOfSection(
|
||||||
|
IN PVOID BaseAddress
|
||||||
|
);
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
NTAPI
|
NTAPI
|
||||||
DbgkpSuspendProcess(
|
DbgkpSuspendProcess(
|
||||||
|
@ -38,6 +53,12 @@ DbgkpSendApiMessage(
|
||||||
IN ULONG Flags
|
IN ULONG Flags
|
||||||
);
|
);
|
||||||
|
|
||||||
|
HANDLE
|
||||||
|
NTAPI
|
||||||
|
DbgkpSectionToFileHandle(
|
||||||
|
IN PVOID Section
|
||||||
|
);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
DbgkCopyProcessDebugPort(
|
DbgkCopyProcessDebugPort(
|
||||||
|
|
|
@ -342,6 +342,13 @@ PsResumeThread(
|
||||||
OUT PULONG PreviousCount OPTIONAL
|
OUT PULONG PreviousCount OPTIONAL
|
||||||
);
|
);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
PsSuspendThread(
|
||||||
|
IN PETHREAD Thread,
|
||||||
|
OUT PULONG PreviousCount OPTIONAL
|
||||||
|
);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Global data inside the Process Manager
|
// Global data inside the Process Manager
|
||||||
//
|
//
|
||||||
|
|
|
@ -3742,6 +3742,18 @@ NtMapViewOfSection(IN HANDLE SectionHandle,
|
||||||
AllocationType,
|
AllocationType,
|
||||||
Protect);
|
Protect);
|
||||||
|
|
||||||
|
/* Check if this is an image for the current process */
|
||||||
|
if ((Section->AllocationAttributes & SEC_IMAGE) &&
|
||||||
|
(Process == PsGetCurrentProcess()) &&
|
||||||
|
(Status != STATUS_IMAGE_NOT_AT_BASE))
|
||||||
|
{
|
||||||
|
/* Notify the debugger */
|
||||||
|
DbgkMapViewOfSection(SectionHandle,
|
||||||
|
SafeBaseAddress,
|
||||||
|
SafeSectionOffset.LowPart,
|
||||||
|
SafeViewSize);
|
||||||
|
}
|
||||||
|
|
||||||
ObDereferenceObject(Section);
|
ObDereferenceObject(Section);
|
||||||
ObDereferenceObject(Process);
|
ObDereferenceObject(Process);
|
||||||
|
|
||||||
|
@ -3945,6 +3957,7 @@ MmUnmapViewOfSection(PEPROCESS Process,
|
||||||
PROS_SECTION_OBJECT Section;
|
PROS_SECTION_OBJECT Section;
|
||||||
PMM_PAGEOP PageOp;
|
PMM_PAGEOP PageOp;
|
||||||
ULONG_PTR Offset;
|
ULONG_PTR Offset;
|
||||||
|
PVOID ImageBaseAddress = 0;
|
||||||
|
|
||||||
DPRINT("Opening memory area Process %x BaseAddress %x\n",
|
DPRINT("Opening memory area Process %x BaseAddress %x\n",
|
||||||
Process, BaseAddress);
|
Process, BaseAddress);
|
||||||
|
@ -4007,7 +4020,6 @@ MmUnmapViewOfSection(PEPROCESS Process,
|
||||||
ULONG NrSegments;
|
ULONG NrSegments;
|
||||||
PMM_IMAGE_SECTION_OBJECT ImageSectionObject;
|
PMM_IMAGE_SECTION_OBJECT ImageSectionObject;
|
||||||
PMM_SECTION_SEGMENT SectionSegments;
|
PMM_SECTION_SEGMENT SectionSegments;
|
||||||
PVOID ImageBaseAddress = 0;
|
|
||||||
PMM_SECTION_SEGMENT Segment;
|
PMM_SECTION_SEGMENT Segment;
|
||||||
|
|
||||||
Segment = MemoryArea->Data.SectionData.Segment;
|
Segment = MemoryArea->Data.SectionData.Segment;
|
||||||
|
@ -4048,6 +4060,10 @@ MmUnmapViewOfSection(PEPROCESS Process,
|
||||||
{
|
{
|
||||||
Status = MmUnmapViewOfSegment(AddressSpace, BaseAddress);
|
Status = MmUnmapViewOfSegment(AddressSpace, BaseAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Notify debugger */
|
||||||
|
if (ImageBaseAddress) DbgkUnMapViewOfSection(ImageBaseAddress);
|
||||||
|
|
||||||
MmUnlockAddressSpace(AddressSpace);
|
MmUnlockAddressSpace(AddressSpace);
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue