自定义身份验证包:CreateLogonSession成功后Winlogon.exe崩溃
自定义身份验证包Winlogon崩溃问题排查与解决
结合你描述的LsaApLogonUserEx执行后Winlogon崩溃的场景,常见原因及对应解决办法如下:
核心问题排查方向
1. 跨堆内存操作错误
Winlogon进程与你的身份验证包使用不同的堆空间,绝对不能用malloc/new分配要返回给LSA的缓冲区,必须使用LSA提供的LsaAllocateMemory函数分配内存。如果用了本地堆分配的内存,Winlogon后续尝试释放时会直接触发堆崩溃。
错误示例:
LOGON_USER_INFO_2* logonInfo = (LOGON_USER_INFO_2*)malloc(sizeof(LOGON_USER_INFO_2));正确做法:
LOGON_USER_INFO_2* logonInfo = NULL; NTSTATUS status = LsaAllocateMemory(sizeof(LOGON_USER_INFO_2), (PVOID*)&logonInfo); if (!NT_SUCCESS(status)) { return status; }
2. 结构体初始化不规范
LSA对输入输出结构体的格式要求极为严格,常见错误点:
UNICODE_STRING成员未正确设置:Length是字符串的字节数(不含终止\0),MaximumLength是缓冲区总字节数(含终止\0),Buffer必须指向有效的Unicode字符串内存。- 结构体版本或大小不匹配:比如返回
LOGON_USER_INFO_2时,LogonInformationLength必须准确设置为sizeof(LOGON_USER_INFO_2),不能用sizeof(PVOID)或其他错误值。 - 未初始化的结构体成员:比如
LogonUserInfo中的UserSessionKey、LogonDomainName等成员必须明确初始化,不能留空或随机值。
3. 令牌句柄管理错误
CreateLogonSession成功后,需确保:
- 返回的令牌句柄未被提前关闭:Winlogon后续需要使用该令牌,若你的代码在函数返回前关闭了句柄,会导致Winlogon访问无效句柄崩溃。
- 令牌权限足够:创建令牌时需包含
TOKEN_QUERY、TOKEN_DUPLICATE、TOKEN_ASSIGN_PRIMARY等Winlogon必需的权限,否则后续令牌操作会触发访问违规。
4. 未捕获的结构化异常
LsaApLogonUserEx运行在Winlogon的进程空间中,函数内部未处理的结构化异常(比如空指针访问、数组越界)会直接导致Winlogon崩溃。必须用__try/__except包裹核心逻辑,捕获异常并返回合法的NTSTATUS错误码:
__try { // 核心登录逻辑 } __except(EXCEPTION_EXECUTE_HANDLER) { // 清理资源 return STATUS_UNSUCCESSFUL; }
额外排查建议
- 结合堆栈截图定位崩溃点:如果崩溃在
ntdll!RtlFreeHeap,优先排查内存分配/释放的堆不匹配问题;如果崩溃在某个结构体成员访问,检查对应结构体的初始化是否正确。 - 启用LSA调试日志:通过修改注册表
HKLM\SYSTEM\CurrentControlSet\Control\Lsa\LsaDebugLevel为0x00000003,获取更详细的LSA交互日志,辅助定位错误。
内容的提问来源于stack exchange,提问作者HNR
相关产品推荐
相关产品推荐

