- probe and capture parameters in NtCreateKey

- added ProbeForWriteUnicodeString and ProbeForReadUnicodeString macros

svn path=/trunk/; revision=18853
This commit is contained in:
Thomas Bluemel 2005-10-29 16:00:00 +00:00
parent bffa3474f4
commit 006d0bc6d7
2 changed files with 161 additions and 113 deletions

View file

@ -184,35 +184,70 @@ NtCreateKey(OUT PHANDLE KeyHandle,
IN ULONG CreateOptions,
OUT PULONG Disposition)
{
UNICODE_STRING RemainingPath;
UNICODE_STRING RemainingPath = {0};
BOOLEAN FreeRemainingPath = TRUE;
ULONG LocalDisposition;
PKEY_OBJECT KeyObject;
NTSTATUS Status;
PVOID Object;
NTSTATUS Status = STATUS_SUCCESS;
PVOID Object = NULL;
PWSTR Start;
UNICODE_STRING ObjectName;
OBJECT_CREATE_INFORMATION ObjectCreateInfo;
unsigned i;
REG_PRE_CREATE_KEY_INFORMATION PreCreateKeyInfo;
REG_POST_CREATE_KEY_INFORMATION PostCreateKeyInfo;
KPROCESSOR_MODE PreviousMode;
UNICODE_STRING CapturedClass = {0};
HANDLE hKey;
PAGED_CODE();
DPRINT("NtCreateKey (Name %wZ KeyHandle 0x%p Root 0x%p)\n",
ObjectAttributes->ObjectName,
KeyHandle,
ObjectAttributes->RootDirectory);
PreviousMode = KeGetPreviousMode();
if (PreviousMode != KernelMode)
{
_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 */
DPRINT("Capturing Create Info\n");
Status = ObpCaptureObjectAttributes(ObjectAttributes,
KeGetPreviousMode(),
PreviousMode,
CmiKeyType,
&ObjectCreateInfo,
&ObjectName);
if (!NT_SUCCESS(Status))
{
DPRINT("ObpCaptureObjectAttributes() failed (Status %lx)\n", Status);
return Status;
goto Cleanup;
}
PostCreateKeyInfo.CompleteName = &ObjectName;
@ -221,13 +256,12 @@ NtCreateKey(OUT PHANDLE KeyHandle,
if (!NT_SUCCESS(Status))
{
ObpReleaseCapturedAttributes(&ObjectCreateInfo);
if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
return Status;
goto Cleanup;
}
Status = ObFindObject(&ObjectCreateInfo,
&ObjectName,
(PVOID*)&Object,
(PVOID*)&Object,
&RemainingPath,
CmiKeyType);
ObpReleaseCapturedAttributes(&ObjectCreateInfo);
@ -236,9 +270,9 @@ NtCreateKey(OUT PHANDLE KeyHandle,
PostCreateKeyInfo.Object = NULL;
PostCreateKeyInfo.Status = Status;
CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo);
if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
DPRINT("CmpFindObject failed, Status: 0x%x\n", Status);
return(Status);
goto Cleanup;
}
DPRINT("RemainingPath %wZ\n", &RemainingPath);
@ -248,33 +282,29 @@ NtCreateKey(OUT PHANDLE KeyHandle,
/* Fail if the key has been deleted */
if (((PKEY_OBJECT) Object)->Flags & KO_MARKED_FOR_DELETE)
{
ObDereferenceObject(Object);
RtlFreeUnicodeString(&RemainingPath);
PostCreateKeyInfo.Object = NULL;
PostCreateKeyInfo.Status = STATUS_UNSUCCESSFUL;
CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo);
if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
DPRINT("Object marked for delete!\n");
return(STATUS_UNSUCCESSFUL);
}
if (Disposition)
*Disposition = REG_OPENED_EXISTING_KEY;
DPRINT("Object marked for delete!\n");
Status = STATUS_UNSUCCESSFUL;
goto Cleanup;
}
Status = ObpCreateHandle(PsGetCurrentProcess(),
Object,
DesiredAccess,
TRUE,
KeyHandle);
&hKey);
DPRINT("ObpCreateHandle failed Status 0x%x\n", Status);
ObDereferenceObject(Object);
RtlFreeUnicodeString(&RemainingPath);
PostCreateKeyInfo.Object = NULL;
PostCreateKeyInfo.Status = Status;
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
@ -287,23 +317,23 @@ NtCreateKey(OUT PHANDLE KeyHandle,
{
if (L'\\' == RemainingPath.Buffer[i])
{
ObDereferenceObject(Object);
DPRINT1("NtCreateKey() doesn't create trees! (found \'\\\' in remaining path: \"%wZ\"!)\n", &RemainingPath);
RtlFreeUnicodeString(&RemainingPath);
PostCreateKeyInfo.Object = NULL;
PostCreateKeyInfo.Status = STATUS_OBJECT_NAME_NOT_FOUND;
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);
Status = ObCreateObject(ExGetPreviousMode(),
Status = ObCreateObject(PreviousMode,
CmiKeyType,
NULL,
ExGetPreviousMode(),
PreviousMode,
NULL,
sizeof(KEY_OBJECT),
0,
@ -315,8 +345,8 @@ NtCreateKey(OUT PHANDLE KeyHandle,
PostCreateKeyInfo.Object = NULL;
PostCreateKeyInfo.Status = Status;
CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo);
if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
return(Status);
goto Cleanup;
}
Status = ObInsertObject((PVOID)KeyObject,
@ -324,17 +354,17 @@ NtCreateKey(OUT PHANDLE KeyHandle,
DesiredAccess,
0,
NULL,
KeyHandle);
&hKey);
if (!NT_SUCCESS(Status))
{
ObDereferenceObject(KeyObject);
RtlFreeUnicodeString(&RemainingPath);
DPRINT1("ObInsertObject() failed!\n");
PostCreateKeyInfo.Object = NULL;
PostCreateKeyInfo.Status = Status;
CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo);
if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
return(Status);
goto Cleanup;
}
KeyObject->ParentKey = Object;
@ -361,7 +391,7 @@ NtCreateKey(OUT PHANDLE KeyHandle,
KeyObject,
&RemainingPath,
TitleIndex,
Class,
&CapturedClass,
CreateOptions);
if (!NT_SUCCESS(Status))
{
@ -370,23 +400,23 @@ NtCreateKey(OUT PHANDLE KeyHandle,
ExReleaseResourceLite(&CmiRegistryLock);
KeLeaveCriticalRegion();
ObDereferenceObject(KeyObject);
ObDereferenceObject(Object);
RtlFreeUnicodeString(&RemainingPath);
PostCreateKeyInfo.Object = NULL;
PostCreateKeyInfo.Status = STATUS_UNSUCCESSFUL;
CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo);
if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
return STATUS_UNSUCCESSFUL;
Status = STATUS_UNSUCCESSFUL;
goto Cleanup;
}
if (Start == RemainingPath.Buffer)
{
KeyObject->Name = RemainingPath;
FreeRemainingPath = FALSE;
}
else
{
RtlpCreateUnicodeString(&KeyObject->Name, Start, NonPagedPool);
RtlFreeUnicodeString(&RemainingPath);
}
if (KeyObject->RegistryHive == KeyObject->ParentKey->RegistryHive)
@ -400,10 +430,7 @@ NtCreateKey(OUT PHANDLE KeyHandle,
KeyObject->KeyCell->SecurityKeyOffset = -1;
/* This key must remain in memory unless it is deleted
or file is unloaded */
ObReferenceObjectByPointer(KeyObject,
STANDARD_RIGHTS_REQUIRED,
NULL,
UserMode);
ObReferenceObject(KeyObject);
}
CmiAddKeyToList(KeyObject->ParentKey, KeyObject);
@ -414,18 +441,38 @@ NtCreateKey(OUT PHANDLE KeyHandle,
ExReleaseResourceLite(&CmiRegistryLock);
KeLeaveCriticalRegion();
ObDereferenceObject(Object);
if (Disposition)
*Disposition = REG_CREATED_NEW_KEY;
PostCreateKeyInfo.Object = KeyObject;
PostCreateKeyInfo.Status = Status;
CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo);
if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
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;
}

View file

@ -83,6 +83,63 @@ RtlpLogException(IN PEXCEPTION_RECORD ExceptionRecord,
#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
*/
@ -102,10 +159,7 @@ ProbeAndCaptureUnicodeString(OUT PUNICODE_STRING Dest,
{
_SEH_TRY
{
ProbeForRead(UnsafeSrc,
sizeof(UNICODE_STRING),
sizeof(ULONG));
*Dest = *UnsafeSrc;
*Dest = ProbeForReadUnicodeString(UnsafeSrc);
if(Dest->Buffer != NULL)
{
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
*/