您的位置:首页 > 其它

注册表操作

2016-04-03 00:17 211 查看
先介绍一个有意思的

在删除文件中 有一个函数

BOOL WINAPI MoveFileEx(
__in      LPCTSTR lpExistingFileName,
__in_opt  LPCTSTR lpNewFileName,
__in      DWORD dwFlags
);


文档中是这么说的

If the dwFlags parameter specifies MOVEFILE_DELAY_UNTIL_REBOOT, MoveFileEx fails if it cannot access the registry. The function stores the locations of the files to be renamed at restart in the following registry value:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\
Session Manager\PendingFileRenameOperations

This registry value is of type REG_MULTI_SZ. Each rename operation stores one of the following NULL-terminated strings, depending on whether the rename is a delete or not:

szDstFile\0\0

szSrcFile\0szDstFile\0

The string szDstFile\0\0 indicates that the file szDstFile is to be deleted on reboot. The string szSrcFile\0szDstFile\0 indicates that szSrcFile is to be renamed szDstFile on reboot.

Note  Although \0\0 is technically not allowed in a REG_MULTI_SZ node, it can because the file is considered to be renamed to a null name.

The system uses these registry entries to complete the operations at restart in the same order that they were issued. For example, the following code fragment creates registry entries that delete szDstFile and rename szSrcFile to be szDstFile at restart:

MoveFileEx(szDstFile, NULL, MOVEFILE_DELAY_UNTIL_REBOOT);
MoveFileEx(szSrcFile, szDstFile, MOVEFILE_DELAY_UNTIL_REBOOT);

Because the actual move and deletion operations specified with the MOVEFILE_DELAY_UNTIL_REBOOT flag take place after the calling application has ceased running, the return value cannot reflect success or failure in moving or deleting the file. Rather, it reflects success or failure in placing the appropriate entries into the registry.

The system deletes a directory that is tagged for deletion with the MOVEFILE_DELAY_UNTIL_REBOOT flag only if it is empty. To ensure deletion of directories, move or delete all files from the directory before attempting to delete it. Files may be in the directory at boot time, but they must be deleted or moved before the system can delete the directory.

The move and deletion operations are carried out at boot time in the same order that they are specified in the calling application. To delete a directory that has files in it at boot time, first delete the files.

Windows Server 2003 and Windows XP:  For information about special situations where MOVEFILE_DELAY_UNTIL_REBOOT functionality can fail, and a suggested workaround solution, see "Files are not exchanged when Windows Server 2003 restarts if you use the MoveFileEx function to schedule a replacement for some files" in the Help and Support Knowledge Base at http://support.microsoft.com/kb/948601. If a file is moved across volumes, MoveFileEx does not move the security descriptor with the file. The file is assigned the default security descriptor in the destination directory.

The MoveFileEx function coordinates its operation with the link tracking service, so link sources can be tracked as they are moved.

To delete or rename a file, you must have either delete permission on the file or delete child permission in the parent directory. If you set up a directory with all access except delete and delete child and the ACLs of new files are inherited, then you should be able to create a file without being able to delete it. However, you can then create a file, and get all the access you request on the handle that is returned to you at the time that you create the file. If you request delete permission at the time you create the file, you can delete or rename the file with that handle but not with any other handle. For more information, see File Security and Access Rights.

Example Code
For an example, see Creating and Using a Temporary File.


其实就是操作注册表 在

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\PendingFileRenameOperations

里面设置重启要删除的文件 这里面需要带\\??\\ 原因大家都应该要懂的

上面只是引入用的啦

注册表有键(Key)和键值(ValueKey) 键就是左边的 键值就是右边的

下面说说注册键值的类型和含义ValueKey

REG_BINARY 二进制

REG_DWORD 四字节

REG_EXPAND_SZ 可以引用系统变量 比如%temp% %systemroot% (ExpandEnvironmentStrings 函数可查询系统变量 )

REG_SZ 字符串


REG_MULTI_SZ
多文本字符串 这个可以多个字符组合 中间以\0隔开 最后以\0\0结尾


REG_MULTI_SZ 补充:

“str1\0str2\0str3\0\0“(str1,str2,str3本身不含’\0’了,也可理解为str1str2str3\0,str1,str2,str3为NULL结尾)

组合方法:

