当运行到内核函数Phase1Initialization里,就是进行内核第一阶段初始化了,这时在这个函数又调用函数Phase1InitializationDiscard进行复杂的处理,在这里有一个重要的步骤,就是打开内核应用程序smss.exe来运行。具体代码如下:
#001 /* Update progress bar */
#002 InbvUpdateProgressBar(90);
#003
#004 /* Launch initial process */
#005 ProcessInfo = &InitBuffer->ProcessInfo;
#006 ExpLoadInitialProcess(InitBuffer, &ProcessParameters, &Environment);
#007
#008 DPRINT1("ExpLoadInitialProcess/n");
#009
#010 /* Update progress bar */
#011 InbvUpdateProgressBar(100);
上面代码就是通过调用函数ExpLoadInitialProcess来初始化一个内核应用程序运行,它的代码如下:
#001 VOID
#002 NTAPI
#003 ExpLoadInitialProcess(IN PINIT_BUFFER InitBuffer,
#004 OUT PRTL_USER_PROCESS_PARAMETERS *ProcessParameters,
#005 OUT PCHAR *ProcessEnvironment)
#006 {
#007 NTSTATUS Status;
#008 ULONG Size;
#009 PWSTR p;
#010 UNICODE_STRING NullString = RTL_CONSTANT_STRING(L"");
#011 UNICODE_STRING SmssName, Environment, SystemDriveString, DebugString;
#012 PVOID EnvironmentPtr = NULL;
#013 PRTL_USER_PROCESS_INFORMATION ProcessInformation;
#014 PRTL_USER_PROCESS_PARAMETERS ProcessParams = NULL;
#015
#016 NullString.Length = sizeof(WCHAR);
#017
获取处理器信息。
#018 /* Use the initial buffer, after the strings */
#019 ProcessInformation = &InitBuffer->ProcessInfo;
#020
给处理器参数分配内存。
#021 /* Allocate memory for the process parameters */
#022 Size = sizeof(*ProcessParams) + ((MAX_PATH * 6) * sizeof(WCHAR));
#023 Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
#024 (PVOID*)&ProcessParams,
#025 0,
#026 &Size,
#027 MEM_COMMIT,
#028 PAGE_READWRITE);
#029 if (!NT_SUCCESS(Status))
#030 {
显示出错信息。
#031 /* Failed, display error */
#032 p = InitBuffer->DebugBuffer;
#033 _snwprintf(p,
#034 256 * sizeof(WCHAR),
#035 L"INIT: Unable to allocate Process Parameters. 0x%lx",
#036 Status);
#037 RtlInitUnicodeString(&DebugString, p);
#038 ZwDisplayString(&DebugString);
#039
#040 /* Bugcheck the system */
#041 KeBugCheckEx(SESSION1_INITIALIZATION_FAILED, Status, 0, 0, 0);
#042 }
#043
设置处理器参数。
#044 /* Setup the basic header, and give the process the low 1MB to itself */
#045 ProcessParams->Length = Size;
#046 ProcessParams->MaximumLength = Size;
#047 ProcessParams->Flags = RTL_USER_PROCESS_PARAMETERS_NORMALIZED |
#048 RTL_USER_PROCESS_PARAMETERS_RESERVE_1MB;
#049
分配一页作环境内存使用。
#050 /* Allocate a page for the environment */
#051 Size = PAGE_SIZE;
#052 Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
#053 &EnvironmentPtr,
#054 0,
#055 &Size,
#056 MEM_COMMIT,
#057 PAGE_READWRITE);
#058 if (!NT_SUCCESS(Status))
#059 {
#060 /* Failed, display error */
#061 p = InitBuffer->DebugBuffer;
#062 _snwprintf(p,
#063 256 * sizeof(WCHAR),
#064 L"INIT: Unable to allocate Process Environment. 0x%lx",
#065 Status);
#066 RtlInitUnicodeString(&DebugString, p);
#067 ZwDisplayString(&DebugString);
#068
#069 /* Bugcheck the system */
#070 KeBugCheckEx(SESSION2_INITIALIZATION_FAILED, Status, 0, 0, 0);
#071 }
#072
#073 /* Write the pointer */
#074 ProcessParams->Environment = EnvironmentPtr;
#075
#076 /* Make a buffer for the DOS path */
#077 p = (PWSTR)(ProcessParams + 1);
#078 ProcessParams->CurrentDirectory.DosPath.Buffer = p;
#079 ProcessParams->CurrentDirectory.DosPath.MaximumLength = MAX_PATH *
#080 sizeof(WCHAR);
#081
#082 /* Copy the DOS path */
#083 RtlCopyUnicodeString(&ProcessParams->CurrentDirectory.DosPath,
#084 &NtSystemRoot);
#085
#086 /* Make a buffer for the DLL Path */
#087 p = (PWSTR)((PCHAR)ProcessParams->CurrentDirectory.DosPath.Buffer +
#088 ProcessParams->CurrentDirectory.DosPath.MaximumLength);
#089 ProcessParams->DllPath.Buffer = p;
#090 ProcessParams->DllPath.MaximumLength = MAX_PATH * sizeof(WCHAR);
#091
拷贝SYSTEM32的目录。
#092 /* Copy the DLL path and append the system32 directory */
#093 RtlCopyUnicodeString(&ProcessParams->DllPath,
#094 &ProcessParams->CurrentDirectory.DosPath);
#095 RtlAppendUnicodeToString(&ProcessParams->DllPath, L"//System32");
#096
#097 /* Make a buffer for the image name */
#098 p = (PWSTR)((PCHAR)ProcessParams->DllPath.Buffer +
#099 ProcessParams->DllPath.MaximumLength);
#100 ProcessParams->ImagePathName.Buffer = p;
#101 ProcessParams->ImagePathName.MaximumLength = MAX_PATH * sizeof(WCHAR);
#102
#103 /* Make sure the buffer is a valid string which within the given length */
#104 if ((NtInitialUserProcessBufferType != REG_SZ) ||
#105 ((NtInitialUserProcessBufferLength != -1U) &&
#106 ((NtInitialUserProcessBufferLength < sizeof(WCHAR)) ||
#107 (NtInitialUserProcessBufferLength >
#108 sizeof(NtInitialUserProcessBuffer) - sizeof(WCHAR)))))
#109 {
#110 /* Invalid initial process string, bugcheck */
#111 KeBugCheckEx(SESSION2_INITIALIZATION_FAILED,
#112 STATUS_INVALID_PARAMETER,
#113 NtInitialUserProcessBufferType,
#114 NtInitialUserProcessBufferLength,
#115 sizeof(NtInitialUserProcessBuffer));
#116 }
#117
#118 /* Cut out anything after a space */
#119 p = NtInitialUserProcessBuffer;
#120 while ((*p) && (*p != L' ')) p++;
#121
#122 /* Set the image path length */
#123 ProcessParams->ImagePathName.Length =
#124 (USHORT)((PCHAR)p - (PCHAR)NtInitialUserProcessBuffer);
#125
#126 /* Copy the actual buffer */
#127 RtlCopyMemory(ProcessParams->ImagePathName.Buffer,
#128 NtInitialUserProcessBuffer,
#129 ProcessParams->ImagePathName.Length);
#130
#131 /* Null-terminate it */
#132 ProcessParams->ImagePathName.Buffer[ProcessParams->ImagePathName.Length /
#133 sizeof(WCHAR)] = UNICODE_NULL;
#134
#135 /* Make a buffer for the command line */
#136 p = (PWSTR)((PCHAR)ProcessParams->ImagePathName.Buffer +
#137 ProcessParams->ImagePathName.MaximumLength);
#138 ProcessParams->CommandLine.Buffer = p;
#139 ProcessParams->CommandLine.MaximumLength = MAX_PATH * sizeof(WCHAR);
#140
#141 /* Add the image name to the command line */
#142 RtlAppendUnicodeToString(&ProcessParams->CommandLine,
#143 NtInitialUserProcessBuffer);
#144
#145 /* Create the environment string */
#146 RtlInitEmptyUnicodeString(&Environment,
#147 ProcessParams->Environment,
#148 (USHORT)Size);
#149
#150 /* Append the DLL path to it */
#151 RtlAppendUnicodeToString(&Environment, L"Path=" );
#152 RtlAppendUnicodeStringToString(&Environment, &ProcessParams->DllPath);
#153 RtlAppendUnicodeStringToString(&Environment, &NullString);
#154
#155 /* Create the system drive string */
#156 SystemDriveString = NtSystemRoot;
#157 SystemDriveString.Length = 2 * sizeof(WCHAR);
#158
#159 /* Append it to the environment */
#160 RtlAppendUnicodeToString(&Environment, L"SystemDrive=");
#161 RtlAppendUnicodeStringToString(&Environment, &SystemDriveString);
#162 RtlAppendUnicodeStringToString(&Environment, &NullString);
#163
#164 /* Append the system root to the environment */
#165 RtlAppendUnicodeToString(&Environment, L"SystemRoot=");
#166 RtlAppendUnicodeStringToString(&Environment, &NtSystemRoot);
#167 RtlAppendUnicodeStringToString(&Environment, &NullString);
#168
#169 /* Prepare the prefetcher */
#170 //CcPfBeginBootPhase(150);
#171
这里加载smss.exe程序,并创建一个进程运行。当是安装的时候,已经在制作光盘时,把usetup.exe文件改名为smss.exe文件,所以这里运行的就是usetup.exe程序。
#172 /* Create SMSS process */
#173 SmssName = ProcessParams->ImagePathName;
#174 Status = RtlCreateUserProcess(&SmssName,
#175 OBJ_CASE_INSENSITIVE,
#176 RtlDeNormalizeProcessParams(ProcessParams),
#177 NULL,
#178 NULL,
#179 NULL,
#180 FALSE,
#181 NULL,
#182 NULL,
#183 ProcessInformation);
#184 if (!NT_SUCCESS(Status))
#185 {
#186 /* Failed, display error */
#187 p = InitBuffer->DebugBuffer;
#188 _snwprintf(p,
#189 256 * sizeof(WCHAR),
#190 L"INIT: Unable to create Session Manager. 0x%lx",
#191 Status);
#192 RtlInitUnicodeString(&DebugString, p);
#193 ZwDisplayString(&DebugString);
#194
#195 /* Bugcheck the system */
#196 KeBugCheckEx(SESSION3_INITIALIZATION_FAILED, Status, 0, 0, 0);
#197 }
#198
#199 /* Resume the thread */
#200 Status = ZwResumeThread(ProcessInformation->ThreadHandle, NULL);
#201 if (!NT_SUCCESS(Status))
#202 {
#203 /* Failed, display error */
#204 p = InitBuffer->DebugBuffer;
#205 _snwprintf(p,
#206 256 * sizeof(WCHAR),
#207 L"INIT: Unable to resume Session Manager. 0x%lx",
#208 Status);
#209 RtlInitUnicodeString(&DebugString, p);
#210 ZwDisplayString(&DebugString);
#211
#212 /* Bugcheck the system */
#213 KeBugCheckEx(SESSION4_INITIALIZATION_FAILED, Status, 0, 0, 0);
#214 }
#215
#216 /* Return success */
#217 *ProcessParameters = ProcessParams;
#218 *ProcessEnvironment = EnvironmentPtr;
#219 }
通过上面的过程,就可以把usetup.exe安装程序运行起来了。结果就出现下面的界面: