/*
功能:创建注册表的根键.
尽管:《深入解析windows操作系统》的第四章有如下说明:
There are six root keys (and you can't add new root keys or delete existing ones) that store information
RegLoadKey函数有如下说明:
Creates a subkey under HKEY_USERS or HKEY_LOCAL_MACHINE and loads the data from the specified registry hive into that subkey.
而且:http://msdn.microsoft.com/en-us/library/windows/hardware/ff546907(v=vs.85).aspx
的补充说明里面说不建议使用如下函数.
NtRestoreKey
NtSaveKey
NtSaveKeyEx
NtLoadKeyEx
NtUnloadKey2
NtUnloadKeyEx
NtReplaceKey
NtRenameKey
NtSetInformationKey
这些函数没有公开的调用接口,但是导出了,而且很早的版本就导出了,所以可以安心的使用.
注册表根键创建的成功与失败可以通过代码的返回值查看.
也可以通过注册表路径HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\hivelist查看.
不足之处,敬请指出.
made by correy
made at 2013.11.13
email:kouleguan at hotmail dot com
homepage:http://correy.webs.com
*/
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
用户层创建注册表根键的代码.
#include <windows.h>
typedef _Return_type_success_(return >= 0) LONG NTSTATUS;
typedef NTSTATUS *PNTSTATUS;
typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
#ifdef MIDL_PASS
[size_is(MaximumLength / 2), length_is((Length) / 2) ] USHORT * Buffer;
#else // MIDL_PASS
_Field_size_bytes_part_(MaximumLength, Length) PWCH Buffer;
#endif // MIDL_PASS
} UNICODE_STRING;
typedef UNICODE_STRING *PUNICODE_STRING;
typedef const UNICODE_STRING *PCUNICODE_STRING;
typedef struct _OBJECT_ATTRIBUTES {
ULONG Length;
HANDLE RootDirectory;
PUNICODE_STRING ObjectName;
ULONG Attributes;
PVOID SecurityDescriptor; // Points to type SECURITY_DESCRIPTOR
PVOID SecurityQualityOfService; // Points to type SECURITY_QUALITY_OF_SERVICE
} OBJECT_ATTRIBUTES;
typedef OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES;
typedef CONST OBJECT_ATTRIBUTES *PCOBJECT_ATTRIBUTES;
#ifdef __cplusplus
extern "C++"
{
char _RTL_CONSTANT_STRING_type_check(const char *s);
char _RTL_CONSTANT_STRING_type_check(const WCHAR *s);
// __typeof would be desirable here instead of sizeof.
template <size_t N> class _RTL_CONSTANT_STRING_remove_const_template_class;
template <> class _RTL_CONSTANT_STRING_remove_const_template_class<sizeof(char)> {public: typedef char T; };
template <> class _RTL_CONSTANT_STRING_remove_const_template_class<sizeof(WCHAR)> {public: typedef WCHAR T; };
#define _RTL_CONSTANT_STRING_remove_const_macro(s) \
(const_cast<_RTL_CONSTANT_STRING_remove_const_template_class<sizeof((s)[0])>::T*>(s))
}
#else
char _RTL_CONSTANT_STRING_type_check(const void *s);
#define _RTL_CONSTANT_STRING_remove_const_macro(s) (s)
#endif
#define RTL_CONSTANT_STRING(s) \
{ \
sizeof( s ) - sizeof( (s)[0] ), \
sizeof( s ) / sizeof(_RTL_CONSTANT_STRING_type_check(s)), \
_RTL_CONSTANT_STRING_remove_const_macro(s) \
}
#define InitializeObjectAttributes( p, n, a, r, s ) { \
(p)->Length = sizeof( OBJECT_ATTRIBUTES ); \
(p)->RootDirectory = r; \
(p)->Attributes = a; \
(p)->ObjectName = n; \
(p)->SecurityDescriptor = s; \
(p)->SecurityQualityOfService = NULL; \
}
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
#define OBJ_INHERIT 0x00000002L
#define OBJ_PERMANENT 0x00000010L
#define OBJ_EXCLUSIVE 0x00000020L
#define OBJ_CASE_INSENSITIVE 0x00000040L
#define OBJ_OPENIF 0x00000080L
#define OBJ_OPENLINK 0x00000100L
#define OBJ_KERNEL_HANDLE 0x00000200L
#define OBJ_FORCE_ACCESS_CHECK 0x00000400L
#define OBJ_VALID_ATTRIBUTES 0x000007F2L
//NTSTATUS ZwUnloadKey(IN POBJECT_ATTRIBUTES KeyObjectAttributes);
//NTSTATUS ZwLoadKey(IN POBJECT_ATTRIBUTES KeyObjectAttributes, IN POBJECT_ATTRIBUTES FileObjectAttributes);
//函数指针.
typedef NTSTATUS (WINAPI * ZWLOADKEY) (IN POBJECT_ATTRIBUTES KeyObjectAttributes, IN POBJECT_ATTRIBUTES FileObjectAttributes);//__stdcall
typedef NTSTATUS (WINAPI * ZWUNLOADKEY) (IN POBJECT_ATTRIBUTES KeyObjectAttributes);//__stdcall
//全局变量
UNICODE_STRING uRegistryPath = RTL_CONSTANT_STRING(L"\\REGISTRY\\correy");
UNICODE_STRING uRegDatPath = RTL_CONSTANT_STRING(L"\\DosDevices\\c:\\correy.DAT");
OBJECT_ATTRIBUTES obj;
OBJECT_ATTRIBUTES HiveFile;
ZWUNLOADKEY ZwUnloadKey;
ZWLOADKEY ZwLoadKey;
BOOL SetPrivilege(
//HANDLE hToken, // access token handle
LPCTSTR lpszPrivilege, // name of privilege to enable/disable
BOOL bEnablePrivilege // to enable or disable privilege
)
{
TOKEN_PRIVILEGES tp;
LUID luid;
HANDLE hToken; // Get a token for this process.
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
{
return( FALSE );
}
if ( !LookupPrivilegeValue(
NULL, // lookup privilege on local system
lpszPrivilege, // privilege to lookup
&luid ) ) // receives LUID of privilege
{
printf("LookupPrivilegeValue error: %u\n", GetLastError() );
return FALSE;
}
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
if (bEnablePrivilege)
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
else
tp.Privileges[0].Attributes = 0;
// Enable the privilege or disable all privileges.
if ( !AdjustTokenPrivileges(
hToken,
FALSE,
&tp,
sizeof(TOKEN_PRIVILEGES),
(PTOKEN_PRIVILEGES) NULL,
(PDWORD) NULL) )
{
printf("AdjustTokenPrivileges error: %u\n", GetLastError() );
return FALSE;
}
if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
{
printf("The token does not have the specified privilege. \n");
return FALSE;
}
return TRUE;
}
void main( )
{
BOOL B;
B = SetPrivilege(SE_BACKUP_NAME, TRUE);
B = SetPrivilege(SE_RESTORE_NAME, TRUE);//必须加上这个RegSaveKey才成功.
int r;
LONG l = RegSaveKey(HKEY_CURRENT_USER, L"c:\\correy.dat", NULL);//如果已经存在,即使不在使用中,这个会失败.
if (l != ERROR_SUCCESS)
{
r = GetLastError();
}
InitializeObjectAttributes(&obj,&uRegistryPath, OBJ_CASE_INSENSITIVE, NULL, NULL );//|OBJ_KERNEL_HANDLE
InitializeObjectAttributes(&HiveFile,&uRegDatPath,OBJ_CASE_INSENSITIVE, NULL, NULL );//|OBJ_KERNEL_HANDLE
HINSTANCE hinstLib = LoadLibrary(TEXT("ntdll.dll")); // Get a handle to the DLL module.
if (hinstLib != NULL) // If the handle is valid, try to get the function address.
{
ZwLoadKey = (ZWLOADKEY) GetProcAddress(hinstLib, "NtLoadKey");
if (NULL != ZwLoadKey) // If the function address is valid, call the function.
{
NTSTATUS status = ZwLoadKey(&obj,&HiveFile);//只一行运行会出错.
if(!NT_SUCCESS(status))
{
MessageBox(0,0,0,0);
//return;
}
}
MessageBox(0,L"下面开始卸载",0,0);
ZwUnloadKey = (ZWUNLOADKEY) GetProcAddress(hinstLib, "NtUnloadKey");
if (NULL != ZwUnloadKey) // If the function address is valid, call the function.
{
NTSTATUS status = ZwUnloadKey(&obj);//只一行运行会出错.
if(!NT_SUCCESS(status))
{
MessageBox(0,0,0,0);
//return;
}
}
FreeLibrary(hinstLib); // Free the DLL module.
}
//BOOL b = CopyFile(L"C:\\Users\\Administrator\\NTUSER.DAT", L"c:\\hkcu_copy.dat",false);
//if (!b)
//{
// r = GetLastError();//0x00000020,另一个程序(system)正在使用此文件,进程无法访问。
//}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
驱动层创建注册表根键的代码如下:
#include <ntifs.h>
NTSTATUS ZwUnloadKey(IN POBJECT_ATTRIBUTES KeyObjectAttributes);
NTSTATUS ZwLoadKey(IN POBJECT_ATTRIBUTES KeyObjectAttributes, IN POBJECT_ATTRIBUTES FileObjectAttributes);
UNICODE_STRING uRegistryPath = RTL_CONSTANT_STRING(L"\\REGISTRY\\correy");
UNICODE_STRING uRegDatPath = RTL_CONSTANT_STRING(L"\\DosDevices\\c:\\correy.DAT");//此文件必须是本计算机的,系统的或者自己生成的.
OBJECT_ATTRIBUTES obj;
OBJECT_ATTRIBUTES HiveFile;
VOID RegisterLoad()
{
NTSTATUS status;
HANDLE hRegister;
ULONG i=0,ulSize=0;
UNICODE_STRING us;
status = ZwLoadKey(&obj,&HiveFile);
if(!NT_SUCCESS(status))
{
DbgPrint("LoadKey failed Error: [%x] \n", status);
return;
}
//一下是列举其子键的,也就是验证下.
status = ZwOpenKey(&hRegister, KEY_ALL_ACCESS, &obj);
if (NT_SUCCESS(status))
{
PKEY_FULL_INFORMATION pfi;
ZwQueryKey(hRegister, KeyFullInformation, NULL, 0, &ulSize);
pfi = (PKEY_FULL_INFORMATION)ExAllocatePool(PagedPool, ulSize);// 第一次调用是为了获取需要的长度
ZwQueryKey(hRegister, KeyFullInformation, pfi, ulSize, &ulSize);// 第二次调用是为了获取数据
for (i = 0; i < pfi->SubKeys; i++)
{
PKEY_BASIC_INFORMATION pbi;
ZwEnumerateKey(hRegister, i, KeyBasicInformation, NULL, 0, &ulSize);// 获取第i个子项的长度
pbi = (PKEY_BASIC_INFORMATION)ExAllocatePool(PagedPool, ulSize);
ZwEnumerateKey(hRegister, i, KeyBasicInformation, pbi, ulSize, &ulSize);// 获取第i个子项的数据
us.Buffer = pbi->Name;
us.Length = (USHORT)pbi->NameLength;
us.MaximumLength = pbi->NameLength + sizeof(wchar_t);
DbgPrint("The %d SubItem Name : %wZ\n", i, &us);
ExFreePool(pbi);// 释放内存
}
ExFreePool(pfi);
ZwClose(hRegister);
} else {
DbgPrint("ZwOpenKey failed unknown cause. Error: [%x] \n", status);
}
}
DRIVER_UNLOAD Unload;
VOID Unload(__in PDRIVER_OBJECT DriverObject)
{
NTSTATUS status;
status = ZwUnloadKey(&obj);
if(!NT_SUCCESS(status))
{
DbgPrint("ZwUnloadKey fail!\n");
}
}
#pragma INITCODE
DRIVER_INITIALIZE DriverEntry;
NTSTATUS DriverEntry(__in struct _DRIVER_OBJECT * DriverObject, __in PUNICODE_STRING RegistryPath)
{
NTSTATUS Status = 0;
KdBreakPoint();// == DbgBreakPoint()
DriverObject->DriverUnload = Unload;
InitializeObjectAttributes(&obj,&uRegistryPath, OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE, NULL, NULL );
InitializeObjectAttributes(&HiveFile,&uRegDatPath,OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE, NULL, NULL );
RegisterLoad();
return Status;
}
没有评论:
发表评论