sprintf(buf,"%s%c%s%c%c","1.1.1.1",0,"2.2.2.2",0,0);

遍历方法:

for(p=multistrz;*p!=L'\0';p=p+wcslen(p)+1)
{
}


常用API

ZwCreateKey
创建KEY

ZwEnumerateKey 枚举KEY

ZwQueryKey 查询KEY

ZwDeleteKey 删除KEY

ZwEnumerateValueKey 枚举valuekey

ZwQueryValueKey 查询valuekey

ZwSetValueKey 设置创建valuekey

ZwDeleteValueKey 删除valuekey


封装好的代码: 包含各种文件注册表操作 除了重命名(ZwRenameKey没有导出,需要自己定位) WinDbg x nt!ZwRenameKey

#include <ntddk.h>
#include <ntstrsafe.h>
#include <windef.h>

NTSTATUS ntCreateKey(WCHAR *szKey);

NTSTATUS ntOpenKey(WCHAR *szKey);
NTSTATUS ntEnumerateSubKey(WCHAR *szKey);

NTSTATUS ntSetValueKey(WCHAR *szKey);
NTSTATUS ntQueryValueKey(WCHAR *szKey);
NTSTATUS ntEnumerateSubValueKey(WCHAR *szKey);
NTSTATUS ntDeleteValueKey(WCHAR *szKey);

NTSTATUS ntDeleteKey(WCHAR *szKey);

VOID DriverUnload(PDRIVER_OBJECT pDriverObject)
{
NTSTATUS ntStatus =  ntDeleteValueKey(L"\\Registry\\Machine\\SoftWare\\Mallocfree");
if (!NT_SUCCESS(ntStatus))
{
DbgPrint("ntSetValueKey() failed:%x\n", ntStatus);
return;
}
ntDeleteKey(L"\\Registry\\Machine\\SoftWare\\Mallocfree");
DbgPrint("Driver Unloaded\n");
}

NTSTATUS RegOper(WCHAR *szKey);

NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegPath)
{
DbgPrint("Driver begin\n");
pDriverObject->DriverUnload = DriverUnload;

RegOper(L"\\Registry\\Machine\\SoftWare\\Mallocfree");

return STATUS_SUCCESS;
}

NTSTATUS RegOper(WCHAR *szKey)
{
NTSTATUS		ntStatus = STATUS_UNSUCCESSFUL;
WCHAR			szDeleteSubKey[MAX_PATH] = {0};

if (szKey == NULL)
{
return ntStatus;
}

ntStatus = ntCreateKey(szKey);
if (!NT_SUCCESS(ntStatus))
{
DbgPrint("ntCreateKey() failed:%x\n", ntStatus);
return ntStatus;
}

ntStatus = ntSetValueKey(szKey);

if (!NT_SUCCESS(ntStatus))
{
DbgPrint("ntSetValueKey() failed:%x\n", ntStatus);
return ntStatus;
}

ntStatus = ntQueryValueKey(szKey);

if (!NT_SUCCESS(ntStatus))
{
DbgPrint("ntQueryValueKey() failed:%x\n", ntStatus);
return ntStatus;
}

ntStatus = ntEnumerateSubValueKey(szKey);

if (!NT_SUCCESS(ntStatus))
{
DbgPrint("ntEnumerateSubValueKey() failed:%x\n", ntStatus);
return ntStatus;
}

// 	ntStatus =  ntDeleteValueKey(szKey);
// 	if (!NT_SUCCESS(ntStatus))
// 	{
// 		DbgPrint("ntSetValueKey() failed:%x\n", ntStatus);
// 		return ntStatus;
// 	}

ntStatus = ntOpenKey(szKey);
if (!NT_SUCCESS(ntStatus))
{
DbgPrint("ntOpenKey() failed:%x\n", ntStatus);
return ntStatus;
}

ntStatus = ntEnumerateSubKey(szKey);
if (!NT_SUCCESS(ntStatus))
{
DbgPrint("ntEnumerateSubItem() failed:%x\n", ntStatus);
return ntStatus;
}

// 	RtlStringCbCopyW(szDeleteSubKey, sizeof(szDeleteSubKey), szKey);
// 	RtlStringCbCatW(szDeleteSubKey, sizeof(szDeleteSubKey), L"\\KernelDriver");
// 	ntStatus = ntDeleteKey(szDeleteSubKey);
// 	if (!NT_SUCCESS(ntStatus))
// 	{
// 		DbgPrint("ntDeleteKey() failed:%x\n", ntStatus);
// 		return ntStatus;
// 	}

return ntStatus;

}

