mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 17:44:45 +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,12 +1503,15 @@ NtQuerySystemInformation (IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
|
|||
IN ULONG Length,
|
||||
OUT PULONG UnsafeResultLength)
|
||||
{
|
||||
KPROCESSOR_MODE PreviousMode;
|
||||
ULONG ResultLength;
|
||||
PVOID SystemInformation;
|
||||
NTSTATUS Status;
|
||||
NTSTATUS FStatus;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
PreviousMode = ExGetPreviousMode();
|
||||
|
||||
|
||||
/* DPRINT("NtQuerySystemInformation Start. Class:%d\n",
|
||||
SystemInformationClass );
|
||||
|
@ -1554,22 +1557,28 @@ NtQuerySystemInformation (IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
|
|||
return(Status);
|
||||
}
|
||||
}*/
|
||||
if (UnsafeResultLength != NULL)
|
||||
if (NT_SUCCESS(FStatus) && UnsafeResultLength != NULL)
|
||||
{
|
||||
/*if (ExGetPreviousMode() == KernelMode)
|
||||
{
|
||||
*UnsafeResultLength = ResultLength;
|
||||
}
|
||||
else
|
||||
{*/
|
||||
Status = MmCopyToCaller(UnsafeResultLength,
|
||||
&ResultLength,
|
||||
sizeof(ULONG));
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return(Status);
|
||||
}
|
||||
/*}*/
|
||||
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;
|
||||
}
|
||||
}
|
||||
return(FStatus);
|
||||
}
|
||||
|
|
|
@ -566,10 +566,6 @@ NTSTATUS MiZeroPage(PFN_TYPE Page);
|
|||
|
||||
/* 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);
|
||||
|
||||
/* pageop.c ******************************************************************/
|
||||
|
@ -765,14 +761,6 @@ NTSTATUS MmReleaseMmInfo(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,
|
||||
PVOID Address,
|
||||
BOOL FreePage,
|
||||
|
|
|
@ -2809,13 +2809,45 @@ NtSetInformationFile(HANDLE FileHandle,
|
|||
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
|
||||
BOOLEAN Failed = FALSE;
|
||||
|
||||
ASSERT(IoStatusBlock != NULL);
|
||||
ASSERT(FileInformation != NULL);
|
||||
|
||||
DPRINT("NtSetInformationFile(Handle 0x%p StatBlk 0x%p FileInfo 0x%p Length %d "
|
||||
"Class %d)\n", FileHandle, IoStatusBlock, FileInformation,
|
||||
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 */
|
||||
Status = ObReferenceObjectByHandle(FileHandle,
|
||||
0,
|
||||
|
@ -2940,13 +2972,43 @@ NtSetInformationFile(HANDLE FileHandle,
|
|||
Length,
|
||||
TAG_SYSB)))
|
||||
{
|
||||
IoFreeIrp(Irp);
|
||||
ObDereferenceObject(FileObject);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
goto failfreeirp;
|
||||
}
|
||||
|
||||
/* 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 */
|
||||
Irp->Tail.Overlay.OriginalFileObject = FileObject;
|
||||
|
|
|
@ -86,17 +86,49 @@ NtQueryVolumeInformationFile(IN HANDLE FileHandle,
|
|||
PFILE_OBJECT FileObject;
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
PIRP Irp;
|
||||
NTSTATUS Status;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
PIO_STACK_LOCATION StackPtr;
|
||||
PVOID SystemBuffer;
|
||||
KPROCESSOR_MODE PreviousMode;
|
||||
|
||||
ASSERT(IoStatusBlock != NULL);
|
||||
ASSERT(FsInformation != NULL);
|
||||
|
||||
DPRINT("FsInformation %p\n", FsInformation);
|
||||
|
||||
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,
|
||||
0, /* FIXME - depends on the information class! */
|
||||
|
@ -165,10 +197,18 @@ NtQueryVolumeInformationFile(IN HANDLE FileHandle,
|
|||
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("Information %lu\n", IoStatusBlock->Information);
|
||||
MmSafeCopyToUser(FsInformation,
|
||||
SystemBuffer,
|
||||
IoStatusBlock->Information);
|
||||
_SEH_TRY
|
||||
{
|
||||
DPRINT("Information %lu\n", IoStatusBlock->Information);
|
||||
RtlCopyMemory(FsInformation,
|
||||
SystemBuffer,
|
||||
IoStatusBlock->Information);
|
||||
}
|
||||
_SEH_HANDLE
|
||||
{
|
||||
Status = _SEH_GetExceptionCode();
|
||||
}
|
||||
_SEH_END;
|
||||
}
|
||||
|
||||
ExFreePool(SystemBuffer);
|
||||
|
@ -276,10 +316,42 @@ NtSetVolumeInformationFile(IN HANDLE FileHandle,
|
|||
PVOID SystemBuffer;
|
||||
KPROCESSOR_MODE PreviousMode;
|
||||
|
||||
ASSERT(IoStatusBlock != NULL);
|
||||
ASSERT(FsInformation != NULL);
|
||||
|
||||
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(FsInformation != NULL);
|
||||
}
|
||||
|
||||
Status = ObReferenceObjectByHandle(FileHandle,
|
||||
FILE_WRITE_ATTRIBUTES,
|
||||
|
@ -306,14 +378,41 @@ NtSetVolumeInformationFile(IN HANDLE FileHandle,
|
|||
TAG_SYSB);
|
||||
if (SystemBuffer == NULL)
|
||||
{
|
||||
IoFreeIrp(Irp);
|
||||
ObDereferenceObject(FileObject);
|
||||
return(STATUS_INSUFFICIENT_RESOURCES);
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
goto failfreeirp;
|
||||
}
|
||||
|
||||
MmSafeCopyFromUser(SystemBuffer,
|
||||
FsInformation,
|
||||
Length);
|
||||
if (PreviousMode != KernelMode)
|
||||
{
|
||||
_SEH_TRY
|
||||
{
|
||||
/* no need to probe again */
|
||||
RtlCopyMemory(SystemBuffer,
|
||||
FsInformation,
|
||||
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 */
|
||||
Irp->Tail.Overlay.OriginalFileObject = FileObject;
|
||||
|
@ -343,7 +442,15 @@ NtSetVolumeInformationFile(IN HANDLE FileHandle,
|
|||
PreviousMode,
|
||||
FALSE,
|
||||
NULL);
|
||||
Status = IoStatusBlock->Status;
|
||||
_SEH_TRY
|
||||
{
|
||||
Status = IoStatusBlock->Status;
|
||||
}
|
||||
_SEH_HANDLE
|
||||
{
|
||||
Status = _SEH_GetExceptionCode();
|
||||
}
|
||||
_SEH_END;
|
||||
}
|
||||
|
||||
ExFreePool(SystemBuffer);
|
||||
|
|
|
@ -47,8 +47,7 @@ extern void DbgPrint(const char *format, ...);
|
|||
extern unsigned int KdbSymPrintAddress(void* address);
|
||||
struct disassemble_info;
|
||||
|
||||
#define KdbpSafeReadMemory(dst, src, size) MmSafeCopyFromUser(dst, src, size)
|
||||
extern long MmSafeCopyFromUser(void *Dest, void *Src, unsigned long NumberOfBytes);
|
||||
extern long KdbpSafeReadMemory(void*, void*, unsigned int);
|
||||
|
||||
|
||||
int
|
||||
|
|
|
@ -1549,3 +1549,53 @@ KdbpGetCommandLineSettings(PCHAR p1)
|
|||
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);
|
||||
/* other functions */
|
||||
|
||||
#define KdbpSafeReadMemory(dst, src, size) MmSafeCopyFromUser(dst, src, size)
|
||||
#define KdbpSafeWriteMemory(dst, src, size) MmSafeCopyToUser(dst, src, size)
|
||||
NTSTATUS
|
||||
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)
|
||||
CHAR
|
||||
|
|
|
@ -100,7 +100,7 @@ KiDispatchException(PEXCEPTION_RECORD ExceptionRecord,
|
|||
ULONG CDest;
|
||||
char temp_space[12 + sizeof(EXCEPTION_RECORD) + sizeof(CONTEXT)]; /* FIXME: HACKHACK */
|
||||
PULONG pNewUserStack = (PULONG)(Tf->Esp - (12 + sizeof(EXCEPTION_RECORD) + sizeof(CONTEXT)));
|
||||
NTSTATUS StatusOfCopy;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
|
||||
/* Enter Debugger if available */
|
||||
Action = KdpEnterDebuggerException(ExceptionRecord,
|
||||
|
@ -130,12 +130,23 @@ KiDispatchException(PEXCEPTION_RECORD ExceptionRecord,
|
|||
memcpy(&Stack[CDest], Context, sizeof(CONTEXT));
|
||||
|
||||
/* Copy Stack */
|
||||
StatusOfCopy = MmCopyToCaller(pNewUserStack,
|
||||
temp_space,
|
||||
(12 + sizeof(EXCEPTION_RECORD) + sizeof(CONTEXT)));
|
||||
_SEH_TRY
|
||||
{
|
||||
ProbeForWrite(pNewUserStack,
|
||||
12 + sizeof(EXCEPTION_RECORD) + sizeof(CONTEXT),
|
||||
1);
|
||||
RtlCopyMemory(pNewUserStack,
|
||||
temp_space,
|
||||
12 + sizeof(EXCEPTION_RECORD) + sizeof(CONTEXT));
|
||||
}
|
||||
_SEH_HANDLE
|
||||
{
|
||||
Status = _SEH_GetExceptionCode();
|
||||
}
|
||||
_SEH_END;
|
||||
|
||||
/* Check for success */
|
||||
if (NT_SUCCESS(StatusOfCopy))
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* Set new Stack Pointer */
|
||||
Tf->Esp = (ULONG)pNewUserStack;
|
||||
|
|
|
@ -25,7 +25,7 @@ print_user_address(PVOID address)
|
|||
PPEB Peb = NULL;
|
||||
ULONG_PTR RelativeAddress;
|
||||
PPEB_LDR_DATA Ldr;
|
||||
NTSTATUS Status;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
|
||||
CurrentProcess = PsGetCurrentProcess();
|
||||
if (NULL != CurrentProcess)
|
||||
|
@ -39,7 +39,17 @@ print_user_address(PVOID address)
|
|||
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))
|
||||
{
|
||||
DbgPrint("<%x>", address);
|
||||
|
|
|
@ -44,42 +44,64 @@ NtEarlyInitVdm(VOID)
|
|||
NTSTATUS STDCALL NtVdmControl(ULONG ControlCode,
|
||||
PVOID ControlData)
|
||||
{
|
||||
switch (ControlCode)
|
||||
KPROCESSOR_MODE PreviousMode;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
|
||||
PreviousMode = ExGetPreviousMode();
|
||||
|
||||
if (PreviousMode != KernelMode)
|
||||
{
|
||||
case 0:
|
||||
memcpy(ControlData, OrigIVT, 1024);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
memcpy(ControlData, OrigBDA, 256);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
_SEH_TRY
|
||||
{
|
||||
KV86M_REGISTERS V86Registers;
|
||||
ULONG ret;
|
||||
switch (ControlCode)
|
||||
{
|
||||
case 0:
|
||||
ProbeForWrite(ControlData,
|
||||
1024,
|
||||
1);
|
||||
memcpy(ControlData, OrigIVT, 1024);
|
||||
break;
|
||||
|
||||
ret = MmCopyFromCaller(&V86Registers,
|
||||
ControlData,
|
||||
sizeof(KV86M_REGISTERS));
|
||||
if(!NT_SUCCESS(ret)) return ret;
|
||||
case 1:
|
||||
ProbeForWrite(ControlData,
|
||||
256,
|
||||
1);
|
||||
memcpy(ControlData, OrigBDA, 256);
|
||||
break;
|
||||
|
||||
/* FIXME: This should use ->VdmObjects */
|
||||
KeGetCurrentProcess()->Unused = 1;
|
||||
Ki386RetToV86Mode(&V86Registers, &V86Registers);
|
||||
case 2:
|
||||
{
|
||||
KV86M_REGISTERS V86Registers;
|
||||
|
||||
ProbeForWrite(ControlData,
|
||||
sizeof(KV86M_REGISTERS),
|
||||
1);
|
||||
memcpy(&V86Registers,
|
||||
ControlData,
|
||||
sizeof(KV86M_REGISTERS));
|
||||
|
||||
/* FIXME: This should use ->VdmObjects */
|
||||
KeGetCurrentProcess()->Unused = 0;
|
||||
/* FIXME: This should use ->VdmObjects */
|
||||
KeGetCurrentProcess()->Unused = 1;
|
||||
Ki386RetToV86Mode(&V86Registers, &V86Registers);
|
||||
|
||||
ret = MmCopyToCaller(ControlData,
|
||||
&V86Registers,
|
||||
sizeof(KV86M_REGISTERS));
|
||||
if(!NT_SUCCESS(ret)) return ret;
|
||||
|
||||
break;
|
||||
/* FIXME: This should use ->VdmObjects */
|
||||
KeGetCurrentProcess()->Unused = 0;
|
||||
|
||||
memcpy(ControlData,
|
||||
&V86Registers,
|
||||
sizeof(KV86M_REGISTERS));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
_SEH_HANDLE
|
||||
{
|
||||
Status = _SEH_GetExceptionCode();
|
||||
}
|
||||
_SEH_END;
|
||||
}
|
||||
return(STATUS_SUCCESS);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -255,21 +255,72 @@ NtConnectPort (PHANDLE UnsafeConnectedPortHandle,
|
|||
PSECTION_OBJECT SectionObject;
|
||||
LARGE_INTEGER SectionOffset;
|
||||
PEPORT ConnectedPort;
|
||||
NTSTATUS Status;
|
||||
KPROCESSOR_MODE PreviousMode;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
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.
|
||||
*/
|
||||
if (UnsafeWriteMap != NULL)
|
||||
{
|
||||
Status = MmCopyFromCaller(&WriteMap,
|
||||
UnsafeWriteMap,
|
||||
sizeof(LPC_SECTION_WRITE));
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return(Status);
|
||||
}
|
||||
if (PreviousMode != KernelMode)
|
||||
{
|
||||
_SEH_TRY
|
||||
{
|
||||
ProbeForWrite(UnsafeWriteMap,
|
||||
sizeof(LPC_SECTION_WRITE),
|
||||
1);
|
||||
RtlCopyMemory(&WriteMap,
|
||||
UnsafeWriteMap,
|
||||
sizeof(LPC_SECTION_WRITE));
|
||||
}
|
||||
_SEH_HANDLE
|
||||
{
|
||||
Status = _SEH_GetExceptionCode();
|
||||
}
|
||||
_SEH_END;
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RtlCopyMemory(&WriteMap,
|
||||
UnsafeWriteMap,
|
||||
sizeof(LPC_SECTION_WRITE));
|
||||
}
|
||||
|
||||
if (WriteMap.Length != sizeof(LPC_SECTION_WRITE))
|
||||
{
|
||||
return(STATUS_INVALID_PARAMETER_4);
|
||||
|
@ -291,34 +342,69 @@ NtConnectPort (PHANDLE UnsafeConnectedPortHandle,
|
|||
}
|
||||
else
|
||||
{
|
||||
if (ExGetPreviousMode() == KernelMode)
|
||||
{
|
||||
ConnectDataLength = *UnsafeConnectDataLength;
|
||||
ConnectData = UnsafeConnectData;
|
||||
}
|
||||
if (PreviousMode != KernelMode)
|
||||
{
|
||||
_SEH_TRY
|
||||
{
|
||||
ProbeForRead(UnsafeConnectDataLength,
|
||||
sizeof(ULONG),
|
||||
1);
|
||||
ConnectDataLength = *UnsafeConnectDataLength;
|
||||
}
|
||||
_SEH_HANDLE
|
||||
{
|
||||
Status = _SEH_GetExceptionCode();
|
||||
}
|
||||
_SEH_END;
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Status = MmCopyFromCaller(&ConnectDataLength,
|
||||
UnsafeConnectDataLength,
|
||||
sizeof(ULONG));
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return(Status);
|
||||
}
|
||||
ConnectData = ExAllocatePool(NonPagedPool, ConnectDataLength);
|
||||
if (ConnectData == NULL && ConnectDataLength != 0)
|
||||
{
|
||||
return(STATUS_NO_MEMORY);
|
||||
}
|
||||
Status = MmCopyFromCaller(ConnectData,
|
||||
UnsafeConnectData,
|
||||
ConnectDataLength);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ExFreePool(ConnectData);
|
||||
return(Status);
|
||||
}
|
||||
}
|
||||
{
|
||||
ConnectDataLength = *UnsafeConnectDataLength;
|
||||
}
|
||||
|
||||
if (ConnectDataLength != 0)
|
||||
{
|
||||
ConnectData = ExAllocatePool(NonPagedPool, ConnectDataLength);
|
||||
if (ConnectData == NULL)
|
||||
{
|
||||
return(STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
if (PreviousMode != KernelMode)
|
||||
{
|
||||
_SEH_TRY
|
||||
{
|
||||
ProbeForWrite(UnsafeConnectData,
|
||||
ConnectDataLength,
|
||||
1);
|
||||
RtlCopyMemory(ConnectData,
|
||||
UnsafeConnectData,
|
||||
ConnectDataLength);
|
||||
}
|
||||
_SEH_HANDLE
|
||||
{
|
||||
Status = _SEH_GetExceptionCode();
|
||||
}
|
||||
_SEH_END;
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ExFreePool(ConnectData);
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RtlCopyMemory(ConnectData,
|
||||
UnsafeConnectData,
|
||||
ConnectDataLength);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -387,16 +473,30 @@ NtConnectPort (PHANDLE UnsafeConnectedPortHandle,
|
|||
/* FIXME: Again, check what NT does here. */
|
||||
if (UnsafeConnectDataLength != NULL)
|
||||
{
|
||||
if (ExGetPreviousMode() != KernelMode)
|
||||
if (PreviousMode != KernelMode)
|
||||
{
|
||||
MmCopyToCaller(UnsafeConnectData,
|
||||
ConnectData,
|
||||
ConnectDataLength);
|
||||
ExFreePool(ConnectData);
|
||||
_SEH_TRY
|
||||
{
|
||||
RtlCopyMemory(UnsafeConnectData,
|
||||
ConnectData,
|
||||
ConnectDataLength);
|
||||
*UnsafeConnectDataLength = ConnectDataLength;
|
||||
}
|
||||
_SEH_HANDLE
|
||||
{
|
||||
Status = _SEH_GetExceptionCode();
|
||||
}
|
||||
_SEH_END;
|
||||
}
|
||||
MmCopyToCaller(UnsafeConnectDataLength,
|
||||
&ConnectDataLength,
|
||||
sizeof(ULONG));
|
||||
else
|
||||
{
|
||||
RtlCopyMemory(UnsafeConnectData,
|
||||
ConnectData,
|
||||
ConnectDataLength);
|
||||
*UnsafeConnectDataLength = ConnectDataLength;
|
||||
}
|
||||
|
||||
ExFreePool(ConnectData);
|
||||
}
|
||||
return(Status);
|
||||
}
|
||||
|
@ -415,28 +515,52 @@ NtConnectPort (PHANDLE UnsafeConnectedPortHandle,
|
|||
/*
|
||||
* Copy the data back to the caller.
|
||||
*/
|
||||
if (ExGetPreviousMode() != KernelMode)
|
||||
|
||||
if (UnsafeConnectDataLength != NULL)
|
||||
{
|
||||
if (UnsafeConnectDataLength != NULL)
|
||||
if (PreviousMode != KernelMode)
|
||||
{
|
||||
Status = MmCopyToCaller(UnsafeConnectDataLength,
|
||||
&ConnectDataLength,
|
||||
sizeof(ULONG));
|
||||
_SEH_TRY
|
||||
{
|
||||
*UnsafeConnectDataLength = ConnectDataLength;
|
||||
|
||||
if (ConnectData != NULL)
|
||||
{
|
||||
RtlCopyMemory(UnsafeConnectData,
|
||||
ConnectData,
|
||||
ConnectDataLength);
|
||||
}
|
||||
}
|
||||
_SEH_HANDLE
|
||||
{
|
||||
Status = _SEH_GetExceptionCode();
|
||||
}
|
||||
_SEH_END;
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return(Status);
|
||||
if (ConnectData != NULL)
|
||||
{
|
||||
ExFreePool(ConnectData);
|
||||
}
|
||||
return(Status);
|
||||
}
|
||||
}
|
||||
if (UnsafeConnectData != NULL && ConnectData != NULL)
|
||||
else
|
||||
{
|
||||
*UnsafeConnectDataLength = ConnectDataLength;
|
||||
|
||||
if (ConnectData != NULL)
|
||||
{
|
||||
RtlCopyMemory(UnsafeConnectData,
|
||||
ConnectData,
|
||||
ConnectDataLength);
|
||||
}
|
||||
}
|
||||
|
||||
if (ConnectData != NULL)
|
||||
{
|
||||
Status = MmCopyToCaller(UnsafeConnectData,
|
||||
ConnectData,
|
||||
ConnectDataLength);
|
||||
ExFreePool(ConnectData);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return(Status);
|
||||
}
|
||||
}
|
||||
}
|
||||
Status = ObInsertObject(ConnectedPort,
|
||||
|
@ -449,42 +573,65 @@ NtConnectPort (PHANDLE UnsafeConnectedPortHandle,
|
|||
{
|
||||
return(Status);
|
||||
}
|
||||
Status = MmCopyToCaller(UnsafeConnectedPortHandle,
|
||||
&ConnectedPortHandle,
|
||||
sizeof(HANDLE));
|
||||
if (!NT_SUCCESS(Status))
|
||||
|
||||
if (PreviousMode != KernelMode)
|
||||
{
|
||||
return(Status);
|
||||
}
|
||||
if (UnsafeWriteMap != NULL)
|
||||
{
|
||||
Status = MmCopyToCaller(UnsafeWriteMap,
|
||||
&WriteMap,
|
||||
sizeof(LPC_SECTION_WRITE));
|
||||
_SEH_TRY
|
||||
{
|
||||
*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;
|
||||
}
|
||||
}
|
||||
_SEH_HANDLE
|
||||
{
|
||||
Status = _SEH_GetExceptionCode();
|
||||
}
|
||||
_SEH_END;
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return(Status);
|
||||
}
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
if (UnsafeReadMap != NULL)
|
||||
else
|
||||
{
|
||||
Status = MmCopyToCaller(UnsafeReadMap,
|
||||
&ReadMap,
|
||||
sizeof(LPC_SECTION_READ));
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return(Status);
|
||||
}
|
||||
}
|
||||
if (UnsafeMaximumMessageSize != NULL)
|
||||
{
|
||||
Status = MmCopyToCaller(UnsafeMaximumMessageSize,
|
||||
&MaximumMessageSize,
|
||||
sizeof(ULONG));
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return(Status);
|
||||
}
|
||||
*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,
|
||||
IN PLARGE_INTEGER Timeout)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PEPORT Port;
|
||||
KIRQL oldIrql;
|
||||
PQUEUEDMESSAGE Request;
|
||||
BOOLEAN Disconnected;
|
||||
LARGE_INTEGER to;
|
||||
KPROCESSOR_MODE PreviousMode;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
|
||||
PreviousMode = ExGetPreviousMode();
|
||||
|
||||
DPRINT("NtReplyWaitReceivePortEx(PortHandle %x, LpcReply %x, "
|
||||
"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,
|
||||
PORT_ALL_ACCESS,
|
||||
LpcPortObjectType,
|
||||
|
@ -238,18 +261,64 @@ NtReplyWaitReceivePortEx(IN HANDLE PortHandle,
|
|||
memcpy(&Header, &Request->Message, sizeof(LPC_MESSAGE));
|
||||
Header.DataSize = CRequest->ConnectDataLength;
|
||||
Header.MessageSize = Header.DataSize + sizeof(LPC_MESSAGE);
|
||||
Status = MmCopyToCaller(LpcMessage, &Header, sizeof(LPC_MESSAGE));
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
Status = MmCopyToCaller((PVOID)(LpcMessage + 1),
|
||||
CRequest->ConnectData,
|
||||
CRequest->ConnectDataLength);
|
||||
}
|
||||
|
||||
if (PreviousMode != KernelMode)
|
||||
{
|
||||
_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->ConnectDataLength);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Status = MmCopyToCaller(LpcMessage, &Request->Message,
|
||||
Request->Message.MessageSize);
|
||||
if (PreviousMode != KernelMode)
|
||||
{
|
||||
_SEH_TRY
|
||||
{
|
||||
ProbeForWrite(LpcMessage,
|
||||
Request->Message.MessageSize,
|
||||
1);
|
||||
|
||||
RtlCopyMemory(LpcMessage,
|
||||
&Request->Message,
|
||||
Request->Message.MessageSize);
|
||||
}
|
||||
_SEH_HANDLE
|
||||
{
|
||||
Status = _SEH_GetExceptionCode();
|
||||
}
|
||||
_SEH_END;
|
||||
}
|
||||
else
|
||||
{
|
||||
RtlCopyMemory(LpcMessage,
|
||||
&Request->Message,
|
||||
Request->Message.MessageSize);
|
||||
}
|
||||
}
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
|
|
|
@ -219,12 +219,43 @@ NtRequestWaitReplyPort (IN HANDLE PortHandle,
|
|||
{
|
||||
PETHREAD CurrentThread;
|
||||
struct _KPROCESS *AttachedProcess;
|
||||
NTSTATUS Status;
|
||||
PEPORT Port;
|
||||
PQUEUEDMESSAGE Message;
|
||||
KIRQL oldIrql;
|
||||
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, "
|
||||
"LpcReply %x)\n", PortHandle, UnsafeLpcRequest, UnsafeLpcReply);
|
||||
|
@ -261,18 +292,6 @@ NtRequestWaitReplyPort (IN HANDLE PortHandle,
|
|||
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 (NULL != AttachedProcess)
|
||||
|
@ -292,19 +311,42 @@ NtRequestWaitReplyPort (IN HANDLE PortHandle,
|
|||
ObDereferenceObject(Port);
|
||||
return(STATUS_NO_MEMORY);
|
||||
}
|
||||
Status = MmCopyFromCaller(LpcRequest, UnsafeLpcRequest,
|
||||
LpcRequestMessageSize);
|
||||
if (!NT_SUCCESS(Status))
|
||||
if (PreviousMode != KernelMode)
|
||||
{
|
||||
ExFreePool(LpcRequest);
|
||||
if (NULL != AttachedProcess)
|
||||
_SEH_TRY
|
||||
{
|
||||
KeAttachProcess(AttachedProcess);
|
||||
RtlCopyMemory(LpcRequest,
|
||||
UnsafeLpcRequest,
|
||||
LpcRequestMessageSize);
|
||||
LpcRequestMessageSize = LpcRequest->MessageSize;
|
||||
LpcRequestDataSize = LpcRequest->DataSize;
|
||||
}
|
||||
_SEH_HANDLE
|
||||
{
|
||||
Status = _SEH_GetExceptionCode();
|
||||
}
|
||||
_SEH_END;
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ExFreePool(LpcRequest);
|
||||
if (NULL != AttachedProcess)
|
||||
{
|
||||
KeAttachProcess(AttachedProcess);
|
||||
}
|
||||
ObDereferenceObject(Port);
|
||||
return(Status);
|
||||
}
|
||||
ObDereferenceObject(Port);
|
||||
return(Status);
|
||||
}
|
||||
LpcRequestMessageSize = LpcRequest->MessageSize;
|
||||
else
|
||||
{
|
||||
RtlCopyMemory(LpcRequest,
|
||||
UnsafeLpcRequest,
|
||||
LpcRequestMessageSize);
|
||||
LpcRequestMessageSize = LpcRequest->MessageSize;
|
||||
LpcRequestDataSize = LpcRequest->DataSize;
|
||||
}
|
||||
|
||||
if (LpcRequestMessageSize > (sizeof(LPC_MESSAGE) + MAX_MESSAGE_DATA))
|
||||
{
|
||||
ExFreePool(LpcRequest);
|
||||
|
@ -315,7 +357,7 @@ NtRequestWaitReplyPort (IN HANDLE PortHandle,
|
|||
ObDereferenceObject(Port);
|
||||
return(STATUS_PORT_MESSAGE_TOO_LONG);
|
||||
}
|
||||
if (LpcRequest->DataSize != (LpcRequest->MessageSize - sizeof(LPC_MESSAGE)))
|
||||
if (LpcRequestDataSize != (LpcRequestMessageSize - sizeof(LPC_MESSAGE)))
|
||||
{
|
||||
ExFreePool(LpcRequest);
|
||||
if (NULL != AttachedProcess)
|
||||
|
@ -366,8 +408,26 @@ NtRequestWaitReplyPort (IN HANDLE PortHandle,
|
|||
{
|
||||
DPRINT("Message->Message.MessageSize %d\n",
|
||||
Message->Message.MessageSize);
|
||||
Status = MmCopyToCaller(UnsafeLpcReply, &Message->Message,
|
||||
Message->Message.MessageSize);
|
||||
if (PreviousMode != KernelMode)
|
||||
{
|
||||
_SEH_TRY
|
||||
{
|
||||
RtlCopyMemory(UnsafeLpcReply,
|
||||
&Message->Message,
|
||||
Message->Message.MessageSize);
|
||||
}
|
||||
_SEH_HANDLE
|
||||
{
|
||||
Status = _SEH_GetExceptionCode();
|
||||
}
|
||||
_SEH_END;
|
||||
}
|
||||
else
|
||||
{
|
||||
RtlCopyMemory(UnsafeLpcReply,
|
||||
&Message->Message,
|
||||
Message->Message.MessageSize);
|
||||
}
|
||||
ExFreePool(Message);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -1,91 +1,7 @@
|
|||
.globl _MmSafeCopyFromUser
|
||||
.globl _MmSafeCopyFromUserUnsafeStart
|
||||
.globl _MmSafeCopyFromUserRestart
|
||||
.globl _MmSafeCopyToUser
|
||||
.globl _MmSafeCopyToUserUnsafeStart
|
||||
.globl _MmSafeCopyToUserRestart
|
||||
.globl @MmSafeReadPtr@4
|
||||
.globl _MmSafeReadPtrStart
|
||||
.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 *******************************************************************/
|
||||
|
||||
extern VOID MmSafeCopyFromUserUnsafeStart(VOID);
|
||||
extern VOID MmSafeCopyFromUserRestart(VOID);
|
||||
extern VOID MmSafeCopyToUserUnsafeStart(VOID);
|
||||
extern VOID MmSafeCopyToUserRestart(VOID);
|
||||
extern VOID MmSafeReadPtrStart(VOID);
|
||||
extern VOID MmSafeReadPtrEnd(VOID);
|
||||
|
||||
|
@ -76,22 +72,7 @@ NTSTATUS MmPageFault(ULONG Cs,
|
|||
KiDeliverApc(KernelMode, NULL, NULL);
|
||||
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) &&
|
||||
((*Eip) >= (ULONG_PTR)MmSafeReadPtrStart) &&
|
||||
((*Eip) <= (ULONG_PTR)MmSafeReadPtrEnd))
|
||||
|
|
|
@ -28,50 +28,6 @@ MM_STATS MmStats;
|
|||
/* 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 Status;
|
||||
|
|
|
@ -269,9 +269,9 @@ NtQueryVirtualMemory (IN HANDLE ProcessHandle,
|
|||
IN ULONG Length,
|
||||
OUT PULONG UnsafeResultLength)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
ULONG ResultLength = 0;
|
||||
KPROCESSOR_MODE PrevMode;
|
||||
KPROCESSOR_MODE PreviousMode;
|
||||
union
|
||||
{
|
||||
MEMORY_BASIC_INFORMATION BasicInfo;
|
||||
|
@ -284,7 +284,27 @@ NtQueryVirtualMemory (IN HANDLE ProcessHandle,
|
|||
VirtualMemoryInformationClass,VirtualMemoryInformation,
|
||||
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)
|
||||
{
|
||||
|
@ -299,19 +319,48 @@ NtQueryVirtualMemory (IN HANDLE ProcessHandle,
|
|||
Length,
|
||||
&ResultLength );
|
||||
|
||||
if (NT_SUCCESS(Status) && ResultLength > 0)
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
Status = MmCopyToCaller(VirtualMemoryInformation, &VirtualMemoryInfo, ResultLength);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ResultLength = 0;
|
||||
}
|
||||
if (PreviousMode != KernelMode)
|
||||
{
|
||||
_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)
|
||||
{
|
||||
*UnsafeResultLength = ResultLength;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (UnsafeResultLength != NULL)
|
||||
{
|
||||
MmCopyToCaller(UnsafeResultLength, &ResultLength, sizeof(ULONG));
|
||||
}
|
||||
return(Status);
|
||||
}
|
||||
|
||||
|
@ -384,17 +433,47 @@ NtProtectVirtualMemory(IN HANDLE ProcessHandle,
|
|||
OUT PULONG UnsafeOldAccessProtection)
|
||||
{
|
||||
PEPROCESS Process;
|
||||
NTSTATUS Status;
|
||||
ULONG OldAccessProtection;
|
||||
PVOID BaseAddress;
|
||||
ULONG NumberOfBytesToProtect;
|
||||
PVOID BaseAddress = NULL;
|
||||
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));
|
||||
|
||||
Status = MmCopyFromCaller(&BaseAddress, UnsafeBaseAddress, sizeof(PVOID));
|
||||
if (!NT_SUCCESS(Status))
|
||||
return Status;
|
||||
Status = MmCopyFromCaller(&NumberOfBytesToProtect, UnsafeNumberOfBytesToProtect, sizeof(ULONG));
|
||||
if (!NT_SUCCESS(Status))
|
||||
return Status;
|
||||
BaseAddress = *UnsafeBaseAddress;
|
||||
NumberOfBytesToProtect = *UnsafeNumberOfBytesToProtect;
|
||||
}
|
||||
_SEH_HANDLE
|
||||
{
|
||||
Status = _SEH_GetExceptionCode();
|
||||
}
|
||||
_SEH_END;
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
BaseAddress = *UnsafeBaseAddress;
|
||||
NumberOfBytesToProtect = *UnsafeNumberOfBytesToProtect;
|
||||
}
|
||||
|
||||
/* (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'
|
||||
|
@ -424,9 +503,26 @@ NtProtectVirtualMemory(IN HANDLE ProcessHandle,
|
|||
|
||||
ObDereferenceObject(Process);
|
||||
|
||||
MmCopyToCaller(UnsafeOldAccessProtection, &OldAccessProtection, sizeof(ULONG));
|
||||
MmCopyToCaller(UnsafeBaseAddress, &BaseAddress, sizeof(PVOID));
|
||||
MmCopyToCaller(UnsafeNumberOfBytesToProtect, &NumberOfBytesToProtect, sizeof(ULONG));
|
||||
if (PreviousMode != KernelMode)
|
||||
{
|
||||
_SEH_TRY
|
||||
{
|
||||
*UnsafeOldAccessProtection = OldAccessProtection;
|
||||
*UnsafeBaseAddress = BaseAddress;
|
||||
*UnsafeNumberOfBytesToProtect = NumberOfBytesToProtect;
|
||||
}
|
||||
_SEH_HANDLE
|
||||
{
|
||||
Status = _SEH_GetExceptionCode();
|
||||
}
|
||||
_SEH_END;
|
||||
}
|
||||
else
|
||||
{
|
||||
*UnsafeOldAccessProtection = OldAccessProtection;
|
||||
*UnsafeBaseAddress = BaseAddress;
|
||||
*UnsafeNumberOfBytesToProtect = NumberOfBytesToProtect;
|
||||
}
|
||||
|
||||
return(Status);
|
||||
}
|
||||
|
@ -648,18 +744,41 @@ NtWriteVirtualMemory(IN HANDLE ProcessHandle,
|
|||
IN ULONG NumberOfBytesToWrite,
|
||||
OUT PULONG NumberOfBytesWritten OPTIONAL)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PMDL Mdl;
|
||||
PVOID SystemAddress;
|
||||
PEPROCESS Process;
|
||||
ULONG OldProtection = 0;
|
||||
PVOID ProtectBaseAddress;
|
||||
ULONG ProtectNumberOfBytes;
|
||||
KPROCESSOR_MODE PreviousMode;
|
||||
NTSTATUS CopyStatus, Status = STATUS_SUCCESS;
|
||||
|
||||
DPRINT("NtWriteVirtualMemory(ProcessHandle %x, BaseAddress %x, "
|
||||
"Buffer %x, NumberOfBytesToWrite %d)\n",ProcessHandle,BaseAddress,
|
||||
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,
|
||||
PROCESS_VM_WRITE,
|
||||
NULL,
|
||||
|
@ -680,6 +799,8 @@ NtWriteVirtualMemory(IN HANDLE ProcessHandle,
|
|||
*/
|
||||
ProtectBaseAddress = BaseAddress;
|
||||
ProtectNumberOfBytes = NumberOfBytesToWrite;
|
||||
|
||||
CopyStatus = STATUS_SUCCESS;
|
||||
|
||||
/* Write memory */
|
||||
if (Process == PsGetCurrentProcess())
|
||||
|
@ -694,7 +815,23 @@ NtWriteVirtualMemory(IN HANDLE ProcessHandle,
|
|||
ObDereferenceObject(Process);
|
||||
return Status;
|
||||
}
|
||||
memcpy(BaseAddress, Buffer, NumberOfBytesToWrite);
|
||||
|
||||
if (PreviousMode != KernelMode)
|
||||
{
|
||||
_SEH_TRY
|
||||
{
|
||||
memcpy(BaseAddress, Buffer, NumberOfBytesToWrite);
|
||||
}
|
||||
_SEH_HANDLE
|
||||
{
|
||||
CopyStatus = _SEH_GetExceptionCode();
|
||||
}
|
||||
_SEH_END;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(BaseAddress, Buffer, NumberOfBytesToWrite);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -730,7 +867,22 @@ NtWriteVirtualMemory(IN HANDLE ProcessHandle,
|
|||
KeAttachProcess(&Process->Pcb);
|
||||
|
||||
SystemAddress = MmGetSystemAddressForMdl(Mdl);
|
||||
memcpy(BaseAddress, SystemAddress, NumberOfBytesToWrite);
|
||||
if (PreviousMode != KernelMode)
|
||||
{
|
||||
_SEH_TRY
|
||||
{
|
||||
memcpy(BaseAddress, SystemAddress, NumberOfBytesToWrite);
|
||||
}
|
||||
_SEH_HANDLE
|
||||
{
|
||||
CopyStatus = _SEH_GetExceptionCode();
|
||||
}
|
||||
_SEH_END;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(BaseAddress, SystemAddress, NumberOfBytesToWrite);
|
||||
}
|
||||
|
||||
KeDetachProcess();
|
||||
|
||||
|
@ -758,9 +910,26 @@ NtWriteVirtualMemory(IN HANDLE ProcessHandle,
|
|||
ObDereferenceObject(Process);
|
||||
|
||||
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
|
||||
MmBuildMdlForNonPagedPool@4
|
||||
MmCanFileBeTruncated@8
|
||||
;MmCopyFromCaller@12
|
||||
;MmCopyToCaller@12
|
||||
MmCreateMdl@12
|
||||
MmCreateSection@32
|
||||
MmDbgTranslatePhysicalAddress@8
|
||||
|
|
|
@ -1135,7 +1135,6 @@ NtSetInformationThread (IN HANDLE ThreadHandle,
|
|||
IN ULONG ThreadInformationLength)
|
||||
{
|
||||
PETHREAD Thread;
|
||||
NTSTATUS Status;
|
||||
union
|
||||
{
|
||||
KPRIORITY Priority;
|
||||
|
@ -1144,8 +1143,12 @@ NtSetInformationThread (IN HANDLE ThreadHandle,
|
|||
HANDLE Handle;
|
||||
PVOID Address;
|
||||
}u;
|
||||
KPROCESSOR_MODE PreviousMode;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
PreviousMode = ExGetPreviousMode();
|
||||
|
||||
if (ThreadInformationClass <= MaxThreadInfoClass &&
|
||||
!SetInformationData[ThreadInformationClass].Implemented)
|
||||
|
@ -1162,20 +1165,41 @@ NtSetInformationThread (IN HANDLE ThreadHandle,
|
|||
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,
|
||||
THREAD_SET_INFORMATION,
|
||||
PsThreadType,
|
||||
ExGetPreviousMode (),
|
||||
(PVOID*)&Thread,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
|
||||
Status = MmCopyFromCaller(&u.Priority,
|
||||
ThreadInformation,
|
||||
SetInformationData[ThreadInformationClass].Size);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
switch (ThreadInformationClass)
|
||||
|
@ -1226,7 +1250,6 @@ NtQueryInformationThread (IN HANDLE ThreadHandle,
|
|||
OUT PULONG ReturnLength OPTIONAL)
|
||||
{
|
||||
PETHREAD Thread;
|
||||
NTSTATUS Status;
|
||||
union
|
||||
{
|
||||
THREAD_BASIC_INFORMATION TBI;
|
||||
|
@ -1235,8 +1258,12 @@ NtQueryInformationThread (IN HANDLE ThreadHandle,
|
|||
LARGE_INTEGER Count;
|
||||
BOOLEAN Last;
|
||||
}u;
|
||||
KPROCESSOR_MODE PreviousMode;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
PreviousMode = ExGetPreviousMode();
|
||||
|
||||
if (ThreadInformationClass <= MaxThreadInfoClass &&
|
||||
!QueryInformationData[ThreadInformationClass].Implemented)
|
||||
|
@ -1253,6 +1280,32 @@ NtQueryInformationThread (IN HANDLE ThreadHandle,
|
|||
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,
|
||||
THREAD_QUERY_INFORMATION,
|
||||
PsThreadType,
|
||||
|
@ -1311,23 +1364,41 @@ NtQueryInformationThread (IN HANDLE ThreadHandle,
|
|||
/* Shoult never occure if the data table is correct */
|
||||
KEBUGCHECK(0);
|
||||
}
|
||||
if (QueryInformationData[ThreadInformationClass].Size)
|
||||
|
||||
if (PreviousMode != KernelMode)
|
||||
{
|
||||
Status = MmCopyToCaller(ThreadInformation,
|
||||
&u.TBI,
|
||||
QueryInformationData[ThreadInformationClass].Size);
|
||||
}
|
||||
if (ReturnLength)
|
||||
{
|
||||
NTSTATUS Status2;
|
||||
static ULONG Null = 0;
|
||||
Status2 = MmCopyToCaller(ReturnLength,
|
||||
NT_SUCCESS(Status) ? &QueryInformationData[ThreadInformationClass].Size : &Null,
|
||||
sizeof(ULONG));
|
||||
if (NT_SUCCESS(Status))
|
||||
_SEH_TRY
|
||||
{
|
||||
Status = Status2;
|
||||
}
|
||||
if (QueryInformationData[ThreadInformationClass].Size)
|
||||
{
|
||||
RtlCopyMemory(ThreadInformation,
|
||||
&u.TBI,
|
||||
QueryInformationData[ThreadInformationClass].Size);
|
||||
}
|
||||
if (ReturnLength != NULL)
|
||||
{
|
||||
*ReturnLength = QueryInformationData[ThreadInformationClass].Size;
|
||||
}
|
||||
}
|
||||
_SEH_HANDLE
|
||||
{
|
||||
Status = _SEH_GetExceptionCode();
|
||||
}
|
||||
_SEH_END;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (QueryInformationData[ThreadInformationClass].Size)
|
||||
{
|
||||
RtlCopyMemory(ThreadInformation,
|
||||
&u.TBI,
|
||||
QueryInformationData[ThreadInformationClass].Size);
|
||||
}
|
||||
|
||||
if (ReturnLength != NULL)
|
||||
{
|
||||
*ReturnLength = QueryInformationData[ThreadInformationClass].Size;
|
||||
}
|
||||
}
|
||||
|
||||
ObDereferenceObject(Thread);
|
||||
|
|
|
@ -2052,6 +2052,7 @@ NtCreateToken(OUT PHANDLE TokenHandle,
|
|||
PVOID EndMem;
|
||||
ULONG uLength;
|
||||
ULONG i;
|
||||
ULONG nTokenPrivileges = 0;
|
||||
KPROCESSOR_MODE PreviousMode;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
|
||||
|
@ -2093,6 +2094,7 @@ NtCreateToken(OUT PHANDLE TokenHandle,
|
|||
ProbeForRead(TokenSource,
|
||||
sizeof(TOKEN_SOURCE),
|
||||
sizeof(ULONG));
|
||||
nTokenPrivileges = TokenPrivileges->PrivilegeCount;
|
||||
}
|
||||
_SEH_HANDLE
|
||||
{
|
||||
|
@ -2105,6 +2107,10 @@ NtCreateToken(OUT PHANDLE TokenHandle,
|
|||
return Status;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
nTokenPrivileges = TokenPrivileges->PrivilegeCount;
|
||||
}
|
||||
|
||||
Status = ZwAllocateLocallyUniqueId(&TokenId);
|
||||
if (!NT_SUCCESS(Status))
|
||||
|
@ -2203,14 +2209,26 @@ NtCreateToken(OUT PHANDLE TokenHandle,
|
|||
uLength,
|
||||
TAG('T', 'O', 'K', 'p'));
|
||||
|
||||
for (i = 0; i < TokenPrivileges->PrivilegeCount; i++)
|
||||
{
|
||||
Status = MmCopyFromCaller(&AccessToken->Privileges[i],
|
||||
&TokenPrivileges->Privileges[i],
|
||||
sizeof(LUID_AND_ATTRIBUTES));
|
||||
if (!NT_SUCCESS(Status))
|
||||
break;
|
||||
}
|
||||
if (PreviousMode != KernelMode)
|
||||
{
|
||||
_SEH_TRY
|
||||
{
|
||||
RtlCopyMemory(AccessToken->Privileges,
|
||||
TokenPrivileges->Privileges,
|
||||
nTokenPrivileges * sizeof(LUID_AND_ATTRIBUTES));
|
||||
}
|
||||
_SEH_HANDLE
|
||||
{
|
||||
Status = _SEH_GetExceptionCode();
|
||||
}
|
||||
_SEH_END;
|
||||
}
|
||||
else
|
||||
{
|
||||
RtlCopyMemory(AccessToken->Privileges,
|
||||
TokenPrivileges->Privileges,
|
||||
nTokenPrivileges * sizeof(LUID_AND_ATTRIBUTES));
|
||||
}
|
||||
}
|
||||
|
||||
if (NT_SUCCESS(Status))
|
||||
|
|
Loading…
Reference in a new issue