欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

[原创]创建注册表的根键

[原创]创建注册表的根键

/*
功能:创建注册表的根键.
尽管:《深入解析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;
}

注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途。
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功