Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Enable interaction with administrative programs


  • Please log in to reply
64 replies to this topic
Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006
EnableUIAccess

Modifies AutoHotkey.exe to allow scripts to do the following even while UAC is enabled:
  • Interact with windows of administrative programs without running the script as administrator.
  • Use SendPlay.
  • There are limitations; please read the post before using this script.
Important Information:

This script modifies the executable file's embedded manifest, then creates and installs a self-signed certificate and uses it to sign the file. It will prompt you for source and destination file. If you select the same file as both source and destination, a backup copy will be created; otherwise, the script will ask you if you want to register a "Run with UI Access" context menu item. Either way, the destination file must be in Program Files or a sub-directory.

Do not modify the executable which this script creates or updates, since that would invalidate its digital signature.

The executable will not run on any other system, unless you install the certificate used to sign the file. To do this on Windows Vista or 7, right click the executable file, click Properties, go to the Digital Signatures tab, double-click the signature, click View Certificate, then click Install Certificate and follow the prompts. If prompted to select a certificate store, choose Trusted Root Certificate Authorities.

CreateProcess fails - Attempting to launch the executable with CreateProcess results in failure - "The requested operation requires elevation." This isn't a problem for the Run command since it falls back to ShellExecuteEx, but it may affect other programs which try to launch AutoHotkey (including SciTE and perhaps other editors).

In the following, "UIA" means "UI Access".

ComObjActive/ComObjGet may fail. UIA programs are probably only able to access the active objects of other UIA programs, not regular programs. For example, ComObjActive("Word.Application") will fail because Word is not marked for UI access. The reverse is also true: objects registered by UIA scripts can only be accessed by other UIA programs/scripts.

The script's own windows can't be automated by non-UIA programs/scripts. This isn't a problem if you run all your scripts with UI access. However, testing has shown that running a non-UIA script which uses a mouse hook (even as simple as #InstallMouseHook) may prevent all mouse hotkeys from working when the mouse is pointing at a window owned by a UIA script, even hotkeys implemented by the UIA script itself. This might also apply to keyboard hooks, but I have been unable to confirm that. A workaround is to ensure UIA scripts are loaded last.

Further Explanation:
 
With User Account Control (UAC) enabled, most programs are prevented from interacting with any windows which are running at a higher privilege level. For AutoHotkey, this usually means that hotkeys and Send won't work with administrative programs unless the script is also run as administrator. Running a script as administrator is fairly simple; however, it has at least two significant drawbacks:
  • The need to deal with a UAC prompt each time the script starts.
  • Any programs the script launches also receive administrative privileges.
Microsoft's recommended solution is to flag the application as one that needs "UI access," with the following additional requirements:
  • The executable must be digitally signed with a trusted certificate.
  • The executable must be in \Program Files\ or \Windows\System32\.
    (On my x64 system, \Program Files (x86)\ also seems to satisfy this requirement.)
This could be solved once and for all by signing AutoHotkey.exe before distribution, except for the following problems:
  • Certificates signed by a trusted certificate authority cost money, and typically need to be renewed each year.
  • If I were to buy a certificate and use it to sign AutoHotkey.exe, every time any script triggered a UAC prompt, my name would appear. I would not like that (I will not be held accountable for the actions of scripts I did not write).
  • If a self-signed certificate is used, it would need to be installed on each system before AutoHotkey.exe can run on that system.
  • The several limitations listed above.
Other Information:

The script can be supplied with one or two filenames on the command line, in which case it will attempt to silently create or update the destination executable file. If the script has been run before, it will reuse the "AutoHotkey" certificate created by a prior run. This certificate can be found in the user's "Personal" certificate store.

I have not tested the script with AutoHotkey Basic. It will not run on AutoHotkey Basic, but running the script on AutoHotkey_L and selecting an AutoHotkey Basic EXE as input will probably work.

I have not tested this script with a compiled script as input. Without a commercial digital signature, it probably wouldn't be very useful since the resulting EXE would not be very portable. However, it should work if given a script compiled with AutoHotkey_L v1.1.01 or later.

Download

nimda
  • Members
  • 4368 posts
  • Last active: Aug 09 2015 02:36 AM
  • Joined: 26 Dec 2010
:D Wow. This is awesome! I've hated when I have one script (admin) launch a browser, then try to use a second scripts' hotkeys on it.
This also brings back SendPlay for those running UAC :)
Thank you for this.

