Userinit 自动弹窗与免登录分析

Userinit 自动弹窗与免登录分析 Userinit 自动弹窗与免登录分析概述本文档分析 ReactOS LiveCD 模式下如何实现不经过用户交互的自动登录以及userinit.exe如何在登录后自动弹出 LiveCD 对话框和安装程序reactos.exe的完整过程。1. 免登录的基础四个关键配置1.1 FreeLDR 传递 /MININT 参数文件[bootcd.ini#L35](file:///d:/reactos/boot/bootdata/bootcd.ini#L35)[LiveCD] BootTypeWindows2003 SystemPath\reactos Options/FASTDETECT /MININTFreeLDR 将/MININT传递给 NT 内核内核将其写入注册表HKLM\SYSTEM\CurrentControlSet\Control\SystemStartOptions。MININTMini NT标志着系统运行在 LiveCD/Minimal 模式。1.2 注册表启用自动管理登录文件[hivesft.inf#L1718](file:///d:/reactos/boot/bootdata/hivesft.inf#L1718)HKLM,...\Winlogon,AutoAdminLogon,0x00000000,1 ← 启用自动登录 HKLM,...\Winlogon,DefaultDomainName,0x00000000, ← 空域名 HKLM,...\Winlogon,DefaultUserName,0x00000000, ← 空用户名 HKLM,...\Winlogon,DefaultPassword,0x00000000, ← 空密码四个值配合使用AutoAdminLogon1且用户名密码均为空 → msgina 以空凭证自动登录创建 LocalSystem 令牌。1.3 设置 Userinit 为 Shell 后继文件[hivesft.inf#L1720](file:////d:/reactos/boot/bootdata/hivesft.inf#L1720)HKLM,...\Winlogon,Userinit,0x00020000,%SystemRoot%\system32\userinit.exe HKLM,...\Winlogon,Shell,0x00020000,%SystemRoot%\explorer.exeUserinit是 WINLOGON 在登录完成后启动的程序Shell是 Userinit 完成后启动的桌面程序。LiveCD 模式下 userinit 会截获控制流在启动 explorer.exe 之前先显示 LiveCD 对话框。1.4 LiveCD INF 设置安装模式文件[livecd.inf#L28](file:///d:/reactos/boot/bootdata/livecd.inf#L28)HKLM,SYSTEM\Setup,CmdLine,0x00020000,setup -mini2. WINLOGON 自动登录过程2.1 WINLOGON 初始化文件[winlogon.c#L431](file:///d:/reactos/base/system/winlogon/winlogon.c#L431)WinMain() ├─ StartServicesManager(services.exe) ← 服务管理器 ├─ StartLsass(lsass.exe) ← LSA ├─ GinaInit(msgina.dll) ← 加载 GINA ├─ InitializeSAS() ← SAS 窗口 ├─ GetSetupType() ← 检查安装模式LiveCD 下为 0 └─ PostMessage(SAS, WLX_SAS_TYPE_CTRL_ALT_DEL) ← 触发登录WINLOGON 发送WLX_SAS_TYPE_CTRL_ALT_DEL给自己进入 SAS 分发SASWindowProc → DispatchSAS() └─ STATE_INIT → GINA.WlxDisplaySASNotice()2.2 msgina 自动登录的三步跳过第一步WlxDisplaySASNotice — 跳过 SAS 提示文件[msgina.c#L910](file:///d:/reactos/dll/win32/msgina/msgina.c#L910)VOID WINAPIWlxDisplaySASNotice(PVOID pWlxContext){if(pgContext-bAutoAdminLogon){if(!Shift键被按下)← 可按住 Shift 跳过自动登录{// 不显示 按 CtrlAltDel 登录 的提示// 直接触发 SAS 事件 → 进入登录流程WlxSasNotify(CTRL_ALT_DEL);return;}}// 否则: 显示标准 SAS 提示窗口}第二步WlxLoggedOutSAS — 显示登录对话框并自动填充文件[gui.c#L1348](file:///d:/reactos/dll/win32/msgina/gui.c#L1348)LogonDialogProc(hwndDlg,WM_INITDIALOG){if(bAutoAdminLogon){SetDlgItemTextW(hwndDlg,IDC_LOGON_USERNAME,);← 空用户名SetDlgItemTextW(hwndDlg,IDC_LOGON_PASSWORD,);← 空密码// ★ 自动点击确定按钮PostMessage(GetDlgItem(hwndDlg,IDOK),BM_CLICK,0,0);}}登录对话框以不可见的方式弹出或在 Winlogon 桌面上弹出、填入空的用户名密码、自动点击确定完成登录。第三步WlxActivateUserShell — 启动 userinit.exe文件[msgina.c#L467](file:///d:/reactos/dll/win32/msgina/msgina.c#L467)BOOL WINAPIWlxActivateUserShell(PVOID pWlxContext,...){// 读取注册表: Userinit %SystemRoot%\system32\userinit.exeRegQueryValueExW(hKey,LUserinit,...);ExpandEnvironmentStringsW(pszUserInitApp,pszExpUserInitApp,...);// → C:\ReactOS\system32\userinit.exe// 创建 userinit.exe 进程WlxStartApplication(pWlxContext,...,pszExpUserInitApp);// → CreateProcessAsUser(UserToken, userinit.exe, ...)}3. Userinit 主流程3.1 wWinMain — 整体控制文件[userinit.c#L659](file:///d:/reactos/base/system/userinit/userinit.c#L659)intWINAPIwWinMain(HINSTANCE hInst,...){BOOL bIsLiveCDIsLiveCD();← 检测 MININT 启动选项 Restart:SetUserSettings();← 应用桌面颜色/壁纸if(bIsLiveCD){State.NextPageLOCALEPAGE;← 从语言选择页面开始 State.RunSHELL;← 默认进入桌面}if(State.NextPage!DONE){RunLiveCD(State);← ★ 显示 LiveCD 对话框}switch(State.Run){caseSHELL:← 运行桌面StartShell(pEnvironment);break;caseINSTALLER:← ★ 运行安装程序StartInstaller(Lreactos.exe);break;caseREBOOT:← 重启ExitWindowsEx(EWX_REBOOT,0);break;}if(bIsLiveCD!Success)gotoRestart;← 失败时回到菜单return0;}3.2 IsLiveCD — 检测 MININT文件[livecd.c#L105](file:///d:/reactos/base/system/userinit/livecd.c#L105)BOOLIsLiveCD(VOID){// 读取注册表:// HKLM\SYSTEM\CurrentControlSet\Control\SystemStartOptionsRegOpenKeyExW(HKEY_LOCAL_MACHINE,System\\CurrentControlSet\\Control,...);// 遍历所有启动选项查找 MININTwhile(每个选项){if(wcscmp(CurrentOption,LMININT)0)returnTRUE;← 检测到 LiveCD}returnFALSE;}4. RunLiveCD — LiveCD 对话框4.1 对话框流程文件[livecd.c#L892](file:///d:/reactos/base/system/userinit/livecd.c#L892)RunLiveCD(State) │ ├─ InitLogo() → 加载 ReactOS 标识位图 │ ├─ 解析 %SystemRoot%\unattend.inf ← 检查是否有无人值守配置 │ └─ while(pState-NextPage ! DONE) │ ├─ LOCALEPAGE: ← 语言选择对话框 │ └─ 选择语言和键盘布局 │ └─ 点击 下一步 → NextPage STARTPAGE │ └─ STARTPAGE: ← ★ 主对话框 ├─ 运行 LiveCD (IDC_RUN) → Run SHELL ├─ 安装 ReactOS (IDC_INSTALL) → Run INSTALLER └─ 取消 (IDCANCEL) → Run REBOOT4.2 StartDlgProc — 按钮处理文件[livecd.c#L757](file:///d:/reactos/base/system/userinit/livecd.c#L757)caseWM_INITDIALOG:// 检查是否能找到 reactos.exe 安装程序if(!ExpandInstallerPath(Lreactos.exe,...))EnableWindow(GetDlgItem(hwndDlg,IDC_INSTALL),FALSE);← 找不到则禁用安装按钮// 无人值守安装模式 → 自动点击运行if(pState-Unattend-bEnabled||!可找到安装程序)PostMessage(hwndDlg,WM_COMMAND,IDC_RUN,...);break;caseIDC_RUN:←运行 LiveCDpState-NextPageDONE;pState-RunSHELL;EndDialog(...);break;caseIDC_INSTALL:←安装 ReactOSpState-NextPageDONE;pState-RunINSTALLER;EndDialog(...);break;5. StartInstaller — 启动安装程序文件[userinit.c#L610](file:///d:/reactos/base/system/userinit/userinit.c#L610)5.1 定位 reactos.exeStartInstaller(reactos.exe) └─ ExpandInstallerPath(reactos.exe, ...) │ ├─ 策略 1: %SystemDrive%\I386\reactos.exe │ → 如 C:\I386\reactos.exe │ → 检查文件是否存在 │ └─ 策略 2: %SystemRoot%\reactos.exe → 如 C:\ReactOS\reactos.exe → 检查文件是否存在5.2 启动 reactos.exeStartInstaller(Lreactos.exe)└─ ExpandInstallerPath → 找到C:\I386\reactos.exe└─StartProcess(C:\I386\reactos.exe,NULL)└─CreateProcessW(NULL,C:\I386\reactos.exe,...)← GUI 第一阶段的安装程序开始运行reactos.exe源码位于d:\reactos\base\setup\reactos\reactos.c是一个使用属性表Property Sheet的多页面安装向导。6. 完整流程图┌─────────────────────────────────────────────────────────────────────┐ │ FreeLDR 读取 bootcd.ini │ │ Options/FASTDETECT /MININT │ │ │ │ │ ▼ │ │ NT 内核 → 写入 SystemStartOptions FASTDETECT MININT │ │ │ │ │ ▼ │ │ ┌──────────────────────────────────────────────────────────────┐ │ │ │ WINLOGON │ │ │ │ ├─ 启动 services.exe / lsass.exe │ │ │ │ ├─ 加载 msgina.dll (GINA) │ │ │ │ ├─ 读取注册表: │ │ │ │ │ AutoAdminLogon1 ← 自动登录已启用 │ │ │ │ │ DefaultUserName ← 空用户名 │ │ │ │ │ DefaultPassword ← 空密码 │ │ │ │ ├─ PostMessage(SAS, CTRL_ALT_DEL) → 进入登录流程 │ │ │ │ │ │ │ │ │ ├─ msgina.WlxDisplaySASNotice() │ │ │ │ │ └─ bAutoAdminLogonTRUE → 直接触发 SAS不显示提示窗口 │ │ │ │ │ │ │ │ │ ├─ msgina.WlxLoggedOutSAS() → LogonDialogProc() │ │ │ │ │ ├─ 填入用户名 │ │ │ │ │ ├─ 填入密码 │ │ │ │ │ └─ PostMessage(IDOK, BM_CLICK) ← 自动点击确定 │ │ │ │ │ └─ DoLoginTasks(, , ) → 获取 LocalSystem 令牌 │ │ │ │ │ │ │ │ │ ├─ WINLOGON.StartUserShell() → StartUserShell() │ │ │ │ │ └─ msgina.WlxActivateUserShell() │ │ │ │ │ └─ 读取 Userinit userinit.exe │ │ │ │ │ └─ CreateProcessAsUser(userinit.exe) │ │ │ │ │ │ │ │ │ └─ NtWaitForMultipleObjects(CSRSS, WINLOGON) │ │ │ │ ← WINLOGON 进入等待状态 │ │ │ └──────────────────────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌──────────────────────────────────────────────────────────────┐ │ │ │ userinit.exe │ │ │ │ ├─ IsLiveCD() → TRUE │ │ │ │ │ └─ 检测 SystemStartOptions 包含 MININT │ │ │ │ │ │ │ │ │ ├─ SetUserSettings() │ │ │ │ │ │ │ │ │ ├─ RunLiveCD() │ │ │ │ │ ├─ LOCALEPAGE: 语言选择对话框 │ │ │ │ │ │ └─ 用户选择语言/键盘 → 下一步 │ │ │ │ │ │ │ │ │ │ │ └─ STARTPAGE: 主页面 │ │ │ │ │ ├─ 检查 reactos.exe 是否存在 │ │ │ │ │ ├─ 运行 LiveCD → Run SHELL │ │ │ │ │ │ → StartShell() → explorer.exe │ │ │ │ │ │ → 桌面显示 Install ReactOS 快捷方式 │ │ │ │ │ │ └─ %SystemDrive%\I386\reactos.exe │ │ │ │ │ │ │ │ │ │ │ └─ 安装 ReactOS → Run INSTALLER ★ │ │ │ │ │ → StartInstaller(reactos.exe) │ │ │ │ │ └─ ExpandInstallerPath() → C:\I386\reactos │ │ │ │ │ └─ CreateProcess(C:\I386\reactos.exe) │ │ │ │ │ └─ GUI 安装向导显示 │ │ │ │ │ │ │ │ │ └─ 失败时 goto Restart → 回到 LiveCD 主菜单 │ │ │ └──────────────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────────┘7. 免登录的关键决策点步骤检查内容没有此配置会怎样FreeLDR 传递 /MININTbootcd.iniOptions 行系统进入正常安装模式或蓝屏WINLOGON PostMessage SASGetSetupType()为 0显示标准登录界面需要用户操作msginaWlxDisplaySASNoticeAutoAdminLogon 1显示 “按 CtrlAltDel 登录” 的提示msgina 登录对话框用户名密码为空显示用户名密码输入框需用户填写userinitIsLiveCD()SystemStartOptions含 MININT直接启动 Shellexplorer.exe无 LiveCD 菜单8. 各组件职责总结组件作用关键注册表/配置FreeLDR传递/MININT启动参数bootcd.iniOptions 行NT 内核将 MININT 写入SystemStartOptionsHKLM\...\Control\SystemStartOptionsWINLOGON管理登录状态机触发 SAS 流程内置逻辑msgina.dll读取自动登录配置自动填充并提交HKLM\...\Winlogon\AutoAdminLogonuserinit.exe检测 LiveCD 模式显示对话框HKLM\...\Winlogon\Userinitlivecd.cLiveCD 对话框 UI语言选择主页面由 userinit 加载reactos.exeGUI 安装程序由 userinit 通过StartInstaller启动