- 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:
Alex Ionescu 2006-11-30 01:57:25 +00:00
parent 9ceed92dda
commit 2a4049fdfc
4 changed files with 207 additions and 3 deletions

View file

@ -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

View file

@ -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(

View file

@ -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
//

View file

@ -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);
}