//创建KEY和SUBKEY示例
NTSTATUS ntCreateKey(WCHAR *szKey)
{

UNICODE_STRING 		uRegKey = {0};
HANDLE 				hRegister = NULL;
ULONG 				ulResult = 0;
OBJECT_ATTRIBUTES 	objectAttributes = {0};
UNICODE_STRING 		subRegKey = {0};
HANDLE 				hSubRegister = NULL;
OBJECT_ATTRIBUTES 	subObjectAttributes = {0};
NTSTATUS			ntStatus = STATUS_SUCCESS;

RtlInitUnicodeString( &uRegKey, szKey);
InitializeObjectAttributes(&objectAttributes,
&uRegKey,
OBJ_CASE_INSENSITIVE,
NULL,
NULL );
ntStatus = ZwCreateKey( &hRegister,
KEY_ALL_ACCESS,
&objectAttributes,
0,
NULL,
REG_OPTION_NON_VOLATILE,
&ulResult);

if (!NT_SUCCESS(ntStatus))
{
return ntStatus;
}

//开始创建SUBKEY

RtlInitUnicodeString( &subRegKey, L"KernelDriver");

InitializeObjectAttributes(&subObjectAttributes,
&subRegKey,
OBJ_CASE_INSENSITIVE,
hRegister,
NULL );
ntStatus = ZwCreateKey( &hSubRegister,
KEY_ALL_ACCESS,
&subObjectAttributes,
0,
NULL,
REG_OPTION_NON_VOLATILE,
&ulResult);

if (!NT_SUCCESS(ntStatus))
{
ZwClose(hRegister);
return ntStatus;
}

ZwClose(hRegister);
ZwClose(hSubRegister);

return ntStatus;
}

NTSTATUS ntOpenKey(WCHAR *szKey)
{
UNICODE_STRING 		RegUnicodeString = {0};
HANDLE 				hRegister = NULL;
OBJECT_ATTRIBUTES 	objectAttributes = {0};
NTSTATUS			ntStatus = STATUS_SUCCESS;

RtlInitUnicodeString( &RegUnicodeString, szKey);

InitializeObjectAttributes(&objectAttributes,
&RegUnicodeString,
OBJ_CASE_INSENSITIVE,
NULL,
NULL );
ntStatus = ZwOpenKey( &hRegister,
KEY_ALL_ACCESS,
&objectAttributes);

if (NT_SUCCESS(ntStatus))
{
return ntStatus;
}

ZwClose(hRegister);
return ntStatus;
}

