mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
- probe and capture parameters in NtCreateKey
- added ProbeForWriteUnicodeString and ProbeForReadUnicodeString macros svn path=/trunk/; revision=18853
This commit is contained in:
parent
bffa3474f4
commit
006d0bc6d7
2 changed files with 161 additions and 113 deletions
|
@ -184,35 +184,70 @@ NtCreateKey(OUT PHANDLE KeyHandle,
|
||||||
IN ULONG CreateOptions,
|
IN ULONG CreateOptions,
|
||||||
OUT PULONG Disposition)
|
OUT PULONG Disposition)
|
||||||
{
|
{
|
||||||
UNICODE_STRING RemainingPath;
|
UNICODE_STRING RemainingPath = {0};
|
||||||
|
BOOLEAN FreeRemainingPath = TRUE;
|
||||||
|
ULONG LocalDisposition;
|
||||||
PKEY_OBJECT KeyObject;
|
PKEY_OBJECT KeyObject;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
PVOID Object;
|
PVOID Object = NULL;
|
||||||
PWSTR Start;
|
PWSTR Start;
|
||||||
UNICODE_STRING ObjectName;
|
UNICODE_STRING ObjectName;
|
||||||
OBJECT_CREATE_INFORMATION ObjectCreateInfo;
|
OBJECT_CREATE_INFORMATION ObjectCreateInfo;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
REG_PRE_CREATE_KEY_INFORMATION PreCreateKeyInfo;
|
REG_PRE_CREATE_KEY_INFORMATION PreCreateKeyInfo;
|
||||||
REG_POST_CREATE_KEY_INFORMATION PostCreateKeyInfo;
|
REG_POST_CREATE_KEY_INFORMATION PostCreateKeyInfo;
|
||||||
|
KPROCESSOR_MODE PreviousMode;
|
||||||
|
UNICODE_STRING CapturedClass = {0};
|
||||||
|
HANDLE hKey;
|
||||||
|
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
DPRINT("NtCreateKey (Name %wZ KeyHandle 0x%p Root 0x%p)\n",
|
PreviousMode = KeGetPreviousMode();
|
||||||
ObjectAttributes->ObjectName,
|
|
||||||
KeyHandle,
|
if (PreviousMode != KernelMode)
|
||||||
ObjectAttributes->RootDirectory);
|
{
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
ProbeForWriteHandle(KeyHandle);
|
||||||
|
if (Disposition != NULL)
|
||||||
|
{
|
||||||
|
ProbeForWriteUlong(Disposition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Class != NULL)
|
||||||
|
{
|
||||||
|
Status = ProbeAndCaptureUnicodeString(&CapturedClass,
|
||||||
|
PreviousMode,
|
||||||
|
Class);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Capture all the info */
|
/* Capture all the info */
|
||||||
DPRINT("Capturing Create Info\n");
|
DPRINT("Capturing Create Info\n");
|
||||||
Status = ObpCaptureObjectAttributes(ObjectAttributes,
|
Status = ObpCaptureObjectAttributes(ObjectAttributes,
|
||||||
KeGetPreviousMode(),
|
PreviousMode,
|
||||||
CmiKeyType,
|
CmiKeyType,
|
||||||
&ObjectCreateInfo,
|
&ObjectCreateInfo,
|
||||||
&ObjectName);
|
&ObjectName);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT("ObpCaptureObjectAttributes() failed (Status %lx)\n", Status);
|
DPRINT("ObpCaptureObjectAttributes() failed (Status %lx)\n", Status);
|
||||||
return Status;
|
goto Cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
PostCreateKeyInfo.CompleteName = &ObjectName;
|
PostCreateKeyInfo.CompleteName = &ObjectName;
|
||||||
|
@ -221,13 +256,12 @@ NtCreateKey(OUT PHANDLE KeyHandle,
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
ObpReleaseCapturedAttributes(&ObjectCreateInfo);
|
ObpReleaseCapturedAttributes(&ObjectCreateInfo);
|
||||||
if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
|
goto Cleanup;
|
||||||
return Status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = ObFindObject(&ObjectCreateInfo,
|
Status = ObFindObject(&ObjectCreateInfo,
|
||||||
&ObjectName,
|
&ObjectName,
|
||||||
(PVOID*)&Object,
|
(PVOID*)&Object,
|
||||||
&RemainingPath,
|
&RemainingPath,
|
||||||
CmiKeyType);
|
CmiKeyType);
|
||||||
ObpReleaseCapturedAttributes(&ObjectCreateInfo);
|
ObpReleaseCapturedAttributes(&ObjectCreateInfo);
|
||||||
|
@ -236,9 +270,9 @@ NtCreateKey(OUT PHANDLE KeyHandle,
|
||||||
PostCreateKeyInfo.Object = NULL;
|
PostCreateKeyInfo.Object = NULL;
|
||||||
PostCreateKeyInfo.Status = Status;
|
PostCreateKeyInfo.Status = Status;
|
||||||
CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo);
|
CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo);
|
||||||
if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
|
|
||||||
DPRINT("CmpFindObject failed, Status: 0x%x\n", Status);
|
DPRINT("CmpFindObject failed, Status: 0x%x\n", Status);
|
||||||
return(Status);
|
goto Cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINT("RemainingPath %wZ\n", &RemainingPath);
|
DPRINT("RemainingPath %wZ\n", &RemainingPath);
|
||||||
|
@ -248,33 +282,29 @@ NtCreateKey(OUT PHANDLE KeyHandle,
|
||||||
/* Fail if the key has been deleted */
|
/* Fail if the key has been deleted */
|
||||||
if (((PKEY_OBJECT) Object)->Flags & KO_MARKED_FOR_DELETE)
|
if (((PKEY_OBJECT) Object)->Flags & KO_MARKED_FOR_DELETE)
|
||||||
{
|
{
|
||||||
ObDereferenceObject(Object);
|
|
||||||
RtlFreeUnicodeString(&RemainingPath);
|
|
||||||
PostCreateKeyInfo.Object = NULL;
|
PostCreateKeyInfo.Object = NULL;
|
||||||
PostCreateKeyInfo.Status = STATUS_UNSUCCESSFUL;
|
PostCreateKeyInfo.Status = STATUS_UNSUCCESSFUL;
|
||||||
CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo);
|
CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo);
|
||||||
if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
|
|
||||||
DPRINT("Object marked for delete!\n");
|
|
||||||
return(STATUS_UNSUCCESSFUL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Disposition)
|
DPRINT("Object marked for delete!\n");
|
||||||
*Disposition = REG_OPENED_EXISTING_KEY;
|
Status = STATUS_UNSUCCESSFUL;
|
||||||
|
goto Cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
Status = ObpCreateHandle(PsGetCurrentProcess(),
|
Status = ObpCreateHandle(PsGetCurrentProcess(),
|
||||||
Object,
|
Object,
|
||||||
DesiredAccess,
|
DesiredAccess,
|
||||||
TRUE,
|
TRUE,
|
||||||
KeyHandle);
|
&hKey);
|
||||||
|
|
||||||
DPRINT("ObpCreateHandle failed Status 0x%x\n", Status);
|
DPRINT("ObpCreateHandle failed Status 0x%x\n", Status);
|
||||||
ObDereferenceObject(Object);
|
|
||||||
RtlFreeUnicodeString(&RemainingPath);
|
|
||||||
PostCreateKeyInfo.Object = NULL;
|
PostCreateKeyInfo.Object = NULL;
|
||||||
PostCreateKeyInfo.Status = Status;
|
PostCreateKeyInfo.Status = Status;
|
||||||
CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo);
|
CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo);
|
||||||
if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
|
|
||||||
return Status;
|
LocalDisposition = REG_OPENED_EXISTING_KEY;
|
||||||
|
goto SuccessReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If RemainingPath contains \ we must return error
|
/* If RemainingPath contains \ we must return error
|
||||||
|
@ -287,23 +317,23 @@ NtCreateKey(OUT PHANDLE KeyHandle,
|
||||||
{
|
{
|
||||||
if (L'\\' == RemainingPath.Buffer[i])
|
if (L'\\' == RemainingPath.Buffer[i])
|
||||||
{
|
{
|
||||||
ObDereferenceObject(Object);
|
|
||||||
DPRINT1("NtCreateKey() doesn't create trees! (found \'\\\' in remaining path: \"%wZ\"!)\n", &RemainingPath);
|
DPRINT1("NtCreateKey() doesn't create trees! (found \'\\\' in remaining path: \"%wZ\"!)\n", &RemainingPath);
|
||||||
RtlFreeUnicodeString(&RemainingPath);
|
|
||||||
PostCreateKeyInfo.Object = NULL;
|
PostCreateKeyInfo.Object = NULL;
|
||||||
PostCreateKeyInfo.Status = STATUS_OBJECT_NAME_NOT_FOUND;
|
PostCreateKeyInfo.Status = STATUS_OBJECT_NAME_NOT_FOUND;
|
||||||
CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo);
|
CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo);
|
||||||
if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
|
|
||||||
return STATUS_OBJECT_NAME_NOT_FOUND;
|
Status = STATUS_OBJECT_NAME_NOT_FOUND;
|
||||||
|
goto Cleanup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINT("RemainingPath %S ParentObject 0x%p\n", RemainingPath.Buffer, Object);
|
DPRINT("RemainingPath %S ParentObject 0x%p\n", RemainingPath.Buffer, Object);
|
||||||
|
|
||||||
Status = ObCreateObject(ExGetPreviousMode(),
|
Status = ObCreateObject(PreviousMode,
|
||||||
CmiKeyType,
|
CmiKeyType,
|
||||||
NULL,
|
NULL,
|
||||||
ExGetPreviousMode(),
|
PreviousMode,
|
||||||
NULL,
|
NULL,
|
||||||
sizeof(KEY_OBJECT),
|
sizeof(KEY_OBJECT),
|
||||||
0,
|
0,
|
||||||
|
@ -315,8 +345,8 @@ NtCreateKey(OUT PHANDLE KeyHandle,
|
||||||
PostCreateKeyInfo.Object = NULL;
|
PostCreateKeyInfo.Object = NULL;
|
||||||
PostCreateKeyInfo.Status = Status;
|
PostCreateKeyInfo.Status = Status;
|
||||||
CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo);
|
CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo);
|
||||||
if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
|
|
||||||
return(Status);
|
goto Cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = ObInsertObject((PVOID)KeyObject,
|
Status = ObInsertObject((PVOID)KeyObject,
|
||||||
|
@ -324,17 +354,17 @@ NtCreateKey(OUT PHANDLE KeyHandle,
|
||||||
DesiredAccess,
|
DesiredAccess,
|
||||||
0,
|
0,
|
||||||
NULL,
|
NULL,
|
||||||
KeyHandle);
|
&hKey);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
ObDereferenceObject(KeyObject);
|
ObDereferenceObject(KeyObject);
|
||||||
RtlFreeUnicodeString(&RemainingPath);
|
|
||||||
DPRINT1("ObInsertObject() failed!\n");
|
DPRINT1("ObInsertObject() failed!\n");
|
||||||
|
|
||||||
PostCreateKeyInfo.Object = NULL;
|
PostCreateKeyInfo.Object = NULL;
|
||||||
PostCreateKeyInfo.Status = Status;
|
PostCreateKeyInfo.Status = Status;
|
||||||
CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo);
|
CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo);
|
||||||
if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
|
|
||||||
return(Status);
|
goto Cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
KeyObject->ParentKey = Object;
|
KeyObject->ParentKey = Object;
|
||||||
|
@ -361,7 +391,7 @@ NtCreateKey(OUT PHANDLE KeyHandle,
|
||||||
KeyObject,
|
KeyObject,
|
||||||
&RemainingPath,
|
&RemainingPath,
|
||||||
TitleIndex,
|
TitleIndex,
|
||||||
Class,
|
&CapturedClass,
|
||||||
CreateOptions);
|
CreateOptions);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
@ -370,23 +400,23 @@ NtCreateKey(OUT PHANDLE KeyHandle,
|
||||||
ExReleaseResourceLite(&CmiRegistryLock);
|
ExReleaseResourceLite(&CmiRegistryLock);
|
||||||
KeLeaveCriticalRegion();
|
KeLeaveCriticalRegion();
|
||||||
ObDereferenceObject(KeyObject);
|
ObDereferenceObject(KeyObject);
|
||||||
ObDereferenceObject(Object);
|
|
||||||
RtlFreeUnicodeString(&RemainingPath);
|
|
||||||
PostCreateKeyInfo.Object = NULL;
|
PostCreateKeyInfo.Object = NULL;
|
||||||
PostCreateKeyInfo.Status = STATUS_UNSUCCESSFUL;
|
PostCreateKeyInfo.Status = STATUS_UNSUCCESSFUL;
|
||||||
CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo);
|
CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo);
|
||||||
if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
|
|
||||||
return STATUS_UNSUCCESSFUL;
|
Status = STATUS_UNSUCCESSFUL;
|
||||||
|
goto Cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Start == RemainingPath.Buffer)
|
if (Start == RemainingPath.Buffer)
|
||||||
{
|
{
|
||||||
KeyObject->Name = RemainingPath;
|
KeyObject->Name = RemainingPath;
|
||||||
|
FreeRemainingPath = FALSE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
RtlpCreateUnicodeString(&KeyObject->Name, Start, NonPagedPool);
|
RtlpCreateUnicodeString(&KeyObject->Name, Start, NonPagedPool);
|
||||||
RtlFreeUnicodeString(&RemainingPath);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (KeyObject->RegistryHive == KeyObject->ParentKey->RegistryHive)
|
if (KeyObject->RegistryHive == KeyObject->ParentKey->RegistryHive)
|
||||||
|
@ -400,10 +430,7 @@ NtCreateKey(OUT PHANDLE KeyHandle,
|
||||||
KeyObject->KeyCell->SecurityKeyOffset = -1;
|
KeyObject->KeyCell->SecurityKeyOffset = -1;
|
||||||
/* This key must remain in memory unless it is deleted
|
/* This key must remain in memory unless it is deleted
|
||||||
or file is unloaded */
|
or file is unloaded */
|
||||||
ObReferenceObjectByPointer(KeyObject,
|
ObReferenceObject(KeyObject);
|
||||||
STANDARD_RIGHTS_REQUIRED,
|
|
||||||
NULL,
|
|
||||||
UserMode);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CmiAddKeyToList(KeyObject->ParentKey, KeyObject);
|
CmiAddKeyToList(KeyObject->ParentKey, KeyObject);
|
||||||
|
@ -414,18 +441,38 @@ NtCreateKey(OUT PHANDLE KeyHandle,
|
||||||
ExReleaseResourceLite(&CmiRegistryLock);
|
ExReleaseResourceLite(&CmiRegistryLock);
|
||||||
KeLeaveCriticalRegion();
|
KeLeaveCriticalRegion();
|
||||||
|
|
||||||
|
|
||||||
ObDereferenceObject(Object);
|
|
||||||
|
|
||||||
if (Disposition)
|
|
||||||
*Disposition = REG_CREATED_NEW_KEY;
|
|
||||||
|
|
||||||
PostCreateKeyInfo.Object = KeyObject;
|
PostCreateKeyInfo.Object = KeyObject;
|
||||||
PostCreateKeyInfo.Status = Status;
|
PostCreateKeyInfo.Status = Status;
|
||||||
CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo);
|
CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo);
|
||||||
if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
|
|
||||||
|
|
||||||
CmiSyncHives();
|
CmiSyncHives();
|
||||||
|
|
||||||
|
LocalDisposition = REG_CREATED_NEW_KEY;
|
||||||
|
|
||||||
|
SuccessReturn:
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
*KeyHandle = hKey;
|
||||||
|
if (Disposition != NULL)
|
||||||
|
{
|
||||||
|
*Disposition = LocalDisposition;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
|
||||||
|
Cleanup:
|
||||||
|
if (Class != NULL)
|
||||||
|
{
|
||||||
|
ReleaseCapturedUnicodeString(&CapturedClass,
|
||||||
|
PreviousMode);
|
||||||
|
}
|
||||||
|
if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
|
||||||
|
if (FreeRemainingPath) RtlFreeUnicodeString(&RemainingPath);
|
||||||
|
if (Object != NULL) ObDereferenceObject(Object);
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,6 +83,63 @@ RtlpLogException(IN PEXCEPTION_RECORD ExceptionRecord,
|
||||||
|
|
||||||
#define ExRaiseStatus RtlRaiseStatus
|
#define ExRaiseStatus RtlRaiseStatus
|
||||||
|
|
||||||
|
static const UNICODE_STRING __emptyUnicodeString = {0};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NOTE: Alignment of the pointers is not verified!
|
||||||
|
*/
|
||||||
|
#define ProbeForWriteGenericType(Ptr, Type) \
|
||||||
|
do { \
|
||||||
|
if ((ULONG_PTR)(Ptr) + sizeof(Type) - 1 < (ULONG_PTR)(Ptr) || \
|
||||||
|
(ULONG_PTR)(Ptr) + sizeof(Type) - 1 >= (ULONG_PTR)MmUserProbeAddress) { \
|
||||||
|
RtlRaiseStatus (STATUS_ACCESS_VIOLATION); \
|
||||||
|
} \
|
||||||
|
*(volatile Type *)(Ptr) = *(volatile Type *)(Ptr); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define ProbeForWriteBoolean(Ptr) ProbeForWriteGenericType(Ptr, BOOLEAN)
|
||||||
|
#define ProbeForWriteUchar(Ptr) ProbeForWriteGenericType(Ptr, UCHAR)
|
||||||
|
#define ProbeForWriteChar(Ptr) ProbeForWriteGenericType(Ptr, Char)
|
||||||
|
#define ProbeForWriteUshort(Ptr) ProbeForWriteGenericType(Ptr, USHORT)
|
||||||
|
#define ProbeForWriteShort(Ptr) ProbeForWriteGenericType(Ptr, SHORT)
|
||||||
|
#define ProbeForWriteUlong(Ptr) ProbeForWriteGenericType(Ptr, ULONG)
|
||||||
|
#define ProbeForWriteLong(Ptr) ProbeForWriteGenericType(Ptr, LONG)
|
||||||
|
#define ProbeForWriteUint(Ptr) ProbeForWriteGenericType(Ptr, UINT)
|
||||||
|
#define ProbeForWriteInt(Ptr) ProbeForWriteGenericType(Ptr, INT)
|
||||||
|
#define ProbeForWriteUlonglong(Ptr) ProbeForWriteGenericType(Ptr, ULONGLONG)
|
||||||
|
#define ProbeForWriteLonglong(Ptr) ProbeForWriteGenericType(Ptr, LONGLONG)
|
||||||
|
#define ProbeForWriteLonglong(Ptr) ProbeForWriteGenericType(Ptr, LONGLONG)
|
||||||
|
#define ProbeForWritePointer(Ptr) ProbeForWriteGenericType(Ptr, PVOID)
|
||||||
|
#define ProbeForWriteHandle(Ptr) ProbeForWriteGenericType(Ptr, HANDLE)
|
||||||
|
#define ProbeForWriteLangid(Ptr) ProbeForWriteGenericType(Ptr, LANGID)
|
||||||
|
#define ProbeForWriteLargeInteger(Ptr) ProbeForWriteGenericType(&(Ptr)->QuadPart, LONGLONG)
|
||||||
|
#define ProbeForWriteUlargeInteger(Ptr) ProbeForWriteGenericType(&(Ptr)->QuadPart, ULONGLONG)
|
||||||
|
#define ProbeForWriteUnicodeString(Ptr) ProbeForWriteGenericType(Ptr, UNICODE_STRING)
|
||||||
|
|
||||||
|
#define ProbeForReadGenericType(Ptr, Type, Default) \
|
||||||
|
(((ULONG_PTR)(Ptr) + sizeof(Type) - 1 < (ULONG_PTR)(Ptr) || \
|
||||||
|
(ULONG_PTR)(Ptr) + sizeof(Type) - 1 >= (ULONG_PTR)MmUserProbeAddress) ? \
|
||||||
|
ExRaiseStatus (STATUS_ACCESS_VIOLATION), Default : \
|
||||||
|
*(volatile Type *)(Ptr))
|
||||||
|
|
||||||
|
#define ProbeForReadBoolean(Ptr) ProbeForReadGenericType(Ptr, BOOLEAN, FALSE)
|
||||||
|
#define ProbeForReadUchar(Ptr) ProbeForReadGenericType(Ptr, UCHAR, 0)
|
||||||
|
#define ProbeForReadChar(Ptr) ProbeForReadGenericType(Ptr, CHAR, 0)
|
||||||
|
#define ProbeForReadUshort(Ptr) ProbeForReadGenericType(Ptr, USHORT, 0)
|
||||||
|
#define ProbeForReadShort(Ptr) ProbeForReadGenericType(Ptr, SHORT, 0)
|
||||||
|
#define ProbeForReadUlong(Ptr) ProbeForReadGenericType(Ptr, ULONG, 0)
|
||||||
|
#define ProbeForReadLong(Ptr) ProbeForReadGenericType(Ptr, LONG, 0)
|
||||||
|
#define ProbeForReadUint(Ptr) ProbeForReadGenericType(Ptr, UINT, 0)
|
||||||
|
#define ProbeForReadInt(Ptr) ProbeForReadGenericType(Ptr, INT, 0)
|
||||||
|
#define ProbeForReadUlonglong(Ptr) ProbeForReadGenericType(Ptr, ULONGLONG, 0)
|
||||||
|
#define ProbeForReadLonglong(Ptr) ProbeForReadGenericType(Ptr, LONGLONG, 0)
|
||||||
|
#define ProbeForReadPointer(Ptr) ProbeForReadGenericType(Ptr, PVOID, NULL)
|
||||||
|
#define ProbeForReadHandle(Ptr) ProbeForReadGenericType(Ptr, HANDLE, NULL)
|
||||||
|
#define ProbeForReadLangid(Ptr) ProbeForReadGenericType(Ptr, LANGID, 0)
|
||||||
|
#define ProbeForReadLargeInteger(Ptr) ((LARGE_INTEGER)ProbeForReadGenericType(&(Ptr)->QuadPart, LONGLONG, 0))
|
||||||
|
#define ProbeForReadUlargeInteger(Ptr) ((ULARGE_INTEGER)ProbeForReadGenericType(&(Ptr)->QuadPart, ULONGLONG, 0))
|
||||||
|
#define ProbeForReadUnicodeString(Ptr) ProbeForReadGenericType(Ptr, UNICODE_STRING, __emptyUnicodeString)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Inlined Probing Macros
|
* Inlined Probing Macros
|
||||||
*/
|
*/
|
||||||
|
@ -102,10 +159,7 @@ ProbeAndCaptureUnicodeString(OUT PUNICODE_STRING Dest,
|
||||||
{
|
{
|
||||||
_SEH_TRY
|
_SEH_TRY
|
||||||
{
|
{
|
||||||
ProbeForRead(UnsafeSrc,
|
*Dest = ProbeForReadUnicodeString(UnsafeSrc);
|
||||||
sizeof(UNICODE_STRING),
|
|
||||||
sizeof(ULONG));
|
|
||||||
*Dest = *UnsafeSrc;
|
|
||||||
if(Dest->Buffer != NULL)
|
if(Dest->Buffer != NULL)
|
||||||
{
|
{
|
||||||
if (Dest->Length != 0)
|
if (Dest->Length != 0)
|
||||||
|
@ -174,59 +228,6 @@ ReleaseCapturedUnicodeString(IN PUNICODE_STRING CapturedString,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* NOTE: Alignment of the pointers is not verified!
|
|
||||||
*/
|
|
||||||
#define ProbeForWriteGenericType(Ptr, Type) \
|
|
||||||
do { \
|
|
||||||
if ((ULONG_PTR)(Ptr) + sizeof(Type) - 1 < (ULONG_PTR)(Ptr) || \
|
|
||||||
(ULONG_PTR)(Ptr) + sizeof(Type) - 1 >= (ULONG_PTR)MmUserProbeAddress) { \
|
|
||||||
RtlRaiseStatus (STATUS_ACCESS_VIOLATION); \
|
|
||||||
} \
|
|
||||||
*(volatile Type *)(Ptr) = *(volatile Type *)(Ptr); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define ProbeForWriteBoolean(Ptr) ProbeForWriteGenericType(Ptr, BOOLEAN)
|
|
||||||
#define ProbeForWriteUchar(Ptr) ProbeForWriteGenericType(Ptr, UCHAR)
|
|
||||||
#define ProbeForWriteChar(Ptr) ProbeForWriteGenericType(Ptr, Char)
|
|
||||||
#define ProbeForWriteUshort(Ptr) ProbeForWriteGenericType(Ptr, USHORT)
|
|
||||||
#define ProbeForWriteShort(Ptr) ProbeForWriteGenericType(Ptr, SHORT)
|
|
||||||
#define ProbeForWriteUlong(Ptr) ProbeForWriteGenericType(Ptr, ULONG)
|
|
||||||
#define ProbeForWriteLong(Ptr) ProbeForWriteGenericType(Ptr, LONG)
|
|
||||||
#define ProbeForWriteUint(Ptr) ProbeForWriteGenericType(Ptr, UINT)
|
|
||||||
#define ProbeForWriteInt(Ptr) ProbeForWriteGenericType(Ptr, INT)
|
|
||||||
#define ProbeForWriteUlonglong(Ptr) ProbeForWriteGenericType(Ptr, ULONGLONG)
|
|
||||||
#define ProbeForWriteLonglong(Ptr) ProbeForWriteGenericType(Ptr, LONGLONG)
|
|
||||||
#define ProbeForWriteLonglong(Ptr) ProbeForWriteGenericType(Ptr, LONGLONG)
|
|
||||||
#define ProbeForWritePointer(Ptr) ProbeForWriteGenericType(Ptr, PVOID)
|
|
||||||
#define ProbeForWriteHandle(Ptr) ProbeForWriteGenericType(Ptr, HANDLE)
|
|
||||||
#define ProbeForWriteLangid(Ptr) ProbeForWriteGenericType(Ptr, LANGID)
|
|
||||||
#define ProbeForWriteLargeInteger(Ptr) ProbeForWriteGenericType(&(Ptr)->QuadPart, LONGLONG)
|
|
||||||
#define ProbeForWriteUlargeInteger(Ptr) ProbeForWriteGenericType(&(Ptr)->QuadPart, ULONGLONG)
|
|
||||||
|
|
||||||
#define ProbeForReadGenericType(Ptr, Type, Default) \
|
|
||||||
(((ULONG_PTR)(Ptr) + sizeof(Type) - 1 < (ULONG_PTR)(Ptr) || \
|
|
||||||
(ULONG_PTR)(Ptr) + sizeof(Type) - 1 >= (ULONG_PTR)MmUserProbeAddress) ? \
|
|
||||||
ExRaiseStatus (STATUS_ACCESS_VIOLATION), Default : \
|
|
||||||
*(volatile Type *)(Ptr))
|
|
||||||
|
|
||||||
#define ProbeForReadBoolean(Ptr) ProbeForReadGenericType(Ptr, BOOLEAN, FALSE)
|
|
||||||
#define ProbeForReadUchar(Ptr) ProbeForReadGenericType(Ptr, UCHAR, 0)
|
|
||||||
#define ProbeForReadChar(Ptr) ProbeForReadGenericType(Ptr, CHAR, 0)
|
|
||||||
#define ProbeForReadUshort(Ptr) ProbeForReadGenericType(Ptr, USHORT, 0)
|
|
||||||
#define ProbeForReadShort(Ptr) ProbeForReadGenericType(Ptr, SHORT, 0)
|
|
||||||
#define ProbeForReadUlong(Ptr) ProbeForReadGenericType(Ptr, ULONG, 0)
|
|
||||||
#define ProbeForReadLong(Ptr) ProbeForReadGenericType(Ptr, LONG, 0)
|
|
||||||
#define ProbeForReadUint(Ptr) ProbeForReadGenericType(Ptr, UINT, 0)
|
|
||||||
#define ProbeForReadInt(Ptr) ProbeForReadGenericType(Ptr, INT, 0)
|
|
||||||
#define ProbeForReadUlonglong(Ptr) ProbeForReadGenericType(Ptr, ULONGLONG, 0)
|
|
||||||
#define ProbeForReadLonglong(Ptr) ProbeForReadGenericType(Ptr, LONGLONG, 0)
|
|
||||||
#define ProbeForReadPointer(Ptr) ProbeForReadGenericType(Ptr, PVOID, NULL)
|
|
||||||
#define ProbeForReadHandle(Ptr) ProbeForReadGenericType(Ptr, HANDLE, NULL)
|
|
||||||
#define ProbeForReadLangid(Ptr) ProbeForReadGenericType(Ptr, LANGID, 0)
|
|
||||||
#define ProbeForReadLargeInteger(Ptr) ((LARGE_INTEGER)ProbeForReadGenericType(&(Ptr)->QuadPart, LONGLONG, 0))
|
|
||||||
#define ProbeForReadUlargeInteger(Ptr) ((ULARGE_INTEGER)ProbeForReadGenericType(&(Ptr)->QuadPart, ULONGLONG, 0))
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* generic information class probing code
|
* generic information class probing code
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in a new issue