Log on to user in lock screen with simulating key strokes using SendInput?

huangapple go评论76阅读模式
英文:

Log on to user in lock screen with simulating key strokes using SendInput?

问题

I want to use SendInput() function to login to my account like I would do in person; press enter, press the password keys, press enter again.

The purpose of this is I wrote a remote connection program that I can get screenshots to check if everything's doing ok. The program starts with task scheduler so when my pc reboots I can still send commands and get screenshots. But I want to add a login option remotely so if my pc reboots I can remotely send a signal to log in.

It works as intended on the desktop, but when I lock my user with Win+L, it doesn't do anything on the lock screen, neither on the desktop when I log on to check.

Here's the code:

void sendPassword(){

    //Map to store keys as char-WORD
    QMap<QString, WORD> keyMap;

    keyMap["Enter"] = 0x0D;
    
    keyMap["0"] = 0x30;    keyMap["1"] = 0x31;    keyMap["2"] = 0x32;    keyMap["3"] = 0x33;
    keyMap["4"] = 0x34;    keyMap["5"] = 0x35;    keyMap["6"] = 0x36;    keyMap["7"] = 0x37;
    keyMap["8"] = 0x38;    keyMap["9"] = 0x39;
    
    keyMap["A"] = 0x41;    keyMap["B"] = 0x42;    keyMap["C"] = 0x43;    keyMap["D"] = 0x44;
    keyMap["E"] = 0x45;    keyMap["F"] = 0x46;    keyMap["G"] = 0x47;    keyMap["H"] = 0x48;
    keyMap["I"] = 0x49;    keyMap["J"] = 0x4A;    keyMap["K"] = 0x4B;    keyMap["L"] = 0x4C;
    keyMap["M"] = 0x4D;    keyMap["N"] = 0x4E;    keyMap["O"] = 0x4F;    keyMap["P"] = 0x50;
    keyMap["Q"] = 0x51;    keyMap["R"] = 0x52;    keyMap["S"] = 0x53;    keyMap["T"] = 0x54;
    keyMap["U"] = 0x55;    keyMap["V"] = 0x56;    keyMap["W"] = 0x57;    keyMap["X"] = 0x58;
    keyMap["Y"] = 0x59;    keyMap["Z"] = 0x5A;

    //Get the password from a file.
    QFile passFile("password.txt");
    passFile.open(QIODevice::ReadOnly);
    QString password = QString::fromUtf8(passFile.readAll()).split("\r\n")[0].split("\n")[0];
    passFile.close();

    //Initialize an inputs array.
    INPUT* inputs = new INPUT[password.length()*2+4] {};

    //Add the Enter button to the inputs array, key down and up.
    inputs[0].type = INPUT_KEYBOARD;
    inputs[0].ki.wVk = keyMap["Enter"];

    inputs[1].type = INPUT_KEYBOARD;
    inputs[1].ki.wVk = keyMap["Enter"];
    inputs[1].ki.dwFlags = KEYEVENTF_KEYUP;

    for(int i=0; i<password.length(); i++){
        
        //Add the password to the inputs array character by character, key down and up.
        inputs[i*2+2].type = INPUT_KEYBOARD;
        inputs[i*2+2].ki.wVk = keyMap[(QString)password[i]];

        inputs[i*2+3].type = INPUT_KEYBOARD;
        inputs[i*2+3].ki.wVk = keyMap[(QString)password[i]];
        inputs[i*2+3].ki.dwFlags = KEYEVENTF_KEYUP;
    }

    //Add the Enter button to the inputs array, key down and up.
    inputs[password.length()*2+2].type = INPUT_KEYBOARD;
    inputs[password.length()*2+2].ki.wVk = keyMap["Enter"];

    inputs[password.length()*2+3].type = INPUT_KEYBOARD;
    inputs[password.length()*2+3].ki.wVk = keyMap["Enter"];
    inputs[password.length()*2+3].ki.dwFlags = KEYEVENTF_KEYUP;

    //SendInput, send the inputs array.
    SendInput(password.length()*2+4, inputs, sizeof(INPUT));

    //Delete the inputs array.
    delete[] inputs;
}

If this has no way to work, then how can I reach my purpose?

英文:

I want to use SendInput() function to login to my account like I would do in person;
press enter, press the password keys, press enter again.

The purpose of this is I wrote a remote connection program that I can get screenshots to check if everything's doing ok. The program starts with task scheduler so when my pc reboots I can still send commands and get screenshots. But I want to add a login option remotely so if my pc reboots I can remotely send signal to log in.

It works as intended in desktop but when I lock my user with win+L, It doesn't do anything in lock screen neither in desktop when I log on to check.

Here's the code