NTSTATUS ntEnumerateSubKey(WCHAR *szKey)
{
UNICODE_STRING 			RegUnicodeString ={0};
HANDLE 					hRegister = NULL;
ULONG 					ulSize = 0;
OBJECT_ATTRIBUTES 		objectAttributes = {0};
NTSTATUS				ntStatus = STATUS_SUCCESS;
UNICODE_STRING			uniKeyName = {0};
PKEY_FULL_INFORMATION	pfi  = NULL;
ULONG					i=0;
PKEY_BASIC_INFORMATION  pbi = NULL;

RtlInitUnicodeString(&RegUnicodeString,szKey);
InitializeObjectAttributes(&objectAttributes,
&RegUnicodeString,
OBJ_CASE_INSENSITIVE,
NULL,
NULL );

ntStatus = ZwOpenKey( &hRegister,
KEY_ALL_ACCESS,
&objectAttributes);

if (!NT_SUCCESS(ntStatus))
{
return ntStatus;
}

//第一次调用ZwQueryKey为了获取KEY_FULL_INFORMATION数据的长度
ntStatus = ZwQueryKey(hRegister,
KeyFullInformation,
NULL,
0,
&ulSize);
if (STATUS_BUFFER_OVERFLOW != ntStatus &&
STATUS_BUFFER_TOO_SMALL != ntStatus)
{
return ntStatus;
}

pfi =
(PKEY_FULL_INFORMATION)
ExAllocatePoolWithTag(PagedPool,ulSize, 'SGER');
if (pfi == NULL)
{
ZwClose(hRegister);
return STATUS_INSUFFICIENT_RESOURCES;
}

//第二次调用ZwQueryKey为了获取KEY_FULL_INFORMATION数据的数据
//这个查询成功后就可以知道这个键下面有多少子键(SubKeys)和右边有多少ValueKey(Value)
ntStatus = ZwQueryKey(hRegister,
KeyFullInformation,
pfi,
ulSize,
&ulSize);
if (!NT_SUCCESS(ntStatus))
{
ExFreePool(pfi);
ZwClose(hRegister);
return ntStatus;
}

for (i=0;i<pfi->SubKeys;i++)
{
//第一次调用ZwEnumerateKey为了获取KEY_BASIC_INFORMATION数据的长度
ntStatus = ZwEnumerateKey(hRegister,
i,
KeyBasicInformation,
NULL,
0,
&ulSize);
if (STATUS_BUFFER_OVERFLOW != ntStatus &&
STATUS_BUFFER_TOO_SMALL != ntStatus)
{
ZwClose(hRegister);
ExFreePool(pfi);
return ntStatus;
}

pbi = (PKEY_BASIC_INFORMATION)
ExAllocatePoolWithTag(PagedPool,ulSize, 'SGER');
if (pbi == NULL)
{
ZwClose(hRegister);
return STATUS_INSUFFICIENT_RESOURCES;
}

//第二次调用ZwEnumerateKey为了获取KEY_BASIC_INFORMATION数据的数据
查询成功后就可以到键名
ntStatus = ZwEnumerateKey(hRegister,
i,
KeyBasicInformation,
pbi,
ulSize,
&ulSize);

if (!NT_SUCCESS(ntStatus))
{
ZwClose(hRegister);
ExFreePool(pfi);
ExFreePool(pbi);
return ntStatus;
}

uniKeyName.Length =
uniKeyName.MaximumLength =
(USHORT)pbi->NameLength;

uniKeyName.Buffer = pbi->Name;

DbgPrint("The %d sub item name is:%wZ\n",i,&uniKeyName);

ExFreePool(pbi);
}

ExFreePool(pfi);
ZwClose(hRegister);

return ntStatus;
}

NTSTATUS ntDeleteKey(WCHAR *szKey)
{
UNICODE_STRING 		RegUnicodeString = {0};
HANDLE 				hRegister = NULL;
OBJECT_ATTRIBUTES 	objectAttributes = {0};
NTSTATUS			ntStatus = STATUS_SUCCESS;

RtlInitUnicodeString(&RegUnicodeString,szKey);

InitializeObjectAttributes(&objectAttributes,
&RegUnicodeString,
OBJ_CASE_INSENSITIVE,
NULL,
NULL );

ntStatus = ZwOpenKey( &hRegister,
KEY_ALL_ACCESS,
&objectAttributes);

if (!NT_SUCCESS(ntStatus))
{
return ntStatus;
}

ntStatus = ZwDeleteKey(hRegister);

ZwClose(hRegister);
return ntStatus;
}

NTSTATUS ntSetValueKey(WCHAR *szKey)
{
UNICODE_STRING 		RegUnicodeString = {0};
HANDLE 				hRegister = NULL;
OBJECT_ATTRIBUTES 	objectAttributes = {0};
UNICODE_STRING 		ValueName = {0};
NTSTATUS			ntStatus = STATUS_SUCCESS;
ULONG				ulValue = 0;
WCHAR				*strValue = L"hello world";
CHAR				buffer[1024] = {0};

RtlInitUnicodeString( &RegUnicodeString,szKey);

InitializeObjectAttributes(
&objectAttributes,
&RegUnicodeString,
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
NULL,
NULL
);

ntStatus = ZwOpenKey( &hRegister,
KEY_ALL_ACCESS,
&objectAttributes);

if (!NT_SUCCESS(ntStatus))
{
return ntStatus;
}

RtlInitUnicodeString( &ValueName, L"REG_DWORD");
ulValue = 1000;
ZwSetValueKey(hRegister,
&ValueName,
0,
REG_DWORD,
&ulValue,
sizeof(ulValue));

RtlInitUnicodeString( &ValueName, L"REG_SZ");

ZwSetValueKey(hRegister,
&ValueName,
0,
REG_SZ,
strValue,
wcslen(strValue)*sizeof(WCHAR)+sizeof(WCHAR));

RtlInitUnicodeString( &ValueName, L"REG_BINARY");

RtlFillMemory(buffer,sizeof(buffer),0xFF);
ZwSetValueKey(hRegister,
&ValueName,
0,
REG_BINARY,
buffer,
sizeof(buffer));

ZwClose(hRegister);
return ntStatus;
}

