Winapi 如何使用CredUIPromptForWindowsCredentials驱动我的凭据提供程序

Winapi 如何使用CredUIPromptForWindowsCredentials驱动我的凭据提供程序,winapi,credential-providers,Winapi,Credential Providers,我一直在使用一个凭据提供程序,并通过日志对其进行调试。最近学习了CredUIPromptForWindowsCredentials()API,以便能够从登录屏幕或远程桌面连接以外的位置调用它。此时,我似乎可以让凭证显示的唯一方法是将最后一个参数设置为CREDUIWIN_SECURE_提示符。我尝试过各种各样的国旗图案,但都不走运。我的CP有效,这不是问题所在。这个问题更容易调试。只有一次,当我的笔记本电脑无法转动时,我不得不进入救援模式使用CREDUIWIN_SECURE_提示符标志的问题是,我

我一直在使用一个凭据提供程序,并通过日志对其进行调试。最近学习了
CredUIPromptForWindowsCredentials()
API,以便能够从登录屏幕或远程桌面连接以外的位置调用它。此时,我似乎可以让凭证显示的唯一方法是将最后一个参数设置为CREDUIWIN_SECURE_提示符。我尝试过各种各样的国旗图案,但都不走运。我的CP有效,这不是问题所在。这个问题更容易调试。只有一次,当我的笔记本电脑无法转动时,我不得不进入救援模式使用CREDUIWIN_SECURE_提示符标志的问题是,我无法访问调试器,因为登录占据了屏幕,我无法返回调试器。我想唯一的解决办法是使用这个API在另一台机器上进行远程调试,但我不想为此烦恼

我的CP在HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\{55157584-ff0f-48ce-9178-a4e290901663}注册,默认属性为“MyCredProvider”(本例中)。(GUID,道具名称已更改以保护罪犯。同时忽略在副本上发生不好事情的地方的LsaString,我不这么做。)

有没有办法不使用安全提示获取我的自定义CP

#include <windows.h>
#include <iostream>
#include <EvoApi.h>
#include <decrypt.h>
#include <atlbase.h>
#include <Lmwksta.h>
#include <StrSafe.h>
#include <LMAPIbuf.h>
#include <LMJoin.h>
#include <wincred.h>
#include <NTSecAPI.h>

#pragma warning(disable : 4996)
#pragma comment(lib, "netapi32.lib")
#pragma comment(lib, "credui.lib")
#pragma comment(lib, "secur32")

using namespace std;


template <size_t SIZE = 256>
struct LsaString : public LSA_STRING
{

    LsaString()
    {
        MaximumLength = SIZE;
        Length = 0;
        Buffer = pBuf.get();
    }

    LsaString(LPCSTR pWhat)
    {
        MaximumLength = SIZE;
        Length = 0;
        Buffer = pBuf.get();
        Init(pWhat);
    }
    void Init(LPCSTR pWhat)
    {
        size_t len = strlen(pWhat);
        if (len >= SIZE)
            throw;
        strcpy(Buffer, pWhat);
        Length = (USHORT) len;
    }
    unique_ptr<char[]> pBuf = make_unique< char[] >(SIZE);
};

int _tmain(int argc, wchar_t* argv[])
{
#if 1
    wstring me(_T("MYLOGING"));
    wstring url(_T("Header"));
    wstring message(_T("Enter credentials for ..."));

    CREDUI_INFOW credInfo;
    credInfo.pszCaptionText = url.c_str();
    credInfo.hbmBanner = nullptr;
    credInfo.hwndParent = NULL;
    credInfo.pszMessageText = message.c_str();
    credInfo.cbSize = sizeof(CREDUI_INFOW);

    ULONG authPackage = 0;

    LSAHANDLE lsaHandle;
    LsaConnectUntrusted(&lsaHandle);

    LsaString<> lsaString("MyCredProvider");
    //LsaString<> lsaString(MICROSOFT_KERBEROS_NAME_A); // works ... as far as finding in LsaLookupAuth...
    //LsaString<> lsaString(NEGOSSP_NAME_A); // works ... as far as finding in LsaLookupAuth...


    ULONG ulPackage = 0;
    LsaLookupAuthenticationPackage(lsaHandle, &lsaString, &ulPackage);

    void* pBlob;
    ULONG blobSize = 0;

    DWORD dwFlags = CREDUIWIN_GENERIC; //CREDUIWIN_SECURE_PROMPT

    CredUIPromptForWindowsCredentials(&credInfo, 0, &ulPackage, NULL, 0, &pBlob, &blobSize, FALSE, dwFlags);
    if (pBlob) CoTaskMemFree(pBlob);

    return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#杂注警告(禁用:4996)
#pragma注释(lib,“netapi32.lib”)
#pragma注释(lib,“credui.lib”)
#pragma注释(lib,“secur32”)
使用名称空间std;
模板
结构LsaString:公共LSA_字符串
{
LsaString()
{
最大长度=尺寸;
长度=0;
Buffer=pBuf.get();
}
LsaString(LPCSTR pWhat)
{
最大长度=尺寸;
长度=0;
Buffer=pBuf.get();
初始(pWhat);
}
无效初始(LPCSTR pWhat)
{
尺寸长度=标准长度(pWhat);
如果(长度>=尺寸)
投掷;
strcpy(缓冲区,pWhat);
长度=(USHORT)len;
}
unique_ptr pBuf=使_唯一(大小);
};
int_tmain(int argc,wchar_t*argv[])
{
#如果1
给我打电话(_T(“MYLOGING”);
wstring url(标题);
wstring消息(_T(“为…输入凭据”);
CREDUI_INFOW credInfo;
credInfo.pszcapontext=url.c_str();
credInfo.hbmBanner=nullptr;
credInfo.hwndpresent=NULL;
credInfo.pszMessageText=message.c_str();
credInfo.cbSize=sizeof(CREDUI_INFOW);
ULONG authPackage=0;
伊萨汉德尔伊萨汉德尔;
lsa连接不受信任(&lsaHandle);
LsaString LsaString(“MyCredProvider”);
//LsaString LsaString(MICROSOFT_KERBEROS_NAME_A);//就在LsaLookupAuth中查找而言,它是有效的。。。
//LsaString LsaString(NEGOSSP_NAME_A);//就在LsaLookupAuth中查找而言,它是有效的。。。
ULONG-ulPackage=0;
LsaLookupAuthenticationPackage(lsaHandle、lsaString和ulPackage);
void*pBlob;
ULONG blobSize=0;
DWORD dwFlags=CREDUIWIN\u GENERIC;//CREDUIWIN\u SECURE\u提示符
CredUIPromptForWindowsCredentials(&credInfo,0,&ulPackage,NULL,0,&pBlob,&blobSize,FALSE,dwFlags);
if(pBlob)CoTaskMemFree(pBlob);
返回0;
}

不久前,我编写了一个简单的hook和trace实用程序,使用setWindowshookxa通过WH\u KEYBOARD\u LL事件查看键盘输入。也许,CredUIPromptForWindowsCredentials()也可以通过同样的方式进行跟踪。我可以发布我的经验(不过这是另一个问题的主题),而不需要远程调试器。这也很容易做到。只需在WinlogonDesktop上首先运行调试器。以及您的提供商如何使用CPU_CREDUI处理SetUsageScenario?@bimjhi-首先,WH_键盘只在一台安装了的桌面上工作。当然不是。第二,这有什么帮助。即使您在winlogon桌面上设置了self-hook?lsaString(“MyCredProvider”);+LsaLookupAuthenticationPackage-在您的案例中没有任何意义,也请看一看这一点及其周围。