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 *LastThread)
|
||||
{
|
||||
/* FIXME: TODO */
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
PETHREAD pFirstThread = NULL, ThisThread, OldThread = NULL, pLastThread;
|
||||
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
|
||||
|
|
|
@ -19,6 +19,21 @@ DbgkExitThread(
|
|||
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
|
||||
NTAPI
|
||||
DbgkpSuspendProcess(
|
||||
|
@ -38,6 +53,12 @@ DbgkpSendApiMessage(
|
|||
IN ULONG Flags
|
||||
);
|
||||
|
||||
HANDLE
|
||||
NTAPI
|
||||
DbgkpSectionToFileHandle(
|
||||
IN PVOID Section
|
||||
);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
DbgkCopyProcessDebugPort(
|
||||
|
|
|
@ -342,6 +342,13 @@ PsResumeThread(
|
|||
OUT PULONG PreviousCount OPTIONAL
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
PsSuspendThread(
|
||||
IN PETHREAD Thread,
|
||||
OUT PULONG PreviousCount OPTIONAL
|
||||
);
|
||||
|
||||
//
|
||||
// Global data inside the Process Manager
|
||||
//
|
||||
|
|
|
@ -3742,6 +3742,18 @@ NtMapViewOfSection(IN HANDLE SectionHandle,
|
|||
AllocationType,
|
||||
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(Process);
|
||||
|
||||
|
@ -3945,6 +3957,7 @@ MmUnmapViewOfSection(PEPROCESS Process,
|
|||
PROS_SECTION_OBJECT Section;
|
||||
PMM_PAGEOP PageOp;
|
||||
ULONG_PTR Offset;
|
||||
PVOID ImageBaseAddress = 0;
|
||||
|
||||
DPRINT("Opening memory area Process %x BaseAddress %x\n",
|
||||
Process, BaseAddress);
|
||||
|
@ -4007,7 +4020,6 @@ MmUnmapViewOfSection(PEPROCESS Process,
|
|||
ULONG NrSegments;
|
||||
PMM_IMAGE_SECTION_OBJECT ImageSectionObject;
|
||||
PMM_SECTION_SEGMENT SectionSegments;
|
||||
PVOID ImageBaseAddress = 0;
|
||||
PMM_SECTION_SEGMENT Segment;
|
||||
|
||||
Segment = MemoryArea->Data.SectionData.Segment;
|
||||
|
@ -4048,6 +4060,10 @@ MmUnmapViewOfSection(PEPROCESS Process,
|
|||
{
|
||||
Status = MmUnmapViewOfSegment(AddressSpace, BaseAddress);
|
||||
}
|
||||
|
||||
/* Notify debugger */
|
||||
if (ImageBaseAddress) DbgkUnMapViewOfSection(ImageBaseAddress);
|
||||
|
||||
MmUnlockAddressSpace(AddressSpace);
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue