Windows屏幕解锁服务原理及实现(1)

这篇具有很好参考价值的文章主要介绍了Windows屏幕解锁服务原理及实现(1)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

https://github.com/zk2013/windows_remote_lock_unlock_screen

 

Windows屏幕解锁服务原理及实现(1)

将生成的DLL注册至注册表 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers ,之后的每次锁屏或开机登录都会加载这个DLL。

实现这个DLL有相关的微软文档:

ICredentialProvider 接口

ICredentialProviderCredential 接口

ICredentialProviderCredential2 接口

以上操作只实现了替换解锁Windows的登录界面功能,接下来是实现自动登录(自动解锁)。

 

实现自动解锁需要有通信机制发送接收Windows账号密码,接收端代码里使用的是 C++的 CreateNamedPipe (命名管道)。

在 ICredentialProviderCredential 接口的现实方法 GetSerialization 内创建了一个 pipe,管道名是 \\.\pipe\NoninteractiveUnlockCredentialProvider,( \\.\管道\管道名。最多可达256个字符的长度,而且不用区分大小写 )。

CPipeListener *pPipeListener = static_cast<CPipeListener *>(lpParameter);

LPTSTR lpszPipename = TEXT("\\\\.\\pipe\\NoninteractiveUnlockCredentialProvider");

hPipe = CreateNamedPipe(
            lpszPipename,
            PIPE_ACCESS_INBOUND,
            PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
            PIPE_UNLIMITED_INSTANCES,
            BUFSIZE, BUFSIZE,
            0,
            &sa);
fConnected = ConnectNamedPipe(hPipe, NULL);

fSuccess = FALSE;
cbUsername = 0;
cbPassword = 0;
fSuccess = ReadFile(hPipe, pPipeListener->_pwzUsername, ALLOCSIZE, &cbUsername, NULL);
fSuccess &= ReadFile(hPipe, pPipeListener->_pwzPassword, ALLOCSIZE, &cbPassword, NULL);

FlushFileBuffers(hPipe);
DisconnectNamedPipe(hPipe);
CloseHandle(hPipe);

if (fSuccess && cbUsername && cbUsername)
{
    pPipeListener->_fUnlocked = TRUE;
    pPipeListener->_pProvider->OnUnlockingStatusChanged();
    break;
}

 

现在实现发送端,使用 C++ 的 CreateFile (这是一个多功能的函数,可打开或创建文件或者I/O设备,并返回可访问的句柄:控制台,通信资源,目录(只读打开),磁盘驱动器,文件,邮槽,管道。)发送账号密码至管道 ( \\.\pipe\NoninteractiveUnlockCredentialProvider ) 。

HANDLE hPipe;
BOOL   fSuccess = FALSE;
DWORD  cbToWrite, cbWritten;

// Wait pipe
if (!WaitNamedPipe(lpszPipename, 5000))
{
    _tprintf(TEXT("Could not open pipe.\n"));
    return;
}

// Open pipe
hPipe = CreateFile(
    lpszPipename,   // pipe name 
    GENERIC_WRITE,  // write access
    0,              // no sharing 
    NULL,           // default security attributes
    OPEN_EXISTING,  // opens existing pipe 
    0,              // default attributes 
    NULL);          // no template file 
if (hPipe == INVALID_HANDLE_VALUE)
{
    _tprintf(TEXT("Could not open pipe. GLE=%d\n"), GetLastError());
    return;
}

// Send username
cbToWrite = (lstrlen(lpvUsername) + 1) * sizeof(TCHAR);
fSuccess = WriteFile(
    hPipe,                  // pipe handle 
    lpvUsername,            // message 
    cbToWrite,              // message length 
    &cbWritten,             // bytes written 
    NULL);                  // not overlapped 
if (!fSuccess)
{
    _tprintf(TEXT("WriteFile to pipe failed. GLE=%d\n"), GetLastError());
    CloseHandle(hPipe);
    return;
}

// Send password
cbToWrite = (lstrlen(lpvPassword) + 1) * sizeof(TCHAR);
fSuccess = WriteFile(
    hPipe,                  // pipe handle 
    lpvPassword,            // message 
    cbToWrite,              // message length 
    &cbWritten,             // bytes written 
    NULL);                  // not overlapped 