rbrtryn
  • Members
  • 1177 posts
  • Last active: Sep 11 2013 08:04 PM
  • Joined: 22 Jun 2011
Fantastic!! :D

This should definitely be made a sticky!

nimda
  • Members
  • 4368 posts
  • Last active: Aug 09 2015 02:36 AM
  • Joined: 26 Dec 2010
This appears to break COM/IE
; AHK_L
pwb := ComObjCreate("InternetExplorer.Application")
pwb.visible := true
pwb.navigate("http://www.autohotkey.com/")
while pwb.readystate != 4
   sleep 50
colLinks := pwb.document.GetElementsByTagName("a")
Loop % colLinks.length
   MsgBox % colLinks[A_Index-1].innertext "`n" colLinks[A_index-1].href
pwb.quit()
I get this error:
---------------------------
IE.ahk
---------------------------
Error:  0x80080005 - Server execution failed


	Line#
--->	002: pwb := ComObjCreate("InternetExplorer.Application")
	003: pwb.visible := true  
	004: pwb.navigate("http://www.autohotkey.com/")  
	005: While,pwb.readystate != 4
	006: Sleep,50
	007: colLinks := pwb.document.GetElementsByTagName("a")
	008: Loop,colLinks.length
	009: MsgBox,colLinks[A_Index-1].innertext "
" colLinks[A_index-1].href

Continue running the script?
---------------------------
Yes   No   
---------------------------
However running it normally (without the 'run with UI Access') works fine :?

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006

This appears to break COM/IE

There's probably nothing I can do about that. Can you automate an existing IE session?

Drugwash
  • Members
  • 1078 posts
  • Last active: May 24 2016 04:20 PM
  • Joined: 07 Sep 2008

The third of Newton's laws of motion of classical mechanics states that forces always occur in pairs. Every action is accompanied by a reaction of equal magnitude but opposite direction.

According to the above law - even if it would originally apply to mechanics only - by now, most if not all of the malware creators must be well documented as to how to circumvent the UAC in order to propagate the "fruit" of their twisted minds, so this UAC would not be a challenge for them anymore. On the other hand, the unaware user, being more and more pushed aside and out of the internals of the operating system, would have a hard time running their daily, valid applications, raising the frustration level. And indeed, this seems to be the only result of this UAC implementation. Personally I don't know one Vista/7 user that doesn't have UAC disabled following their getting fed up with its prompts and limitations.
I could get more into the opacity of the current (and definitely future) Windows OS versions, but it would be off-topic and unneeded. Thing is, all this struggle from Microsoft to keep users completely blind in respect to what the OS is and does as well as limiting users' rights and possibilities on their own hardware while using an OS that they paid for, makes me feel lucky for being poor, thus unable to "upgrade" hardware and software and become "one of the crowd".

Please, take the above rant purely as an act of freely speaking one's mind, completely unrelated to Lexikos' otherwise very well appreciated work; it just happened to "fall into" this topic, is all. And well, I also needed to post something in order to receive updates, in case I ever decide to make my scripts AHK_L compatible or in other way needed the information in this topic. :)

(AHK 1.0.48.05 and Win98SE) forever | My scripts are here


nimda
  • Members
  • 4368 posts
  • Last active: Aug 09 2015 02:36 AM
  • Joined: 26 Dec 2010

There's probably nothing I can do about that. Can you automate an existing IE session?

Well sure, and its also not a problem to just run it as admin instead of using the UI Access whenever I need COM. It was just a hard-to-track bug.

ajl
  • Guests
  • Last active:
  • Joined: --
Hello:

Is it possible to use this functionality to create digitally signed compiled scripts, as requested in http://www.autohotke...topic56500.html

Perhaps instead of generating the self-signed certificate, an (optional) dialog could ask the user to provide a PFX or PVK certificate s/he already has, perhaps even from Verisign et al?

This would also eliminate Lexiko's issue:

If I were to buy a certificate and use it to sign AutoHotkey.exe, every time any script triggered a UAC prompt, my name would appear. I would not like that.


by enabling users to roll their own (custom/in-house) autohotkey.exe with their personal certificate attached to it.

Thanks for your consideration, Achim

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006
You can edit the following to use a different certificate:
; Locate "AutoHotkey" certificate created by a previous run of this script.
ahk_cert := my.FindCertificates(0, Cert.FIND_SUBJECT_STR, "wstr", "[color=red]AutoHotkey[/color]")[1]

