Compare commits

...

30 Commits

Author SHA1 Message Date
Hervé Poussineau
f1171128ca [NTOS:EX] HACK: on livecd, disable security features in NtSystemDebugControl
WinDBG can do some local debugging using 'windbg -kl'. In that case,
WinDBG tries to directly use NtSystemDebugControl. If this function
returns an error, WinDBG extracts a driver from its resources.
WinDBG will send IOCTLs to this driver, and this driver will call
KdSystemDebugControl.

However, on livecd (where %SYSTEMROOT% is read-only), WinDBG is unable
to extract the driver from its resources, and can't use the driver to
call KdSystemDebugControl.

As a work-around, allow all control classes in NtSystemDebugControl
in case of livecd.
WinDBG local debugging now also works on livecd (windbg -kl).
2025-01-28 17:13:18 +01:00
Hervé Poussineau
daa34596d8 [NTOS:KD64] Fix freezes on first chance exception when KDBG is enabled and KdIgnoreUmExceptions is TRUE
This fixes the following use case:
- Execute 'kdbgctrl.exe -du'
- Execute 'kdbgctrl.exe -cu'
- See that last command never finishes
2025-01-28 17:13:17 +01:00
Hermès Bélusca-Maïto
ae70120a18 [NTOS:KD64] Add a missing KdEnteredDebugger reset in KdExitDebugger() 2025-01-28 17:13:17 +01:00
Hervé Poussineau
a269aae455 [NTOS:EX] Implement NtSystemDebugControl: SysDbgGetKdBlockEnable/SysDbgSetKdBlockEnable 2025-01-28 17:13:15 +01:00
Hervé Poussineau
e6c20b5446 [NTOS:EX] Implement NtSystemDebugControl: SysDbgGetKdUmExceptionEnable/SysDbgSetKdUmExceptionEnable 2025-01-28 17:13:14 +01:00
Hervé Poussineau
b5f4a928ae [NTOS:EX] Implement NtSystemDebugControl: SysDbgGetPrintBufferSize 2025-01-28 17:13:13 +01:00
Hervé Poussineau
7a5d450218 [NTOS:EX] Implement NtSystemDebugControl: SysDbgGetAutoKdEnable/SysDbgSetAutoKdEnable 2025-01-28 17:13:11 +01:00
Hervé Poussineau
698eaaceda [NTOS:EX] Implement NtSystemDebugControl: SysDbgEnableKernelDebugger/SysDbgDisableKernelDebugger 2025-01-28 17:13:10 +01:00
Hervé Poussineau
55d91fccdf [NTOS:EX] Implement NtSystemDebugControl: SysDbgBreakPoint 2025-01-28 17:13:08 +01:00
Hervé Poussineau
936e7a8b36 [NTOS:KD64] Implement KdSystemDebugControl: SysDbgCheckLowMemory 2025-01-28 17:13:08 +01:00
Hervé Poussineau
c570cbf5cd [NTOS:KD64] Implement KdSystemDebugControl: SysDbgReadBusData/SysDbgWriteBusData 2025-01-28 17:13:07 +01:00
Hervé Poussineau
2d378eeeb7 [NTOS:KD64] Implement KdSystemDebugControl: SysDbgReadMsr/SysDbgWriteMsr 2025-01-28 17:13:06 +01:00
Hervé Poussineau
a8e03d6da9 [NTOS:KD64] Implement KdSystemDebugControl: SysDbgReadIoSpace/SysDbgWriteIoSpace 2025-01-28 17:13:05 +01:00
Hervé Poussineau
d27c012891 [NTOS:KD64] Implement KdSystemDebugControl: SysDbgReadControlSpace/SysDbgWriteControlSpace 2025-01-28 17:13:03 +01:00
Hervé Poussineau
1bec6a3094 [NTOS:KD64] Implement KdSystemDebugControl: SysDbgReadPhysical/SysDbgWritePhysical 2025-01-28 17:13:01 +01:00
Hervé Poussineau
7974e47690 [NTOS:KD64] Implement KdSystemDebugControl: SysDbgReadVirtual/SysDbgWriteVirtual 2025-01-28 17:13:00 +01:00
Hervé Poussineau
51e13a366a [NTOS:KD64] Implement KdSystemDebugControl: SysDbgQueryVersion 2025-01-28 17:12:57 +01:00
Hervé Poussineau
1c0d5734dd [NTOS:EX] In NtSystemDebugControl, check for SeDebugPrivilege 2025-01-28 17:12:56 +01:00
Hervé Poussineau
bdfc074a41 [NTOS:EX] Improve NtSystemDebugControl
- Add SEH probing for user buffer
- Mark some classes as i386 only
- Explicitly return STATUS_NOT_IMPLEMENTED on disabled classes (must use KdSystemDebugControl instead)
- Explicitly return STATUS_NOT_IMPLEMENTED on not implemented classes
- Return STATUS_INVALID_INFO_CLASS on all other classes
2025-01-28 17:12:55 +01:00
Hervé Poussineau
9cb25e62b3 [NTOS:KD64] Improve KdSystemDebugControl
- Explicitly return STATUS_NOT_IMPLEMENTED on not implemented classes
- Return STATUS_INVALID_INFO_CLASS on all other classes
2025-01-28 17:12:54 +01:00
Hermès Bélusca-Maïto
8eda8b69d5 [NTOS:EX:KD64] Add Doxygen documentation for Nt/KdSystemDebugControl.
Based from external documentation:
https://www.ivanlef0u.tuxfamily.org/?p=21
https://www.ivanlef0u.tuxfamily.org/?p=382
http://pds8.egloos.com/pds/200807/09/51/Subverting_Windows_2003_Service_Pack_1_Kernel_Integrity_Protection.pdf
http://www.nynaeve.net/?p=114
https://media.defcon.org/DEF%20CON%2030/DEF%20CON%2030%20presentations/Eran%20Segal%20-%20The%20COW%20%28Container%20On%20Windows%29%20Who%20Escaped%20the%20Silo.pdf
https://vidstromlabs.com/blog/memory-dumping-with-ntsystemdebugcontrol/
https://www.kernelmode.info/forum/viewtopic0aa3.html?t=5317
2025-01-28 17:12:53 +01:00
Hermès Bélusca-Maïto
5fc675515b [NDK][NTOS:EX:KD64] Add SAL annotations to Kd/Nt/ZwSystemDebugControl. 2025-01-28 17:12:51 +01:00
Hermès Bélusca-Maïto
b1407aae4c [NTOS:KD64] Simplify some code in debugging helpers 2025-01-28 17:12:50 +01:00
Hermès Bélusca-Maïto
20179408eb [NTOS:KD64] Add annotations to debugger control routines used in Kd/Nt/ZwSystemDebugControl 2025-01-28 17:12:48 +01:00
Hervé Poussineau
bef9e57cf7 [NTOS:MM] Allow not providing MMDBG_COPY_UNSAFE in MmDbgCopyMemory
Replace an assert by a log, as this works most of the times.
2025-01-28 17:12:47 +01:00
Hervé Poussineau
5948011612 [NTOS:EX] Allow calling ExLockUserBuffer up to DISPATCH_LEVEL 2025-01-28 17:12:46 +01:00
Hervé Poussineau
402a2b1401 [NTOS:EX] Add prototypes for ExLockUserBuffer/ExUnlockUserBuffer 2025-01-28 17:12:45 +01:00
Hermès Bélusca-Maïto
f416c4f16e [NDK] SYSDBG: Add SysDbgKdPullRemoteFile enum value and structure (Win10 19041+)
From https://github.com/processhacker/phnt/
2025-01-28 17:12:43 +01:00
Hermès Bélusca-Maïto
06bf42d900 [NDK] SYSDBG: Add SysDbgGetLiveKernelDump enum value and structures for kernel live dump.
For more information, see:
https://crashdmp.wordpress.com/2014/08/04/livedump-1-0-is-available/
https://github.com/lilhoser/livedump
https://gary-nebbett.blogspot.com/2016/04/examining-windows-kernel-mode-stacks.html
https://github.com/processhacker/phnt
2025-01-28 17:12:42 +01:00
Hermès Bélusca-Maïto
e2a3da5a13 [NDK] SYSDBG: Add versioning info for Vista+ commands. 2025-01-28 17:12:34 +01:00
12 changed files with 918 additions and 324 deletions

View File