if (!fSuccess)
{
    _tprintf(TEXT("WriteFile to pipe failed. GLE=%d\n"), GetLastError());
    CloseHandle(hPipe);
    return;
}

CloseHandle(hPipe);

 

接收端收到账号密码后,在 GetSerialization 方法内 通过 KerbInteractiveUnlockLogonInit 和 KerbInteractiveUnlockLogonPack 校验登录。正确后触发Windows登录机制并解开屏幕锁。文章来源地址https://www.toymoban.com/news/detail-432297.html

HRESULT CSampleCredential::GetSerialization(
    CREDENTIAL_PROVIDER_GET_SERIALIZATION_RESPONSE* pcpgsr,
    CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION* pcpcs, 
    PWSTR* ppwszOptionalStatusText, 
    CREDENTIAL_PROVIDER_STATUS_ICON* pcpsiOptionalStatusIcon
    )
{
    UNREFERENCED_PARAMETER(ppwszOptionalStatusText);
    UNREFERENCED_PARAMETER(pcpsiOptionalStatusIcon);

    KERB_INTERACTIVE_LOGON kil;
    ZeroMemory(&kil, sizeof(kil));

    HRESULT hr;

    WCHAR wsz[MAX_COMPUTERNAME_LENGTH+1];
    DWORD cch = ARRAYSIZE(wsz);
    if (GetComputerNameW(wsz, &cch))
    {
        PWSTR pwzProtectedPassword;

        hr = ProtectIfNecessaryAndCopyPassword(_rgFieldStrings[SFI_PASSWORD], _cpus, &pwzProtectedPassword);

        if (SUCCEEDED(hr))
        {
            KERB_INTERACTIVE_UNLOCK_LOGON kiul;

            // Initialize kiul with weak references to our credential.
            hr = KerbInteractiveUnlockLogonInit(wsz, _pwzUsername, _pwzPassword, _cpus, &kiul);

            if (SUCCEEDED(hr))
            {
                // We use KERB_INTERACTIVE_UNLOCK_LOGON in both unlock and logon scenarios.  It contains a
                // KERB_INTERACTIVE_LOGON to hold the creds plus a LUID that is filled in for us by Winlogon
                // as necessary.
                hr = KerbInteractiveUnlockLogonPack(kiul, &pcpcs->rgbSerialization, &pcpcs->cbSerialization);

                if (SUCCEEDED(hr))
                {
                    ULONG ulAuthPackage;
                    hr = RetrieveNegotiateAuthPackage(&ulAuthPackage);
                    if (SUCCEEDED(hr))
                    {
                        pcpcs->ulAuthenticationPackage = ulAuthPackage;
                        pcpcs->clsidCredentialProvider = CLSID_CSampleProvider;
 
                        // At this point the credential has created the serialized credential used for logon
                        // By setting this to CPGSR_RETURN_CREDENTIAL_FINISHED we are letting logonUI know
                        // that we have all the information we need and it should attempt to submit the 
                        // serialized credential.
                        *pcpgsr = CPGSR_RETURN_CREDENTIAL_FINISHED;
                    }
                }
            }

            CoTaskMemFree(pwzProtectedPassword);
        }
    }
    else
    {
        DWORD dwErr = GetLastError();
        hr = HRESULT_FROM_WIN32(dwErr);
    }

    return hr;
}