This would also eliminate Lexiko's issue:

My issue was with the effects of pre-signing the executable. Requiring users to use their own certificate is no more a solution than providing this script (either way they need to specifically sign the executable).

nimda
  • Members
  • 4368 posts
  • Last active: Aug 09 2015 02:36 AM
  • Joined: 26 Dec 2010
This needs to be added to the documentation on SendPlay :wink:

ajl
  • Guests
  • Last active:
  • Joined: --

You can edit the following to use a different certificate:

; Locate "AutoHotkey" certificate created by a previous run of this script.
ahk_cert := my.FindCertificates(0, Cert.FIND_SUBJECT_STR, "wstr", "[color=red]AutoHotkey[/color]")[1]


Excellent: that does the trick to select an already installed 3rd party Authenticode certificate. In combination with an updated call to
SignFile(out_file, ahk_cert, "YOURCOMPANYNAME")
this produces compiled, UAC-compliant signed AHK binaries!

This would also eliminate Lexiko's issue:

My issue was with the effects of pre-signing the executable. Requiring users to use their own certificate is no more a solution than providing this script (either way they need to specifically sign the executable).


We are saying the same thing: don't sign the default autohotkey.exe, but give users the ability to do so: just like you did!

An addition: in order to make timestamps work, I added this to SignFile.ahk immediately after the call to SignerSign:

timeserver := "http://timestamp.verisign.com/scripts/timestamp.dll"

   hr := hr + DllCall("MSSign32\SignerTimeStamp"
        , "ptr", &subject_info
        , "wstr", timeserver ; pwszHttpTimeStamp
        , "ptr", 0 ; psRequest
        , "ptr", 0 ; pSipData
        , "uint")

Passing the timeserver variable directly in SignerSign should work in theory, but does not always in practise, as some other people also figured out: http://blogs.msdn.co... ... 70020.aspx

As a result, we first sign the binary, and then timestamp it.

Hope this is helpful for somebody?

Best regards, and thank you again, Achim

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006

An addition: in order to make timestamps work, I added this to SignFile.ahk immediately after the call to SignerSign:

Thanks. I was wondering how to do that, though I don't have any use for it personally.

Passing the timeserver variable directly in SignerSign should work in theory,

That's what I thought, but couldn't get it to work.

LuckMan212
  • Members
  • 4 posts
  • Last active: Feb 01 2012 04:27 PM
  • Joined: 13 Feb 2006
Great stuff. Thanks so much for this! I was scratching my head trying to figure out why my global keyboard hooks were not working while an "elevated" app was in the foreground. Some searching led me here, and after applying the manifest patch, my script is working universally now without needing to launch the main process with elevated privs.

I realize that a "real" certificate is expensive but surely the community could chip in yearly for this, each member giving $1 or something and get you to the goal amount? Or maybe I am too optimistic?

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006
The bigger problem is that a proper certificate would have my name on it, essentially giving the impression that every script which triggers a UAC prompt is published by me personally.

bpm
  • Members
  • 8 posts
  • Last active: Feb 29 2012 05:46 PM
  • Joined: 22 Jan 2012
Thank-you, Lexikos!

For others who may be as unclear as I was as to what, in lay terms, this achieves, one thing is - it lets you run a script from the startup folder.

My case: running Win7 with standard-level UAC, no script would launch from Startup. So I tried something mentioned in this thread - starting as a logon task in Task Manager, with elevated authority. That worked until I added Fileread operations. Other scripts did them fine, but not the startup script. No error message, no prompt - just failure. I eventually got suspicious of UAC, and tried exiting and manually starting the script (including the dim-screen authorization prompt) - which then read files. So TM's elevated privileges are not as good as those conferred when prompted, and not enough to read a file.

Tried what this post advises - putting a shortcut to AHK.exe in startup - hoping to add the script as argument, start it that way. But - add the argument, and the app won't start. So you can't actually launch a script.

Installed this patch, and my script starts & loads variables from file without a hitch - and all scripts run without the screen-dimming UAC challenge.

I think this ought to be put prominently in the path of the frustrated novice. (I tried to put a plug in the Wiki, where there's an FAQ about this, but the member list seems to be closed: the "login/signup page" has no signup area.)