@@ -146,93 +146,257 @@ ExpDebuggerWorker(
}
}
/*++
* @name NtSystemDebugControl
* @implemented
/**
* @brief
* Perform various queries to the kernel debugger.
*
* Perform various queries to debugger.
* This API is subject to test-case creation to further evaluate its
* abilities (if needed to at all)
* @param[in] Command
* A SYSDBG_COMMAND value describing the kernel debugger command to perform.
*
* See: http://www.osronline.com/showthread.cfm?link=93915
* http://void.ru/files/Ntexapi.h
* http://www.codeguru.com/code/legacy/system/ntexapi.zip
* http://www.securityfocus.com/bid/9694
* @param[in] InputBuffer
* Pointer to a user-provided input command-specific buffer, whose length
* is given by InputBufferLength.
*
* @param ControlCode
* Description of the parameter. Wrapped to more lines on ~70th
* column.
* @param[in] InputBufferLength
* The size (in bytes) of the buffer pointed by InputBuffer.
*
* @param InputBuffer
* FILLME
* @param[out] OutputBuffer
* Pointer to a user-provided command-specific output buffer, whose length
* is given by OutputBufferLength.
*
* @param InputBufferLength
* FILLME
* @param[in] OutputBufferLength
* The size (in bytes) of the buffer pointed by OutputBuffer.
*
* @param OutputBuffer
* FILLME
* @param[out] ReturnLength
* Optional pointer to a ULONG variable that receives the actual length of
* data written written in the output buffer. It is always zero, except for
* the live dump commands where an actual non-zero length is returned.
*
* @param OutputBufferLength
* FILLME
* @return
* STATUS_SUCCESS in case of success, or a proper error code otherwise.
*
* @param ReturnLength
* FILLME
* @remarks
*
* @return STATUS_SUCCESS in case of success, proper error code otherwise
* - The caller must have SeDebugPrivilege, otherwise the function fails
* with STATUS_ACCESS_DENIED.
*
* @remarks None
* - Only the live dump commands: SysDbgGetTriageDump, and SysDbgGetLiveKernelDump
* (Win8.1+) are available even if the debugger is disabled or absent.
*
*--*/
* - The following system-critical commands are not accessible anymore
* for user-mode usage with this API on NT 5.2+ (Windows 2003 SP1 and later)
* systems:
*
* SysDbgQueryVersion,
* SysDbgReadVirtual and SysDbgWriteVirtual,
* SysDbgReadPhysical and SysDbgWritePhysical,
* SysDbgReadControlSpace and SysDbgWriteControlSpace,
* SysDbgReadIoSpace and SysDbgWriteIoSpace,
* SysDbgReadMsr and SysDbgWriteMsr,
* SysDbgReadBusData and SysDbgWriteBusData,
* SysDbgCheckLowMemory.
*
* For these, NtSystemDebugControl() will return STATUS_NOT_IMPLEMENTED.
* They are now available from kernel-mode only with KdSystemDebugControl().
*
* @note
* See: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2004-2339
*
* @see KdSystemDebugControl()
**/
NTSTATUS
NTAPI
NtSystemDebugControl(SYSDBG_COMMAND ControlCode,
PVOID InputBuffer,
ULONG InputBufferLength,
PVOID OutputBuffer,
ULONG OutputBufferLength,
PULONG ReturnLength)
NtSystemDebugControl(
_In_ SYSDBG_COMMAND Command,
_In_reads_bytes_(InputBufferLength) PVOID InputBuffer,
_In_ ULONG InputBufferLength,
_Out_writes_bytes_(OutputBufferLength) PVOID OutputBuffer,
_In_ ULONG OutputBufferLength,
_Out_opt_ PULONG ReturnLength)
{
switch (ControlCode)
KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
ULONG Length = 0;
NTSTATUS Status;
/* Debugger controlling requires the debug privilege */
if (!SeSinglePrivilegeCheck(SeDebugPrivilege, PreviousMode))
return STATUS_ACCESS_DENIED;
_SEH2_TRY
{
case SysDbgQueryModuleInformation:
case SysDbgQueryTraceInformation:
case SysDbgSetTracepoint:
case SysDbgSetSpecialCall:
case SysDbgClearSpecialCalls:
case SysDbgQuerySpecialCalls:
case SysDbgQueryVersion:
case SysDbgReadVirtual:
case SysDbgWriteVirtual:
case SysDbgReadPhysical:
case SysDbgWritePhysical:
case SysDbgReadControlSpace:
case SysDbgWriteControlSpace:
case SysDbgReadIoSpace:
case SysDbgWriteIoSpace:
case SysDbgReadMsr:
case SysDbgWriteMsr:
case SysDbgReadBusData:
case SysDbgWriteBusData:
case SysDbgCheckLowMemory:
case SysDbgGetTriageDump:
return STATUS_NOT_IMPLEMENTED;
case SysDbgBreakPoint:
case SysDbgEnableKernelDebugger:
case SysDbgDisableKernelDebugger:
case SysDbgGetAutoKdEnable:
case SysDbgSetAutoKdEnable:
case SysDbgGetPrintBufferSize:
case SysDbgSetPrintBufferSize:
case SysDbgGetKdUmExceptionEnable:
case SysDbgSetKdUmExceptionEnable:
case SysDbgGetKdBlockEnable:
case SysDbgSetKdBlockEnable:
return KdSystemDebugControl(
ControlCode,
InputBuffer, InputBufferLength,
OutputBuffer, OutputBufferLength,
ReturnLength, KeGetPreviousMode());
default:
return STATUS_INVALID_INFO_CLASS;
if (PreviousMode != KernelMode)
{
if (InputBufferLength)
ProbeForRead(InputBuffer, InputBufferLength, sizeof(ULONG));
if (OutputBufferLength)
ProbeForWrite(OutputBuffer, OutputBufferLength, sizeof(ULONG));
if (ReturnLength)
ProbeForWriteUlong(ReturnLength);
}
switch (Command)
{
case SysDbgQueryModuleInformation:
/* Removed in WinNT4 */
Status = STATUS_INVALID_INFO_CLASS;
break;
#ifdef _M_IX86
case SysDbgQueryTraceInformation:
case SysDbgSetTracepoint:
case SysDbgSetSpecialCall:
case SysDbgClearSpecialCalls:
case SysDbgQuerySpecialCalls:
UNIMPLEMENTED;
Status = STATUS_NOT_IMPLEMENTED;
break;
#endif
case SysDbgQueryVersion:
case SysDbgReadVirtual:
case SysDbgWriteVirtual:
case SysDbgReadPhysical:
case SysDbgWritePhysical:
case SysDbgReadControlSpace:
case SysDbgWriteControlSpace:
case SysDbgReadIoSpace:
case SysDbgWriteIoSpace:
case SysDbgReadMsr:
case SysDbgWriteMsr:
case SysDbgReadBusData:
case SysDbgWriteBusData:
case SysDbgCheckLowMemory:
/* Those are implemented in KdSystemDebugControl */
if (InitIsWinPEMode)
{
Status = KdSystemDebugControl(Command,
InputBuffer, InputBufferLength,
OutputBuffer, OutputBufferLength,
&Length, PreviousMode);
}
else
{
Status = STATUS_NOT_IMPLEMENTED;
}
break;
case SysDbgBreakPoint:
if (KdDebuggerEnabled)
{
DbgBreakPointWithStatus(DBG_STATUS_DEBUG_CONTROL);
Status = STATUS_SUCCESS;
}
else
Status = STATUS_UNSUCCESSFUL;
break;
case SysDbgEnableKernelDebugger:
Status = KdEnableDebugger();
break;
case SysDbgDisableKernelDebugger:
Status = KdDisableDebugger();
break;
case SysDbgGetAutoKdEnable:
if (OutputBufferLength != sizeof(BOOLEAN))
Status = STATUS_INFO_LENGTH_MISMATCH;
else
{
*(PBOOLEAN)OutputBuffer = KdAutoEnableOnEvent;
Status = STATUS_SUCCESS;
}
break;
case SysDbgSetAutoKdEnable:
if (InputBufferLength != sizeof(BOOLEAN))
Status = STATUS_INFO_LENGTH_MISMATCH;
else if (KdPitchDebugger)
Status = STATUS_ACCESS_DENIED;
else
{
KdAutoEnableOnEvent = *(PBOOLEAN)InputBuffer;
Status = STATUS_SUCCESS;
}
break;
case SysDbgGetPrintBufferSize:
if (OutputBufferLength != sizeof(ULONG))
Status = STATUS_INFO_LENGTH_MISMATCH;
else
{
/* Return buffer size only if KD is enabled */
*(PULONG)OutputBuffer = KdPitchDebugger ? 0 : KdPrintBufferSize;
Status = STATUS_SUCCESS;
}
break;
case SysDbgSetPrintBufferSize:
UNIMPLEMENTED;
Status = STATUS_NOT_IMPLEMENTED;
break;
case SysDbgGetKdUmExceptionEnable:
if (OutputBufferLength != sizeof(BOOLEAN))
Status = STATUS_INFO_LENGTH_MISMATCH;
else
{
/* Unfortunately, the internal flag says if UM exceptions are disabled */
*(PBOOLEAN)OutputBuffer = !KdIgnoreUmExceptions;
Status = STATUS_SUCCESS;
}
break;
case SysDbgSetKdUmExceptionEnable:
if (InputBufferLength != sizeof(BOOLEAN))
Status = STATUS_INFO_LENGTH_MISMATCH;
else if (KdPitchDebugger)
Status = STATUS_ACCESS_DENIED;
else
{
/* Unfortunately, the internal flag says if UM exceptions are disabled */
KdIgnoreUmExceptions = !*(PBOOLEAN)InputBuffer;
Status = STATUS_SUCCESS;
}
break;
case SysDbgGetTriageDump:
UNIMPLEMENTED;
Status = STATUS_NOT_IMPLEMENTED;
break;
case SysDbgGetKdBlockEnable:
if (OutputBufferLength != sizeof(BOOLEAN))
Status = STATUS_INFO_LENGTH_MISMATCH;
else
{
*(PBOOLEAN)OutputBuffer = KdBlockEnable;
Status = STATUS_SUCCESS;
}
break;
case SysDbgSetKdBlockEnable:
Status = KdChangeOption(KD_OPTION_SET_BLOCK_ENABLE,
InputBufferLength,
InputBuffer,
OutputBufferLength,
OutputBuffer,
&Length);
break;
default:
Status = STATUS_INVALID_INFO_CLASS;
break;
}
if (ReturnLength)
*ReturnLength = Length;
_SEH2_YIELD(return Status);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
_SEH2_YIELD(return _SEH2_GetExceptionCode());
}
_SEH2_END;
}