NTSTATUS ntDeleteValueKey(WCHAR *szKey)
{
UNICODE_STRING 		RegUnicodeString = {0};
HANDLE 				hRegister = NULL;
OBJECT_ATTRIBUTES 	objectAttributes = {0};
UNICODE_STRING 		ValueName ={0};
ULONG 				ulSize = 0;
NTSTATUS			ntStatus = STATUS_SUCCESS;

RtlInitUnicodeString( &RegUnicodeString,szKey);

InitializeObjectAttributes(&objectAttributes,
&RegUnicodeString,
OBJ_CASE_INSENSITIVE,
NULL,
NULL );
ntStatus = ZwOpenKey( &hRegister,
KEY_ALL_ACCESS,
&objectAttributes);
if (!NT_SUCCESS(ntStatus))
{
return ntStatus;
}

RtlInitUnicodeString( &ValueName, L"REG_DWORD");
ntStatus = ZwDeleteValueKey(hRegister, &ValueName);

ZwClose(hRegister);
return ntStatus;
}

NTSTATUS ntQueryValueKey(WCHAR *szKey)
{
UNICODE_STRING 					RegUnicodeString = {0};
HANDLE 							hRegister = 0;
OBJECT_ATTRIBUTES 				objectAttributes = {0};
UNICODE_STRING 					ValueName = {0};
ULONG 							ulSize = 0;
NTSTATUS						ntStatus = STATUS_SUCCESS;
PKEY_VALUE_PARTIAL_INFORMATION	pvpi = NULL;

RtlInitUnicodeString( &RegUnicodeString,szKey);

InitializeObjectAttributes(&objectAttributes,
&RegUnicodeString,
OBJ_CASE_INSENSITIVE,
NULL,
NULL );
ntStatus = ZwOpenKey( &hRegister,
KEY_ALL_ACCESS,
&objectAttributes);
if (!NT_SUCCESS(ntStatus))
{
return ntStatus;
}

RtlInitUnicodeString( &ValueName, L"REG_DWORD");

ntStatus = ZwQueryValueKey(hRegister,
&ValueName,
KeyValuePartialInformation ,
NULL,
0,
&ulSize);

if (ntStatus != STATUS_BUFFER_OVERFLOW &&
ntStatus != STATUS_BUFFER_TOO_SMALL)
{
ZwClose(hRegister);
return ntStatus;
}

pvpi =
(PKEY_VALUE_PARTIAL_INFORMATION)
ExAllocatePoolWithTag(PagedPool,ulSize, 'SGER');
if (pvpi == NULL)
{
return STATUS_INSUFFICIENT_RESOURCES;
}

ntStatus = ZwQueryValueKey(hRegister,
&ValueName,
KeyValuePartialInformation ,
pvpi,
ulSize,
&ulSize);
if (!NT_SUCCESS(ntStatus))
{
ExFreePool(pvpi);
ZwClose(hRegister);
return ntStatus;
}

if (pvpi->Type==REG_DWORD && pvpi->DataLength==sizeof(ULONG))
{
PULONG pulValue = (PULONG) pvpi->Data;
}

ExFreePool(pvpi);

RtlInitUnicodeString( &ValueName, L"REG_SZ");

ntStatus = ZwQueryValueKey(hRegister,
&ValueName,
KeyValuePartialInformation ,
NULL,
0,
&ulSize);

if (ntStatus==STATUS_OBJECT_NAME_NOT_FOUND || ulSize==0)
{
ZwClose(hRegister);
return ntStatus;
}
pvpi =
(PKEY_VALUE_PARTIAL_INFORMATION)
ExAllocatePoolWithTag(PagedPool,ulSize, 'SGER');
if (pvpi == NULL)
{
return STATUS_INSUFFICIENT_RESOURCES;
}

ntStatus = ZwQueryValueKey(hRegister,
&ValueName,
KeyValuePartialInformation ,
pvpi,
ulSize,
&ulSize);
if (!NT_SUCCESS(ntStatus))
{
ExFreePool(pvpi);
ZwClose(hRegister);
return ntStatus;
}

if (pvpi->Type==REG_SZ)
{
UNICODE_STRING uStr;
uStr.Length=pvpi->DataLength;
uStr.MaximumLength = pvpi->DataLength;

uStr.Buffer = pvpi->Data;

DbgPrint("Value:%S\n",pvpi->Data);
DbgPrint("Value:%wZ\n", &uStr);
}
ExFreePool(pvpi);
ZwClose(hRegister);
return ntStatus;
}

