函数原型
CREDUIAPI DWORD CredUIPromptForCredentialsA( [in, optional] PCREDUI_INFOA pUiInfo, [in] PCSTR pszTargetName, [in] PCtxtHandle pContext, [in, optional] DWORD dwAuthError, [in, out] PSTR pszUserName, [in] ULONG ulUserNameBufferSize, [in, out] PSTR pszPassword, [in] ULONG ulPasswordBufferSize, [in, out] BOOL *save, [in] DWORD dwFlags );
BOOL LogonUserW( [in] LPCWSTR lpszUsername, [in, optional] LPCWSTR lpszDomain, [in, optional] LPCWSTR lpszPassword, [in] DWORD dwLogonType, [in] DWORD dwLogonProvider, [out] PHANDLE phToken );
CREDUIAPI DWORD CredUIParseUserNameA( [in] PCSTR userName, [out] CHAR *user, [in] ULONG userBufferSize, [out] CHAR *domain, [in] ULONG domainBufferSize );
CredUIParseUserName 函数从完全限定的用户名中提取域和用户帐户名。
CredUIPromptForCredentials 函数创建并显示一个可接受用户凭据信息的可配置对话框。
思路:先用第一个函数向用户询问,随后用第二个函数验证。
头文件导入:
#include<wincred.h> #include<ntsecapi.h>
静态库链接:
#pragma comment(lib,"Secur32.lib") #pragma comment(lib,"Credui.lib")
定义变量:
PCREDUI_INFOW info = new CREDUI_INFOW(); info->cbSize = sizeof(CREDUI_INFO); info->hbmBanner = NULL; info->hwndParent = NULL; info->pszCaptionText = L"UAC-Review"; info->pszMessageText = L"To test"; BOOL saved = false; LPWSTR username = (WCHAR*)malloc(100), password = (WCHAR*)malloc(100), appName = const_cast<WCHAR*>(L"TestCerd.exe"); memset(username, 0, 100); memset(password, 0, 100);//动态分配内存
调用函数:
if (CredUIPromptForCredentialsW(info/*凭据窗口UI信息*/, appName, NULL/*系统保留*/, 0, username/*执行后返回包含域名的用户名*/, 100, password/*执行后返回密码*/, 100, &saved, CREDUI_FLAGS_COMPLETE_USERNAME | CREDUI_FLAGS_EXPECT_CONFIRMATION | CREDUI_FLAGS_REQUEST_ADMINISTRATOR/*仅默认枚举管理员用户*/ | CREDUI_FLAGS_USERNAME_TARGET_CREDENTIALS /*带有这个标志后TargetName可以使用程序名*/| CREDUI_FLAGS_VALIDATE_USERNAME | CREDUI_FLAGS_DO_NOT_PERSIST/*不自动保存凭据*/| CREDUI_FLAGS_INCORRECT_PASSWORD| CREDUI_FLAGS_PASSWORD_ONLY_OK) == NO_ERROR) {
LPWSTR user = (WCHAR*)malloc(100),domain = (WCHAR*)malloc(100);//再次动态分配
memset(user, 0, 100);
memset(domain, 0, 100);
CredUIParseUserNameW(username, user, 100, domain, 100);//解析用户名 "Domain\UserName" -> "Domain","UserName"
HANDLE tempToken = NULL;
if(LogonUser(user, domain, password, LOGON32_LOGON_BATCH, LOGON32_PROVIDER_DEFAULT, &tempToken))//用提供的凭据尝试登录
MessageBox(NULL, L"Successful Really", L"Tips", MB_OK);
else
MessageBox(NULL, L"Login Failed", L"Tips", MB_OK);
CloseHandle(tempToken);//释放局部资源
free(user);
free(domain);
}释放剩余资源:
clean: SecureZeroMemory(password, sizeof(password)); free(username); free(password);