View File

@@ -208,7 +208,7 @@ ExLockUserBuffer(
PMDL *OutMdl)
{
PMDL Mdl;
PAGED_CODE();
ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
*MappedSystemVa = NULL;
*OutMdl = NULL;

View File

@@ -1510,6 +1510,20 @@ ExTimerRundown(
VOID
);
VOID
NTAPI
ExUnlockUserBuffer(PMDL Mdl);
NTSTATUS
NTAPI
ExLockUserBuffer(
PVOID BaseAddress,
ULONG Length,
KPROCESSOR_MODE AccessMode,
LOCK_OPERATION Operation,
PVOID *MappedSystemVa,
PMDL *OutMdl);
CODE_SEG("INIT")
VOID
NTAPI

View File

@@ -375,8 +375,7 @@ KdpZeroMemory(
VOID
NTAPI
KdpSysGetVersion(
IN PDBGKD_GET_VERSION64 Version
);
_Out_ PDBGKD_GET_VERSION64 Version);
//
// Context
@@ -401,16 +400,14 @@ KdpSetContextState(
NTSTATUS
NTAPI
KdpSysReadMsr(
IN ULONG Msr,
OUT PLARGE_INTEGER MsrValue
);
_In_ ULONG Msr,
_Out_ PULONGLONG MsrValue);
NTSTATUS
NTAPI
KdpSysWriteMsr(
IN ULONG Msr,
IN PLARGE_INTEGER MsrValue
);
_In_ ULONG Msr,
_In_ PULONGLONG MsrValue);
//
// Bus
@@ -418,26 +415,24 @@ KdpSysWriteMsr(
NTSTATUS
NTAPI
KdpSysReadBusData(
IN ULONG BusDataType,
IN ULONG BusNumber,
IN ULONG SlotNumber,
IN ULONG Offset,
IN PVOID Buffer,
IN ULONG Length,
OUT PULONG ActualLength
);
_In_ BUS_DATA_TYPE BusDataType,
_In_ ULONG BusNumber,
_In_ ULONG SlotNumber,
_In_ ULONG Offset,
_Out_writes_bytes_(Length) PVOID Buffer,
_In_ ULONG Length,
_Out_ PULONG ActualLength);
NTSTATUS
NTAPI
KdpSysWriteBusData(
IN ULONG BusDataType,
IN ULONG BusNumber,
IN ULONG SlotNumber,
IN ULONG Offset,
IN PVOID Buffer,
IN ULONG Length,
OUT PULONG ActualLength
);
_In_ BUS_DATA_TYPE BusDataType,
_In_ ULONG BusNumber,
_In_ ULONG SlotNumber,
_In_ ULONG Offset,
_In_reads_bytes_(Length) PVOID Buffer,
_In_ ULONG Length,
_Out_ PULONG ActualLength);
//
// Control Space
@@ -445,22 +440,20 @@ KdpSysWriteBusData(
NTSTATUS
NTAPI
KdpSysReadControlSpace(
IN ULONG Processor,
IN ULONG64 BaseAddress,
IN PVOID Buffer,
IN ULONG Length,
OUT PULONG ActualLength
);
_In_ ULONG Processor,
_In_ ULONG64 BaseAddress,
_Out_writes_bytes_(Length) PVOID Buffer,
_In_ ULONG Length,
_Out_ PULONG ActualLength);
NTSTATUS
NTAPI
KdpSysWriteControlSpace(
IN ULONG Processor,
IN ULONG64 BaseAddress,
IN PVOID Buffer,
IN ULONG Length,
OUT PULONG ActualLength
);
_In_ ULONG Processor,
_In_ ULONG64 BaseAddress,
_In_reads_bytes_(Length) PVOID Buffer,
_In_ ULONG Length,
_Out_ PULONG ActualLength);
//
// I/O Space
@@ -468,26 +461,24 @@ KdpSysWriteControlSpace(
NTSTATUS
NTAPI
KdpSysReadIoSpace(
IN ULONG InterfaceType,
IN ULONG BusNumber,
IN ULONG AddressSpace,
IN ULONG64 IoAddress,
IN PVOID DataValue,
IN ULONG DataSize,
OUT PULONG ActualDataSize
);
_In_ INTERFACE_TYPE InterfaceType,
_In_ ULONG BusNumber,
_In_ ULONG AddressSpace,
_In_ ULONG64 IoAddress,
_Out_writes_bytes_(DataSize) PVOID DataValue,
_In_ ULONG DataSize,
_Out_ PULONG ActualDataSize);
NTSTATUS
NTAPI
KdpSysWriteIoSpace(
IN ULONG InterfaceType,
IN ULONG BusNumber,
IN ULONG AddressSpace,
IN ULONG64 IoAddress,
IN PVOID DataValue,
IN ULONG DataSize,
OUT PULONG ActualDataSize
);
_In_ INTERFACE_TYPE InterfaceType,
_In_ ULONG BusNumber,
_In_ ULONG AddressSpace,
_In_ ULONG64 IoAddress,
_In_reads_bytes_(DataSize) PVOID DataValue,
_In_ ULONG DataSize,
_Out_ PULONG ActualDataSize);
//
// Low Memory

View File

