调用LsaLookupAuthenticationPackage获取Kerberos认证包时触发段错误的原因及解决
问题:调用LsaLookupAuthenticationPackage触发段错误的原因及解决方法
问题描述
我想通过LsaLookupAuthenticationPackage()获取Kerberos认证包,根据Windows文档,该函数接收PHandle(命名为lsaHandle)、PLSA_STRING(命名为packageNamePointer)和PULONG(命名为authPackage)三个参数。我写的代码如下:
LSA_STRING packageName; LPSTR tempPkgName = const_cast<LPSTR>("ker-beros"); packageName.Length = static_cast<USHORT>(strlen(tempPkgName)); packageName.MaximumLength = packageName.Length+1; packageName.Buffer = tempPkgName; PLSA_STRING packageNamePointer = &packageName; PULONG authPackage; errorCode = LsaLookupAuthenticationPackage(lsaHandle, packageNamePointer, authPackage); if(errorCode != SCESTATUS_SUCCESS){ std::cout << LsaNtStatusToWinError(errorCode) << std::endl; return 1; }
调用该函数时总是触发段错误,gdb回溯信息如下:
#0 0x00007fff641f28f4 in SspiCli!LsaLookupAuthenticationPackage () from C:\Windows\SYSTEM32\sspicli.dll #1 0x00007ff774f514fe in main () at C:/Users/user/Documents/folder/folder/folder/temp.cpp:38
我尝试找sspicli.lib来获取更详细回溯但没找到,想问这段代码触发段错误的原因是什么,该怎么解决?
原因分析与解决方法
1. 核心触发原因:野指针authPackage
你声明了PULONG authPackage;但未给它分配内存或指向有效的变量。LsaLookupAuthenticationPackage需要将认证包ID写入这个指针指向的内存地址,而当前authPackage是一个未初始化的野指针,函数尝试向非法内存地址写入数据,直接导致段错误。
2. 额外问题:Kerberos包名拼写错误
你使用的包名是"ker-beros",正确的Kerberos认证包名应为"Kerberos"(无连字符,首字母大写),拼写错误会导致函数无法找到目标包,即便解决指针问题也会返回错误。
3. 潜在风险:不安全的const_cast操作
字符串字面量在C++中是const char*类型,你用const_cast<LPSTR>强制转换后,若后续代码或系统函数尝试修改该缓冲区(尽管LsaLookupAuthenticationPackage不会这么做),会触发未定义行为。
修正后的代码示例
LSA_STRING packageName; // 使用栈缓冲区存储包名,避免const_cast的不安全操作 char pkgName[] = "Kerberos"; packageName.Length = static_cast<USHORT>(strlen(pkgName)); packageName.MaximumLength = static_cast<USHORT>(sizeof(pkgName)); packageName.Buffer = pkgName; // 声明栈上的ULONG变量,直接传递地址给函数,确保有合法内存供写入 ULONG authPackageId; NTSTATUS errorCode = LsaLookupAuthenticationPackage(lsaHandle, &packageName, &authPackageId); if(errorCode != STATUS_SUCCESS){ std::cout << LsaNtStatusToWinError(errorCode) << std::endl; return 1; } // 此处可使用authPackageId获取到的Kerberos认证包ID
关键修正点
- 用栈上的
ULONG authPackageId替代野指针PULONG authPackage,直接传递&authPackageId给函数,提供合法的内存地址供函数写入结果。 - 修正Kerberos包名为正确的
"Kerberos"。 - 使用栈缓冲区存储包名,规避对字符串字面量的不安全强制转换。
内容的提问来源于stack exchange,提问作者ConnoK0lan
相关产品推荐
相关产品推荐

