windows 注册表的初始化

看了看wrk的代码,发现一个函数会调用ZwCreateFile打开注册表的文件,这个函数就是CmpOpenHiveFiles

这个函数会打开两个注册表文件,master为不带后辍的,secondary为带后辍的。

system32\config\system和software就是这样被加载的。

 

查找过程,先找SAM,这个词不常见,grep一下找到一个配置表:

HIVE_LIST_ENTRY CmpMachineHiveList[] = {     { L"HARDWARE", L"MACHINE\\", NULL, HIVE_VOLATILE    , 0                         ,   NULL,   FALSE,  FALSE,  FALSE},     { L"SECURITY", L"MACHINE\\", NULL, 0                , 0                         ,   NULL,   FALSE,  FALSE,  FALSE},     { L"SOFTWARE", L"MACHINE\\", NULL, 0                , 0                         ,   NULL,   FALSE,  FALSE,  FALSE},     { L"SYSTEM",   L"MACHINE\\", NULL, 0                , 0                         ,   NULL,   FALSE,  FALSE,  FALSE},     { L"DEFAULT",  L"USER\\.DEFAULT", NULL, 0           , CM_CMHIVE_FLAG_UNTRUSTED  ,   NULL,   FALSE,  FALSE,  FALSE},     { L"SAM",      L"MACHINE\\", NULL, HIVE_NOLAZYFLUSH , 0                         ,   NULL,   FALSE,  FALSE,  FALSE},     { NULL,        NULL,         0, 0                   , 0                         ,   NULL,   FALSE,  FALSE,  FALSE}     };

注册表应该就是从这里初始化的了。

再找引用:

    for (i = 0; i < CM_NUMBER_OF_MACHINE_HIVES; i++) {         ASSERT( CmpMachineHiveList[i].Name != NULL );         //           // just spawn the Threads to load the hives in parallel         //           Status = PsCreateSystemThread(             &Thread,             THREAD_ALL_ACCESS,             NULL,             0,               NULL,             CmpLoadHiveThread,             (PVOID)(ULONG_PTR)(ULONG)i             );           if (NT_SUCCESS(Status)) {             ZwClose(Thread);         } else {             //               // cannot spawn thread; Fatal error             //               CM_BUGCHECK(BAD_SYSTEM_CONFIG_INFO,BAD_HIVE_LIST,3,i,Status);         }        }   

这里为每个hive创建一个线程,进入CmpLoadHiveThread函数:

  

  // <sysroot>\config\hive     if (CmpMachineHiveList[i].CmHive == NULL) {         //         // Hive has not been initialized in any way.         //         CmpMachineHiveList[i].Allocate = TRUE;         Status = CmpInitHiveFromFile(&FileName,                                      CmpMachineHiveList[i].HHiveFlags,                                      &CmHive,                                      &(CmpMachineHiveList[i].Allocate),                                      CM_CHECK_REGISTRY_CHECK_CLEAN                                      );         if ( (!NT_SUCCESS(Status)) ||              (!CmpShareSystemHives && (CmHive->FileHandles[HFILE_TYPE_LOG] == NULL)) )         {             ErrorParameters = &FileName;             ExRaiseHardError(                 STATUS_CANNOT_LOAD_REGISTRY_FILE,                 1,                 1,                 (PULONG_PTR)&ErrorParameters,                 OptionOk,                 &ErrorResponse                 );         }  

CmpInitHiveFromFile会调用CmpOpenHiveFiles,后者会调用zwcreatefile打开相应的注册表文件。

如果要保护注册表,在创建线程前处理一下就好了。还只是猜想,哪天闲出毛病了再试试。