ntdll.dll里面的NtCreateKey/ZwCreateKey:
(源自MSDN)
NTSTATUS ZwCreateKey(
__out PHANDLE KeyHandle,
__in ACCESS_MASK DesiredAccess,
__in POBJECT_ATTRIBUTES ObjectAttributes,
__reserved ULONG TitleIndex,
__in_opt PUNICODE_STRING Class,
__in ULONG CreateOptions,
__out_opt PULONG Disposition
);
参数:
KeyHandle [out]
Pointer to a HANDLE variable that receives a handle to the key.
指向一个HANDLE类型的值,此值储存返回的键的句柄
DesiredAccess [in]
Specifies an ACCESS_MASK value that determines the requested access to the object. In addition to the access rights that are defined for all types of objects (see ACCESS_MASK), the caller can specify one or more of the following access rights, which are specific to object directories:
DesiredAccess flag | Allows caller to do this |
---|---|
KEY_QUERY_VALUE | Read key values. |
KEY_SET_VALUE | Write key values. |
KEY_CREATE_SUB_KEY | Create subkeys for the key. |
KEY_ENUMERATE_SUB_KEYS | Read the key's subkeys. |
KEY_CREATE_LINK | Create a symbolic link to the key. This flag is not used by device and intermediate drivers. |
KEY_NOTIFY | Ask to receive notification when the name, value, or attributes of the key change. For more information, see ZwNotifyChangeKey. |
The caller can also specify one of the following constants, which combines several ACCESS_MASK flags.
Constant | Consists of these ACCESS_MASK flags |
---|---|
KEY_READ | STANDARD_RIGHTS_READ, KEY_QUERY_VALUE, KEY_ENUMERATE_SUB_KEYS, and KEY_NOTIFY |
KEY_WRITE | STANDARD_RIGHTS_WRITE, KEY_SET_VALUE, and KEY_CREATE_SUBKEY |
KEY_EXECUTE | Same as KEY_READ. |
KEY_ALL_ACCESS | STANDARD_RIGHTS_ALL, KEY_QUERY_VALUE, KEY_SET_VALUE, KEY_CREATE_SUB_KEY, KEY_ENUMERATE_SUB_KEYS, KEY_NOTIFY, and KEY_CREATE_LINK |
ObjectAttributes [in]
Pointer to an OBJECT_ATTRIBUTES structure that specifies the object name and other attributes. Use InitializeObjectAttributes to initialize this structure. If the caller is not running in a system thread context, it must set the OBJ_KERNEL_HANDLE attribute when it callsInitializeObjectAttributes.
指向一个OBJECT_ATTRIBUTES结构体。此结构体说明了对象的名字和其它的性质。(下面有解释)
TitleIndex
Device and intermediate drivers set this parameter to zero.
Class [in, optional]
Pointer to a Unicode string that contains the key's object class. This information is used by the configuration manager.
指向一个PUNICODE_STRING结构体,此结构体中包含了此键的对象所属的类(下面有解释)
eateOptions [in]
Specifies the options to apply when creating or opening a key, specified as a compatible combination of the following flags.
CreateOptions flag | Description |
---|---|
REG_OPTION_VOLATILE | Key is not preserved when the system is rebooted. |
REG_OPTION_NON_VOLATILE | Key is preserved when the system is rebooted. |
REG_OPTION_CREATE_LINK | The newly created key is a symbolic link. This flag is not used by device and intermediate drivers. |
REG_OPTION_BACKUP_RESTORE | Key should be created or opened with special privileges that allow backup and restore operations. This flag is not used by device and intermediate drivers. |
Disposition [out, optional]
Pointer to a variable that receives a value indicating whether a new key was created or an existing one opened.
指向一个用来储存结果的值,此值反应了新键被创建还是已经存在的键被打开
Disposition value | Description |
---|---|
REG_CREATED_NEW_KEY | A new key was created. |
REG_OPENED_EXISTING_KEY | An existing key was opened. |
返回值:
ZwCreateKey returns STATUS_SUCCESS on success, or the appropriate NTSTATUS error code on failure.
如果成功,ZwCreateKey返回STATUS_SUCCESS,否则返回何时的NTSTATUS错误值
UNICODE_STRING:
typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;
Members
Length
The length in bytes of the string stored in Buffer.
以字节计算的存在Buffer中的字符串长度
MaximumLength
The length in bytes of Buffer.
Buffer的长度
Buffer
Pointer to a buffer used to contain a string of wide characters.
指向一个用来储存宽字节字符串的缓冲区
Remarks
The UNICODE_STRING structure is used to pass Unicode strings. Use RtlInitUnicodeString to initialize a UNICODE_STRING.
If the string is NULL-terminated, Length does not include the trailing NULL.(Length并不包括结尾的"\0"的长度)
The MaximumLength is used to indicate the length of Buffer so that if the string is passed to a conversion routine such as RtlAnsiStringToUnicodeString the returned string does not exceed the buffer size.
OBJECT_ATTRIBUTES
typedef struct _OBJECT_ATTRIBUTES {
ULONG Length;
HANDLE RootDirectory;
PUNICODE_STRING ObjectName;
ULONG Attributes;
PVOID SecurityDescriptor;
PVOID SecurityQualityOfService;
} OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;
Members
-
Length
-
The number of bytes of data contained in this structure. The InitializeObjectAttributes macro sets this member tosizeof(OBJECT_ATTRIBUTES).
RootDirectory
-
Optional handle to the root object directory for the path name specified by the ObjectName member. If RootDirectory is NULL,ObjectName must point to a fully qualified object name that includes the full path to the target object. If RootDirectory is non-NULL,ObjectName specifies an object name relative to the RootDirectory directory. The RootDirectory handle can refer to a file system directory or an object directory in the object manager namespace.
ObjectName
-
Pointer to a Unicode string that contains the name of the object for which a handle is to be opened. This must either be a fully qualified object name, or a relative path name to the directory specified by the RootDirectory member.
Attributes
-
Bitmask of flags that specify object handle attributes. This member can contain one or more of the flags in the following table.
Flag Meaning OBJ_INHERIT
This handle can be inherited by child processes of the current process.
OBJ_PERMANENT
This flag only applies to objects that are named within the object manager. By default, such objects are deleted when all open handles to them are closed. If this flag is specified, the object is not deleted when all open handles are closed. Drivers can use the ZwMakeTemporaryObject routine to make a permanent object non-permanent.
OBJ_EXCLUSIVE
If this flag is set and the OBJECT_ATTRIBUTES structure is passed to a routine that creates an object, the object can be accessed exclusively. That is, once a process opens such a handle to the object, no other processes can open handles to this object.
If this flag is set and the OBJECT_ATTRIBUTES structure is passed to a routine that creates an object handle, the caller is requesting exclusive access to the object for the process context that the handle was created in. This request can be granted only if the OBJ_EXCLUSIVE flag was set when the object was created.
OBJ_CASE_INSENSITIVE
If this flag is specified, a case-insensitive comparison is used when matching the name pointed to by the ObjectName member against the names of existing objects. Otherwise, object names are compared using the default system settings.
OBJ_OPENIF
If this flag is specified, by using the object handle, to a routine that creates objects and if that object already exists, the routine should open that object. Otherwise, the routine creating the object returns an NTSTATUS code of STATUS_OBJECT_NAME_COLLISION.
OBJ_OPENLINK
If an object handle, with this flag set, is passed to a routine that opens objects and if the object is a symbolic link object, the routine should open the symbolic link object itself, rather than the object that the symbolic link refers to (which is the default behavior).
OBJ_KERNEL_HANDLE
The handle is created in system process context and can only be accessed from kernel mode.
OBJ_FORCE_ACCESS_CHECK
The routine that opens the handle should enforce all access checks for the object, even if the handle is being opened in kernel mode.
OBJ_VALID_ATTRIBUTES
Reserved.
SecurityDescriptor
-
Specifies a security descriptor (SECURITY_DESCRIPTOR) for the object when the object is created. If this member is NULL, the object will receive default security settings.
SecurityQualityOfService
-
Optional quality of service to be applied to the object when it is created. Used to indicate the security impersonation level and context tracking mode (dynamic or static). Currently, the InitializeObjectAttributes macro sets this member to NULL.
英文的有点看不懂。下面是网上摘录的中文说明:
Length:结构体大小
RootDirectory:备选的句柄指向一个根对象目录的路径名称所指定的ObjectName成员。
ObjectName: 驱动对象的名称
Attributes : 用来指定一个handle的一些属性的。
OBJ_INHERIT
OBJ_PERMANENT
OBJ_EXCLUSIVE
OBJ_CASE_INSENSITIVE
OBJ_OPENIF
OBJ_OPENLINK
OBJ_KERNEL_HANDLE
OBJ_FORCE_ACCESS_CHECK
OBJ_VALID_ATTRIBUTES
它可以有许多属性值,这里需要注意OBJ_KERNEL_HANDLE 这个值。
如果指定了这个属性,那么这个handle只能在内核模式下使用,否则它既可以在内核模式下使用也可以在用户模式下
使用。既然这样是不是就不用指定这个参数了呢?
不是这样的。
如果在内核模式下不指定这个参数,当driver在运行时,如果用Driver Verifier来测试,它会报一个蓝屏bug。
DRIVER_VERIFIER_DETECTED_VIOLATION (c4)
它认为这个handle既可以在内核模式中使用也可以在用户模式下使用,这样一个内核模式的handle可能会在用户模式下被改掉。
发生这样的情况对内核来说是不安全的,所以它就蓝屏了。
SecurityDescriptor:指定一个当驱动对象被创建时指定的安全描述(安全_描述符)。如果这个成员是NULL,物体会收到默认安全设置。
SecurityQualityOfService:可选参数
可以用 Initializeobjectattributes 宏初始化这个结构; 注意:用这个宏初始化 OBJECT_ATTRIBUTES 时 SecurityQualityOfService必须为 NULL,如果需要使用这个参数,可以在这之后进行手动修改...
在这结构包含一个对象或对象处理的应用属性,通过一个指针对这结构一个进行存取对象或返回对象句柄
最后是一个函数,没仔细研究:
VOID InitializeObjectAttributes(
[out] POBJECT_ATTRIBUTES InitializedAttributes,
[in] PUNICODE_STRING ObjectName,
[in] ULONG Attributes,
[in] HANDLE RootDirectory,
[in, optional] PSECURITY_DESCRIPTOR SecurityDescriptor
);
用来初始化OBJECT_ATTRIBUTES对象