NTSTATUS ntEnumerateSubValueKey(WCHAR *szKey)
{
UNICODE_STRING 					RegUnicodeString ={0};
HANDLE 							hRegister = NULL;
OBJECT_ATTRIBUTES 				objectAttributes ={0};
ULONG 							ulSize = 0;
UNICODE_STRING					uniKeyName = {0};
ULONG							i = 0;
NTSTATUS						ntStatus = 0;
PKEY_VALUE_BASIC_INFORMATION	pvbi = NULL;
PKEY_FULL_INFORMATION			pfi = NULL;

RtlInitUnicodeString( &RegUnicodeString,szKey);

InitializeObjectAttributes(&objectAttributes,
&RegUnicodeString,
OBJ_CASE_INSENSITIVE,
NULL,
NULL );
ntStatus = ZwOpenKey( &hRegister,
KEY_ALL_ACCESS,
&objectAttributes);

if (!NT_SUCCESS(ntStatus))
{
return ntStatus;
}

ntStatus = ZwQueryKey(hRegister,
KeyFullInformation,
NULL,
0,
&ulSize);
if (STATUS_BUFFER_OVERFLOW != ntStatus &&
STATUS_BUFFER_TOO_SMALL != ntStatus)
{
ZwClose(hRegister);
return ntStatus;
}

pfi =
(PKEY_FULL_INFORMATION)
ExAllocatePoolWithTag(PagedPool,ulSize, 'SGER');
if (pfi == NULL)
{
ZwClose(hRegister);
return STATUS_INSUFFICIENT_RESOURCES;
}

ntStatus = ZwQueryKey(hRegister,
KeyFullInformation,
pfi,
ulSize,
&ulSize);
if (!NT_SUCCESS(ntStatus))
{
ZwClose(hRegister);
ExFreePool(pfi);
return ntStatus;
}

for (i=0;i<pfi->Values;i++)
{
ntStatus = ZwEnumerateValueKey(hRegister,
i,
KeyValueBasicInformation,
NULL,
0,
&ulSize);

if (STATUS_BUFFER_OVERFLOW != ntStatus &&
STATUS_BUFFER_TOO_SMALL != ntStatus)
{
ZwClose(hRegister);
ExFreePool(pfi);
return ntStatus;
}

pvbi =
(PKEY_VALUE_BASIC_INFORMATION)
ExAllocatePoolWithTag(PagedPool,ulSize, 'SGER');
if (pvbi == NULL)
{
ZwClose(hRegister);
ExFreePool(pfi);
return ntStatus;
}

ntStatus = ZwEnumerateValueKey(hRegister,
i,
KeyValueBasicInformation,
pvbi,
ulSize,
&ulSize);
if (!NT_SUCCESS(ntStatus))
{
ZwClose(hRegister);
ExFreePool(pfi);
ExFreePool(pvbi);
return ntStatus;
}

uniKeyName.Length =
uniKeyName.MaximumLength =
(USHORT)pvbi->NameLength;

uniKeyName.Buffer = pvbi->Name;

DbgPrint("The %d sub value name:%wZ\n",i,&uniKeyName);

if (pvbi->Type==REG_SZ)
{
DbgPrint("type:REG_SZ\n");
}
else if (pvbi->Type==REG_MULTI_SZ)
{
DbgPrint("type:REG_MULTI_SZ\n");

}
else if (pvbi->Type==REG_DWORD)
{
DbgPrint("type:REG_DWORD\n");
}
else if (pvbi->Type==REG_BINARY)
{
DbgPrint("type:REG_BINARY\n");
}

ExFreePool(pvbi);
}

ExFreePool(pfi);
ZwClose(hRegister);

return ntStatus;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: