3

I created an application that sends keyboard input to cmd.exe. This works when running cmd as a normal user but fails when cmd is run as Administrator.

This is my code:

Var
   Wnd:hwnd;
begin
   wnd:=FindWindow('ConsoleWindowClass',0);
   if wnd <> 0 then
    begin
      setforegroundWindow(wnd);
      keybd_event(Ord('A'),0,0,0);
    end;
end;

Notice that ConsoleWindowClass is the class name of cmd.

How can I send input to cmd when cmd is running as administrator?

Cœur
  • 37,241
  • 25
  • 195
  • 267
M.MARAMI
  • 95
  • 9
  • 1
    Most likely you cannot access the window because the program you are running from does not have privileges to do so. It is after all being run as administrator and you cannot access processes that are not within your set of privileges. – Paul Michael Dec 16 '16 at 14:25
  • 2
    Comment from deleted answer: *You can include UIAccess=true in the requested permissions of the application's manifest - with caveats. This allows circumvention of UIPI for non-elevated applications but the application in question must be authenticode signed and needs to be executed from a protected directory (like %programfiles%, etc). Satisfying this, however, the application can be installed with an elevated installer but thereafter can run with user permissions while retaining permission to send input to elevated applications.* – David Heffernan Dec 16 '16 at 16:16
  • Thank you. Your right but we can send input by On-Screen Keyboard after run cmd as admin? – M.MARAMI Dec 16 '16 at 16:21
  • See also : https://en.wikipedia.org/wiki/User_Interface_Privilege_Isolation – J... Dec 16 '16 at 16:41
  • https://msdn.microsoft.com/en-us/library/windows/desktop/ee671610(v=vs.85).aspx#uiaccess_requirements_for_assistive_technology_applications_ – J... Dec 16 '16 at 16:42
  • https://msdn.microsoft.com/en-us/library/bb756929.aspx – J... Dec 16 '16 at 16:47
  • 1
    @DavidHeffernan I don't think you should have deleted your answer - it is generally almost exclusively the case that it is true. The uiAccess token is something of an esoteric workaround which is rather impractical to implement correctly in a lot of circumstances. – J... Dec 16 '16 at 16:52
  • 1
    @m.m osk.exe is signed. – Sertac Akyuz Dec 16 '16 at 17:56
  • @Remy - This case fits with the first condition of setting the foreground window *"The process is the foreground process."*. Indeed the poster reports that the code succeeds when console is not elevated. And, with my test, I can confirm the console window comes to the foreground when it's elevated or not. Also, the documentation of SendInput states *"This function is subject to UIPI."*. – Sertac Akyuz Dec 17 '16 at 00:16
  • @SertacAkyuz on modern Windows versions, `keybd_event()` is simply a wrapper for `SendInput()` (actually `NtUserSendInput()`, which `SendInput()` is an alias for), so it makes sense that `keybd_event()` can't simulate input on a window of a higher integrity process since `SendInput()` is subject to UIPI. – Remy Lebeau Dec 17 '16 at 00:55

2 Answers2

3

How can I type with this code inside cmd when cmd is runing as administrator?

You cannot. This behaviour is by design. The cmd process runs with a higher integrity level than your process. Your only way to overcome this is to arrange that the process that fakes input also runs as administrator.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • You can also include `UIAccess=true` in the requested permissions of the application's manifest - with caveats. This allows circumvention of [UIPI](https://en.wikipedia.org/wiki/User_Interface_Privilege_Isolation) for non-elevated applications but the application in question must be authenticode signed and needs to be executed from a protected directory (like `%programfiles%`, etc). Satisfying this, however, the application can be installed with an elevated installer but thereafter can run with user permissions while retaining permission to send input to elevated applications. – J... Dec 16 '16 at 15:17
  • @J... Yes, but the application is cmd which is out of our control – David Heffernan Dec 16 '16 at 15:18
  • `cmd` is the *target* of the input - the steps above are requirements for the *sending* application, which is under our control, to gain permission, without needing full elevation, to send input to elevated programs. – J... Dec 16 '16 at 15:20
  • OK. Which I guess is how explorer manages it. Anyway, you might write an answer stating that. I can then delete this one. – David Heffernan Dec 16 '16 at 15:27
  • Thank you David Heffernan. yes cmd is the target of the input but now how can i do that? – M.MARAMI Dec 16 '16 at 16:02
  • `keybd_event()` (which is deprecated, use `SendInput()` instead) is not subject to UIPI blockage, since the input simply goes into the same input queue as the actual keyboard driver. The keystrokes will go through the same processing as if the user had typed them manually, and eventually end up in the foreground window. Whether that window is running as an admin or not is not a factor in this situation. That would only apply if the sending app were sending keyboard messages *directly* to the target window using `SendMessage()` or `PostMessage()`, which is not the case. – Remy Lebeau Dec 16 '16 at 22:46
0

Finally found that if we run the base application as admin and then try to send an input to cmd it works fine.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
M.MARAMI
  • 95
  • 9
  • 4
    Strange that you've found it now. The deleted answer, which you have commented on, said the same thing more than a day ago. – Sertac Akyuz Dec 18 '16 at 02:32