void sendPassword(){

    //Map to store keys as char-WORD
    QMap&lt;QString, WORD&gt; keyMap;

    keyMap[&quot;Enter&quot;] = 0x0D;
    
    keyMap[&quot;0&quot;] = 0x30;    keyMap[&quot;1&quot;] = 0x31;    keyMap[&quot;2&quot;] = 0x32;    keyMap[&quot;3&quot;] = 0x33;
    keyMap[&quot;4&quot;] = 0x34;    keyMap[&quot;5&quot;] = 0x35;    keyMap[&quot;6&quot;] = 0x36;    keyMap[&quot;7&quot;] = 0x37;
    keyMap[&quot;8&quot;] = 0x38;    keyMap[&quot;9&quot;] = 0x39;
    
    keyMap[&quot;A&quot;] = 0x41;    keyMap[&quot;B&quot;] = 0x42;    keyMap[&quot;C&quot;] = 0x43;    keyMap[&quot;D&quot;] = 0x44;
    keyMap[&quot;E&quot;] = 0x45;    keyMap[&quot;F&quot;] = 0x46;    keyMap[&quot;G&quot;] = 0x47;    keyMap[&quot;H&quot;] = 0x48;
    keyMap[&quot;I&quot;] = 0x49;    keyMap[&quot;J&quot;] = 0x4A;    keyMap[&quot;K&quot;] = 0x4B;    keyMap[&quot;L&quot;] = 0x4C;
    keyMap[&quot;M&quot;] = 0x4D;    keyMap[&quot;N&quot;] = 0x4E;    keyMap[&quot;O&quot;] = 0x4F;    keyMap[&quot;P&quot;] = 0x50;
    keyMap[&quot;Q&quot;] = 0x51;    keyMap[&quot;R&quot;] = 0x52;    keyMap[&quot;S&quot;] = 0x53;    keyMap[&quot;T&quot;] = 0x54;
    keyMap[&quot;U&quot;] = 0x55;    keyMap[&quot;V&quot;] = 0x56;    keyMap[&quot;W&quot;] = 0x57;    keyMap[&quot;X&quot;] = 0x58;
    keyMap[&quot;Y&quot;] = 0x59;    keyMap[&quot;Z&quot;] = 0x5A;

    //Get password from file.
    QFile passFile(&quot;password.txt&quot;);
    passFile.open(QIODevice::ReadOnly);
    QString password = QString::fromUtf8(passFile.readAll()).split(&quot;\r\n&quot;)[0].split(&quot;\n&quot;)[0];
    passFile.close();

    //Initialize inputs array.
    INPUT* inputs = new INPUT[password.length()*2+4] {};

    //Add enter button to inputs array, key down and up.
    inputs[0].type = INPUT_KEYBOARD;
    inputs[0].ki.wVk = keyMap[&quot;Enter&quot;];

    inputs[1].type = INPUT_KEYBOARD;
    inputs[1].ki.wVk = keyMap[&quot;Enter&quot;];
    inputs[1].ki.dwFlags = KEYEVENTF_KEYUP;


    for(int i=0; i&lt;password.length(); i++){
        
        //Add password to inputs array char by char, key down and up.
        inputs[i*2+2].type = INPUT_KEYBOARD;
        inputs[i*2+2].ki.wVk = keyMap[(QString)password[i]];

        inputs[i*2+3].type = INPUT_KEYBOARD;
        inputs[i*2+3].ki.wVk = keyMap[(QString)password[i]];
        inputs[i*2+3].ki.dwFlags = KEYEVENTF_KEYUP;
    }

    //Add enter button to inputs array, key down and up.
    inputs[password.length()*2+2].type = INPUT_KEYBOARD;
    inputs[password.length()*2+2].ki.wVk = keyMap[&quot;Enter&quot;];

    inputs[password.length()*2+3].type = INPUT_KEYBOARD;
    inputs[password.length()*2+3].ki.wVk = keyMap[&quot;Enter&quot;];
    inputs[password.length()*2+3].ki.dwFlags = KEYEVENTF_KEYUP;

    
    //SendInput, send inputs array.
    SendInput(password.length()*2+4, inputs, sizeof(INPUT));

    //Delete inputs array.
    delete[] inputs;
}

If this has no way to work, then how can I reach my purpose?

答案1

得分: 2

The problem is that when you lock the screen, Windows changes which session is displayed for security reasons. 用户模式服务和驱动程序在Session 0中运行,而首次登录的用户在Session 1中运行。实际上,sendInput()是将按键发送到您的桌面,而不是以不同会话运行的锁定屏幕:

https://techcommunity.microsoft.com/t5/ask-the-performance-team/application-compatibility-session-0-isolation/ba-p/372361#:~:text=The%20first%20user%20on%20the,used%20to%20target%20unsuspecting%20users.&amp;text=In%20Windows%20Vista%2C%20Session%200,user%20run%20in%20Session%201

https://learn.microsoft.com/en-us/previous-versions/bb756986(v=msdn.10)

您可以尝试通过创造性地使用CreateProcessAsUserA()并在lpStartupInfo参数中指定要使用的桌面(具体而言,设置STARTUPINFOAlpDesktop)来解决这个限制。这将涉及创建一个专门用于解锁屏幕的小子程序,然后让父进程使用CreateProcessAsUserA()运行子进程。

https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessasusera

https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/ns-processthreadsapi-startupinfoa

作为一个更简单(可能更安全)的替代方案,您是否尝试使用远程桌面?

英文:

The problem is that when you lock the screen, Windows changes which session is displayed for security reasons. The usermode services and drivers runs in Session 0, and the first user to login runs in Session 1. Essentially, sendInput() is sending the keystrokes to your desktop rather than the lock screen which is running in a different session:

https://techcommunity.microsoft.com/t5/ask-the-performance-team/application-compatibility-session-0-isolation/ba-p/372361#:~:text=The%20first%20user%20on%20the,used%20to%20target%20unsuspecting%20users.&amp;text=In%20Windows%20Vista%2C%20Session%200,user%20run%20in%20Session%201.

https://learn.microsoft.com/en-us/previous-versions/bb756986(v=msdn.10)

You may be able to work around this limitation with creative use of CreateProcessAsUserA() and specifying the desktop to use in the lpStartupInfo parameter (specifically, set the lpDesktop of the STARTUPINFOA). This will involve having a small child program whose sole purpose is to unlock the screen, and have your parent process run the child process with CreateProcessAsUserA().

https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessasusera

https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/ns-processthreadsapi-startupinfoa

As a simpler (and probably more secure) alternative, have you tried using Remote Desktop?

huangapple
  • 本文由 发表于 2023年4月10日 23:13:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/75978307.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定