到了这里,关于Windows屏幕解锁服务原理及实现(1)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • fatal: 无法访问 https://github.com/ :Failed to connect to github.com port 443: 拒绝连接的解决办法

    最近在ubuntu20.04安装PCL1.9.1的过程中,在从github 下载pcl时遇到了 fatal: 无法访问 https://github.com/PointCloudLibrary/pcl.git/ :Failed to connect to github.com port 443: 拒绝连接 这个问题。 解决办法:在终端输入 sudo gedit /etc/hosts ,打开/etc/hosts文件,然后注释掉所有只涉及到github.com的行(注意是

    2024年02月12日
    浏览(59)
  • 【解决问题 fatal: unable to access ‘https://github.com/.../.git‘: Could not resolve host: github.com】

    1.发现vulhub靶场不全,重新下载发现下这个问题,记录一下。 2.出现以下报错,如下图 fatal: unable to access ‘https://github.com/…/.git’: Could not resolve host: github.com 3.只需要在命令行中执行 git config --global --unset http.proxy git config --global --unset https.proxy 4.既可解决以上问题。

    2024年02月05日
    浏览(57)
  • clone报错fatal: unable to access ‘https://github.com/...‘: Failed to connect to github.com port

    原因是本机代理端口和git端口不一致。 第一步、找到本机代理端口号(红框部分) 第二步、修改git端口号 在git-bash执行如下两条指令 问题解决! [1][报错解决] Failed to connect to github.com port 443 after ***** ms: Couldn‘t connect to server [2]GitHub 新手详细教程

    2024年02月06日
    浏览(65)
  • 【已解决】fatal: Authentication failed for ‘https://github.com/.../‘

    在 Linux 服务器上使用 git push 命令,输入用户名和密码之后,总会显示一个报错: 起初我认为可能是密码输错了,但重新试过很多次后依然不行 到网上查阅,才知道原来是 github 的问题… 长话短说:大概就是 github 现在不让使用 用户名+密码 的方式进行验证 ,解决起来也不难

    2024年01月18日
    浏览(47)
  • lkx语言的总体设计已经发布到github上 (https://github.com/lichuan/lkx)

    Lkx is a new strongly typed scripting language, simpler and faster than lua. It can easily interact with c/c++ , the name Lkx comes from my daughter’s name ( Li Kaixin ), so this language is also a gift for my daughter. simple and clear variable typed hot reloading garbage collection user defined structure shared function shared variable faster than Lua c-

    2024年02月10日
    浏览(43)
  • Git clone报错:fatal: unable to access ‘https://github.com/.....‘: Failed to connect to github.com port

    使用Git克隆项目是,有时候会报错:Failed to connect to github.com port 443 after 21096 ms: Couldn’t connect to server 原因是本机代理端口和git端口不一致。 我的解决方法: 然后开启手动代理模式: 随便在哪个地方,右键选择Git Bash Here(得安装了Git),然后在弹出的命令行窗口中分别输入一

    2024年04月13日
    浏览(82)
  • fatal: unable to access ‘https://github.com/xxx/123.git/‘: Failed connect to github.com:443 解决方案

    在linux上git clone时遇到 fatal: unable to access \\\'https://github.com/xx/xx.git/\\\': Failed connect to github.com:443; Connection timed out时如图 解决方法:把https:改成git 如果没有成功,遇上以下报错 配置用户名,邮箱 给该邮箱设置公钥 回车三次后 得到如图  设置成功后进入~/.ssh,    复制公钥(ssh-r

    2024年02月05日
    浏览(73)
  • fatal: unable to access ‘https://github.com/.../.git‘: Could not resolve host: github.com解决方法【亲测有效】

    今天在使用Github的时候突然出现了这样的报错,云里雾里,看了网上的解决办法,说是代理服务器的问题,尝试了无数遍无果 然后Ping了一下github网站,发现Ping不通: 这里考虑应该是hosts文件解析的问题☘️ 在hosts文件中加入如下三行: 140.82.112.3 是github网站服务器的真实I

    2024年02月12日
    浏览(52)
  • 解决 fatal: Authentication failed for ‘https://github.com/*/*.git/‘

    原因:github 的认证策略发生了改变,在  2021年8月13日  的时候, 用户名加密码 的认证方式被去掉了,换成了 个人令牌(Personal Access Token) 的校验方式。 官网解决方案:管理个人访问令牌 - GitHub 文档  填写生成令牌的目的,然后选择令牌的有效期,最后勾选令牌的作用范

    2024年02月07日
    浏览(48)
  • 解决git fatal: Authentication failed for ‘https://github.com

    git clone 遇到的错误 remote: Support for password authentication was removed on August 13, 2021. remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication. fatal: Authentication failed for ‘https://github.com/Drif

    2024年02月03日
    浏览(50)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包