@@ -93,13 +93,14 @@ KdpSetContextState(IN PDBGKD_ANY_WAIT_STATE_CHANGE WaitStateChange,
NTSTATUS
NTAPI
KdpSysReadMsr(IN ULONG Msr,
OUT PLARGE_INTEGER MsrValue)
KdpSysReadMsr(
_In_ ULONG Msr,
_Out_ PULONGLONG MsrValue)
{
/* Use SEH to protect from invalid MSRs */
_SEH2_TRY
{
MsrValue->QuadPart = __readmsr(Msr);
*MsrValue = __readmsr(Msr);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
@@ -112,13 +113,14 @@ KdpSysReadMsr(IN ULONG Msr,
NTSTATUS
NTAPI
KdpSysWriteMsr(IN ULONG Msr,
IN PLARGE_INTEGER MsrValue)
KdpSysWriteMsr(
_In_ ULONG Msr,
_In_ PULONGLONG MsrValue)
{
/* Use SEH to protect from invalid MSRs */
_SEH2_TRY
{
__writemsr(Msr, MsrValue->QuadPart);
__writemsr(Msr, *MsrValue);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
@@ -131,13 +133,14 @@ KdpSysWriteMsr(IN ULONG Msr,
NTSTATUS
NTAPI
KdpSysReadBusData(IN ULONG BusDataType,
IN ULONG BusNumber,
IN ULONG SlotNumber,
IN ULONG Offset,
IN PVOID Buffer,
IN ULONG Length,
OUT PULONG ActualLength)
KdpSysReadBusData(
_In_ BUS_DATA_TYPE BusDataType,
_In_ ULONG BusNumber,
_In_ ULONG SlotNumber,
_In_ ULONG Offset,
_Out_writes_bytes_(Length) PVOID Buffer,
_In_ ULONG Length,
_Out_ PULONG ActualLength)
{
UNIMPLEMENTED;
return STATUS_UNSUCCESSFUL;
@@ -145,13 +148,14 @@ KdpSysReadBusData(IN ULONG BusDataType,
NTSTATUS
NTAPI
KdpSysWriteBusData(IN ULONG BusDataType,
IN ULONG BusNumber,
IN ULONG SlotNumber,
IN ULONG Offset,
IN PVOID Buffer,
IN ULONG Length,
OUT PULONG ActualLength)
KdpSysWriteBusData(
_In_ BUS_DATA_TYPE BusDataType,
_In_ ULONG BusNumber,
_In_ ULONG SlotNumber,
_In_ ULONG Offset,
_In_reads_bytes_(Length) PVOID Buffer,
_In_ ULONG Length,
_Out_ PULONG ActualLength)
{
UNIMPLEMENTED;
return STATUS_UNSUCCESSFUL;
@@ -159,11 +163,12 @@ KdpSysWriteBusData(IN ULONG BusDataType,
NTSTATUS
NTAPI
KdpSysReadControlSpace(IN ULONG Processor,
IN ULONG64 BaseAddress,
IN PVOID Buffer,
IN ULONG Length,
OUT PULONG ActualLength)
KdpSysReadControlSpace(
_In_ ULONG Processor,
_In_ ULONG64 BaseAddress,
_Out_writes_bytes_(Length) PVOID Buffer,
_In_ ULONG Length,
_Out_ PULONG ActualLength)
{
PVOID ControlStart;
PKPRCB Prcb = KiProcessorBlock[Processor];
@@ -210,11 +215,12 @@ KdpSysReadControlSpace(IN ULONG Processor,
NTSTATUS
NTAPI
KdpSysWriteControlSpace(IN ULONG Processor,
IN ULONG64 BaseAddress,
IN PVOID Buffer,
IN ULONG Length,
OUT PULONG ActualLength)
KdpSysWriteControlSpace(
_In_ ULONG Processor,
_In_ ULONG64 BaseAddress,
_In_reads_bytes_(Length) PVOID Buffer,
_In_ ULONG Length,
_Out_ PULONG ActualLength)
{
PVOID ControlStart;
PKPRCB Prcb = KiProcessorBlock[Processor];
@@ -241,13 +247,14 @@ KdpSysWriteControlSpace(IN ULONG Processor,
NTSTATUS
NTAPI
KdpSysReadIoSpace(IN ULONG InterfaceType,
IN ULONG BusNumber,
IN ULONG AddressSpace,
IN ULONG64 IoAddress,
OUT PVOID DataValue,
IN ULONG DataSize,
OUT PULONG ActualDataSize)
KdpSysReadIoSpace(
_In_ INTERFACE_TYPE InterfaceType,
_In_ ULONG BusNumber,
_In_ ULONG AddressSpace,
_In_ ULONG64 IoAddress,
_Out_writes_bytes_(DataSize) PVOID DataValue,
_In_ ULONG DataSize,
_Out_ PULONG ActualDataSize)
{
/* Verify parameters */
if (InterfaceType != Isa || BusNumber != 0 || AddressSpace != 1)
@@ -297,13 +304,14 @@ KdpSysReadIoSpace(IN ULONG InterfaceType,
NTSTATUS
NTAPI
KdpSysWriteIoSpace(IN ULONG InterfaceType,
IN ULONG BusNumber,
IN ULONG AddressSpace,
IN ULONG64 IoAddress,
IN PVOID DataValue,
IN ULONG DataSize,
OUT PULONG ActualDataSize)
KdpSysWriteIoSpace(
_In_ INTERFACE_TYPE InterfaceType,
_In_ ULONG BusNumber,
_In_ ULONG AddressSpace,
_In_ ULONG64 IoAddress,
_In_reads_bytes_(DataSize) PVOID DataValue,
_In_ ULONG DataSize,
_Out_ PULONG ActualDataSize)
{
/* Verify parameters */
if (InterfaceType != Isa || BusNumber != 0 || AddressSpace != 1)

View File

@@ -35,8 +35,9 @@ KdpSetContextState(IN PDBGKD_ANY_WAIT_STATE_CHANGE WaitStateChange,
NTSTATUS
NTAPI
KdpSysReadMsr(IN ULONG Msr,
OUT PLARGE_INTEGER MsrValue)
KdpSysReadMsr(
_In_ ULONG Msr,
_Out_ PULONGLONG MsrValue)
{
UNIMPLEMENTED;
return STATUS_UNSUCCESSFUL;
@@ -44,8 +45,9 @@ KdpSysReadMsr(IN ULONG Msr,
NTSTATUS
NTAPI
KdpSysWriteMsr(IN ULONG Msr,
IN PLARGE_INTEGER MsrValue)
KdpSysWriteMsr(
_In_ ULONG Msr,
_In_ PULONGLONG MsrValue)
{
UNIMPLEMENTED;
return STATUS_UNSUCCESSFUL;
@@ -53,13 +55,14 @@ KdpSysWriteMsr(IN ULONG Msr,
NTSTATUS
NTAPI
KdpSysReadBusData(IN ULONG BusDataType,
IN ULONG BusNumber,
IN ULONG SlotNumber,
IN ULONG Offset,
IN PVOID Buffer,
IN ULONG Length,
OUT PULONG ActualLength)
KdpSysReadBusData(
_In_ BUS_DATA_TYPE BusDataType,
_In_ ULONG BusNumber,
_In_ ULONG SlotNumber,
_In_ ULONG Offset,
_Out_writes_bytes_(Length) PVOID Buffer,
_In_ ULONG Length,
_Out_ PULONG ActualLength)
{
UNIMPLEMENTED;
return STATUS_UNSUCCESSFUL;
@@ -67,13 +70,14 @@ KdpSysReadBusData(IN ULONG BusDataType,
NTSTATUS
NTAPI
KdpSysWriteBusData(IN ULONG BusDataType,
IN ULONG BusNumber,
IN ULONG SlotNumber,
IN ULONG Offset,
IN PVOID Buffer,
IN ULONG Length,
OUT PULONG ActualLength)
KdpSysWriteBusData(
_In_ BUS_DATA_TYPE BusDataType,
_In_ ULONG BusNumber,
_In_ ULONG SlotNumber,
_In_ ULONG Offset,
_In_reads_bytes_(Length) PVOID Buffer,
_In_ ULONG Length,
_Out_ PULONG ActualLength)
{
UNIMPLEMENTED;
return STATUS_UNSUCCESSFUL;
@@ -81,11 +85,12 @@ KdpSysWriteBusData(IN ULONG BusDataType,
NTSTATUS
NTAPI
KdpSysReadControlSpace(IN ULONG Processor,
IN ULONG64 BaseAddress,
IN PVOID Buffer,
IN ULONG Length,
OUT PULONG ActualLength)
KdpSysReadControlSpace(
_In_ ULONG Processor,
_In_ ULONG64 BaseAddress,
_Out_writes_bytes_(Length) PVOID Buffer,
_In_ ULONG Length,
_Out_ PULONG ActualLength)
{
UNIMPLEMENTED;
return STATUS_UNSUCCESSFUL;
@@ -93,11 +98,12 @@ KdpSysReadControlSpace(IN ULONG Processor,
NTSTATUS
NTAPI
KdpSysWriteControlSpace(IN ULONG Processor,
IN ULONG64 BaseAddress,
IN PVOID Buffer,
IN ULONG Length,
OUT PULONG ActualLength)
KdpSysWriteControlSpace(
_In_ ULONG Processor,
_In_ ULONG64 BaseAddress,
_In_reads_bytes_(Length) PVOID Buffer,
_In_ ULONG Length,
_Out_ PULONG ActualLength)
{
UNIMPLEMENTED;
return STATUS_UNSUCCESSFUL;
@@ -105,13 +111,14 @@ KdpSysWriteControlSpace(IN ULONG Processor,
NTSTATUS
NTAPI
KdpSysReadIoSpace(IN ULONG InterfaceType,
IN ULONG BusNumber,
IN ULONG AddressSpace,
IN ULONG64 IoAddress,
IN PVOID DataValue,
IN ULONG DataSize,
OUT PULONG ActualDataSize)
KdpSysReadIoSpace(
_In_ INTERFACE_TYPE InterfaceType,
_In_ ULONG BusNumber,
_In_ ULONG AddressSpace,
_In_ ULONG64 IoAddress,
_Out_writes_bytes_(DataSize) PVOID DataValue,
_In_ ULONG DataSize,
_Out_ PULONG ActualDataSize)
{
UNIMPLEMENTED;
return STATUS_UNSUCCESSFUL;
@@ -119,13 +126,14 @@ KdpSysReadIoSpace(IN ULONG InterfaceType,
NTSTATUS
NTAPI
KdpSysWriteIoSpace(IN ULONG InterfaceType,
IN ULONG BusNumber,
IN ULONG AddressSpace,
IN ULONG64 IoAddress,
IN PVOID DataValue,
IN ULONG DataSize,
OUT PULONG ActualDataSize)
KdpSysWriteIoSpace(
_In_ INTERFACE_TYPE InterfaceType,
_In_ ULONG BusNumber,
_In_ ULONG AddressSpace,
_In_ ULONG64 IoAddress,
_In_reads_bytes_(DataSize) PVOID DataValue,
_In_ ULONG DataSize,
_Out_ PULONG ActualDataSize)
{
UNIMPLEMENTED;
return STATUS_UNSUCCESSFUL;

View File

@@ -91,57 +91,54 @@ KdpSetContextState(IN PDBGKD_ANY_WAIT_STATE_CHANGE WaitStateChange,
NTSTATUS
NTAPI
KdpSysReadMsr(IN ULONG Msr,
OUT PLARGE_INTEGER MsrValue)
KdpSysReadMsr(
_In_ ULONG Msr,
_Out_ PULONGLONG MsrValue)
{
/* Wrap this in SEH in case the MSR doesn't exist */
/* Use SEH to protect from invalid MSRs */
_SEH2_TRY
{
/* Read from the MSR */
MsrValue->QuadPart = __readmsr(Msr);
*MsrValue = __readmsr(Msr);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
/* Invalid MSR */
_SEH2_YIELD(return STATUS_NO_SUCH_DEVICE);
}
_SEH2_END;
/* Success */
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
KdpSysWriteMsr(IN ULONG Msr,
IN PLARGE_INTEGER MsrValue)
KdpSysWriteMsr(
_In_ ULONG Msr,
_In_ PULONGLONG MsrValue)
{
/* Wrap this in SEH in case the MSR doesn't exist */
/* Use SEH to protect from invalid MSRs */
_SEH2_TRY
{
/* Write to the MSR */
__writemsr(Msr, MsrValue->QuadPart);
__writemsr(Msr, *MsrValue);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
/* Invalid MSR */
_SEH2_YIELD(return STATUS_NO_SUCH_DEVICE);
}
_SEH2_END;
/* Success */
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
KdpSysReadBusData(IN ULONG BusDataType,
IN ULONG BusNumber,
IN ULONG SlotNumber,
IN ULONG Offset,
IN PVOID Buffer,
IN ULONG Length,
OUT PULONG ActualLength)
KdpSysReadBusData(
_In_ BUS_DATA_TYPE BusDataType,
_In_ ULONG BusNumber,
_In_ ULONG SlotNumber,
_In_ ULONG Offset,
_Out_writes_bytes_(Length) PVOID Buffer,
_In_ ULONG Length,
_Out_ PULONG ActualLength)
{
/* Just forward to HAL */
*ActualLength = HalGetBusDataByOffset(BusDataType,
@@ -152,18 +149,19 @@ KdpSysReadBusData(IN ULONG BusDataType,
Length);
/* Return status */
return *ActualLength != 0 ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
return (*ActualLength != 0 ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL);
}
NTSTATUS
NTAPI
KdpSysWriteBusData(IN ULONG BusDataType,
IN ULONG BusNumber,
IN ULONG SlotNumber,
IN ULONG Offset,
IN PVOID Buffer,
IN ULONG Length,
OUT PULONG ActualLength)
KdpSysWriteBusData(
_In_ BUS_DATA_TYPE BusDataType,
_In_ ULONG BusNumber,
_In_ ULONG SlotNumber,
_In_ ULONG Offset,
_In_reads_bytes_(Length) PVOID Buffer,
_In_ ULONG Length,
_Out_ PULONG ActualLength)
{
/* Just forward to HAL */
*ActualLength = HalSetBusDataByOffset(BusDataType,
@@ -174,16 +172,17 @@ KdpSysWriteBusData(IN ULONG BusDataType,
Length);
/* Return status */
return *ActualLength != 0 ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
return (*ActualLength != 0 ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL);
}
NTSTATUS
NTAPI
KdpSysReadControlSpace(IN ULONG Processor,
IN ULONG64 BaseAddress,
IN PVOID Buffer,
IN ULONG Length,
OUT PULONG ActualLength)
KdpSysReadControlSpace(
_In_ ULONG Processor,
_In_ ULONG64 BaseAddress,
_Out_writes_bytes_(Length) PVOID Buffer,
_In_ ULONG Length,
_Out_ PULONG ActualLength)
{
PVOID ControlStart;
ULONG RealLength;
@@ -219,11 +218,12 @@ KdpSysReadControlSpace(IN ULONG Processor,
NTSTATUS
NTAPI
KdpSysWriteControlSpace(IN ULONG Processor,
IN ULONG64 BaseAddress,
IN PVOID Buffer,
IN ULONG Length,
OUT PULONG ActualLength)
KdpSysWriteControlSpace(
_In_ ULONG Processor,
_In_ ULONG64 BaseAddress,
_In_reads_bytes_(Length) PVOID Buffer,
_In_ ULONG Length,
_Out_ PULONG ActualLength)
{
PVOID ControlStart;
@@ -254,20 +254,19 @@ KdpSysWriteControlSpace(IN ULONG Processor,
NTSTATUS
NTAPI
KdpSysReadIoSpace(IN ULONG InterfaceType,
IN ULONG BusNumber,
IN ULONG AddressSpace,
IN ULONG64 IoAddress,
IN PVOID DataValue,
IN ULONG DataSize,
OUT PULONG ActualDataSize)
KdpSysReadIoSpace(
_In_ INTERFACE_TYPE InterfaceType,
_In_ ULONG BusNumber,
_In_ ULONG AddressSpace,
_In_ ULONG64 IoAddress,
_Out_writes_bytes_(DataSize) PVOID DataValue,
_In_ ULONG DataSize,
_Out_ PULONG ActualDataSize)
{
NTSTATUS Status;
/* Verify parameters */
if ((InterfaceType != Isa) ||
(BusNumber != 0) ||
(AddressSpace != 1))
if ((InterfaceType != Isa) || (BusNumber != 0) || (AddressSpace != 1))
{
/* Fail, we don't support this */
*ActualDataSize = 0;
@@ -278,16 +277,17 @@ KdpSysReadIoSpace(IN ULONG InterfaceType,
switch (DataSize)
{
case sizeof(UCHAR):
{
/* Read 1 byte */
*(PUCHAR)DataValue =
READ_PORT_UCHAR((PUCHAR)(ULONG_PTR)IoAddress);
*ActualDataSize = sizeof(UCHAR);
Status = STATUS_SUCCESS;
break;
}
case sizeof(USHORT):
{
/* Make sure the address is aligned */
if ((IoAddress & (sizeof(USHORT) - 1)) != 0)
{
@@ -303,9 +303,10 @@ KdpSysReadIoSpace(IN ULONG InterfaceType,
*ActualDataSize = sizeof(USHORT);
Status = STATUS_SUCCESS;
break;
}
case sizeof(ULONG):
{
/* Make sure the address is aligned */
if ((IoAddress & (sizeof(ULONG) - 1)) != 0)
{
@@ -321,9 +322,9 @@ KdpSysReadIoSpace(IN ULONG InterfaceType,
*ActualDataSize = sizeof(ULONG);
Status = STATUS_SUCCESS;
break;
}
default:
/* Invalid size, fail */
*ActualDataSize = 0;
Status = STATUS_INVALID_PARAMETER;
@@ -335,20 +336,19 @@ KdpSysReadIoSpace(IN ULONG InterfaceType,
NTSTATUS
NTAPI
KdpSysWriteIoSpace(IN ULONG InterfaceType,
IN ULONG BusNumber,
IN ULONG AddressSpace,
IN ULONG64 IoAddress,
IN PVOID DataValue,
IN ULONG DataSize,
OUT PULONG ActualDataSize)
KdpSysWriteIoSpace(
_In_ INTERFACE_TYPE InterfaceType,
_In_ ULONG BusNumber,
_In_ ULONG AddressSpace,
_In_ ULONG64 IoAddress,
_In_reads_bytes_(DataSize) PVOID DataValue,
_In_ ULONG DataSize,
_Out_ PULONG ActualDataSize)
{
NTSTATUS Status;
/* Verify parameters */
if ((InterfaceType != Isa) ||
(BusNumber != 0) ||
(AddressSpace != 1))
if ((InterfaceType != Isa) || (BusNumber != 0) || (AddressSpace != 1))
{
/* Fail, we don't support this */
*ActualDataSize = 0;
@@ -359,16 +359,17 @@ KdpSysWriteIoSpace(IN ULONG InterfaceType,
switch (DataSize)
{
case sizeof(UCHAR):
{
/* Write 1 byte */
WRITE_PORT_UCHAR((PUCHAR)(ULONG_PTR)IoAddress,
*(PUCHAR)DataValue);
*ActualDataSize = sizeof(UCHAR);
Status = STATUS_SUCCESS;
break;
}
case sizeof(USHORT):
{
/* Make sure the address is aligned */
if ((IoAddress & (sizeof(USHORT) - 1)) != 0)
{
@@ -384,9 +385,10 @@ KdpSysWriteIoSpace(IN ULONG InterfaceType,
*ActualDataSize = sizeof(USHORT);
Status = STATUS_SUCCESS;
break;
}
case sizeof(ULONG):
{
/* Make sure the address is aligned */
if ((IoAddress & (sizeof(ULONG) - 1)) != 0)
{
@@ -402,9 +404,9 @@ KdpSysWriteIoSpace(IN ULONG InterfaceType,
*ActualDataSize = sizeof(ULONG);
Status = STATUS_SUCCESS;
break;
}
default:
/* Invalid size, fail */
*ActualDataSize = 0;
Status = STATUS_INVALID_PARAMETER;

View File

@@ -430,7 +430,8 @@ KdpSetCommonState(IN ULONG NewState,
VOID
NTAPI
KdpSysGetVersion(IN PDBGKD_GET_VERSION64 Version)
KdpSysGetVersion(
_Out_ PDBGKD_GET_VERSION64 Version)
{
/* Copy the version block */
KdpMoveMemory(Version,
@@ -960,7 +961,7 @@ KdpReadMachineSpecificRegister(IN PDBGKD_MANIPULATE_STATE64 State,
{
STRING Header;
PDBGKD_READ_WRITE_MSR ReadMsr = &State->u.ReadWriteMsr;
LARGE_INTEGER MsrValue;
ULARGE_INTEGER MsrValue;
/* Setup the header */
Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
@@ -968,8 +969,7 @@ KdpReadMachineSpecificRegister(IN PDBGKD_MANIPULATE_STATE64 State,
ASSERT(Data->Length == 0);
/* Call the internal routine */
State->ReturnStatus = KdpSysReadMsr(ReadMsr->Msr,
&MsrValue);
State->ReturnStatus = KdpSysReadMsr(ReadMsr->Msr, &MsrValue.QuadPart);
/* Return the data */
ReadMsr->DataValueLow = MsrValue.LowPart;
@@ -990,7 +990,7 @@ KdpWriteMachineSpecificRegister(IN PDBGKD_MANIPULATE_STATE64 State,
{
STRING Header;
PDBGKD_READ_WRITE_MSR WriteMsr = &State->u.ReadWriteMsr;
LARGE_INTEGER MsrValue;
ULARGE_INTEGER MsrValue;
/* Setup the header */
Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
@@ -1000,8 +1000,7 @@ KdpWriteMachineSpecificRegister(IN PDBGKD_MANIPULATE_STATE64 State,
/* Call the internal routine */
MsrValue.LowPart = WriteMsr->DataValueLow;
MsrValue.HighPart = WriteMsr->DataValueHigh;
State->ReturnStatus = KdpSysWriteMsr(WriteMsr->Msr,
&MsrValue);
State->ReturnStatus = KdpSysWriteMsr(WriteMsr->Msr, &MsrValue.QuadPart);
/* Send the reply */
KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
@@ -1061,7 +1060,6 @@ KdpSetBusData(IN PDBGKD_MANIPULATE_STATE64 State,
{
STRING Header;
PDBGKD_GET_SET_BUS_DATA SetBusData = &State->u.GetSetBusData;
ULONG Length;
/* Setup the header */
Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
@@ -1074,10 +1072,7 @@ KdpSetBusData(IN PDBGKD_MANIPULATE_STATE64 State,
SetBusData->Offset,
Data->Buffer,
SetBusData->Length,
&Length);
/* Return the actual length written */
SetBusData->Length = Length;
&SetBusData->Length);
/* Send the reply */
KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
@@ -1925,7 +1920,7 @@ KdEnterDebugger(IN PKTRAP_FRAME TrapFrame,
/* Freeze all CPUs, raising also the IRQL to HIGH_LEVEL */
Enable = KeFreezeExecution(TrapFrame, ExceptionFrame);
/* Lock the port, save the state and set debugger entered */
/* Lock the port, save its state and set the debugger entered flag */
KdpPortLocked = KeTryToAcquireSpinLockAtDpcLevel(&KdpDebuggerLock);
KdSave(FALSE);
KdEnteredDebugger = TRUE;
@@ -1957,7 +1952,8 @@ KdExitDebugger(IN BOOLEAN Enable)
{
ULONG TimeSlip;
/* Restore the state and unlock the port */
/* Reset the debugger entered flag, restore the port state and unlock it */
KdEnteredDebugger = FALSE;
KdRestore(FALSE);
if (KdpPortLocked) KdpPortUnlock();
@@ -2176,20 +2172,60 @@ KdDisableDebugger(VOID)
return KdDisableDebuggerWithLock(TRUE);
}
/*
* @unimplemented
*/
/**
* @brief
* Perform various queries to the kernel debugger.
*
* @param[in] Command
* A SYSDBG_COMMAND value describing the kernel debugger command to perform.
*
* @param[in] InputBuffer
* Pointer to a user-provided input command-specific buffer, whose length
* is given by InputBufferLength.
*
* @param[in] InputBufferLength
* The size (in bytes) of the buffer pointed by InputBuffer.
*
* @param[out] OutputBuffer
* Pointer to a user-provided command-specific output buffer, whose length
* is given by OutputBufferLength.
*
* @param[in] OutputBufferLength
* The size (in bytes) of the buffer pointed by OutputBuffer.
*
* @param[out] ReturnLength
* Optional pointer to a ULONG variable that receives the actual length of
* data written written in the output buffer. It is always zero, except for
* the live dump commands where an actual non-zero length is returned.
*
* @param[in] PreviousMode
* FILLME
*
* @return
* STATUS_SUCCESS in case of success, or a proper error code otherwise.
*
* @remarks
* - This is a kernel-mode function, accessible only by kernel-mode drivers.
*
* @note
* See: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2004-2339
*
* @see NtSystemDebugControl()
**/
NTSTATUS
NTAPI
KdSystemDebugControl(
_In_ SYSDBG_COMMAND Command,
_In_ PVOID InputBuffer,
_In_reads_bytes_(InputBufferLength) PVOID InputBuffer,
_In_ ULONG InputBufferLength,
_Out_ PVOID OutputBuffer,
_Out_writes_bytes_(OutputBufferLength) PVOID OutputBuffer,
_In_ ULONG OutputBufferLength,
_Inout_ PULONG ReturnLength,
_Out_opt_ PULONG ReturnLength,
_In_ KPROCESSOR_MODE PreviousMode)
{
NTSTATUS Status;
ULONG Length = 0;
/* Handle some internal commands */
switch ((ULONG)Command)
{
@@ -2253,9 +2289,279 @@ KdSystemDebugControl(
break;
}
/* Local kernel debugging is not yet supported */
DbgPrint("KdSystemDebugControl is unimplemented!\n");
return STATUS_NOT_IMPLEMENTED;
switch (Command)
{
case SysDbgQueryVersion:
if (OutputBufferLength != sizeof(DBGKD_GET_VERSION64))
Status = STATUS_INFO_LENGTH_MISMATCH;
else
{
KdpSysGetVersion((PDBGKD_GET_VERSION64)OutputBuffer);
Status = STATUS_SUCCESS;
}
break;
case SysDbgReadVirtual:
case SysDbgWriteVirtual:
if (InputBufferLength != sizeof(SYSDBG_VIRTUAL))
Status = STATUS_INFO_LENGTH_MISMATCH;
else
{
SYSDBG_VIRTUAL Request = *(PSYSDBG_VIRTUAL)InputBuffer;
PVOID LockedBuffer;
PMDL LockVariable;
Status = ExLockUserBuffer(Request.Buffer,
Request.Request,
PreviousMode,
Command == SysDbgReadVirtual ? IoWriteAccess : IoReadAccess,
&LockedBuffer,
&LockVariable);
if (NT_SUCCESS(Status))
{
Status = KdpCopyMemoryChunks((ULONG64)(ULONG_PTR)Request.Address,
Request.Buffer,
Request.Request,
0,
Command == SysDbgReadVirtual ? 0 : MMDBG_COPY_WRITE,
&Length);
ExUnlockUserBuffer(LockVariable);
}
}
break;
case SysDbgReadPhysical:
case SysDbgWritePhysical:
if (InputBufferLength != sizeof(SYSDBG_PHYSICAL))
Status = STATUS_INFO_LENGTH_MISMATCH;
else
{
SYSDBG_PHYSICAL Request = *(PSYSDBG_PHYSICAL)InputBuffer;
PVOID LockedBuffer;
PMDL LockVariable;
Status = ExLockUserBuffer(Request.Buffer,
Request.Request,
PreviousMode,
Command == SysDbgReadVirtual ? IoWriteAccess : IoReadAccess,
&LockedBuffer,
&LockVariable);
if (NT_SUCCESS(Status))
{
Status = KdpCopyMemoryChunks(Request.Address.QuadPart,
Request.Buffer,
Request.Request,
0,
MMDBG_COPY_PHYSICAL | (Command == SysDbgReadVirtual ? 0 : MMDBG_COPY_WRITE),
&Length);
ExUnlockUserBuffer(LockVariable);
}
}
break;
case SysDbgReadControlSpace:
if (InputBufferLength != sizeof(SYSDBG_CONTROL_SPACE))
Status = STATUS_INFO_LENGTH_MISMATCH;
else
{
SYSDBG_CONTROL_SPACE Request = *(PSYSDBG_CONTROL_SPACE)InputBuffer;
PVOID LockedBuffer;
PMDL LockVariable;
Status = ExLockUserBuffer(Request.Buffer,
Request.Request,
PreviousMode,
IoWriteAccess,
&LockedBuffer,
&LockVariable);
if (NT_SUCCESS(Status))
{
Status = KdpSysReadControlSpace(Request.Processor,
Request.Address,
LockedBuffer,
Request.Request,
&Length);
ExUnlockUserBuffer(LockVariable);
}
}
break;
case SysDbgWriteControlSpace:
if (InputBufferLength != sizeof(SYSDBG_CONTROL_SPACE))
Status = STATUS_INFO_LENGTH_MISMATCH;
else
{
SYSDBG_CONTROL_SPACE Request = *(PSYSDBG_CONTROL_SPACE)InputBuffer;
PVOID LockedBuffer;
PMDL LockVariable;
Status = ExLockUserBuffer(Request.Buffer,
Request.Request,
PreviousMode,
IoReadAccess,
&LockedBuffer,
&LockVariable);
if (NT_SUCCESS(Status))
{
Status = KdpSysWriteControlSpace(Request.Processor,
Request.Address,
LockedBuffer,
Request.Request,
&Length);
ExUnlockUserBuffer(LockVariable);
}
}
break;
case SysDbgReadIoSpace:
if (InputBufferLength != sizeof(SYSDBG_IO_SPACE))
Status = STATUS_INFO_LENGTH_MISMATCH;
else
{
SYSDBG_IO_SPACE Request = *(PSYSDBG_IO_SPACE)InputBuffer;
PVOID LockedBuffer;
PMDL LockVariable;
Status = ExLockUserBuffer(Request.Buffer,
Request.Request,
PreviousMode,
IoWriteAccess,
&LockedBuffer,
&LockVariable);
if (NT_SUCCESS(Status))
{
Status = KdpSysReadIoSpace(Request.InterfaceType,
Request.BusNumber,
Request.AddressSpace,
Request.Address,
LockedBuffer,
Request.Request,
&Length);
ExUnlockUserBuffer(LockVariable);
}
}
break;
case SysDbgWriteIoSpace:
if (InputBufferLength != sizeof(SYSDBG_IO_SPACE))
Status = STATUS_INFO_LENGTH_MISMATCH;
else
{
SYSDBG_IO_SPACE Request = *(PSYSDBG_IO_SPACE)InputBuffer;
PVOID LockedBuffer;
PMDL LockVariable;
Status = ExLockUserBuffer(Request.Buffer,
Request.Request,
PreviousMode,
IoReadAccess,
&LockedBuffer,
&LockVariable);
if (NT_SUCCESS(Status))
{
Status = KdpSysWriteIoSpace(Request.InterfaceType,
Request.BusNumber,
Request.AddressSpace,
Request.Address,
LockedBuffer,
Request.Request,
&Length);
ExUnlockUserBuffer(LockVariable);
}
}
break;
case SysDbgReadMsr:
if (InputBufferLength != sizeof(SYSDBG_MSR))
Status = STATUS_INFO_LENGTH_MISMATCH;
else
{
PSYSDBG_MSR Request = (PSYSDBG_MSR)InputBuffer;
Status = KdpSysReadMsr(Request->Address, &Request->Data);
}
break;
case SysDbgWriteMsr:
if (InputBufferLength != sizeof(SYSDBG_MSR))
Status = STATUS_INFO_LENGTH_MISMATCH;
else
{
PSYSDBG_MSR Request = (PSYSDBG_MSR)InputBuffer;
Status = KdpSysWriteMsr(Request->Address, &Request->Data);
}
break;
case SysDbgReadBusData:
if (InputBufferLength != sizeof(SYSDBG_BUS_DATA))
Status = STATUS_INFO_LENGTH_MISMATCH;
else
{
SYSDBG_BUS_DATA Request = *(PSYSDBG_BUS_DATA)InputBuffer;
PVOID LockedBuffer;
PMDL LockVariable;
Status = ExLockUserBuffer(Request.Buffer,
Request.Request,
PreviousMode,
IoWriteAccess,
&LockedBuffer,
&LockVariable);
if (NT_SUCCESS(Status))
{
Status = KdpSysReadBusData(Request.BusDataType,
Request.BusNumber,
Request.SlotNumber,
Request.Address,
LockedBuffer,
Request.Request,
&Length);
ExUnlockUserBuffer(LockVariable);
}
}
break;
case SysDbgWriteBusData:
if (InputBufferLength != sizeof(SYSDBG_BUS_DATA))
Status = STATUS_INFO_LENGTH_MISMATCH;
else
{
SYSDBG_BUS_DATA Request = *(PSYSDBG_BUS_DATA)InputBuffer;
PVOID LockedBuffer;
PMDL LockVariable;
Status = ExLockUserBuffer(Request.Buffer,
Request.Request,
PreviousMode,
IoReadAccess,
&LockedBuffer,
&LockVariable);
if (NT_SUCCESS(Status))
{
Status = KdpSysWriteBusData(Request.BusDataType,
Request.BusNumber,
Request.SlotNumber,
Request.Address,
LockedBuffer,
Request.Request,
&Length);
ExUnlockUserBuffer(LockVariable);
}
}
break;
case SysDbgCheckLowMemory:
Status = KdpSysCheckLowMemory(0);
break;
default:
Status = STATUS_INVALID_INFO_CLASS;
break;
}
if (ReturnLength)
*ReturnLength = Length;
return Status;
}
/*

View File

@@ -318,7 +318,6 @@ KdIsThisAKdTrap(IN PEXCEPTION_RECORD ExceptionRecord,
IN PCONTEXT Context,
IN KPROCESSOR_MODE PreviousMode)
{
#ifdef _WINKD_
/*
* Determine if this is a valid debug service call and make sure that
* it isn't a software breakpoint
@@ -335,8 +334,4 @@ KdIsThisAKdTrap(IN PEXCEPTION_RECORD ExceptionRecord,
/* We don't have to handle it */
return FALSE;
}
#else
/* KDBG has its own mechanism for ignoring user mode exceptions */
return FALSE;
#endif
}

View File

@@ -132,7 +132,15 @@ MmDbgCopyMemory(IN ULONG64 Address,
PVOID CopyDestination, CopySource;
/* No local kernel debugging support yet, so don't worry about locking */
ASSERT(Flags & MMDBG_COPY_UNSAFE);
if (!(Flags & MMDBG_COPY_UNSAFE))
{
static BOOLEAN Warned = FALSE;
if (!Warned)
{
KdpDprintf("MmDbgCopyMemory: not providing MMDBG_COPY_UNSAFE is UNIMPLEMENTED\n");
Warned = TRUE;
}
}
/* We only handle 1, 2, 4 and 8 byte requests */
if ((Size != 1) &&

View File

@@ -34,11 +34,11 @@ NTSTATUS
NTAPI
KdSystemDebugControl(
_In_ SYSDBG_COMMAND Command,
_In_ PVOID InputBuffer,
_In_reads_bytes_(InputBufferLength) PVOID InputBuffer,
_In_ ULONG InputBufferLength,
_Out_ PVOID OutputBuffer,
_Out_writes_bytes_(OutputBufferLength) PVOID OutputBuffer,
_In_ ULONG OutputBufferLength,
_Inout_ PULONG ReturnLength,
_Out_opt_ PULONG ReturnLength,
_In_ KPROCESSOR_MODE PreviousMode
);
@@ -74,12 +74,12 @@ NTSYSCALLAPI
NTSTATUS
NTAPI
NtSystemDebugControl(
SYSDBG_COMMAND ControlCode,
PVOID InputBuffer,
ULONG InputBufferLength,
PVOID OutputBuffer,
ULONG OutputBufferLength,
PULONG ReturnLength
_In_ SYSDBG_COMMAND Command,
_In_reads_bytes_(InputBufferLength) PVOID InputBuffer,
_In_ ULONG InputBufferLength,
_Out_writes_bytes_(OutputBufferLength) PVOID OutputBuffer,
_In_ ULONG OutputBufferLength,
_Out_opt_ PULONG ReturnLength
);
NTSYSAPI
@@ -103,11 +103,11 @@ NTSYSAPI
NTSTATUS
NTAPI
ZwSystemDebugControl(
SYSDBG_COMMAND ControlCode,
PVOID InputBuffer,
ULONG InputBufferLength,
PVOID OutputBuffer,
ULONG OutputBufferLength,
PULONG ReturnLength
_In_ SYSDBG_COMMAND Command,
_In_reads_bytes_(InputBufferLength) PVOID InputBuffer,
_In_ ULONG InputBufferLength,
_Out_writes_bytes_(OutputBufferLength) PVOID OutputBuffer,
_In_ ULONG OutputBufferLength,
_Out_opt_ PULONG ReturnLength
);
#endif

View File

@@ -91,11 +91,19 @@ typedef enum _SYSDBG_COMMAND
SysDbgGetTriageDump = 29,
SysDbgGetKdBlockEnable = 30,
SysDbgSetKdBlockEnable = 31,
#if (NTDDI_VERSION >= NTDDI_VISTA)
SysDbgRegisterForUmBreakInfo = 32,
SysDbgGetUmBreakPid = 33,
SysDbgClearUmBreakPid = 34,
SysDbgGetUmAttachPid = 35,
SysDbgClearUmAttachPid = 36,
#endif
#if (NTDDI_VERSION >= NTDDI_WINBLUE) // NTDDI_WIN81
SysDbgGetLiveKernelDump = 37,
#endif
#if (NTDDI_VERSION >= NTDDI_WIN10_VB)
SysDbgKdPullRemoteFile = 38,
#endif
} SYSDBG_COMMAND;
//
@@ -162,6 +170,96 @@ typedef struct _SYSDBG_TRIAGE_DUMP
PHANDLE Handles;
} SYSDBG_TRIAGE_DUMP, *PSYSDBG_TRIAGE_DUMP;
#if (NTDDI_VERSION >= NTDDI_WINBLUE) // NTDDI_WIN81
typedef union _SYSDBG_LIVEDUMP_CONTROL_FLAGS
{
struct
{
ULONG UseDumpStorageStack : 1;
ULONG CompressMemoryPagesData : 1;
ULONG IncludeUserSpaceMemoryPages : 1;
#if (NTDDI_VERSION >= NTDDI_WIN10_RS4)
ULONG AbortIfMemoryPressure : 1;
#if (NTDDI_VERSION >= NTDDI_WIN11)
ULONG SelectiveDump : 1;
ULONG Reserved : 27;
#else
ULONG Reserved : 28;
#endif // (NTDDI_VERSION >= NTDDI_WIN11)
#else
ULONG Reserved : 29;
#endif // (NTDDI_VERSION >= NTDDI_WIN10_RS4)
};
ULONG AsUlong;
} SYSDBG_LIVEDUMP_CONTROL_FLAGS;
typedef union _SYSDBG_LIVEDUMP_CONTROL_ADDPAGES
{
struct
{
ULONG HypervisorPages : 1;
#if (NTDDI_VERSION >= NTDDI_WIN11)
ULONG NonEssentialHypervisorPages : 1;
ULONG Reserved : 30;
#else
ULONG Reserved : 31;
#endif
};
ULONG AsUlong;
} SYSDBG_LIVEDUMP_CONTROL_ADDPAGES;
#if (NTDDI_VERSION >= NTDDI_WIN11)
typedef struct _SYSDBG_LIVEDUMP_SELECTIVE_CONTROL
{
ULONG Version;
ULONG Size;
union
{
ULONGLONG Flags;
struct
{
ULONGLONG ThreadKernelStacks : 1;
ULONGLONG ReservedFlags : 63;
};
};
ULONGLONG Reserved[4];
} SYSDBG_LIVEDUMP_SELECTIVE_CONTROL, *PSYSDBG_LIVEDUMP_SELECTIVE_CONTROL;
#define SYSDBG_LIVEDUMP_CONTROL_VERSION 1
#define SYSDBG_LIVEDUMP_CONTROL_VERSION_WIN11 2
#endif // (NTDDI_VERSION >= NTDDI_WIN11)
typedef struct _SYSDBG_LIVEDUMP_CONTROL
{
ULONG Version;
ULONG BugCheckCode;
ULONG_PTR BugCheckParam1;
ULONG_PTR BugCheckParam2;
ULONG_PTR BugCheckParam3;
ULONG_PTR BugCheckParam4;
PVOID DumpFileHandle;
PVOID CancelEventHandle;
SYSDBG_LIVEDUMP_CONTROL_FLAGS Flags;
SYSDBG_LIVEDUMP_CONTROL_ADDPAGES AddPagesControl;
#if (NTDDI_VERSION >= NTDDI_WIN11)
PSYSDBG_LIVEDUMP_SELECTIVE_CONTROL SelectiveControl;
#endif
} SYSDBG_LIVEDUMP_CONTROL, *PSYSDBG_LIVEDUMP_CONTROL;
#endif // (NTDDI_VERSION >= NTDDI_WINBLUE)
#if (NTDDI_VERSION >= NTDDI_WIN10_VB)
typedef struct _SYSDBG_KD_PULL_REMOTE_FILE
{
UNICODE_STRING ImageFileName;
} SYSDBG_KD_PULL_REMOTE_FILE, *PSYSDBG_KD_PULL_REMOTE_FILE;
#endif
//
// KD Structures
//