Tuesday, 22 October 2013

UAC Privilege Elevation for SetWindowsHookEx on visual studio 2012

We have encountered a problem when working with windows hooks. The SetWindowsHookEx function is returning NULL handles when we are trying to establish a HOOK. After a simple work around, it looks like programs that capture Windows Hooks need special privileges. The UIPI (User Interface Privilege Isolation) feature blocks the lower privilege process to access the higher privilege process and hence the NULL handle and Access denied error.

This used to be quite simple in Windows XP. However Windows Vista and higher OS have more add-on security features that will restrict you (UIPI, Session Isolation etc.,).

The most simplest thing that can be done is to change the UAC features in your machine.

Go to Start > type “UAC” > NEVER NOTIFY > OK

This will make your application Run. However, when you run your executable in another machine with different UAC settings it will fail to run giving NULL handles.

So, you have to make some trivial changes in the visual studio solution files to get resolved the with the problem.

Go to Project Properties > Linker settings > set UAC Execution level to “requireAdministrator” and set the UAC bypass UI protection to “true”

If your application does not have a digital signature and has uiAccess=true in its manifest, it will fail with "A referral was returned from the server."

Applications that request uiAccess=true must have a valid, trusted digital signature to execute.

Also, applications by default must reside in a trusted location on the hard drive (such as windows or program files) to receive the uiAccess privilege. They will still run if they are not in one of these locations, but they will not receive the privilege. You can disable this preferred directory location based security feature through the local security policy mmc snap-in.

If you want to create a trusted "test" certificate to sign your application with so that you can use your application on your current machine, here's how:

NOTE: These instructions assume you have visual studio installed and are using a command prompt that has all the environment variables set to find SDK utilities such as makecert and signtool. If not, you will need to find these tools on your hard drive before running them.

(Easy way: Run your visual studio developer tools command prompt with admin rights to get these tools)

1) Open an elevated visual studio command prompt. To do that,

- Click start
- Find Developer Command prompt for VS12 ( its a windows Cmd Shell )
- Right-click, click Run As Administrator
2) Create a trusted root certificate
- Browse to the folder that you wish to contain a copy of the certificate
- In the command shell, execute the following commands:
# makecert -r -pe -n "CN=Test Certificate - For Internal Use Only" -ss PrivateCertStore testcert.cer
# certmgr.exe -add testcert.cer -s -r localMachine root
3) Sign your file
- In the command shell, browse to the location of your exe
- In the command shell, type:
# SignTool sign /v /s PrivateCertStore /n "Test Certificate - For Internal Use Only" /t http://timestamp.verisign.com/scripts/timestamp.dll YOUR-APP.exe

Replace YOUR-APP.exe with your application name.exe.

Now, after having the digital signature, move the exe to c:\Windows\System32

Your EXE will ask permission before it starts running and you can make sure of verifying the Digital signature.

Note: you have to have digital signature for every build you generate.

Just run the program there: you will get the Hooks working :)