mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
removed MmCopyFromCaller and MmCopyToCaller and depend on SEH instead
svn path=/trunk/; revision=16691
This commit is contained in:
parent
4bfbd2cfaf
commit
9f2bf70ddb
20 changed files with 1080 additions and 430 deletions
|
@ -1503,13 +1503,16 @@ NtQuerySystemInformation (IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
|
||||||
IN ULONG Length,
|
IN ULONG Length,
|
||||||
OUT PULONG UnsafeResultLength)
|
OUT PULONG UnsafeResultLength)
|
||||||
{
|
{
|
||||||
|
KPROCESSOR_MODE PreviousMode;
|
||||||
ULONG ResultLength;
|
ULONG ResultLength;
|
||||||
PVOID SystemInformation;
|
PVOID SystemInformation;
|
||||||
NTSTATUS Status;
|
|
||||||
NTSTATUS FStatus;
|
NTSTATUS FStatus;
|
||||||
|
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
|
PreviousMode = ExGetPreviousMode();
|
||||||
|
|
||||||
|
|
||||||
/* DPRINT("NtQuerySystemInformation Start. Class:%d\n",
|
/* DPRINT("NtQuerySystemInformation Start. Class:%d\n",
|
||||||
SystemInformationClass );
|
SystemInformationClass );
|
||||||
*/
|
*/
|
||||||
|
@ -1554,22 +1557,28 @@ NtQuerySystemInformation (IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
}*/
|
}*/
|
||||||
if (UnsafeResultLength != NULL)
|
if (NT_SUCCESS(FStatus) && UnsafeResultLength != NULL)
|
||||||
{
|
{
|
||||||
/*if (ExGetPreviousMode() == KernelMode)
|
if (PreviousMode != KernelMode)
|
||||||
|
{
|
||||||
|
FStatus = STATUS_SUCCESS;
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
ProbeForWrite(UnsafeResultLength,
|
||||||
|
sizeof(ULONG),
|
||||||
|
sizeof(ULONG));
|
||||||
|
*UnsafeResultLength = ResultLength;
|
||||||
|
}
|
||||||
|
_SEH_EXCEPT(_SEH_ExSystemExceptionFilter)
|
||||||
|
{
|
||||||
|
FStatus = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
*UnsafeResultLength = ResultLength;
|
*UnsafeResultLength = ResultLength;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{*/
|
|
||||||
Status = MmCopyToCaller(UnsafeResultLength,
|
|
||||||
&ResultLength,
|
|
||||||
sizeof(ULONG));
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
return(Status);
|
|
||||||
}
|
|
||||||
/*}*/
|
|
||||||
}
|
}
|
||||||
return(FStatus);
|
return(FStatus);
|
||||||
}
|
}
|
||||||
|
|
|
@ -566,10 +566,6 @@ NTSTATUS MiZeroPage(PFN_TYPE Page);
|
||||||
|
|
||||||
/* memsafe.s *****************************************************************/
|
/* memsafe.s *****************************************************************/
|
||||||
|
|
||||||
NTSTATUS MmSafeCopyFromUser(PVOID Dest, const VOID *Src, ULONG Count);
|
|
||||||
|
|
||||||
NTSTATUS MmSafeCopyToUser(PVOID Dest, const VOID *Src, ULONG Count);
|
|
||||||
|
|
||||||
PVOID FASTCALL MmSafeReadPtr(PVOID Source);
|
PVOID FASTCALL MmSafeReadPtr(PVOID Source);
|
||||||
|
|
||||||
/* pageop.c ******************************************************************/
|
/* pageop.c ******************************************************************/
|
||||||
|
@ -765,14 +761,6 @@ NTSTATUS MmReleaseMmInfo(struct _EPROCESS* Process);
|
||||||
|
|
||||||
NTSTATUS Mmi386ReleaseMmInfo(struct _EPROCESS* Process);
|
NTSTATUS Mmi386ReleaseMmInfo(struct _EPROCESS* Process);
|
||||||
|
|
||||||
NTSTATUS MmSafeCopyFromUser(PVOID Dest, const VOID *Src, ULONG NumberOfBytes);
|
|
||||||
NTSTATUS MmSafeCopyToUser(PVOID Dest, const VOID *Src, ULONG NumberOfBytes);
|
|
||||||
|
|
||||||
NTSTATUS STDCALL
|
|
||||||
MmCopyFromCaller(PVOID Dest, const VOID *Src, ULONG NumberOfBytes);
|
|
||||||
NTSTATUS STDCALL
|
|
||||||
MmCopyToCaller(PVOID Dest, const VOID *Src, ULONG NumberOfBytes);
|
|
||||||
|
|
||||||
VOID MmDeleteVirtualMapping(struct _EPROCESS* Process,
|
VOID MmDeleteVirtualMapping(struct _EPROCESS* Process,
|
||||||
PVOID Address,
|
PVOID Address,
|
||||||
BOOL FreePage,
|
BOOL FreePage,
|
||||||
|
|
|
@ -2809,13 +2809,45 @@ NtSetInformationFile(HANDLE FileHandle,
|
||||||
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
|
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
|
||||||
BOOLEAN Failed = FALSE;
|
BOOLEAN Failed = FALSE;
|
||||||
|
|
||||||
ASSERT(IoStatusBlock != NULL);
|
|
||||||
ASSERT(FileInformation != NULL);
|
|
||||||
|
|
||||||
DPRINT("NtSetInformationFile(Handle 0x%p StatBlk 0x%p FileInfo 0x%p Length %d "
|
DPRINT("NtSetInformationFile(Handle 0x%p StatBlk 0x%p FileInfo 0x%p Length %d "
|
||||||
"Class %d)\n", FileHandle, IoStatusBlock, FileInformation,
|
"Class %d)\n", FileHandle, IoStatusBlock, FileInformation,
|
||||||
Length, FileInformationClass);
|
Length, FileInformationClass);
|
||||||
|
|
||||||
|
if (PreviousMode != KernelMode)
|
||||||
|
{
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
if (IoStatusBlock != NULL)
|
||||||
|
{
|
||||||
|
ProbeForWrite(IoStatusBlock,
|
||||||
|
sizeof(IO_STATUS_BLOCK),
|
||||||
|
sizeof(ULONG));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Length != 0)
|
||||||
|
{
|
||||||
|
ProbeForRead(FileInformation,
|
||||||
|
Length,
|
||||||
|
1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ASSERT(IoStatusBlock != NULL);
|
||||||
|
ASSERT(FileInformation != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/* Get the file object from the file handle */
|
/* Get the file object from the file handle */
|
||||||
Status = ObReferenceObjectByHandle(FileHandle,
|
Status = ObReferenceObjectByHandle(FileHandle,
|
||||||
0,
|
0,
|
||||||
|
@ -2940,13 +2972,43 @@ NtSetInformationFile(HANDLE FileHandle,
|
||||||
Length,
|
Length,
|
||||||
TAG_SYSB)))
|
TAG_SYSB)))
|
||||||
{
|
{
|
||||||
IoFreeIrp(Irp);
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
ObDereferenceObject(FileObject);
|
goto failfreeirp;
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy the data inside */
|
/* Copy the data inside */
|
||||||
MmSafeCopyFromUser(Irp->AssociatedIrp.SystemBuffer, FileInformation, Length);
|
if (PreviousMode != KernelMode)
|
||||||
|
{
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
/* no need to probe again */
|
||||||
|
RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
|
||||||
|
FileInformation,
|
||||||
|
Length);
|
||||||
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
ExFreePoolWithTag(Irp->AssociatedIrp.SystemBuffer,
|
||||||
|
TAG_SYSB);
|
||||||
|
Irp->AssociatedIrp.SystemBuffer = NULL;
|
||||||
|
failfreeirp:
|
||||||
|
IoFreeIrp(Irp);
|
||||||
|
ObDereferenceObject(FileObject);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
|
||||||
|
FileInformation,
|
||||||
|
Length);
|
||||||
|
}
|
||||||
|
|
||||||
/* Set up the IRP */
|
/* Set up the IRP */
|
||||||
Irp->Tail.Overlay.OriginalFileObject = FileObject;
|
Irp->Tail.Overlay.OriginalFileObject = FileObject;
|
||||||
|
|
|
@ -86,18 +86,50 @@ NtQueryVolumeInformationFile(IN HANDLE FileHandle,
|
||||||
PFILE_OBJECT FileObject;
|
PFILE_OBJECT FileObject;
|
||||||
PDEVICE_OBJECT DeviceObject;
|
PDEVICE_OBJECT DeviceObject;
|
||||||
PIRP Irp;
|
PIRP Irp;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
PIO_STACK_LOCATION StackPtr;
|
PIO_STACK_LOCATION StackPtr;
|
||||||
PVOID SystemBuffer;
|
PVOID SystemBuffer;
|
||||||
KPROCESSOR_MODE PreviousMode;
|
KPROCESSOR_MODE PreviousMode;
|
||||||
|
|
||||||
ASSERT(IoStatusBlock != NULL);
|
|
||||||
ASSERT(FsInformation != NULL);
|
|
||||||
|
|
||||||
DPRINT("FsInformation %p\n", FsInformation);
|
DPRINT("FsInformation %p\n", FsInformation);
|
||||||
|
|
||||||
PreviousMode = ExGetPreviousMode();
|
PreviousMode = ExGetPreviousMode();
|
||||||
|
|
||||||
|
if (PreviousMode != KernelMode)
|
||||||
|
{
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
if (IoStatusBlock != NULL)
|
||||||
|
{
|
||||||
|
ProbeForWrite(IoStatusBlock,
|
||||||
|
sizeof(IO_STATUS_BLOCK),
|
||||||
|
sizeof(ULONG));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Length != 0)
|
||||||
|
{
|
||||||
|
ProbeForWrite(FsInformation,
|
||||||
|
Length,
|
||||||
|
1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ASSERT(IoStatusBlock != NULL);
|
||||||
|
ASSERT(FsInformation != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
Status = ObReferenceObjectByHandle(FileHandle,
|
Status = ObReferenceObjectByHandle(FileHandle,
|
||||||
0, /* FIXME - depends on the information class! */
|
0, /* FIXME - depends on the information class! */
|
||||||
IoFileObjectType,
|
IoFileObjectType,
|
||||||
|
@ -164,12 +196,20 @@ NtQueryVolumeInformationFile(IN HANDLE FileHandle,
|
||||||
DPRINT("Status %x\n", Status);
|
DPRINT("Status %x\n", Status);
|
||||||
|
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
_SEH_TRY
|
||||||
{
|
{
|
||||||
DPRINT("Information %lu\n", IoStatusBlock->Information);
|
DPRINT("Information %lu\n", IoStatusBlock->Information);
|
||||||
MmSafeCopyToUser(FsInformation,
|
RtlCopyMemory(FsInformation,
|
||||||
SystemBuffer,
|
SystemBuffer,
|
||||||
IoStatusBlock->Information);
|
IoStatusBlock->Information);
|
||||||
}
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
}
|
||||||
|
|
||||||
ExFreePool(SystemBuffer);
|
ExFreePool(SystemBuffer);
|
||||||
|
|
||||||
|
@ -276,10 +316,42 @@ NtSetVolumeInformationFile(IN HANDLE FileHandle,
|
||||||
PVOID SystemBuffer;
|
PVOID SystemBuffer;
|
||||||
KPROCESSOR_MODE PreviousMode;
|
KPROCESSOR_MODE PreviousMode;
|
||||||
|
|
||||||
|
PreviousMode = ExGetPreviousMode();
|
||||||
|
|
||||||
|
if (PreviousMode != KernelMode)
|
||||||
|
{
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
if (IoStatusBlock != NULL)
|
||||||
|
{
|
||||||
|
ProbeForWrite(IoStatusBlock,
|
||||||
|
sizeof(IO_STATUS_BLOCK),
|
||||||
|
sizeof(ULONG));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Length != 0)
|
||||||
|
{
|
||||||
|
ProbeForRead(FsInformation,
|
||||||
|
Length,
|
||||||
|
1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
ASSERT(IoStatusBlock != NULL);
|
ASSERT(IoStatusBlock != NULL);
|
||||||
ASSERT(FsInformation != NULL);
|
ASSERT(FsInformation != NULL);
|
||||||
|
}
|
||||||
PreviousMode = ExGetPreviousMode();
|
|
||||||
|
|
||||||
Status = ObReferenceObjectByHandle(FileHandle,
|
Status = ObReferenceObjectByHandle(FileHandle,
|
||||||
FILE_WRITE_ATTRIBUTES,
|
FILE_WRITE_ATTRIBUTES,
|
||||||
|
@ -306,14 +378,41 @@ NtSetVolumeInformationFile(IN HANDLE FileHandle,
|
||||||
TAG_SYSB);
|
TAG_SYSB);
|
||||||
if (SystemBuffer == NULL)
|
if (SystemBuffer == NULL)
|
||||||
{
|
{
|
||||||
IoFreeIrp(Irp);
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
ObDereferenceObject(FileObject);
|
goto failfreeirp;
|
||||||
return(STATUS_INSUFFICIENT_RESOURCES);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MmSafeCopyFromUser(SystemBuffer,
|
if (PreviousMode != KernelMode)
|
||||||
|
{
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
/* no need to probe again */
|
||||||
|
RtlCopyMemory(SystemBuffer,
|
||||||
FsInformation,
|
FsInformation,
|
||||||
Length);
|
Length);
|
||||||
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
ExFreePoolWithTag(SystemBuffer,
|
||||||
|
TAG_SYSB);
|
||||||
|
failfreeirp:
|
||||||
|
IoFreeIrp(Irp);
|
||||||
|
ObDereferenceObject(FileObject);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RtlCopyMemory(SystemBuffer,
|
||||||
|
FsInformation,
|
||||||
|
Length);
|
||||||
|
}
|
||||||
|
|
||||||
/* Trigger FileObject/Event dereferencing */
|
/* Trigger FileObject/Event dereferencing */
|
||||||
Irp->Tail.Overlay.OriginalFileObject = FileObject;
|
Irp->Tail.Overlay.OriginalFileObject = FileObject;
|
||||||
|
@ -343,8 +442,16 @@ NtSetVolumeInformationFile(IN HANDLE FileHandle,
|
||||||
PreviousMode,
|
PreviousMode,
|
||||||
FALSE,
|
FALSE,
|
||||||
NULL);
|
NULL);
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
Status = IoStatusBlock->Status;
|
Status = IoStatusBlock->Status;
|
||||||
}
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
}
|
||||||
|
|
||||||
ExFreePool(SystemBuffer);
|
ExFreePool(SystemBuffer);
|
||||||
|
|
||||||
|
|
|
@ -47,8 +47,7 @@ extern void DbgPrint(const char *format, ...);
|
||||||
extern unsigned int KdbSymPrintAddress(void* address);
|
extern unsigned int KdbSymPrintAddress(void* address);
|
||||||
struct disassemble_info;
|
struct disassemble_info;
|
||||||
|
|
||||||
#define KdbpSafeReadMemory(dst, src, size) MmSafeCopyFromUser(dst, src, size)
|
extern long KdbpSafeReadMemory(void*, void*, unsigned int);
|
||||||
extern long MmSafeCopyFromUser(void *Dest, void *Src, unsigned long NumberOfBytes);
|
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
|
@ -1549,3 +1549,53 @@ KdbpGetCommandLineSettings(PCHAR p1)
|
||||||
p1 = p2;
|
p1 = p2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
KdbpSafeReadMemory(OUT PVOID Dest,
|
||||||
|
IN PVOID Src,
|
||||||
|
IN ULONG Bytes)
|
||||||
|
{
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
ProbeForRead(Src,
|
||||||
|
Bytes,
|
||||||
|
1);
|
||||||
|
RtlCopyMemory(Dest,
|
||||||
|
Src,
|
||||||
|
Bytes);
|
||||||
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
KdbpSafeWriteMemory(OUT PVOID Dest,
|
||||||
|
IN PVOID Src,
|
||||||
|
IN ULONG Bytes)
|
||||||
|
{
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
ProbeForWrite(Dest,
|
||||||
|
Bytes,
|
||||||
|
1);
|
||||||
|
RtlCopyMemory(Dest,
|
||||||
|
Src,
|
||||||
|
Bytes);
|
||||||
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
|
@ -237,8 +237,15 @@ KdbEnterDebuggerException(PEXCEPTION_RECORD ExceptionRecord,
|
||||||
BOOLEAN FirstChance);
|
BOOLEAN FirstChance);
|
||||||
/* other functions */
|
/* other functions */
|
||||||
|
|
||||||
#define KdbpSafeReadMemory(dst, src, size) MmSafeCopyFromUser(dst, src, size)
|
NTSTATUS
|
||||||
#define KdbpSafeWriteMemory(dst, src, size) MmSafeCopyToUser(dst, src, size)
|
KdbpSafeReadMemory(OUT PVOID Dest,
|
||||||
|
IN PVOID Src,
|
||||||
|
IN ULONG Bytes);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
KdbpSafeWriteMemory(OUT PVOID Dest,
|
||||||
|
IN PVOID Src,
|
||||||
|
IN ULONG Bytes);
|
||||||
|
|
||||||
#define KdbpGetCharKeyboard(ScanCode) KdbpTryGetCharKeyboard(ScanCode, 0)
|
#define KdbpGetCharKeyboard(ScanCode) KdbpTryGetCharKeyboard(ScanCode, 0)
|
||||||
CHAR
|
CHAR
|
||||||
|
|
|
@ -100,7 +100,7 @@ KiDispatchException(PEXCEPTION_RECORD ExceptionRecord,
|
||||||
ULONG CDest;
|
ULONG CDest;
|
||||||
char temp_space[12 + sizeof(EXCEPTION_RECORD) + sizeof(CONTEXT)]; /* FIXME: HACKHACK */
|
char temp_space[12 + sizeof(EXCEPTION_RECORD) + sizeof(CONTEXT)]; /* FIXME: HACKHACK */
|
||||||
PULONG pNewUserStack = (PULONG)(Tf->Esp - (12 + sizeof(EXCEPTION_RECORD) + sizeof(CONTEXT)));
|
PULONG pNewUserStack = (PULONG)(Tf->Esp - (12 + sizeof(EXCEPTION_RECORD) + sizeof(CONTEXT)));
|
||||||
NTSTATUS StatusOfCopy;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
/* Enter Debugger if available */
|
/* Enter Debugger if available */
|
||||||
Action = KdpEnterDebuggerException(ExceptionRecord,
|
Action = KdpEnterDebuggerException(ExceptionRecord,
|
||||||
|
@ -130,12 +130,23 @@ KiDispatchException(PEXCEPTION_RECORD ExceptionRecord,
|
||||||
memcpy(&Stack[CDest], Context, sizeof(CONTEXT));
|
memcpy(&Stack[CDest], Context, sizeof(CONTEXT));
|
||||||
|
|
||||||
/* Copy Stack */
|
/* Copy Stack */
|
||||||
StatusOfCopy = MmCopyToCaller(pNewUserStack,
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
ProbeForWrite(pNewUserStack,
|
||||||
|
12 + sizeof(EXCEPTION_RECORD) + sizeof(CONTEXT),
|
||||||
|
1);
|
||||||
|
RtlCopyMemory(pNewUserStack,
|
||||||
temp_space,
|
temp_space,
|
||||||
(12 + sizeof(EXCEPTION_RECORD) + sizeof(CONTEXT)));
|
12 + sizeof(EXCEPTION_RECORD) + sizeof(CONTEXT));
|
||||||
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
|
||||||
/* Check for success */
|
/* Check for success */
|
||||||
if (NT_SUCCESS(StatusOfCopy))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
/* Set new Stack Pointer */
|
/* Set new Stack Pointer */
|
||||||
Tf->Esp = (ULONG)pNewUserStack;
|
Tf->Esp = (ULONG)pNewUserStack;
|
||||||
|
|
|
@ -25,7 +25,7 @@ print_user_address(PVOID address)
|
||||||
PPEB Peb = NULL;
|
PPEB Peb = NULL;
|
||||||
ULONG_PTR RelativeAddress;
|
ULONG_PTR RelativeAddress;
|
||||||
PPEB_LDR_DATA Ldr;
|
PPEB_LDR_DATA Ldr;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
CurrentProcess = PsGetCurrentProcess();
|
CurrentProcess = PsGetCurrentProcess();
|
||||||
if (NULL != CurrentProcess)
|
if (NULL != CurrentProcess)
|
||||||
|
@ -39,7 +39,17 @@ print_user_address(PVOID address)
|
||||||
return(TRUE);
|
return(TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = MmSafeCopyFromUser(&Ldr, &Peb->Ldr, sizeof(PPEB_LDR_DATA));
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
RtlCopyMemory(&Ldr,
|
||||||
|
&Peb->Ldr,
|
||||||
|
sizeof(PPEB_LDR_DATA));
|
||||||
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DbgPrint("<%x>", address);
|
DbgPrint("<%x>", address);
|
||||||
|
|
|
@ -44,25 +44,41 @@ NtEarlyInitVdm(VOID)
|
||||||
NTSTATUS STDCALL NtVdmControl(ULONG ControlCode,
|
NTSTATUS STDCALL NtVdmControl(ULONG ControlCode,
|
||||||
PVOID ControlData)
|
PVOID ControlData)
|
||||||
{
|
{
|
||||||
|
KPROCESSOR_MODE PreviousMode;
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
PreviousMode = ExGetPreviousMode();
|
||||||
|
|
||||||
|
if (PreviousMode != KernelMode)
|
||||||
|
{
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
switch (ControlCode)
|
switch (ControlCode)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
|
ProbeForWrite(ControlData,
|
||||||
|
1024,
|
||||||
|
1);
|
||||||
memcpy(ControlData, OrigIVT, 1024);
|
memcpy(ControlData, OrigIVT, 1024);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
|
ProbeForWrite(ControlData,
|
||||||
|
256,
|
||||||
|
1);
|
||||||
memcpy(ControlData, OrigBDA, 256);
|
memcpy(ControlData, OrigBDA, 256);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
{
|
{
|
||||||
KV86M_REGISTERS V86Registers;
|
KV86M_REGISTERS V86Registers;
|
||||||
ULONG ret;
|
|
||||||
|
|
||||||
ret = MmCopyFromCaller(&V86Registers,
|
ProbeForWrite(ControlData,
|
||||||
|
sizeof(KV86M_REGISTERS),
|
||||||
|
1);
|
||||||
|
memcpy(&V86Registers,
|
||||||
ControlData,
|
ControlData,
|
||||||
sizeof(KV86M_REGISTERS));
|
sizeof(KV86M_REGISTERS));
|
||||||
if(!NT_SUCCESS(ret)) return ret;
|
|
||||||
|
|
||||||
/* FIXME: This should use ->VdmObjects */
|
/* FIXME: This should use ->VdmObjects */
|
||||||
KeGetCurrentProcess()->Unused = 1;
|
KeGetCurrentProcess()->Unused = 1;
|
||||||
|
@ -71,15 +87,21 @@ NTSTATUS STDCALL NtVdmControl(ULONG ControlCode,
|
||||||
/* FIXME: This should use ->VdmObjects */
|
/* FIXME: This should use ->VdmObjects */
|
||||||
KeGetCurrentProcess()->Unused = 0;
|
KeGetCurrentProcess()->Unused = 0;
|
||||||
|
|
||||||
ret = MmCopyToCaller(ControlData,
|
memcpy(ControlData,
|
||||||
&V86Registers,
|
&V86Registers,
|
||||||
sizeof(KV86M_REGISTERS));
|
sizeof(KV86M_REGISTERS));
|
||||||
if(!NT_SUCCESS(ret)) return ret;
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return(STATUS_SUCCESS);
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -255,21 +255,72 @@ NtConnectPort (PHANDLE UnsafeConnectedPortHandle,
|
||||||
PSECTION_OBJECT SectionObject;
|
PSECTION_OBJECT SectionObject;
|
||||||
LARGE_INTEGER SectionOffset;
|
LARGE_INTEGER SectionOffset;
|
||||||
PEPORT ConnectedPort;
|
PEPORT ConnectedPort;
|
||||||
NTSTATUS Status;
|
KPROCESSOR_MODE PreviousMode;
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
PEPORT NamedPort;
|
PEPORT NamedPort;
|
||||||
|
|
||||||
|
PreviousMode = ExGetPreviousMode();
|
||||||
|
|
||||||
|
if (PreviousMode != KernelMode)
|
||||||
|
{
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
ProbeForWrite(UnsafeConnectedPortHandle,
|
||||||
|
sizeof(HANDLE),
|
||||||
|
sizeof(ULONG));
|
||||||
|
if (UnsafeMaximumMessageSize != NULL)
|
||||||
|
{
|
||||||
|
ProbeForWrite(UnsafeMaximumMessageSize,
|
||||||
|
sizeof(ULONG),
|
||||||
|
sizeof(ULONG));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copy in write map and partially validate.
|
* Copy in write map and partially validate.
|
||||||
*/
|
*/
|
||||||
if (UnsafeWriteMap != NULL)
|
if (UnsafeWriteMap != NULL)
|
||||||
{
|
{
|
||||||
Status = MmCopyFromCaller(&WriteMap,
|
if (PreviousMode != KernelMode)
|
||||||
|
{
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
ProbeForWrite(UnsafeWriteMap,
|
||||||
|
sizeof(LPC_SECTION_WRITE),
|
||||||
|
1);
|
||||||
|
RtlCopyMemory(&WriteMap,
|
||||||
UnsafeWriteMap,
|
UnsafeWriteMap,
|
||||||
sizeof(LPC_SECTION_WRITE));
|
sizeof(LPC_SECTION_WRITE));
|
||||||
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
return(Status);
|
return Status;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RtlCopyMemory(&WriteMap,
|
||||||
|
UnsafeWriteMap,
|
||||||
|
sizeof(LPC_SECTION_WRITE));
|
||||||
|
}
|
||||||
|
|
||||||
if (WriteMap.Length != sizeof(LPC_SECTION_WRITE))
|
if (WriteMap.Length != sizeof(LPC_SECTION_WRITE))
|
||||||
{
|
{
|
||||||
return(STATUS_INVALID_PARAMETER_4);
|
return(STATUS_INVALID_PARAMETER_4);
|
||||||
|
@ -291,32 +342,67 @@ NtConnectPort (PHANDLE UnsafeConnectedPortHandle,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (ExGetPreviousMode() == KernelMode)
|
if (PreviousMode != KernelMode)
|
||||||
{
|
{
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
ProbeForRead(UnsafeConnectDataLength,
|
||||||
|
sizeof(ULONG),
|
||||||
|
1);
|
||||||
ConnectDataLength = *UnsafeConnectDataLength;
|
ConnectDataLength = *UnsafeConnectDataLength;
|
||||||
ConnectData = UnsafeConnectData;
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Status = MmCopyFromCaller(&ConnectDataLength,
|
ConnectDataLength = *UnsafeConnectDataLength;
|
||||||
UnsafeConnectDataLength,
|
|
||||||
sizeof(ULONG));
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
return(Status);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ConnectDataLength != 0)
|
||||||
|
{
|
||||||
ConnectData = ExAllocatePool(NonPagedPool, ConnectDataLength);
|
ConnectData = ExAllocatePool(NonPagedPool, ConnectDataLength);
|
||||||
if (ConnectData == NULL && ConnectDataLength != 0)
|
if (ConnectData == NULL)
|
||||||
{
|
{
|
||||||
return(STATUS_NO_MEMORY);
|
return(STATUS_NO_MEMORY);
|
||||||
}
|
}
|
||||||
Status = MmCopyFromCaller(ConnectData,
|
|
||||||
|
if (PreviousMode != KernelMode)
|
||||||
|
{
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
ProbeForWrite(UnsafeConnectData,
|
||||||
|
ConnectDataLength,
|
||||||
|
1);
|
||||||
|
RtlCopyMemory(ConnectData,
|
||||||
UnsafeConnectData,
|
UnsafeConnectData,
|
||||||
ConnectDataLength);
|
ConnectDataLength);
|
||||||
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
ExFreePool(ConnectData);
|
ExFreePool(ConnectData);
|
||||||
return(Status);
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RtlCopyMemory(ConnectData,
|
||||||
|
UnsafeConnectData,
|
||||||
|
ConnectDataLength);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -387,16 +473,30 @@ NtConnectPort (PHANDLE UnsafeConnectedPortHandle,
|
||||||
/* FIXME: Again, check what NT does here. */
|
/* FIXME: Again, check what NT does here. */
|
||||||
if (UnsafeConnectDataLength != NULL)
|
if (UnsafeConnectDataLength != NULL)
|
||||||
{
|
{
|
||||||
if (ExGetPreviousMode() != KernelMode)
|
if (PreviousMode != KernelMode)
|
||||||
{
|
{
|
||||||
MmCopyToCaller(UnsafeConnectData,
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
RtlCopyMemory(UnsafeConnectData,
|
||||||
ConnectData,
|
ConnectData,
|
||||||
ConnectDataLength);
|
ConnectDataLength);
|
||||||
ExFreePool(ConnectData);
|
*UnsafeConnectDataLength = ConnectDataLength;
|
||||||
}
|
}
|
||||||
MmCopyToCaller(UnsafeConnectDataLength,
|
_SEH_HANDLE
|
||||||
&ConnectDataLength,
|
{
|
||||||
sizeof(ULONG));
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RtlCopyMemory(UnsafeConnectData,
|
||||||
|
ConnectData,
|
||||||
|
ConnectDataLength);
|
||||||
|
*UnsafeConnectDataLength = ConnectDataLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExFreePool(ConnectData);
|
||||||
}
|
}
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
|
@ -415,29 +515,53 @@ NtConnectPort (PHANDLE UnsafeConnectedPortHandle,
|
||||||
/*
|
/*
|
||||||
* Copy the data back to the caller.
|
* Copy the data back to the caller.
|
||||||
*/
|
*/
|
||||||
if (ExGetPreviousMode() != KernelMode)
|
|
||||||
{
|
|
||||||
if (UnsafeConnectDataLength != NULL)
|
if (UnsafeConnectDataLength != NULL)
|
||||||
{
|
{
|
||||||
Status = MmCopyToCaller(UnsafeConnectDataLength,
|
if (PreviousMode != KernelMode)
|
||||||
&ConnectDataLength,
|
|
||||||
sizeof(ULONG));
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
{
|
||||||
return(Status);
|
_SEH_TRY
|
||||||
}
|
|
||||||
}
|
|
||||||
if (UnsafeConnectData != NULL && ConnectData != NULL)
|
|
||||||
{
|
{
|
||||||
Status = MmCopyToCaller(UnsafeConnectData,
|
*UnsafeConnectDataLength = ConnectDataLength;
|
||||||
|
|
||||||
|
if (ConnectData != NULL)
|
||||||
|
{
|
||||||
|
RtlCopyMemory(UnsafeConnectData,
|
||||||
ConnectData,
|
ConnectData,
|
||||||
ConnectDataLength);
|
ConnectDataLength);
|
||||||
ExFreePool(ConnectData);
|
}
|
||||||
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
if (ConnectData != NULL)
|
||||||
|
{
|
||||||
|
ExFreePool(ConnectData);
|
||||||
|
}
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*UnsafeConnectDataLength = ConnectDataLength;
|
||||||
|
|
||||||
|
if (ConnectData != NULL)
|
||||||
|
{
|
||||||
|
RtlCopyMemory(UnsafeConnectData,
|
||||||
|
ConnectData,
|
||||||
|
ConnectDataLength);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ConnectData != NULL)
|
||||||
|
{
|
||||||
|
ExFreePool(ConnectData);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Status = ObInsertObject(ConnectedPort,
|
Status = ObInsertObject(ConnectedPort,
|
||||||
NULL,
|
NULL,
|
||||||
|
@ -449,41 +573,64 @@ NtConnectPort (PHANDLE UnsafeConnectedPortHandle,
|
||||||
{
|
{
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
Status = MmCopyToCaller(UnsafeConnectedPortHandle,
|
|
||||||
&ConnectedPortHandle,
|
if (PreviousMode != KernelMode)
|
||||||
sizeof(HANDLE));
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
{
|
||||||
return(Status);
|
_SEH_TRY
|
||||||
}
|
{
|
||||||
|
*UnsafeConnectedPortHandle = ConnectedPortHandle;
|
||||||
|
|
||||||
if (UnsafeWriteMap != NULL)
|
if (UnsafeWriteMap != NULL)
|
||||||
{
|
{
|
||||||
Status = MmCopyToCaller(UnsafeWriteMap,
|
RtlCopyMemory(UnsafeWriteMap,
|
||||||
&WriteMap,
|
&WriteMap,
|
||||||
sizeof(LPC_SECTION_WRITE));
|
sizeof(LPC_SECTION_WRITE));
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
return(Status);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (UnsafeReadMap != NULL)
|
if (UnsafeReadMap != NULL)
|
||||||
{
|
{
|
||||||
Status = MmCopyToCaller(UnsafeReadMap,
|
RtlCopyMemory(UnsafeReadMap,
|
||||||
&ReadMap,
|
&ReadMap,
|
||||||
sizeof(LPC_SECTION_READ));
|
sizeof(LPC_SECTION_READ));
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
return(Status);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (UnsafeMaximumMessageSize != NULL)
|
if (UnsafeMaximumMessageSize != NULL)
|
||||||
{
|
{
|
||||||
Status = MmCopyToCaller(UnsafeMaximumMessageSize,
|
*UnsafeMaximumMessageSize = MaximumMessageSize;
|
||||||
&MaximumMessageSize,
|
}
|
||||||
sizeof(ULONG));
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
return(Status);
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*UnsafeConnectedPortHandle = ConnectedPortHandle;
|
||||||
|
|
||||||
|
if (UnsafeWriteMap != NULL)
|
||||||
|
{
|
||||||
|
RtlCopyMemory(UnsafeWriteMap,
|
||||||
|
&WriteMap,
|
||||||
|
sizeof(LPC_SECTION_WRITE));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (UnsafeReadMap != NULL)
|
||||||
|
{
|
||||||
|
RtlCopyMemory(UnsafeReadMap,
|
||||||
|
&ReadMap,
|
||||||
|
sizeof(LPC_SECTION_READ));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (UnsafeMaximumMessageSize != NULL)
|
||||||
|
{
|
||||||
|
*UnsafeMaximumMessageSize = MaximumMessageSize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -141,16 +141,39 @@ NtReplyWaitReceivePortEx(IN HANDLE PortHandle,
|
||||||
OUT PLPC_MESSAGE LpcMessage,
|
OUT PLPC_MESSAGE LpcMessage,
|
||||||
IN PLARGE_INTEGER Timeout)
|
IN PLARGE_INTEGER Timeout)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
|
||||||
PEPORT Port;
|
PEPORT Port;
|
||||||
KIRQL oldIrql;
|
KIRQL oldIrql;
|
||||||
PQUEUEDMESSAGE Request;
|
PQUEUEDMESSAGE Request;
|
||||||
BOOLEAN Disconnected;
|
BOOLEAN Disconnected;
|
||||||
LARGE_INTEGER to;
|
LARGE_INTEGER to;
|
||||||
|
KPROCESSOR_MODE PreviousMode;
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
PreviousMode = ExGetPreviousMode();
|
||||||
|
|
||||||
DPRINT("NtReplyWaitReceivePortEx(PortHandle %x, LpcReply %x, "
|
DPRINT("NtReplyWaitReceivePortEx(PortHandle %x, LpcReply %x, "
|
||||||
"LpcMessage %x)\n", PortHandle, LpcReply, LpcMessage);
|
"LpcMessage %x)\n", PortHandle, LpcReply, LpcMessage);
|
||||||
|
|
||||||
|
if (PreviousMode != KernelMode)
|
||||||
|
{
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
ProbeForWrite(LpcMessage,
|
||||||
|
sizeof(LPC_MESSAGE),
|
||||||
|
1);
|
||||||
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Status = ObReferenceObjectByHandle(PortHandle,
|
Status = ObReferenceObjectByHandle(PortHandle,
|
||||||
PORT_ALL_ACCESS,
|
PORT_ALL_ACCESS,
|
||||||
LpcPortObjectType,
|
LpcPortObjectType,
|
||||||
|
@ -238,19 +261,65 @@ NtReplyWaitReceivePortEx(IN HANDLE PortHandle,
|
||||||
memcpy(&Header, &Request->Message, sizeof(LPC_MESSAGE));
|
memcpy(&Header, &Request->Message, sizeof(LPC_MESSAGE));
|
||||||
Header.DataSize = CRequest->ConnectDataLength;
|
Header.DataSize = CRequest->ConnectDataLength;
|
||||||
Header.MessageSize = Header.DataSize + sizeof(LPC_MESSAGE);
|
Header.MessageSize = Header.DataSize + sizeof(LPC_MESSAGE);
|
||||||
Status = MmCopyToCaller(LpcMessage, &Header, sizeof(LPC_MESSAGE));
|
|
||||||
if (NT_SUCCESS(Status))
|
if (PreviousMode != KernelMode)
|
||||||
{
|
{
|
||||||
Status = MmCopyToCaller((PVOID)(LpcMessage + 1),
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
ProbeForWrite((PVOID)(LpcMessage + 1),
|
||||||
|
CRequest->ConnectDataLength,
|
||||||
|
1);
|
||||||
|
|
||||||
|
RtlCopyMemory(LpcMessage,
|
||||||
|
&Header,
|
||||||
|
sizeof(LPC_MESSAGE));
|
||||||
|
RtlCopyMemory((PVOID)(LpcMessage + 1),
|
||||||
|
CRequest->ConnectData,
|
||||||
|
CRequest->ConnectDataLength);
|
||||||
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RtlCopyMemory(LpcMessage,
|
||||||
|
&Header,
|
||||||
|
sizeof(LPC_MESSAGE));
|
||||||
|
RtlCopyMemory((PVOID)(LpcMessage + 1),
|
||||||
CRequest->ConnectData,
|
CRequest->ConnectData,
|
||||||
CRequest->ConnectDataLength);
|
CRequest->ConnectDataLength);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Status = MmCopyToCaller(LpcMessage, &Request->Message,
|
if (PreviousMode != KernelMode)
|
||||||
|
{
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
ProbeForWrite(LpcMessage,
|
||||||
|
Request->Message.MessageSize,
|
||||||
|
1);
|
||||||
|
|
||||||
|
RtlCopyMemory(LpcMessage,
|
||||||
|
&Request->Message,
|
||||||
Request->Message.MessageSize);
|
Request->Message.MessageSize);
|
||||||
}
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RtlCopyMemory(LpcMessage,
|
||||||
|
&Request->Message,
|
||||||
|
Request->Message.MessageSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -219,12 +219,43 @@ NtRequestWaitReplyPort (IN HANDLE PortHandle,
|
||||||
{
|
{
|
||||||
PETHREAD CurrentThread;
|
PETHREAD CurrentThread;
|
||||||
struct _KPROCESS *AttachedProcess;
|
struct _KPROCESS *AttachedProcess;
|
||||||
NTSTATUS Status;
|
|
||||||
PEPORT Port;
|
PEPORT Port;
|
||||||
PQUEUEDMESSAGE Message;
|
PQUEUEDMESSAGE Message;
|
||||||
KIRQL oldIrql;
|
KIRQL oldIrql;
|
||||||
PLPC_MESSAGE LpcRequest;
|
PLPC_MESSAGE LpcRequest;
|
||||||
USHORT LpcRequestMessageSize;
|
USHORT LpcRequestMessageSize = 0, LpcRequestDataSize = 0;
|
||||||
|
KPROCESSOR_MODE PreviousMode;
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
PreviousMode = ExGetPreviousMode();
|
||||||
|
|
||||||
|
if (PreviousMode != KernelMode)
|
||||||
|
{
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
ProbeForRead(UnsafeLpcRequest,
|
||||||
|
sizeof(LPC_MESSAGE),
|
||||||
|
1);
|
||||||
|
ProbeForWrite(UnsafeLpcReply,
|
||||||
|
sizeof(LPC_MESSAGE),
|
||||||
|
1);
|
||||||
|
LpcRequestMessageSize = UnsafeLpcRequest->MessageSize;
|
||||||
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LpcRequestMessageSize = UnsafeLpcRequest->MessageSize;
|
||||||
|
}
|
||||||
|
|
||||||
DPRINT("NtRequestWaitReplyPort(PortHandle %x, LpcRequest %x, "
|
DPRINT("NtRequestWaitReplyPort(PortHandle %x, LpcRequest %x, "
|
||||||
"LpcReply %x)\n", PortHandle, UnsafeLpcRequest, UnsafeLpcReply);
|
"LpcReply %x)\n", PortHandle, UnsafeLpcRequest, UnsafeLpcReply);
|
||||||
|
@ -261,18 +292,6 @@ NtRequestWaitReplyPort (IN HANDLE PortHandle,
|
||||||
KeDetachProcess();
|
KeDetachProcess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = MmCopyFromCaller(&LpcRequestMessageSize,
|
|
||||||
&UnsafeLpcRequest->MessageSize,
|
|
||||||
sizeof(USHORT));
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
if (NULL != AttachedProcess)
|
|
||||||
{
|
|
||||||
KeAttachProcess(AttachedProcess);
|
|
||||||
}
|
|
||||||
ObDereferenceObject(Port);
|
|
||||||
return(Status);
|
|
||||||
}
|
|
||||||
if (LpcRequestMessageSize > (sizeof(LPC_MESSAGE) + MAX_MESSAGE_DATA))
|
if (LpcRequestMessageSize > (sizeof(LPC_MESSAGE) + MAX_MESSAGE_DATA))
|
||||||
{
|
{
|
||||||
if (NULL != AttachedProcess)
|
if (NULL != AttachedProcess)
|
||||||
|
@ -292,8 +311,22 @@ NtRequestWaitReplyPort (IN HANDLE PortHandle,
|
||||||
ObDereferenceObject(Port);
|
ObDereferenceObject(Port);
|
||||||
return(STATUS_NO_MEMORY);
|
return(STATUS_NO_MEMORY);
|
||||||
}
|
}
|
||||||
Status = MmCopyFromCaller(LpcRequest, UnsafeLpcRequest,
|
if (PreviousMode != KernelMode)
|
||||||
|
{
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
RtlCopyMemory(LpcRequest,
|
||||||
|
UnsafeLpcRequest,
|
||||||
LpcRequestMessageSize);
|
LpcRequestMessageSize);
|
||||||
|
LpcRequestMessageSize = LpcRequest->MessageSize;
|
||||||
|
LpcRequestDataSize = LpcRequest->DataSize;
|
||||||
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
ExFreePool(LpcRequest);
|
ExFreePool(LpcRequest);
|
||||||
|
@ -304,7 +337,16 @@ NtRequestWaitReplyPort (IN HANDLE PortHandle,
|
||||||
ObDereferenceObject(Port);
|
ObDereferenceObject(Port);
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RtlCopyMemory(LpcRequest,
|
||||||
|
UnsafeLpcRequest,
|
||||||
|
LpcRequestMessageSize);
|
||||||
LpcRequestMessageSize = LpcRequest->MessageSize;
|
LpcRequestMessageSize = LpcRequest->MessageSize;
|
||||||
|
LpcRequestDataSize = LpcRequest->DataSize;
|
||||||
|
}
|
||||||
|
|
||||||
if (LpcRequestMessageSize > (sizeof(LPC_MESSAGE) + MAX_MESSAGE_DATA))
|
if (LpcRequestMessageSize > (sizeof(LPC_MESSAGE) + MAX_MESSAGE_DATA))
|
||||||
{
|
{
|
||||||
ExFreePool(LpcRequest);
|
ExFreePool(LpcRequest);
|
||||||
|
@ -315,7 +357,7 @@ NtRequestWaitReplyPort (IN HANDLE PortHandle,
|
||||||
ObDereferenceObject(Port);
|
ObDereferenceObject(Port);
|
||||||
return(STATUS_PORT_MESSAGE_TOO_LONG);
|
return(STATUS_PORT_MESSAGE_TOO_LONG);
|
||||||
}
|
}
|
||||||
if (LpcRequest->DataSize != (LpcRequest->MessageSize - sizeof(LPC_MESSAGE)))
|
if (LpcRequestDataSize != (LpcRequestMessageSize - sizeof(LPC_MESSAGE)))
|
||||||
{
|
{
|
||||||
ExFreePool(LpcRequest);
|
ExFreePool(LpcRequest);
|
||||||
if (NULL != AttachedProcess)
|
if (NULL != AttachedProcess)
|
||||||
|
@ -366,8 +408,26 @@ NtRequestWaitReplyPort (IN HANDLE PortHandle,
|
||||||
{
|
{
|
||||||
DPRINT("Message->Message.MessageSize %d\n",
|
DPRINT("Message->Message.MessageSize %d\n",
|
||||||
Message->Message.MessageSize);
|
Message->Message.MessageSize);
|
||||||
Status = MmCopyToCaller(UnsafeLpcReply, &Message->Message,
|
if (PreviousMode != KernelMode)
|
||||||
|
{
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
RtlCopyMemory(UnsafeLpcReply,
|
||||||
|
&Message->Message,
|
||||||
Message->Message.MessageSize);
|
Message->Message.MessageSize);
|
||||||
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RtlCopyMemory(UnsafeLpcReply,
|
||||||
|
&Message->Message,
|
||||||
|
Message->Message.MessageSize);
|
||||||
|
}
|
||||||
ExFreePool(Message);
|
ExFreePool(Message);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -1,91 +1,7 @@
|
||||||
.globl _MmSafeCopyFromUser
|
|
||||||
.globl _MmSafeCopyFromUserUnsafeStart
|
|
||||||
.globl _MmSafeCopyFromUserRestart
|
|
||||||
.globl _MmSafeCopyToUser
|
|
||||||
.globl _MmSafeCopyToUserUnsafeStart
|
|
||||||
.globl _MmSafeCopyToUserRestart
|
|
||||||
.globl @MmSafeReadPtr@4
|
.globl @MmSafeReadPtr@4
|
||||||
.globl _MmSafeReadPtrStart
|
.globl _MmSafeReadPtrStart
|
||||||
.globl _MmSafeReadPtrEnd
|
.globl _MmSafeReadPtrEnd
|
||||||
|
|
||||||
/*
|
|
||||||
* NTSTATUS MmSafeCopyFromUser(PVOID Dest, PVOID Src,
|
|
||||||
* ULONG NumberOfBytes)
|
|
||||||
*/
|
|
||||||
_MmSafeCopyFromUser:
|
|
||||||
pushl %ebp
|
|
||||||
movl %esp,%ebp
|
|
||||||
|
|
||||||
pushl %esi
|
|
||||||
pushl %edi
|
|
||||||
pushl %ecx
|
|
||||||
|
|
||||||
movl 8(%ebp),%edi
|
|
||||||
movl 12(%ebp),%esi
|
|
||||||
movl 16(%ebp),%ecx
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Default return code
|
|
||||||
*/
|
|
||||||
movl $0,%eax
|
|
||||||
|
|
||||||
_MmSafeCopyFromUserUnsafeStart:
|
|
||||||
/*
|
|
||||||
* This is really a synthetic instruction since if we incur a
|
|
||||||
* pagefault then eax will be set to an appropiate STATUS code
|
|
||||||
*/
|
|
||||||
cld
|
|
||||||
rep movsb
|
|
||||||
|
|
||||||
_MmSafeCopyFromUserRestart:
|
|
||||||
|
|
||||||
popl %ecx
|
|
||||||
popl %edi
|
|
||||||
popl %esi
|
|
||||||
|
|
||||||
popl %ebp
|
|
||||||
ret
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* NTSTATUS MmSafeCopyToUser(PVOID Dest, PVOID Src,
|
|
||||||
* ULONG NumberOfBytes)
|
|
||||||
*/
|
|
||||||
_MmSafeCopyToUser:
|
|
||||||
pushl %ebp
|
|
||||||
movl %esp,%ebp
|
|
||||||
|
|
||||||
pushl %esi
|
|
||||||
pushl %edi
|
|
||||||
pushl %ecx
|
|
||||||
|
|
||||||
movl 8(%ebp),%edi
|
|
||||||
movl 12(%ebp),%esi
|
|
||||||
movl 16(%ebp),%ecx
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Default return code
|
|
||||||
*/
|
|
||||||
movl $0,%eax
|
|
||||||
|
|
||||||
_MmSafeCopyToUserUnsafeStart:
|
|
||||||
/*
|
|
||||||
* This is really a synthetic instruction since if we incur a
|
|
||||||
* pagefault then eax will be set to an appropiate STATUS code
|
|
||||||
*/
|
|
||||||
cld
|
|
||||||
rep movsb
|
|
||||||
|
|
||||||
_MmSafeCopyToUserRestart:
|
|
||||||
|
|
||||||
popl %ecx
|
|
||||||
popl %edi
|
|
||||||
popl %esi
|
|
||||||
|
|
||||||
popl %ebp
|
|
||||||
ret
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -16,10 +16,6 @@
|
||||||
|
|
||||||
/* EXTERNS *******************************************************************/
|
/* EXTERNS *******************************************************************/
|
||||||
|
|
||||||
extern VOID MmSafeCopyFromUserUnsafeStart(VOID);
|
|
||||||
extern VOID MmSafeCopyFromUserRestart(VOID);
|
|
||||||
extern VOID MmSafeCopyToUserUnsafeStart(VOID);
|
|
||||||
extern VOID MmSafeCopyToUserRestart(VOID);
|
|
||||||
extern VOID MmSafeReadPtrStart(VOID);
|
extern VOID MmSafeReadPtrStart(VOID);
|
||||||
extern VOID MmSafeReadPtrEnd(VOID);
|
extern VOID MmSafeReadPtrEnd(VOID);
|
||||||
|
|
||||||
|
@ -76,22 +72,7 @@ NTSTATUS MmPageFault(ULONG Cs,
|
||||||
KiDeliverApc(KernelMode, NULL, NULL);
|
KiDeliverApc(KernelMode, NULL, NULL);
|
||||||
KeLowerIrql(oldIrql);
|
KeLowerIrql(oldIrql);
|
||||||
}
|
}
|
||||||
if (!NT_SUCCESS(Status) && (Mode == KernelMode) &&
|
|
||||||
((*Eip) >= (ULONG_PTR)MmSafeCopyFromUserUnsafeStart) &&
|
|
||||||
((*Eip) <= (ULONG_PTR)MmSafeCopyFromUserRestart))
|
|
||||||
{
|
|
||||||
(*Eip) = (ULONG_PTR)MmSafeCopyFromUserRestart;
|
|
||||||
(*Eax) = STATUS_ACCESS_VIOLATION;
|
|
||||||
return(STATUS_SUCCESS);
|
|
||||||
}
|
|
||||||
if (!NT_SUCCESS(Status) && (Mode == KernelMode) &&
|
|
||||||
((*Eip) >= (ULONG_PTR)MmSafeCopyToUserUnsafeStart) &&
|
|
||||||
((*Eip) <= (ULONG_PTR)MmSafeCopyToUserRestart))
|
|
||||||
{
|
|
||||||
(*Eip) = (ULONG_PTR)MmSafeCopyToUserRestart;
|
|
||||||
(*Eax) = STATUS_ACCESS_VIOLATION;
|
|
||||||
return(STATUS_SUCCESS);
|
|
||||||
}
|
|
||||||
if (!NT_SUCCESS(Status) && (Mode == KernelMode) &&
|
if (!NT_SUCCESS(Status) && (Mode == KernelMode) &&
|
||||||
((*Eip) >= (ULONG_PTR)MmSafeReadPtrStart) &&
|
((*Eip) >= (ULONG_PTR)MmSafeReadPtrStart) &&
|
||||||
((*Eip) <= (ULONG_PTR)MmSafeReadPtrEnd))
|
((*Eip) <= (ULONG_PTR)MmSafeReadPtrEnd))
|
||||||
|
|
|
@ -28,50 +28,6 @@ MM_STATS MmStats;
|
||||||
/* FUNCTIONS ****************************************************************/
|
/* FUNCTIONS ****************************************************************/
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS STDCALL
|
|
||||||
MmCopyToCaller(PVOID Dest, const VOID *Src, ULONG NumberOfBytes)
|
|
||||||
{
|
|
||||||
NTSTATUS Status;
|
|
||||||
|
|
||||||
if (ExGetPreviousMode() == UserMode)
|
|
||||||
{
|
|
||||||
if (Dest >= MmSystemRangeStart)
|
|
||||||
{
|
|
||||||
return(STATUS_ACCESS_VIOLATION);
|
|
||||||
}
|
|
||||||
Status = MmSafeCopyToUser(Dest, Src, NumberOfBytes);
|
|
||||||
return(Status);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
memcpy(Dest, Src, NumberOfBytes);
|
|
||||||
return(STATUS_SUCCESS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS STDCALL
|
|
||||||
MmCopyFromCaller(PVOID Dest, const VOID *Src, ULONG NumberOfBytes)
|
|
||||||
{
|
|
||||||
NTSTATUS Status;
|
|
||||||
|
|
||||||
if (ExGetPreviousMode() == UserMode)
|
|
||||||
{
|
|
||||||
if (Src >= MmSystemRangeStart)
|
|
||||||
{
|
|
||||||
return(STATUS_ACCESS_VIOLATION);
|
|
||||||
}
|
|
||||||
Status = MmSafeCopyFromUser(Dest, Src, NumberOfBytes);
|
|
||||||
return(Status);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
memcpy(Dest, Src, NumberOfBytes);
|
|
||||||
return(STATUS_SUCCESS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS MmReleaseMemoryArea(PEPROCESS Process, PMEMORY_AREA Marea)
|
NTSTATUS MmReleaseMemoryArea(PEPROCESS Process, PMEMORY_AREA Marea)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
|
@ -269,9 +269,9 @@ NtQueryVirtualMemory (IN HANDLE ProcessHandle,
|
||||||
IN ULONG Length,
|
IN ULONG Length,
|
||||||
OUT PULONG UnsafeResultLength)
|
OUT PULONG UnsafeResultLength)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
ULONG ResultLength = 0;
|
ULONG ResultLength = 0;
|
||||||
KPROCESSOR_MODE PrevMode;
|
KPROCESSOR_MODE PreviousMode;
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
MEMORY_BASIC_INFORMATION BasicInfo;
|
MEMORY_BASIC_INFORMATION BasicInfo;
|
||||||
|
@ -284,7 +284,27 @@ NtQueryVirtualMemory (IN HANDLE ProcessHandle,
|
||||||
VirtualMemoryInformationClass,VirtualMemoryInformation,
|
VirtualMemoryInformationClass,VirtualMemoryInformation,
|
||||||
Length,ResultLength);
|
Length,ResultLength);
|
||||||
|
|
||||||
PrevMode = ExGetPreviousMode();
|
PreviousMode = ExGetPreviousMode();
|
||||||
|
|
||||||
|
if (PreviousMode != KernelMode && UnsafeResultLength != NULL)
|
||||||
|
{
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
ProbeForWrite(UnsafeResultLength,
|
||||||
|
sizeof(ULONG),
|
||||||
|
sizeof(ULONG));
|
||||||
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (Address >= MmSystemRangeStart)
|
if (Address >= MmSystemRangeStart)
|
||||||
{
|
{
|
||||||
|
@ -299,19 +319,48 @@ NtQueryVirtualMemory (IN HANDLE ProcessHandle,
|
||||||
Length,
|
Length,
|
||||||
&ResultLength );
|
&ResultLength );
|
||||||
|
|
||||||
if (NT_SUCCESS(Status) && ResultLength > 0)
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
Status = MmCopyToCaller(VirtualMemoryInformation, &VirtualMemoryInfo, ResultLength);
|
if (PreviousMode != KernelMode)
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
{
|
||||||
ResultLength = 0;
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
if (ResultLength > 0)
|
||||||
|
{
|
||||||
|
ProbeForWrite(VirtualMemoryInformation,
|
||||||
|
ResultLength,
|
||||||
|
1);
|
||||||
|
RtlCopyMemory(VirtualMemoryInformation,
|
||||||
|
&VirtualMemoryInfo,
|
||||||
|
ResultLength);
|
||||||
}
|
}
|
||||||
|
if (UnsafeResultLength != NULL)
|
||||||
|
{
|
||||||
|
*UnsafeResultLength = ResultLength;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (ResultLength > 0)
|
||||||
|
{
|
||||||
|
RtlCopyMemory(VirtualMemoryInformation,
|
||||||
|
&VirtualMemoryInfo,
|
||||||
|
ResultLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (UnsafeResultLength != NULL)
|
if (UnsafeResultLength != NULL)
|
||||||
{
|
{
|
||||||
MmCopyToCaller(UnsafeResultLength, &ResultLength, sizeof(ULONG));
|
*UnsafeResultLength = ResultLength;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -384,17 +433,47 @@ NtProtectVirtualMemory(IN HANDLE ProcessHandle,
|
||||||
OUT PULONG UnsafeOldAccessProtection)
|
OUT PULONG UnsafeOldAccessProtection)
|
||||||
{
|
{
|
||||||
PEPROCESS Process;
|
PEPROCESS Process;
|
||||||
NTSTATUS Status;
|
|
||||||
ULONG OldAccessProtection;
|
ULONG OldAccessProtection;
|
||||||
PVOID BaseAddress;
|
PVOID BaseAddress = NULL;
|
||||||
ULONG NumberOfBytesToProtect;
|
ULONG NumberOfBytesToProtect = 0;
|
||||||
|
KPROCESSOR_MODE PreviousMode;
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
PreviousMode = ExGetPreviousMode();
|
||||||
|
|
||||||
|
if (PreviousMode != KernelMode)
|
||||||
|
{
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
ProbeForWrite(UnsafeBaseAddress,
|
||||||
|
sizeof(PVOID),
|
||||||
|
sizeof(ULONG));
|
||||||
|
ProbeForWrite(UnsafeBaseAddress,
|
||||||
|
sizeof(ULONG),
|
||||||
|
sizeof(ULONG));
|
||||||
|
ProbeForWrite(UnsafeOldAccessProtection,
|
||||||
|
sizeof(ULONG),
|
||||||
|
sizeof(ULONG));
|
||||||
|
|
||||||
|
BaseAddress = *UnsafeBaseAddress;
|
||||||
|
NumberOfBytesToProtect = *UnsafeNumberOfBytesToProtect;
|
||||||
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
|
||||||
Status = MmCopyFromCaller(&BaseAddress, UnsafeBaseAddress, sizeof(PVOID));
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
return Status;
|
|
||||||
Status = MmCopyFromCaller(&NumberOfBytesToProtect, UnsafeNumberOfBytesToProtect, sizeof(ULONG));
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
return Status;
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BaseAddress = *UnsafeBaseAddress;
|
||||||
|
NumberOfBytesToProtect = *UnsafeNumberOfBytesToProtect;
|
||||||
|
}
|
||||||
|
|
||||||
/* (tMk 2004.II.5) in Microsoft SDK I read:
|
/* (tMk 2004.II.5) in Microsoft SDK I read:
|
||||||
* 'if this parameter is NULL or does not point to a valid variable, the function fails'
|
* 'if this parameter is NULL or does not point to a valid variable, the function fails'
|
||||||
|
@ -424,9 +503,26 @@ NtProtectVirtualMemory(IN HANDLE ProcessHandle,
|
||||||
|
|
||||||
ObDereferenceObject(Process);
|
ObDereferenceObject(Process);
|
||||||
|
|
||||||
MmCopyToCaller(UnsafeOldAccessProtection, &OldAccessProtection, sizeof(ULONG));
|
if (PreviousMode != KernelMode)
|
||||||
MmCopyToCaller(UnsafeBaseAddress, &BaseAddress, sizeof(PVOID));
|
{
|
||||||
MmCopyToCaller(UnsafeNumberOfBytesToProtect, &NumberOfBytesToProtect, sizeof(ULONG));
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
*UnsafeOldAccessProtection = OldAccessProtection;
|
||||||
|
*UnsafeBaseAddress = BaseAddress;
|
||||||
|
*UnsafeNumberOfBytesToProtect = NumberOfBytesToProtect;
|
||||||
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*UnsafeOldAccessProtection = OldAccessProtection;
|
||||||
|
*UnsafeBaseAddress = BaseAddress;
|
||||||
|
*UnsafeNumberOfBytesToProtect = NumberOfBytesToProtect;
|
||||||
|
}
|
||||||
|
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
|
@ -648,18 +744,41 @@ NtWriteVirtualMemory(IN HANDLE ProcessHandle,
|
||||||
IN ULONG NumberOfBytesToWrite,
|
IN ULONG NumberOfBytesToWrite,
|
||||||
OUT PULONG NumberOfBytesWritten OPTIONAL)
|
OUT PULONG NumberOfBytesWritten OPTIONAL)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
|
||||||
PMDL Mdl;
|
PMDL Mdl;
|
||||||
PVOID SystemAddress;
|
PVOID SystemAddress;
|
||||||
PEPROCESS Process;
|
PEPROCESS Process;
|
||||||
ULONG OldProtection = 0;
|
ULONG OldProtection = 0;
|
||||||
PVOID ProtectBaseAddress;
|
PVOID ProtectBaseAddress;
|
||||||
ULONG ProtectNumberOfBytes;
|
ULONG ProtectNumberOfBytes;
|
||||||
|
KPROCESSOR_MODE PreviousMode;
|
||||||
|
NTSTATUS CopyStatus, Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
DPRINT("NtWriteVirtualMemory(ProcessHandle %x, BaseAddress %x, "
|
DPRINT("NtWriteVirtualMemory(ProcessHandle %x, BaseAddress %x, "
|
||||||
"Buffer %x, NumberOfBytesToWrite %d)\n",ProcessHandle,BaseAddress,
|
"Buffer %x, NumberOfBytesToWrite %d)\n",ProcessHandle,BaseAddress,
|
||||||
Buffer,NumberOfBytesToWrite);
|
Buffer,NumberOfBytesToWrite);
|
||||||
|
|
||||||
|
PreviousMode = ExGetPreviousMode();
|
||||||
|
|
||||||
|
if (PreviousMode != KernelMode && NumberOfBytesWritten != NULL)
|
||||||
|
{
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
ProbeForWrite(NumberOfBytesWritten,
|
||||||
|
sizeof(ULONG),
|
||||||
|
sizeof(ULONG));
|
||||||
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Status = ObReferenceObjectByHandle(ProcessHandle,
|
Status = ObReferenceObjectByHandle(ProcessHandle,
|
||||||
PROCESS_VM_WRITE,
|
PROCESS_VM_WRITE,
|
||||||
NULL,
|
NULL,
|
||||||
|
@ -681,6 +800,8 @@ NtWriteVirtualMemory(IN HANDLE ProcessHandle,
|
||||||
ProtectBaseAddress = BaseAddress;
|
ProtectBaseAddress = BaseAddress;
|
||||||
ProtectNumberOfBytes = NumberOfBytesToWrite;
|
ProtectNumberOfBytes = NumberOfBytesToWrite;
|
||||||
|
|
||||||
|
CopyStatus = STATUS_SUCCESS;
|
||||||
|
|
||||||
/* Write memory */
|
/* Write memory */
|
||||||
if (Process == PsGetCurrentProcess())
|
if (Process == PsGetCurrentProcess())
|
||||||
{
|
{
|
||||||
|
@ -694,8 +815,24 @@ NtWriteVirtualMemory(IN HANDLE ProcessHandle,
|
||||||
ObDereferenceObject(Process);
|
ObDereferenceObject(Process);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (PreviousMode != KernelMode)
|
||||||
|
{
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
memcpy(BaseAddress, Buffer, NumberOfBytesToWrite);
|
memcpy(BaseAddress, Buffer, NumberOfBytesToWrite);
|
||||||
}
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
CopyStatus = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memcpy(BaseAddress, Buffer, NumberOfBytesToWrite);
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Create MDL describing the source buffer. */
|
/* Create MDL describing the source buffer. */
|
||||||
|
@ -730,7 +867,22 @@ NtWriteVirtualMemory(IN HANDLE ProcessHandle,
|
||||||
KeAttachProcess(&Process->Pcb);
|
KeAttachProcess(&Process->Pcb);
|
||||||
|
|
||||||
SystemAddress = MmGetSystemAddressForMdl(Mdl);
|
SystemAddress = MmGetSystemAddressForMdl(Mdl);
|
||||||
|
if (PreviousMode != KernelMode)
|
||||||
|
{
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
memcpy(BaseAddress, SystemAddress, NumberOfBytesToWrite);
|
memcpy(BaseAddress, SystemAddress, NumberOfBytesToWrite);
|
||||||
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
CopyStatus = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memcpy(BaseAddress, SystemAddress, NumberOfBytesToWrite);
|
||||||
|
}
|
||||||
|
|
||||||
KeDetachProcess();
|
KeDetachProcess();
|
||||||
|
|
||||||
|
@ -758,9 +910,26 @@ NtWriteVirtualMemory(IN HANDLE ProcessHandle,
|
||||||
ObDereferenceObject(Process);
|
ObDereferenceObject(Process);
|
||||||
|
|
||||||
if (NumberOfBytesWritten != NULL)
|
if (NumberOfBytesWritten != NULL)
|
||||||
MmCopyToCaller(NumberOfBytesWritten, &NumberOfBytesToWrite, sizeof(ULONG));
|
{
|
||||||
|
if (PreviousMode != KernelMode)
|
||||||
|
{
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
*NumberOfBytesWritten = NumberOfBytesToWrite;
|
||||||
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*NumberOfBytesWritten = NumberOfBytesToWrite;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return(STATUS_SUCCESS);
|
return(NT_SUCCESS(CopyStatus) ? Status : CopyStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -688,8 +688,6 @@ MmAllocateNonCachedMemory@4
|
||||||
MmAllocatePagesForMdl@28
|
MmAllocatePagesForMdl@28
|
||||||
MmBuildMdlForNonPagedPool@4
|
MmBuildMdlForNonPagedPool@4
|
||||||
MmCanFileBeTruncated@8
|
MmCanFileBeTruncated@8
|
||||||
;MmCopyFromCaller@12
|
|
||||||
;MmCopyToCaller@12
|
|
||||||
MmCreateMdl@12
|
MmCreateMdl@12
|
||||||
MmCreateSection@32
|
MmCreateSection@32
|
||||||
MmDbgTranslatePhysicalAddress@8
|
MmDbgTranslatePhysicalAddress@8
|
||||||
|
|
|
@ -1135,7 +1135,6 @@ NtSetInformationThread (IN HANDLE ThreadHandle,
|
||||||
IN ULONG ThreadInformationLength)
|
IN ULONG ThreadInformationLength)
|
||||||
{
|
{
|
||||||
PETHREAD Thread;
|
PETHREAD Thread;
|
||||||
NTSTATUS Status;
|
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
KPRIORITY Priority;
|
KPRIORITY Priority;
|
||||||
|
@ -1144,9 +1143,13 @@ NtSetInformationThread (IN HANDLE ThreadHandle,
|
||||||
HANDLE Handle;
|
HANDLE Handle;
|
||||||
PVOID Address;
|
PVOID Address;
|
||||||
}u;
|
}u;
|
||||||
|
KPROCESSOR_MODE PreviousMode;
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
|
PreviousMode = ExGetPreviousMode();
|
||||||
|
|
||||||
if (ThreadInformationClass <= MaxThreadInfoClass &&
|
if (ThreadInformationClass <= MaxThreadInfoClass &&
|
||||||
!SetInformationData[ThreadInformationClass].Implemented)
|
!SetInformationData[ThreadInformationClass].Implemented)
|
||||||
{
|
{
|
||||||
|
@ -1162,20 +1165,41 @@ NtSetInformationThread (IN HANDLE ThreadHandle,
|
||||||
return STATUS_INFO_LENGTH_MISMATCH;
|
return STATUS_INFO_LENGTH_MISMATCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (PreviousMode != KernelMode)
|
||||||
|
{
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
ProbeForRead(ThreadInformation,
|
||||||
|
SetInformationData[ThreadInformationClass].Size,
|
||||||
|
1);
|
||||||
|
RtlCopyMemory(&u.Priority,
|
||||||
|
ThreadInformation,
|
||||||
|
SetInformationData[ThreadInformationClass].Size);
|
||||||
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RtlCopyMemory(&u.Priority,
|
||||||
|
ThreadInformation,
|
||||||
|
SetInformationData[ThreadInformationClass].Size);
|
||||||
|
}
|
||||||
|
|
||||||
Status = ObReferenceObjectByHandle (ThreadHandle,
|
Status = ObReferenceObjectByHandle (ThreadHandle,
|
||||||
THREAD_SET_INFORMATION,
|
THREAD_SET_INFORMATION,
|
||||||
PsThreadType,
|
PsThreadType,
|
||||||
ExGetPreviousMode (),
|
ExGetPreviousMode (),
|
||||||
(PVOID*)&Thread,
|
(PVOID*)&Thread,
|
||||||
NULL);
|
NULL);
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = MmCopyFromCaller(&u.Priority,
|
|
||||||
ThreadInformation,
|
|
||||||
SetInformationData[ThreadInformationClass].Size);
|
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
switch (ThreadInformationClass)
|
switch (ThreadInformationClass)
|
||||||
|
@ -1226,7 +1250,6 @@ NtQueryInformationThread (IN HANDLE ThreadHandle,
|
||||||
OUT PULONG ReturnLength OPTIONAL)
|
OUT PULONG ReturnLength OPTIONAL)
|
||||||
{
|
{
|
||||||
PETHREAD Thread;
|
PETHREAD Thread;
|
||||||
NTSTATUS Status;
|
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
THREAD_BASIC_INFORMATION TBI;
|
THREAD_BASIC_INFORMATION TBI;
|
||||||
|
@ -1235,9 +1258,13 @@ NtQueryInformationThread (IN HANDLE ThreadHandle,
|
||||||
LARGE_INTEGER Count;
|
LARGE_INTEGER Count;
|
||||||
BOOLEAN Last;
|
BOOLEAN Last;
|
||||||
}u;
|
}u;
|
||||||
|
KPROCESSOR_MODE PreviousMode;
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
|
PreviousMode = ExGetPreviousMode();
|
||||||
|
|
||||||
if (ThreadInformationClass <= MaxThreadInfoClass &&
|
if (ThreadInformationClass <= MaxThreadInfoClass &&
|
||||||
!QueryInformationData[ThreadInformationClass].Implemented)
|
!QueryInformationData[ThreadInformationClass].Implemented)
|
||||||
{
|
{
|
||||||
|
@ -1253,6 +1280,32 @@ NtQueryInformationThread (IN HANDLE ThreadHandle,
|
||||||
return STATUS_INFO_LENGTH_MISMATCH;
|
return STATUS_INFO_LENGTH_MISMATCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (PreviousMode != KernelMode)
|
||||||
|
{
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
ProbeForWrite(ThreadInformation,
|
||||||
|
QueryInformationData[ThreadInformationClass].Size,
|
||||||
|
1);
|
||||||
|
if (ReturnLength != NULL)
|
||||||
|
{
|
||||||
|
ProbeForWrite(ReturnLength,
|
||||||
|
sizeof(ULONG),
|
||||||
|
sizeof(ULONG));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Status = ObReferenceObjectByHandle(ThreadHandle,
|
Status = ObReferenceObjectByHandle(ThreadHandle,
|
||||||
THREAD_QUERY_INFORMATION,
|
THREAD_QUERY_INFORMATION,
|
||||||
PsThreadType,
|
PsThreadType,
|
||||||
|
@ -1311,22 +1364,40 @@ NtQueryInformationThread (IN HANDLE ThreadHandle,
|
||||||
/* Shoult never occure if the data table is correct */
|
/* Shoult never occure if the data table is correct */
|
||||||
KEBUGCHECK(0);
|
KEBUGCHECK(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (PreviousMode != KernelMode)
|
||||||
|
{
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
if (QueryInformationData[ThreadInformationClass].Size)
|
if (QueryInformationData[ThreadInformationClass].Size)
|
||||||
{
|
{
|
||||||
Status = MmCopyToCaller(ThreadInformation,
|
RtlCopyMemory(ThreadInformation,
|
||||||
&u.TBI,
|
&u.TBI,
|
||||||
QueryInformationData[ThreadInformationClass].Size);
|
QueryInformationData[ThreadInformationClass].Size);
|
||||||
}
|
}
|
||||||
if (ReturnLength)
|
if (ReturnLength != NULL)
|
||||||
{
|
{
|
||||||
NTSTATUS Status2;
|
*ReturnLength = QueryInformationData[ThreadInformationClass].Size;
|
||||||
static ULONG Null = 0;
|
}
|
||||||
Status2 = MmCopyToCaller(ReturnLength,
|
}
|
||||||
NT_SUCCESS(Status) ? &QueryInformationData[ThreadInformationClass].Size : &Null,
|
_SEH_HANDLE
|
||||||
sizeof(ULONG));
|
|
||||||
if (NT_SUCCESS(Status))
|
|
||||||
{
|
{
|
||||||
Status = Status2;
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (QueryInformationData[ThreadInformationClass].Size)
|
||||||
|
{
|
||||||
|
RtlCopyMemory(ThreadInformation,
|
||||||
|
&u.TBI,
|
||||||
|
QueryInformationData[ThreadInformationClass].Size);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ReturnLength != NULL)
|
||||||
|
{
|
||||||
|
*ReturnLength = QueryInformationData[ThreadInformationClass].Size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2052,6 +2052,7 @@ NtCreateToken(OUT PHANDLE TokenHandle,
|
||||||
PVOID EndMem;
|
PVOID EndMem;
|
||||||
ULONG uLength;
|
ULONG uLength;
|
||||||
ULONG i;
|
ULONG i;
|
||||||
|
ULONG nTokenPrivileges = 0;
|
||||||
KPROCESSOR_MODE PreviousMode;
|
KPROCESSOR_MODE PreviousMode;
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
@ -2093,6 +2094,7 @@ NtCreateToken(OUT PHANDLE TokenHandle,
|
||||||
ProbeForRead(TokenSource,
|
ProbeForRead(TokenSource,
|
||||||
sizeof(TOKEN_SOURCE),
|
sizeof(TOKEN_SOURCE),
|
||||||
sizeof(ULONG));
|
sizeof(ULONG));
|
||||||
|
nTokenPrivileges = TokenPrivileges->PrivilegeCount;
|
||||||
}
|
}
|
||||||
_SEH_HANDLE
|
_SEH_HANDLE
|
||||||
{
|
{
|
||||||
|
@ -2105,6 +2107,10 @@ NtCreateToken(OUT PHANDLE TokenHandle,
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nTokenPrivileges = TokenPrivileges->PrivilegeCount;
|
||||||
|
}
|
||||||
|
|
||||||
Status = ZwAllocateLocallyUniqueId(&TokenId);
|
Status = ZwAllocateLocallyUniqueId(&TokenId);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
@ -2203,13 +2209,25 @@ NtCreateToken(OUT PHANDLE TokenHandle,
|
||||||
uLength,
|
uLength,
|
||||||
TAG('T', 'O', 'K', 'p'));
|
TAG('T', 'O', 'K', 'p'));
|
||||||
|
|
||||||
for (i = 0; i < TokenPrivileges->PrivilegeCount; i++)
|
if (PreviousMode != KernelMode)
|
||||||
{
|
{
|
||||||
Status = MmCopyFromCaller(&AccessToken->Privileges[i],
|
_SEH_TRY
|
||||||
&TokenPrivileges->Privileges[i],
|
{
|
||||||
sizeof(LUID_AND_ATTRIBUTES));
|
RtlCopyMemory(AccessToken->Privileges,
|
||||||
if (!NT_SUCCESS(Status))
|
TokenPrivileges->Privileges,
|
||||||
break;
|
nTokenPrivileges * sizeof(LUID_AND_ATTRIBUTES));
|
||||||
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RtlCopyMemory(AccessToken->Privileges,
|
||||||
|
TokenPrivileges->Privileges,
|
||||||
|
nTokenPrivileges * sizeof(LUID_AND_ATTRIBUTES));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue