Author: sginsberg Date: Thu Oct 15 12:56:19 2015 New Revision: 69539
URL: http://svn.reactos.org/svn/reactos?rev=69539&view=rev Log: [NTOS] Isolate KD a bit by replacing Rtl* memory routines with internal versions. Lets one put breakpoints inside kernel memcpy/memset without making KD very, very sad. Fix MmDbgCopyMemory to also not use RtlCopyMemory -- there is no need for it since it only performs 1-to-8 byte copies anyway. Minor fixes in the print/prompt routines.
Modified: trunk/reactos/ntoskrnl/include/internal/kd64.h trunk/reactos/ntoskrnl/kd64/kdapi.c trunk/reactos/ntoskrnl/kd64/kdprint.c trunk/reactos/ntoskrnl/kd64/kdtrap.c trunk/reactos/ntoskrnl/mm/ARM3/session.c
Modified: trunk/reactos/ntoskrnl/include/internal/kd64.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/k... ============================================================================== --- trunk/reactos/ntoskrnl/include/internal/kd64.h [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/include/internal/kd64.h [iso-8859-1] Thu Oct 15 12:56:19 2015 @@ -349,6 +349,24 @@ IN ULONG ChunkSize, IN ULONG Flags, OUT PULONG ActualSize OPTIONAL +); + +// +// Internal memory handling routines for KD isolation +// +VOID +NTAPI +KdpMoveMemory( + IN PVOID Destination, + IN PVOID Source, + IN SIZE_T Length +); + +VOID +NTAPI +KdpZeroMemory( + IN PVOID Destination, + IN SIZE_T Length );
//
Modified: trunk/reactos/ntoskrnl/kd64/kdapi.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/kd64/kdapi.c?rev=6... ============================================================================== --- trunk/reactos/ntoskrnl/kd64/kdapi.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/kd64/kdapi.c [iso-8859-1] Thu Oct 15 12:56:19 2015 @@ -14,6 +14,32 @@ #include <debug.h>
/* PRIVATE FUNCTIONS *********************************************************/ + +VOID +NTAPI +KdpMoveMemory(IN PVOID Destination, + IN PVOID Source, + IN SIZE_T Length) +{ + PCHAR DestinationBytes, SourceBytes; + + /* Copy the buffers 1 byte at a time */ + DestinationBytes = Destination; + SourceBytes = Source; + while (Length--) *DestinationBytes++ = *SourceBytes++; +} + +VOID +NTAPI +KdpZeroMemory(IN PVOID Destination, + IN SIZE_T Length) +{ + PCHAR DestinationBytes; + + /* Zero the buffer 1 byte at a time */ + DestinationBytes = Destination; + while (Length--) *DestinationBytes++ = 0; +}
NTSTATUS NTAPI @@ -368,7 +394,7 @@ WaitStateChange->ProgramCounter = (ULONG64)(LONG_PTR)KeGetContextPc(Context);
/* Zero out the entire Control Report */ - RtlZeroMemory(&WaitStateChange->AnyControlReport, + KdpZeroMemory(&WaitStateChange->AnyControlReport, sizeof(DBGKD_ANY_CONTROL_REPORT));
/* Now copy the instruction stream and set the count */ @@ -402,7 +428,9 @@ KdpSysGetVersion(IN PDBGKD_GET_VERSION64 Version) { /* Copy the version block */ - RtlCopyMemory(Version, &KdVersionBlock, sizeof(DBGKD_GET_VERSION64)); + KdpMoveMemory(Version, + &KdVersionBlock, + sizeof(DBGKD_GET_VERSION64)); }
VOID @@ -711,7 +739,9 @@ }
/* Copy it over to the debugger */ - RtlCopyMemory(Data->Buffer, TargetContext, sizeof(CONTEXT)); + KdpMoveMemory(Data->Buffer, + TargetContext, + sizeof(CONTEXT)); Data->Length = sizeof(CONTEXT);
/* Let the debugger set the context now */ @@ -765,7 +795,9 @@ }
/* Copy the new context to it */ - RtlCopyMemory(TargetContext, Data->Buffer, sizeof(CONTEXT)); + KdpMoveMemory(TargetContext, + Data->Buffer, + sizeof(CONTEXT));
/* Finish up */ State->ReturnStatus = STATUS_SUCCESS; @@ -819,7 +851,7 @@ }
/* Copy what is requested */ - RtlCopyMemory(Data->Buffer, + KdpMoveMemory(Data->Buffer, (PVOID)((ULONG_PTR)TargetContext + ContextEx->Offset), ContextEx->ByteCount);
@@ -883,7 +915,7 @@ }
/* Copy what is requested */ - RtlCopyMemory((PVOID)((ULONG_PTR)TargetContext + ContextEx->Offset), + KdpMoveMemory((PVOID)((ULONG_PTR)TargetContext + ContextEx->Offset), Data->Buffer, ContextEx->ByteCount);
@@ -1639,7 +1671,7 @@ KdpSetContextState(&WaitStateChange, Context);
/* Clear the command string structure */ - RtlZeroMemory(&WaitStateChange.u.CommandString, + KdpZeroMemory(&WaitStateChange.u.CommandString, sizeof(DBGKD_COMMAND_STRING));
/* Normalize name string to max */ @@ -1709,15 +1741,22 @@ /* Build the architecture common parts of the message */ KdpSetCommonState(DbgKdExceptionStateChange, Context, &WaitStateChange);
- /* Copy the Exception Record and set First Chance flag */ #if !defined(_WIN64) + + /* Convert it and copy it over */ ExceptionRecord32To64((PEXCEPTION_RECORD32)ExceptionRecord, &WaitStateChange.u.Exception.ExceptionRecord); + #else - RtlCopyMemory(&WaitStateChange.u.Exception.ExceptionRecord, + + /* Just copy it directly, no need to convert */ + KdpMoveMemory(&WaitStateChange.u.Exception.ExceptionRecord, ExceptionRecord, sizeof(EXCEPTION_RECORD)); + #endif + + /* Set the First Chance flag */ WaitStateChange.u.Exception.FirstChance = !SecondChanceException;
/* Now finish creating the structure */
Modified: trunk/reactos/ntoskrnl/kd64/kdprint.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/kd64/kdprint.c?rev... ============================================================================== --- trunk/reactos/ntoskrnl/kd64/kdprint.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/kd64/kdprint.c [iso-8859-1] Thu Oct 15 12:56:19 2015 @@ -21,12 +21,15 @@ { STRING Data, Header; DBGKD_DEBUG_IO DebugIo; - USHORT Length = Output->Length; + USHORT Length;
/* Copy the string */ - RtlMoveMemory(KdpMessageBuffer, Output->Buffer, Length); + KdpMoveMemory(KdpMessageBuffer, + Output->Buffer, + Output->Length);
/* Make sure we don't exceed the KD Packet size */ + Length = Output->Length; if ((sizeof(DBGKD_DEBUG_IO) + Length) > PACKET_MAX_SIZE) { /* Normalize length */ @@ -59,15 +62,16 @@ { STRING Data, Header; DBGKD_DEBUG_IO DebugIo; - ULONG Length = PromptString->Length; + ULONG Length; KDSTATUS Status;
/* Copy the string to the message buffer */ - RtlCopyMemory(KdpMessageBuffer, + KdpMoveMemory(KdpMessageBuffer, PromptString->Buffer, PromptString->Length);
/* Make sure we don't exceed the KD Packet size */ + Length = PromptString->Length; if ((sizeof(DBGKD_DEBUG_IO) + Length) > PACKET_MAX_SIZE) { /* Normalize length */ @@ -84,7 +88,7 @@ Header.Buffer = (PCHAR)&DebugIo;
/* Build the data */ - Data.Length = PromptString->Length; + Data.Length = Length; Data.Buffer = KdpMessageBuffer;
/* Send the packet */ @@ -111,10 +115,13 @@ } while (Status != KdPacketReceived);
/* Don't copy back a larger response than there is room for */ - Length = min(Length, ResponseString->MaximumLength); + Length = min(Length, + ResponseString->MaximumLength);
/* Copy back the string and return the length */ - RtlCopyMemory(ResponseString->Buffer, KdpMessageBuffer, Length); + KdpMoveMemory(ResponseString->Buffer, + KdpMessageBuffer, + Length); ResponseString->Length = (USHORT)Length;
/* Success; we don't need to resend */ @@ -141,7 +148,7 @@
/* Save the CPU Control State and save the context */ KiSaveProcessorControlState(&Prcb->ProcessorState); - RtlCopyMemory(&Prcb->ProcessorState.ContextFrame, + KdpMoveMemory(&Prcb->ProcessorState.ContextFrame, ContextRecord, sizeof(CONTEXT));
@@ -151,7 +158,7 @@ &Prcb->ProcessorState.ContextFrame);
/* Restore the processor state */ - RtlCopyMemory(ContextRecord, + KdpMoveMemory(ContextRecord, &Prcb->ProcessorState.ContextFrame, sizeof(CONTEXT)); KiRestoreProcessorControlState(&Prcb->ProcessorState); @@ -181,7 +188,7 @@
/* Save the CPU Control State and save the context */ KiSaveProcessorControlState(&Prcb->ProcessorState); - RtlCopyMemory(&Prcb->ProcessorState.ContextFrame, + KdpMoveMemory(&Prcb->ProcessorState.ContextFrame, ContextRecord, sizeof(CONTEXT));
@@ -192,7 +199,7 @@ &Prcb->ProcessorState.ContextFrame);
/* Restore the processor state */ - RtlCopyMemory(ContextRecord, + KdpMoveMemory(ContextRecord, &Prcb->ProcessorState.ContextFrame, sizeof(CONTEXT)); KiRestoreProcessorControlState(&Prcb->ProcessorState); @@ -216,38 +223,48 @@ PVOID CapturedPrompt, CapturedResponse;
/* Normalize the lengths */ - PromptLength = min(PromptLength, 512); - MaximumResponseLength = min(MaximumResponseLength, 512); + PromptLength = min(PromptLength, + 512); + MaximumResponseLength = min(MaximumResponseLength, + 512);
/* Check if we need to verify the string */ if (PreviousMode != KernelMode) { - /* Capture user-mode buffers */ + /* Handle user-mode buffers safely */ _SEH2_TRY { - ProbeForRead(PromptString, PromptLength, 1); - CapturedPrompt = alloca(512); - RtlMoveMemory(CapturedPrompt, PromptString, PromptLength); + /* Probe the prompt */ + ProbeForRead(PromptString, + PromptLength, + 1); + + /* Capture prompt */ + CapturedPrompt = _alloca(PromptLength); + KdpMoveMemory(CapturedPrompt, + PromptString, + PromptLength); PromptString = CapturedPrompt;
- ProbeForWrite(ResponseString, MaximumResponseLength, 1); - CapturedResponse = alloca(512); + /* Probe and make room for response */ + ProbeForWrite(ResponseString, + MaximumResponseLength, + 1); + CapturedResponse = _alloca(MaximumResponseLength); + ResponseString = CapturedResponse; } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { + /* Bad string pointer, bail out */ _SEH2_YIELD(return 0); } _SEH2_END; - } - else - { - CapturedResponse = ResponseString; }
/* Setup the prompt and response buffers */ PromptBuffer.Buffer = PromptString; PromptBuffer.Length = PromptLength; - ResponseBuffer.Buffer = CapturedResponse; + ResponseBuffer.Buffer = ResponseString; ResponseBuffer.Length = 0; ResponseBuffer.MaximumLength = MaximumResponseLength;
@@ -274,10 +291,14 @@ { _SEH2_TRY { - RtlMoveMemory(ResponseString, ResponseBuffer.Buffer, ResponseBuffer.Length); + /* Safely copy back response to user mode */ + KdpMoveMemory(ResponseString, + ResponseBuffer.Buffer, + ResponseBuffer.Length); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { + /* String became invalid after we exited, fail */ _SEH2_YIELD(return 0); } _SEH2_END; @@ -326,13 +347,21 @@ /* Capture user-mode buffers */ _SEH2_TRY { - ProbeForRead(String, Length, 1); - CapturedString = alloca(512); - RtlMoveMemory(CapturedString, String, Length); + /* Probe the string */ + ProbeForRead(String, + Length, + 1); + + /* Capture it */ + CapturedString = alloca(Length); + KdpMoveMemory(CapturedString, + String, + Length); String = CapturedString; } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { + /* Bad pointer, fail the print */ _SEH2_YIELD(return STATUS_ACCESS_VIOLATION); } _SEH2_END;
Modified: trunk/reactos/ntoskrnl/kd64/kdtrap.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/kd64/kdtrap.c?rev=... ============================================================================== --- trunk/reactos/ntoskrnl/kd64/kdtrap.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/kd64/kdtrap.c [iso-8859-1] Thu Oct 15 12:56:19 2015 @@ -58,13 +58,14 @@ { BOOLEAN Enable, Handled; PKPRCB Prcb; - NTSTATUS ExceptionCode = ExceptionRecord->ExceptionCode; + NTSTATUS ExceptionCode;
/* * Determine whether to pass the exception to the debugger. * First, check if this is a "debug exception", meaning breakpoint * (including debug service), single step and assertion failure exceptions. */ + ExceptionCode = ExceptionRecord->ExceptionCode; if ((ExceptionCode == STATUS_BREAKPOINT) || (ExceptionCode == STATUS_SINGLE_STEP) || (ExceptionCode == STATUS_ASSERTION_FAILURE)) @@ -92,8 +93,8 @@ else if (SecondChanceException == FALSE) { /* - * This isn't a debug exception and the stop-on-exception flag isn't - * set, so don't bother + * This isn't a debug exception and the stop-on-exception flag isn't set, + * so don't bother handling it */ return FALSE; } @@ -107,7 +108,7 @@ */ Prcb = KeGetCurrentPrcb(); KiSaveProcessorControlState(&Prcb->ProcessorState); - RtlCopyMemory(&Prcb->ProcessorState.ContextFrame, + KdpMoveMemory(&Prcb->ProcessorState.ContextFrame, ContextRecord, sizeof(CONTEXT));
@@ -118,7 +119,7 @@ SecondChanceException);
/* Now restore the processor state, manually again. */ - RtlCopyMemory(ContextRecord, + KdpMoveMemory(ContextRecord, &Prcb->ProcessorState.ContextFrame, sizeof(CONTEXT)); KiRestoreProcessorControlState(&Prcb->ProcessorState); @@ -138,7 +139,7 @@ IN KPROCESSOR_MODE PreviousMode, IN BOOLEAN SecondChanceException) { - BOOLEAN Unload = FALSE; + BOOLEAN Unload; ULONG_PTR ProgramCounter; BOOLEAN Handled; NTSTATUS ReturnStatus; @@ -156,6 +157,7 @@ ProgramCounter = KeGetContextPc(ContextRecord);
/* Check what kind of operation was requested from us */ + Unload = FALSE; switch (ExceptionRecord->ExceptionInformation[0]) { /* DbgPrint */ @@ -164,27 +166,24 @@ /* Call the worker routine */ ReturnStatus = KdpPrint((ULONG)KdpGetParameterThree(ContextRecord), (ULONG)KdpGetParameterFour(ContextRecord), - (LPSTR)ExceptionRecord-> - ExceptionInformation[1], - (USHORT)ExceptionRecord-> - ExceptionInformation[2], + (LPSTR)ExceptionRecord->ExceptionInformation[1], + (USHORT)ExceptionRecord->ExceptionInformation[2], PreviousMode, TrapFrame, ExceptionFrame, &Handled);
/* Update the return value for the caller */ - KeSetContextReturnRegister(ContextRecord, ReturnStatus); + KeSetContextReturnRegister(ContextRecord, + ReturnStatus); break;
/* DbgPrompt */ case BREAKPOINT_PROMPT:
/* Call the worker routine */ - ReturnLength = KdpPrompt((LPSTR)ExceptionRecord-> - ExceptionInformation[1], - (USHORT)ExceptionRecord-> - ExceptionInformation[2], + ReturnLength = KdpPrompt((LPSTR)ExceptionRecord->ExceptionInformation[1], + (USHORT)ExceptionRecord->ExceptionInformation[2], (LPSTR)KdpGetParameterThree(ContextRecord), (USHORT)KdpGetParameterFour(ContextRecord), PreviousMode, @@ -276,9 +275,10 @@ IN KPROCESSOR_MODE PreviousMode, IN BOOLEAN SecondChanceException) { - ULONG_PTR ExceptionCommand = ExceptionRecord->ExceptionInformation[0]; + ULONG_PTR ExceptionCommand;
/* Check if this was a breakpoint due to DbgPrint or Load/UnloadSymbols */ + ExceptionCommand = ExceptionRecord->ExceptionInformation[0]; if ((ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) && (ExceptionRecord->NumberParameters > 0) && ((ExceptionCommand == BREAKPOINT_LOAD_SYMBOLS) ||
Modified: trunk/reactos/ntoskrnl/mm/ARM3/session.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/session.c?... ============================================================================== --- trunk/reactos/ntoskrnl/mm/ARM3/session.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/mm/ARM3/session.c [iso-8859-1] Thu Oct 15 12:56:19 2015 @@ -42,6 +42,14 @@ /* Initialize the list heads */ InitializeListHead(&MiSessionWsList); InitializeListHead(&MmWorkingSetExpansionHead); +} + +BOOLEAN +NTAPI +MmIsSessionAddress(IN PVOID Address) +{ + /* Check if it is in range */ + return MI_IS_SESSION_ADDRESS(Address) ? TRUE : FALSE; }
LCID