mirror of
https://github.com/reactos/reactos.git
synced 2025-05-18 16:51:18 +00:00
1. A few Nt vs. Zw fixes
2. Fixed and extended RtlCaptureUnicodeString() 3. securely access buffers in NtQuerySystemEnvironmentValue() and NtSetSystemEnvironmentValue() and check for required SeSystemEnvironmentPrivilege privilege svn path=/trunk/; revision=13208
This commit is contained in:
parent
9fbbec950f
commit
72ae3c4197
9 changed files with 294 additions and 243 deletions
|
@ -139,7 +139,7 @@ NTSTATUS STDCALL DriverEntry(IN PDRIVER_OBJECT DriverObject,
|
||||||
0 );
|
0 );
|
||||||
allocsize.u.LowPart = allocsize.u.HighPart = 0;
|
allocsize.u.LowPart = allocsize.u.HighPart = 0;
|
||||||
|
|
||||||
Status = NtOpenFile( &file,
|
Status = ZwOpenFile( &file,
|
||||||
GENERIC_READ,
|
GENERIC_READ,
|
||||||
&objattr,
|
&objattr,
|
||||||
&iosb,
|
&iosb,
|
||||||
|
@ -157,7 +157,7 @@ NTSTATUS STDCALL DriverEntry(IN PDRIVER_OBJECT DriverObject,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0 );
|
0 );
|
||||||
Status = NtCreateEvent( &event,
|
Status = ZwCreateEvent( &event,
|
||||||
0,
|
0,
|
||||||
&objattr,
|
&objattr,
|
||||||
NotificationEvent,
|
NotificationEvent,
|
||||||
|
@ -168,7 +168,7 @@ NTSTATUS STDCALL DriverEntry(IN PDRIVER_OBJECT DriverObject,
|
||||||
goto cleanfile;
|
goto cleanfile;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = NtQueryInformationFile( file,
|
Status = ZwQueryInformationFile( file,
|
||||||
&iosb,
|
&iosb,
|
||||||
&finfo,
|
&finfo,
|
||||||
sizeof( finfo ),
|
sizeof( finfo ),
|
||||||
|
@ -187,7 +187,7 @@ NTSTATUS STDCALL DriverEntry(IN PDRIVER_OBJECT DriverObject,
|
||||||
goto cleanevent;
|
goto cleanevent;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = NtReadFile( file,
|
Status = ZwReadFile( file,
|
||||||
event,
|
event,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
|
@ -202,7 +202,7 @@ NTSTATUS STDCALL DriverEntry(IN PDRIVER_OBJECT DriverObject,
|
||||||
DPRINT( "Failed to read floppy\n" );
|
DPRINT( "Failed to read floppy\n" );
|
||||||
goto cleantbuff;
|
goto cleantbuff;
|
||||||
}
|
}
|
||||||
Status = NtWaitForSingleObject( event, FALSE, 0 );
|
Status = ZwWaitForSingleObject( event, FALSE, 0 );
|
||||||
if( Status != STATUS_WAIT_0 || !NT_SUCCESS( iosb.Status ) )
|
if( Status != STATUS_WAIT_0 || !NT_SUCCESS( iosb.Status ) )
|
||||||
{
|
{
|
||||||
DPRINT( "Failed to read floppy\n" );
|
DPRINT( "Failed to read floppy\n" );
|
||||||
|
@ -221,16 +221,16 @@ NTSTATUS STDCALL DriverEntry(IN PDRIVER_OBJECT DriverObject,
|
||||||
}
|
}
|
||||||
else DbgPrint( "RAMDRV: Failed to decomparess image, error: %d\n", err );
|
else DbgPrint( "RAMDRV: Failed to decomparess image, error: %d\n", err );
|
||||||
ExFreePool( tbuff );
|
ExFreePool( tbuff );
|
||||||
NtClose( file );
|
ZwClose( file );
|
||||||
NtClose( event );
|
ZwClose( event );
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
|
|
||||||
cleantbuff:
|
cleantbuff:
|
||||||
ExFreePool( tbuff );
|
ExFreePool( tbuff );
|
||||||
cleanevent:
|
cleanevent:
|
||||||
NtClose( event );
|
ZwClose( event );
|
||||||
cleanfile:
|
cleanfile:
|
||||||
NtClose( file );
|
ZwClose( file );
|
||||||
cleanbuffer:
|
cleanbuffer:
|
||||||
ExFreePool( devext->Buffer );
|
ExFreePool( devext->Buffer );
|
||||||
|
|
||||||
|
|
|
@ -3107,19 +3107,19 @@ ZwQuerySymbolicLinkObject(
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
STDCALL
|
STDCALL
|
||||||
NtQuerySystemEnvironmentValue(
|
NtQuerySystemEnvironmentValue(
|
||||||
IN PUNICODE_STRING Name,
|
IN PUNICODE_STRING VariableName,
|
||||||
OUT PVOID Value,
|
OUT PWSTR ValueBuffer,
|
||||||
ULONG Length,
|
IN ULONG ValueBufferLength,
|
||||||
PULONG ReturnLength
|
OUT PULONG ReturnLength OPTIONAL
|
||||||
);
|
);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
STDCALL
|
STDCALL
|
||||||
ZwQuerySystemEnvironmentValue(
|
ZwQuerySystemEnvironmentValue(
|
||||||
IN PUNICODE_STRING Name,
|
IN PUNICODE_STRING VariableName,
|
||||||
OUT PVOID Value,
|
OUT PWSTR ValueBuffer,
|
||||||
ULONG Length,
|
IN ULONG ValueBufferLength,
|
||||||
PULONG ReturnLength
|
OUT PULONG ReturnLength OPTIONAL
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -90,10 +90,10 @@ ExGetCurrentProcessorCounts (
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS STDCALL
|
NTSTATUS STDCALL
|
||||||
NtQuerySystemEnvironmentValue (IN PUNICODE_STRING UnsafeName,
|
NtQuerySystemEnvironmentValue (IN PUNICODE_STRING VariableName,
|
||||||
OUT PVOID UnsafeValue,
|
OUT PWCHAR ValueBuffer,
|
||||||
IN ULONG Length,
|
IN ULONG ValueBufferLength,
|
||||||
IN OUT PULONG UnsafeReturnLength)
|
IN OUT PULONG ReturnLength OPTIONAL)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
ANSI_STRING AName;
|
ANSI_STRING AName;
|
||||||
|
@ -102,225 +102,197 @@ NtQuerySystemEnvironmentValue (IN PUNICODE_STRING UnsafeName,
|
||||||
PCH Value;
|
PCH Value;
|
||||||
ANSI_STRING AValue;
|
ANSI_STRING AValue;
|
||||||
UNICODE_STRING WValue;
|
UNICODE_STRING WValue;
|
||||||
ULONG ReturnLength;
|
KPROCESSOR_MODE PreviousMode;
|
||||||
|
|
||||||
|
PreviousMode = ExGetPreviousMode();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copy the name to kernel space if necessary and convert it to ANSI.
|
* Copy the name to kernel space if necessary and convert it to ANSI.
|
||||||
*/
|
*/
|
||||||
if (ExGetPreviousMode() != KernelMode)
|
Status = RtlCaptureUnicodeString(&WName,
|
||||||
|
PreviousMode,
|
||||||
|
NonPagedPool,
|
||||||
|
FALSE,
|
||||||
|
VariableName);
|
||||||
|
if(NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
if(PreviousMode != KernelMode)
|
||||||
{
|
{
|
||||||
Status = RtlCaptureUnicodeString(&WName, UnsafeName);
|
ProbeForWrite(ValueBuffer,
|
||||||
if (!NT_SUCCESS(Status))
|
ValueBufferLength,
|
||||||
{
|
sizeof(WCHAR));
|
||||||
return(Status);
|
if(ReturnLength != NULL)
|
||||||
}
|
{
|
||||||
Status = RtlUnicodeStringToAnsiString(&AName, UnsafeName, TRUE);
|
ProbeForWrite(ReturnLength,
|
||||||
if (!NT_SUCCESS(Status))
|
sizeof(ULONG),
|
||||||
{
|
sizeof(ULONG));
|
||||||
return(Status);
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
/*
|
||||||
|
* according to ntinternals the SeSystemEnvironmentName privilege is required!
|
||||||
|
*/
|
||||||
|
if(!SeSinglePrivilegeCheck(SeSystemEnvironmentPrivilege,
|
||||||
|
PreviousMode))
|
||||||
{
|
{
|
||||||
Status = RtlUnicodeStringToAnsiString(&AName, UnsafeName, TRUE);
|
RtlRelaseCapturedUnicodeString(&WName,
|
||||||
if (!NT_SUCCESS(Status))
|
PreviousMode,
|
||||||
{
|
FALSE);
|
||||||
return(Status);
|
return STATUS_PRIVILEGE_NOT_HELD;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* convert the value name to ansi
|
||||||
|
*/
|
||||||
|
Status = RtlUnicodeStringToAnsiString(&AName, &WName, TRUE);
|
||||||
|
RtlRelaseCapturedUnicodeString(&WName,
|
||||||
|
PreviousMode,
|
||||||
|
FALSE);
|
||||||
|
if(!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create a temporary buffer for the value
|
* Create a temporary buffer for the value
|
||||||
*/
|
*/
|
||||||
Value = ExAllocatePool(NonPagedPool, Length);
|
Value = ExAllocatePool(NonPagedPool, ValueBufferLength);
|
||||||
if (Value == NULL)
|
if (Value == NULL)
|
||||||
{
|
{
|
||||||
RtlFreeAnsiString(&AName);
|
RtlFreeAnsiString(&AName);
|
||||||
if (ExGetPreviousMode() != KernelMode)
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
{
|
|
||||||
RtlFreeUnicodeString(&WName);
|
|
||||||
}
|
|
||||||
return(STATUS_NO_MEMORY);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get the environment variable
|
* Get the environment variable
|
||||||
*/
|
*/
|
||||||
Result = HalGetEnvironmentVariable(AName.Buffer, Value, Length);
|
Result = HalGetEnvironmentVariable(AName.Buffer, Value, ValueBufferLength);
|
||||||
if (!Result)
|
if(!Result)
|
||||||
{
|
{
|
||||||
RtlFreeAnsiString(&AName);
|
RtlFreeAnsiString(&AName);
|
||||||
if (ExGetPreviousMode() != KernelMode)
|
|
||||||
{
|
|
||||||
RtlFreeUnicodeString(&WName);
|
|
||||||
}
|
|
||||||
ExFreePool(Value);
|
ExFreePool(Value);
|
||||||
return(STATUS_UNSUCCESSFUL);
|
return STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Convert the result to UNICODE.
|
* Convert the result to UNICODE, protect with SEH in case the value buffer
|
||||||
*/
|
* isn't NULL-terminated!
|
||||||
RtlInitAnsiString(&AValue, Value);
|
*/
|
||||||
Status = RtlAnsiStringToUnicodeString(&WValue, &AValue, TRUE);
|
_SEH_TRY
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
{
|
||||||
RtlFreeAnsiString(&AName);
|
RtlInitAnsiString(&AValue, Value);
|
||||||
if (ExGetPreviousMode() != KernelMode)
|
Status = RtlAnsiStringToUnicodeString(&WValue, &AValue, TRUE);
|
||||||
{
|
|
||||||
RtlFreeUnicodeString(&WName);
|
|
||||||
}
|
|
||||||
ExFreePool(Value);
|
|
||||||
return(Status);
|
|
||||||
}
|
}
|
||||||
ReturnLength = WValue.Length;
|
_SEH_HANDLE
|
||||||
|
|
||||||
/*
|
|
||||||
* Copy the result back to the caller.
|
|
||||||
*/
|
|
||||||
if (ExGetPreviousMode() != KernelMode)
|
|
||||||
{
|
{
|
||||||
Status = MmCopyToCaller(UnsafeValue, WValue.Buffer, ReturnLength);
|
Status = _SEH_GetExceptionCode();
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
RtlFreeAnsiString(&AName);
|
|
||||||
if (ExGetPreviousMode() != KernelMode)
|
|
||||||
{
|
|
||||||
RtlFreeUnicodeString(&WName);
|
|
||||||
}
|
|
||||||
ExFreePool(Value);
|
|
||||||
RtlFreeUnicodeString(&WValue);
|
|
||||||
return(Status);
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = MmCopyToCaller(UnsafeReturnLength, &ReturnLength,
|
|
||||||
sizeof(ULONG));
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
RtlFreeAnsiString(&AName);
|
|
||||||
if (ExGetPreviousMode() != KernelMode)
|
|
||||||
{
|
|
||||||
RtlFreeUnicodeString(&WName);
|
|
||||||
}
|
|
||||||
ExFreePool(Value);
|
|
||||||
RtlFreeUnicodeString(&WValue);
|
|
||||||
return(Status);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
_SEH_END;
|
||||||
|
|
||||||
|
if(NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
memcpy(UnsafeValue, WValue.Buffer, ReturnLength);
|
/*
|
||||||
memcpy(UnsafeReturnLength, &ReturnLength, sizeof(ULONG));
|
* Copy the result back to the caller.
|
||||||
}
|
*/
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
RtlCopyMemory(ValueBuffer, WValue.Buffer, WValue.Length);
|
||||||
|
ValueBuffer[WValue.Length / sizeof(WCHAR)] = L'\0';
|
||||||
|
if(ReturnLength != NULL)
|
||||||
|
{
|
||||||
|
*ReturnLength = WValue.Length + sizeof(WCHAR);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
Status = STATUS_SUCCESS;
|
||||||
* Free temporary buffers.
|
}
|
||||||
*/
|
_SEH_HANDLE
|
||||||
RtlFreeAnsiString(&AName);
|
{
|
||||||
if (ExGetPreviousMode() != KernelMode)
|
Status = _SEH_GetExceptionCode();
|
||||||
{
|
}
|
||||||
RtlFreeUnicodeString(&WName);
|
_SEH_END;
|
||||||
}
|
}
|
||||||
ExFreePool(Value);
|
|
||||||
RtlFreeUnicodeString(&WValue);
|
/*
|
||||||
|
* Cleanup allocated resources.
|
||||||
|
*/
|
||||||
|
RtlFreeAnsiString(&AName);
|
||||||
|
ExFreePool(Value);
|
||||||
|
}
|
||||||
|
|
||||||
return(STATUS_SUCCESS);
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS STDCALL
|
NTSTATUS STDCALL
|
||||||
NtSetSystemEnvironmentValue (IN PUNICODE_STRING UnsafeName,
|
NtSetSystemEnvironmentValue (IN PUNICODE_STRING VariableName,
|
||||||
IN PUNICODE_STRING UnsafeValue)
|
IN PUNICODE_STRING Value)
|
||||||
{
|
{
|
||||||
UNICODE_STRING WName;
|
UNICODE_STRING CapturedName, CapturedValue;
|
||||||
ANSI_STRING AName;
|
ANSI_STRING AName, AValue;
|
||||||
UNICODE_STRING WValue;
|
KPROCESSOR_MODE PreviousMode;
|
||||||
ANSI_STRING AValue;
|
|
||||||
BOOLEAN Result;
|
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
PreviousMode = ExGetPreviousMode();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check for required privilege.
|
* Copy the strings to kernel space if necessary
|
||||||
*/
|
*/
|
||||||
/* FIXME: Not implemented. */
|
Status = RtlCaptureUnicodeString(&CapturedName,
|
||||||
|
PreviousMode,
|
||||||
|
NonPagedPool,
|
||||||
|
FALSE,
|
||||||
|
VariableName);
|
||||||
|
if(NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
Status = RtlCaptureUnicodeString(&CapturedValue,
|
||||||
|
PreviousMode,
|
||||||
|
NonPagedPool,
|
||||||
|
FALSE,
|
||||||
|
Value);
|
||||||
|
if(NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* according to ntinternals the SeSystemEnvironmentName privilege is required!
|
||||||
|
*/
|
||||||
|
if(SeSinglePrivilegeCheck(SeSystemEnvironmentPrivilege,
|
||||||
|
PreviousMode))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* convert the strings to ANSI
|
||||||
|
*/
|
||||||
|
Status = RtlUnicodeStringToAnsiString(&AName,
|
||||||
|
&CapturedName,
|
||||||
|
TRUE);
|
||||||
|
if(NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
Status = RtlUnicodeStringToAnsiString(&AValue,
|
||||||
|
&CapturedValue,
|
||||||
|
TRUE);
|
||||||
|
if(NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
BOOLEAN Result = HalSetEnvironmentVariable(AName.Buffer,
|
||||||
|
AValue.Buffer);
|
||||||
|
|
||||||
/*
|
Status = (Result ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL);
|
||||||
* Copy the name to kernel space if necessary and convert it to ANSI.
|
}
|
||||||
*/
|
}
|
||||||
if (ExGetPreviousMode() != KernelMode)
|
}
|
||||||
{
|
else
|
||||||
Status = RtlCaptureUnicodeString(&WName, UnsafeName);
|
{
|
||||||
if (!NT_SUCCESS(Status))
|
Status = STATUS_PRIVILEGE_NOT_HELD;
|
||||||
{
|
}
|
||||||
return(Status);
|
|
||||||
}
|
RtlRelaseCapturedUnicodeString(&CapturedValue,
|
||||||
Status = RtlUnicodeStringToAnsiString(&AName, UnsafeName, TRUE);
|
PreviousMode,
|
||||||
if (!NT_SUCCESS(Status))
|
FALSE);
|
||||||
{
|
|
||||||
return(Status);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Status = RtlUnicodeStringToAnsiString(&AName, UnsafeName, TRUE);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
return(Status);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
RtlRelaseCapturedUnicodeString(&CapturedName,
|
||||||
* Copy the value to kernel space and convert to ANSI.
|
PreviousMode,
|
||||||
*/
|
FALSE);
|
||||||
if (ExGetPreviousMode() != KernelMode)
|
}
|
||||||
{
|
|
||||||
Status = RtlCaptureUnicodeString(&WValue, UnsafeValue);
|
return Status;
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
RtlFreeUnicodeString(&WName);
|
|
||||||
RtlFreeAnsiString(&AName);
|
|
||||||
return(Status);
|
|
||||||
}
|
|
||||||
Status = RtlUnicodeStringToAnsiString(&AValue, UnsafeValue, TRUE);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
RtlFreeUnicodeString(&WName);
|
|
||||||
RtlFreeAnsiString(&AName);
|
|
||||||
RtlFreeUnicodeString(&WValue);
|
|
||||||
return(Status);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Status = RtlUnicodeStringToAnsiString(&AValue, UnsafeValue, TRUE);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
RtlFreeAnsiString(&AName);
|
|
||||||
return(Status);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set the environment variable
|
|
||||||
*/
|
|
||||||
Result = HalSetEnvironmentVariable(AName.Buffer, AValue.Buffer);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Free everything and return status.
|
|
||||||
*/
|
|
||||||
RtlFreeAnsiString(&AName);
|
|
||||||
RtlFreeAnsiString(&AValue);
|
|
||||||
if (ExGetPreviousMode() != KernelMode)
|
|
||||||
{
|
|
||||||
RtlFreeUnicodeString(&WName);
|
|
||||||
RtlFreeUnicodeString(&WValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Result)
|
|
||||||
{
|
|
||||||
return(STATUS_UNSUCCESSFUL);
|
|
||||||
}
|
|
||||||
return(STATUS_SUCCESS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,15 @@ NTSTATUS STDCALL
|
||||||
MmCopyToCaller(PVOID Dest, const VOID *Src, ULONG NumberOfBytes);
|
MmCopyToCaller(PVOID Dest, const VOID *Src, ULONG NumberOfBytes);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
RtlCaptureUnicodeString(PUNICODE_STRING Dest,
|
RtlCaptureUnicodeString(OUT PUNICODE_STRING Dest,
|
||||||
PUNICODE_STRING UnsafeSrc);
|
IN KPROCESSOR_MODE CurrentMode,
|
||||||
|
IN POOL_TYPE PoolType,
|
||||||
|
IN BOOLEAN CaptureIfKernel,
|
||||||
|
IN PUNICODE_STRING UnsafeSrc);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
RtlRelaseCapturedUnicodeString(IN PUNICODE_STRING CapturedString,
|
||||||
|
IN KPROCESSOR_MODE CurrentMode,
|
||||||
|
IN BOOLEAN CaptureIfKernel);
|
||||||
|
|
||||||
#endif /* __NTOSKRNL_INCLUDE_INTERNAL_SAFE_Hb */
|
#endif /* __NTOSKRNL_INCLUDE_INTERNAL_SAFE_Hb */
|
||||||
|
|
|
@ -34,7 +34,7 @@ IoCreateNotificationEvent(PUNICODE_STRING EventName,
|
||||||
NULL,
|
NULL,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
Status = NtCreateEvent(&Handle,
|
Status = ZwCreateEvent(&Handle,
|
||||||
EVENT_ALL_ACCESS,
|
EVENT_ALL_ACCESS,
|
||||||
&ObjectAttributes,
|
&ObjectAttributes,
|
||||||
NotificationEvent,
|
NotificationEvent,
|
||||||
|
@ -65,21 +65,40 @@ IoCreateSynchronizationEvent(PUNICODE_STRING EventName,
|
||||||
PHANDLE EventHandle)
|
PHANDLE EventHandle)
|
||||||
{
|
{
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
UNICODE_STRING CapturedEventName;
|
||||||
|
KPROCESSOR_MODE PreviousMode;
|
||||||
PKEVENT Event;
|
PKEVENT Event;
|
||||||
HANDLE Handle;
|
HANDLE Handle;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
PreviousMode = ExGetPreviousMode();
|
||||||
|
|
||||||
|
Status = RtlCaptureUnicodeString(&CapturedEventName,
|
||||||
|
PreviousMode,
|
||||||
|
NonPagedPool,
|
||||||
|
FALSE,
|
||||||
|
EventName);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
InitializeObjectAttributes(&ObjectAttributes,
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
EventName,
|
&CapturedEventName,
|
||||||
OBJ_OPENIF,
|
OBJ_OPENIF,
|
||||||
NULL,
|
NULL,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
Status = NtCreateEvent(&Handle,
|
Status = ZwCreateEvent(&Handle,
|
||||||
EVENT_ALL_ACCESS,
|
EVENT_ALL_ACCESS,
|
||||||
&ObjectAttributes,
|
&ObjectAttributes,
|
||||||
SynchronizationEvent,
|
SynchronizationEvent,
|
||||||
TRUE);
|
TRUE);
|
||||||
|
|
||||||
|
RtlRelaseCapturedUnicodeString(&CapturedEventName,
|
||||||
|
PreviousMode,
|
||||||
|
FALSE);
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -748,7 +748,7 @@ ExpInitializeExecutive(VOID)
|
||||||
0,
|
0,
|
||||||
NULL,
|
NULL,
|
||||||
NULL);
|
NULL);
|
||||||
Status = NtCreateEvent(&InitDoneEventHandle,
|
Status = ZwCreateEvent(&InitDoneEventHandle,
|
||||||
EVENT_ALL_ACCESS,
|
EVENT_ALL_ACCESS,
|
||||||
&ObjectAttributes,
|
&ObjectAttributes,
|
||||||
SynchronizationEvent,
|
SynchronizationEvent,
|
||||||
|
@ -778,7 +778,7 @@ ExpInitializeExecutive(VOID)
|
||||||
|
|
||||||
/* Wait for the system to be initialized */
|
/* Wait for the system to be initialized */
|
||||||
Timeout.QuadPart = (LONGLONG)-1200000000; /* 120 second timeout */
|
Timeout.QuadPart = (LONGLONG)-1200000000; /* 120 second timeout */
|
||||||
Status = NtWaitForMultipleObjects(((LONG) sizeof(Handles) / sizeof(HANDLE)),
|
Status = ZwWaitForMultipleObjects(((LONG) sizeof(Handles) / sizeof(HANDLE)),
|
||||||
Handles,
|
Handles,
|
||||||
WaitAny,
|
WaitAny,
|
||||||
FALSE, /* Non-alertable */
|
FALSE, /* Non-alertable */
|
||||||
|
@ -804,9 +804,9 @@ ExpInitializeExecutive(VOID)
|
||||||
InbvEnableBootDriver(FALSE);
|
InbvEnableBootDriver(FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
NtSetEvent(InitDoneEventHandle, NULL);
|
ZwSetEvent(InitDoneEventHandle, NULL);
|
||||||
|
|
||||||
NtClose(InitDoneEventHandle);
|
ZwClose(InitDoneEventHandle);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -820,7 +820,7 @@ ExpInitializeExecutive(VOID)
|
||||||
* Crash the system if the initial process terminates within 5 seconds.
|
* Crash the system if the initial process terminates within 5 seconds.
|
||||||
*/
|
*/
|
||||||
Timeout.QuadPart = (LONGLONG)-50000000; /* 5 second timeout */
|
Timeout.QuadPart = (LONGLONG)-50000000; /* 5 second timeout */
|
||||||
Status = NtWaitForSingleObject(ProcessHandle,
|
Status = ZwWaitForSingleObject(ProcessHandle,
|
||||||
FALSE,
|
FALSE,
|
||||||
&Timeout);
|
&Timeout);
|
||||||
if (Status != STATUS_TIMEOUT)
|
if (Status != STATUS_TIMEOUT)
|
||||||
|
@ -834,8 +834,8 @@ ExpInitializeExecutive(VOID)
|
||||||
|
|
||||||
KiTimerSystemAuditing = 1;
|
KiTimerSystemAuditing = 1;
|
||||||
|
|
||||||
NtClose(ThreadHandle);
|
ZwClose(ThreadHandle);
|
||||||
NtClose(ProcessHandle);
|
ZwClose(ProcessHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID __attribute((noinline))
|
VOID __attribute((noinline))
|
||||||
|
|
|
@ -35,43 +35,95 @@
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
RtlCaptureUnicodeString(PUNICODE_STRING Dest,
|
RtlCaptureUnicodeString(OUT PUNICODE_STRING Dest,
|
||||||
PUNICODE_STRING UnsafeSrc)
|
IN KPROCESSOR_MODE CurrentMode,
|
||||||
|
IN POOL_TYPE PoolType,
|
||||||
|
IN BOOLEAN CaptureIfKernel,
|
||||||
|
IN PUNICODE_STRING UnsafeSrc)
|
||||||
{
|
{
|
||||||
PUNICODE_STRING Src;
|
UNICODE_STRING Src;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
ASSERT(Dest != NULL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copy the source string structure to kernel space.
|
* Copy the source string structure to kernel space.
|
||||||
*/
|
*/
|
||||||
Status = MmCopyFromCaller(&Src, UnsafeSrc, sizeof(UNICODE_STRING));
|
|
||||||
if (!NT_SUCCESS(Status))
|
if(CurrentMode == UserMode)
|
||||||
|
{
|
||||||
|
_SEH_TRY
|
||||||
{
|
{
|
||||||
return(Status);
|
ProbeForRead(UnsafeSrc,
|
||||||
|
sizeof(UNICODE_STRING),
|
||||||
|
sizeof(ULONG));
|
||||||
|
Src = *UnsafeSrc;
|
||||||
}
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
|
||||||
|
if(!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(!CaptureIfKernel)
|
||||||
|
{
|
||||||
|
/* just copy the UNICODE_STRING structure, the pointers are considered valid */
|
||||||
|
*Dest = *UnsafeSrc;
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* capture the string even though it is considered to be valid */
|
||||||
|
Src = *UnsafeSrc;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize the destination string.
|
* Initialize the destination string.
|
||||||
*/
|
*/
|
||||||
Dest->Length = Src->Length;
|
Dest->Length = Src.Length;
|
||||||
Dest->MaximumLength = Src->MaximumLength;
|
Dest->MaximumLength = Src.Length + sizeof(WCHAR);
|
||||||
Dest->Buffer = ExAllocatePool(NonPagedPool, Dest->MaximumLength);
|
Dest->Buffer = ExAllocatePool(PoolType, Dest->MaximumLength);
|
||||||
if (Dest->Buffer == NULL)
|
if (Dest->Buffer == NULL)
|
||||||
{
|
{
|
||||||
return(STATUS_NO_MEMORY);
|
Dest->Length = Dest->MaximumLength = 0;
|
||||||
}
|
Dest->Buffer = NULL;
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copy the source string to kernel space.
|
* Copy the source string to kernel space.
|
||||||
*/
|
*/
|
||||||
Status = MmCopyFromCaller(Dest->Buffer, Src->Buffer, Dest->Length);
|
if(Src.Length > 0)
|
||||||
if (!NT_SUCCESS(Status))
|
{
|
||||||
|
_SEH_TRY
|
||||||
{
|
{
|
||||||
ExFreePool(Dest->Buffer);
|
RtlCopyMemory(Dest->Buffer, Src.Buffer, Src.Length);
|
||||||
return(Status);
|
Dest->Buffer[Src.Length / sizeof(WCHAR)] = L'\0';
|
||||||
}
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
return(STATUS_SUCCESS);
|
VOID
|
||||||
|
RtlRelaseCapturedUnicodeString(IN PUNICODE_STRING CapturedString,
|
||||||
|
IN KPROCESSOR_MODE CurrentMode,
|
||||||
|
IN BOOLEAN CaptureIfKernel)
|
||||||
|
{
|
||||||
|
if(CurrentMode != KernelMode || CaptureIfKernel )
|
||||||
|
{
|
||||||
|
RtlFreeUnicodeString(CapturedString);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
|
|
@ -84,7 +84,7 @@ SeInitSRM(VOID)
|
||||||
OBJ_PERMANENT,
|
OBJ_PERMANENT,
|
||||||
0,
|
0,
|
||||||
NULL);
|
NULL);
|
||||||
Status = NtCreateDirectoryObject(&DirectoryHandle,
|
Status = ZwCreateDirectoryObject(&DirectoryHandle,
|
||||||
DIRECTORY_ALL_ACCESS,
|
DIRECTORY_ALL_ACCESS,
|
||||||
&ObjectAttributes);
|
&ObjectAttributes);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
@ -101,7 +101,7 @@ SeInitSRM(VOID)
|
||||||
OBJ_PERMANENT,
|
OBJ_PERMANENT,
|
||||||
DirectoryHandle,
|
DirectoryHandle,
|
||||||
SePublicDefaultSd);
|
SePublicDefaultSd);
|
||||||
Status = NtCreateEvent(&EventHandle,
|
Status = ZwCreateEvent(&EventHandle,
|
||||||
EVENT_ALL_ACCESS,
|
EVENT_ALL_ACCESS,
|
||||||
&ObjectAttributes,
|
&ObjectAttributes,
|
||||||
SynchronizationEvent,
|
SynchronizationEvent,
|
||||||
|
@ -113,8 +113,8 @@ SeInitSRM(VOID)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
NtClose(EventHandle);
|
ZwClose(EventHandle);
|
||||||
NtClose(DirectoryHandle);
|
ZwClose(DirectoryHandle);
|
||||||
|
|
||||||
/* FIXME: Create SRM port and listener thread */
|
/* FIXME: Create SRM port and listener thread */
|
||||||
|
|
||||||
|
|
|
@ -735,16 +735,16 @@ NTOSAPI
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
ZwQuerySystemEnvironmentValue(
|
ZwQuerySystemEnvironmentValue(
|
||||||
IN PUNICODE_STRING Name,
|
IN PUNICODE_STRING VariableName,
|
||||||
OUT PVOID Value,
|
OUT PWSTR ValueBuffer,
|
||||||
IN ULONG ValueLength,
|
IN ULONG ValueBufferLength,
|
||||||
OUT PULONG ReturnLength OPTIONAL);
|
OUT PULONG ReturnLength OPTIONAL);
|
||||||
|
|
||||||
NTOSAPI
|
NTOSAPI
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
ZwSetSystemEnvironmentValue(
|
ZwSetSystemEnvironmentValue(
|
||||||
IN PUNICODE_STRING Name,
|
IN PUNICODE_STRING VariableName,
|
||||||
IN PUNICODE_STRING Value);
|
IN PUNICODE_STRING Value);
|
||||||
|
|
||||||
typedef enum _SHUTDOWN_ACTION {
|
typedef enum _SHUTDOWN_ACTION {
|
||||||
|
|
Loading…
Reference in a new issue