views:

437

answers:

5

We have a C++ unmanaged application that appears to cause a UAC prompt. It seems to happen on Win7 and NOT on Vista

Unfortunately the UAC dlg is system modal so I can't attach a debugger to check in the code where it is, and running under msdev (we're using 2008) runs in elevated mode.

We put a message box at the start of our program/winmain but it doesn't even get that far, so apparently this is in the startup code.

What can cause a UAC notification so early and what other things can I do to track down the cause?

EDIT

Apparently the manifest is an important issue here, but it seems not to be helping me - or perhaps I am not configuring the manifest file correctly.

Can someone provide a sample manifest?

Also, does the linker/UAC magic figure out that the program "might" write to the registry and set its UAC requirements based on that? There are code paths that might trigger UAC, but we are not even at that point when the UAC dlg comes up.

An additional oddity is that this does not seem to happen on Vista with UAC turned on.

Here is a manifest (that I think is/was generated automatically):

<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel level='asInvoker' uiAccess='false' />
      </requestedPrivileges>
    </security>
  </trustInfo>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*' />
    </dependentAssembly>
  </dependency>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*' />
    </dependentAssembly>
  </dependency>
</assembly>

And then this one was added to the manifest list to see if it would help

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity 
    version="1.0.0.0" 
    processorArchitecture="x86" 
    name="[removed for anonymity]" 
    type="win32" 
/> 
<description>
    [removed for anonymity]
</description>
<dependency>
    <dependentAssembly>
        <assemblyIdentity 
            type="win32" 
            name="Microsoft.Windows.Common-Controls" 
            version="6.0.0.0" 
            processorArchitecture="x86" 
            publicKeyToken="6595b64144ccf1df" 
            language="*" 
        />
    </dependentAssembly>
</dependency>
 <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
    <security>
      <requestedPrivileges>        
        <requestedExecutionLevel
          level="asInvoker"
          uiAccess="false"/>
      </requestedPrivileges>
    </security>
  </trustInfo>
</assembly>

The following is from the actual EXE using the ManifestViewer tool

- <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <assemblyIdentity version="1.0.0.0" processorArchitecture="x86" name="[removed]" type="win32" /> 
  <description>[removed]</description> 
- <dependency>
- <dependentAssembly>
  <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="x86" publicKeyToken="6595b64144ccf1df" language="*" /> 
  </dependentAssembly>
  </dependency>
- <dependency>
- <dependentAssembly>
  <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*" /> 
  </dependentAssembly>
  </dependency>
- <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
- <security>
- <requestedPrivileges>
  <requestedExecutionLevel level="asInvoker" uiAccess="false" /> 
  </requestedPrivileges>
  </security>
  </trustInfo>
  </assembly>

It appears that it might be due to the xp compatibility setting on our app. I'll have to test that. (we set that in the installer I found out because some sound drivers don't work correctly on win7)

+5  A: 

If you are not even getting to your main function, then either a DLL used by your app is doing something in its DllMain initialization or your app has a manifest requesting elevation.

I think you should be able to remotely debug it with windbg; when the prompt is shown you can break into the debugger and see what your app is trying to do.

Luke
the manifest does not request elevation as far as I can see.
Tim
+2  A: 

The first thing I would check is the application manifest. It's one of the first thing Windows looks at when creating a process. It definitely interacts with UAC.

MSalters
And what am I looking for in there?
Tim
`requestedExecutionLevel` in particular, but that seems normal.
MSalters
+3  A: 

Windows automatically elevates applications based on various criteria (listed in Understanding and Configuring User Account Control in Windows Vista):

Before a 32 bit process is created, the following attributes are checked to determine whether it is an installer:

  • Filename includes keywords like "install," "setup," "update," etc.
  • Keywords in the following Versioning Resource fields: Vendor, Company Name, Product Name, File Description, Original Filename, Internal Name, and Export Name.
  • Keywords in the side-by-side manifest embedded in the executable.
  • Keywords in specific StringTable entries linked in the executable.
  • Key attributes in the RC data linked in the executable.
  • Targeted sequences of bytes within the executable.

The best solution to all of these is to create a manifest that prevents elevation, though renaming the file may be enough.

bk1e
I followed that link and added "asInvoker" but I still get the UAC dlg. (at startup) Any other clues? Perhaps i have not created the manifest correctly?
Tim
How do I figure out WHICH one of those caused the elevation request at startup? This information is great, but it does nothing to identify exactly what I need to change to get it to stop... Any clues about how to do that?
Tim
@tim: That's an excellent question, and one I don't know the answer to. (When I ran into problems with this, it was the filename.) However, I can at least suggest running `sxstrace` to determine whether it's an issue with the manifest. And maybe one of the security audit settings in `gpedit.msc` will log something useful about installer detection to the event viewer (but probably not).
bk1e
Thanks again. I'll take a look. It is odd that this SEEMS to happen on WIn7 and not vista (With the same level of UAC)
Tim
We've noticed UAC in Windows 7 behaving differently from Vista too, it's a problem.
Colen
+1  A: 

On Windows 7 (but not Vista) if you say the app needs XP compatibility settings, it will also elevate. See http://stackoverflow.com/questions/2210737/is-uac-on-win7-different-than-vista - if you don't need to elevate, but you do need to be marked XP compat, I don't think there's anything you can do. OTOH if you don't need to be XP compat, stop asking to be.

Kate Gregory
Unfortunately there is a bad driver issue for Win7 that xp compat seems to fix... We're in a catch 22 it seems.
Tim
A: 

Dependency Walker (depends.exe) wqs orignally written to troubleshoot DLL problems, but its profiling mode is more useful than that. It can be used to capture a lot of information about process creation. It would be interesting to see in particular which DLLs are needed, and which of those have been loaded at the moment of the UAC prompt. It's also quite possible that the output from Depenceny Walker mentions UAC explicitly.

MSalters