none
SendInput fail beause Interface Privilege Isolation (UIPI) and integrity

    Question

  • I am try to simulate mouse event on Win7, and my application using an open source project "Windows Input Simulator" on website http://inputsimulator.codeplex.com/ which internally use codes below to simulate mouse event:

    [DllImport("user32.dll", SetLastError = true)]

    public static extern UInt32 SendInput(UInt32 numberOfInputs, INPUT[] inputs, Int32 sizeOfInputStructure);


    My application runs perfectly when I debug it with Visual Studio 2010. The left button click event, right button click event and mouse move event are ok. But the click events not send when I start my application from Explorer by double click the .exe application excutable file. Only the mouse move event is OK, if I try to simulate left button click or right click, my application will receive an exception and exit.
    I have found the exception is throw by codes below:
    public void DispatchInput(INPUT[] inputs)
    {
        if (inputs == null) throw new ArgumentNullException("inputs");
        if (inputs.Length == 0) throw new ArgumentException("The input array was empty", "inputs");
        var successful = NativeMethods.SendInput((UInt32)inputs.Length, inputs, Marshal.SizeOf(typeof (INPUT)));
        if (successful != inputs.Length)
                throw new Exception("Some simulated input commands were not sent successfully. The most common reason for this happening are the security features of Windows including User Interface Privacy Isolation (UIPI). Your application can only send commands to applications of the same or lower elevation. Similarly certain commands are restricted to Accessibility/UIAutomation applications. Refer to the project home page and the code samples for more information.");
    }

    That says UIPI blocked the SendInput(...). So I Google this topic, and get some advises.

    1) Add uiAccess="true" to my application's manifest
    <requestedExecutionLevel level="requireAdministrator" uiAccess="true" />

    2) Create a test certificate and add this certificate to local machine Trusted Root Certification Authorities certificate store and the Trusted Publishers certificate store.
    MakeCert -r -pe -ss PrivateCertStore -n "CN=Test Certificate - For Internal Use Only" testcert.cer
    CertMgr.exe /add testcert.cer /s /r localMachine root
    CertMgr.exe /add testcert.cer /s /r localMachine trustedpublisher

    3) Sign my application with previous digital signature
        
    SignTool sign /v /s PrivateCertStore /n "Test Certificate - For Internal Use Only" /t http://timestamp.verisign.com/scripts/timestamp.dll MyApplication.exe
    4) Install my application to "C:\Program Files" folder which is one of the secure locations on my computer.

    I think I have done all things to satisfy UIPI requirements, but the problem still not solve after I start my application and agree the UAC prompt. Only mouse move event is ok.

    PS: if I don't sign my application with test certificate and only add "requestedExecutionLevel" with uiAccess="true" in manifest, application will not start and Windows show a dialog with message "A referral was returned from the server.". If I signed my application with test certificate, UAC will work when I start my application. The application will work until I call SendInput to simulate click event and then exception threw.

    I have read the requirements about "Interface Privilege Isolation (UIPI) and integrity" at http://msdn.microsoft.com/en-us/library/bb625963.aspx, but after doing all this, still not work.

    Any one can help me about this?
    Monday, July 15, 2013 12:47 AM

All replies

  • I found something in blog, but I can past the link or I can not submit.

    By specifying UIAccess=”true” in the requestedPrivileges attribute [of the application manifest], the application is stating a requirement to bypass UIPI restrictions on sending window messages across privilege levels. Windows Vista implements the following policy checks before starting an application with UIAccess privilege.
    The application must have a digital signature that can be verified using a digital certificate that chains up to a trusted root in the local machine Trusted Root
    Certification Authorities certificate store.
    The application must be installed in a local folder application directory that is writeable only by administrators, such as the Program Files directory.

    Unfortunately this is not going to work if you application can be installed by non-admin users.

    what the sentence "Unfortunately this is not going to work if you application can be installed by non-admin users." really mean?

    Tuesday, July 16, 2013 3:14 PM
  • Grey on black is really hard to read. Ironic in an accessibility forum!

    This doesn't sound like a UIPI problem. The steps you mention to flag as UIAccess sound correct and you're not getting the typical errors for improper signing, etc. I believe you can examine this with Process Explorer as well.

    The exception you are raising after SendInput is just guessing that this is UIPI without checking errors correctly. Does SendInput succeed or fail? If it fails, what does GetLastError return?

    SendInput does not indicate that a failure is due to UIPI.

    --Rob

    Wednesday, July 17, 2013 2:29 PM
  • Hi Rob,

    Really thanks for your reply.

    I have examined with Process Explorer. If I add level="requireAdministrator" and uiAccess="true" in the manifest file, my application's Intergraty Level will be High.

    <requestedExecutionLevel level="requireAdministrator" uiAccess="true" />

    And, when I set uiAccess="false", my application will run ok, click event is ok, but if I set uiAccess="true", click event simulate will not work.

    In my application, When I call SendInput to simulate click event, I compare the return value with the inputsLength, if they not equal, then I throw a exception.

    var successful = NativeMethods.SendInput((UInt32)inputs.Length, inputs, Marshal.SizeOf(typeof (INPUT)));
    if (successful != inputs.Length) { throw new exception(""); }

    I have read the API document about SendInput on MSDN,  it says:

    The function returns the number of events that it successfully inserted into the keyboard or mouse input stream. If the function returns zero, the input was already blocked by another thread. To get extended error information, call GetLastError.

    This function fails when it is blocked by UIPI. Note that neither GetLastError nor the return value will indicate the failure was caused by UIPI blocking.

    I get the last error when exception occur, the value is 5(ERROR_ACCESS_DENIED), and the return value of SendInput is 0, but the parameter inputs.Length is not zero, so exception will be fire.

    If I change the uiAccess to false, all will be OK. So I think it is a trouble caused by the UIPI.


    Thursday, July 18, 2013 10:22 AM
  • I get the last error when exception occur, the value is 5(ERROR_ACCESS_DENIED)

    Seems you need sign app.exe after changes of manifest file, otherwise hash-sum of app.exe different

    Wednesday, January 15, 2014 1:27 PM
  • You need to sign your application with a first-class certificate (like Verisign) or with your personal certificate, added to the Trusted Root Certification Authorities.

    The second condition is to run your application from a secure location like %SystemRoot%\system32 or %ProgramFiles% unless you change the local or domain policy to allow you run uiAccess apps from any location.

    Security Considerations for Assistive Technologies

    A step-by-step is, for exmaple, here: UAC Automation (Success!)

    Sunday, January 19, 2014 7:58 AM