7

I've seen several questions that are the opposite of this; "How do I disable virtualization?" That is not my question. I want to force an application to run with virtualization enabled.

I have an application that ran just fine under Windows XP, but, because it writes its configuration to its working directory (a subfolder of "C:\Program Files (x86)"), it does not work completely under Windows 7. If I use task manager to turn on UAC Virtualization, it saves its config just fine, but of course it then can't load that config.

I do not want to set it to run as administrator, as it does not need those privileges. I want to set it to run with UAC Virtualization enabled.

I found a suggestion that I put some magic in the registry at HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags. For completeness I also put it in Wow6432Node, but neither had any effect.

DaleStan
  • 595
  • 2
  • 6
  • 19
  • why can't you just change the app to keep the config file in AppData? – Kate Gregory Jan 27 '12 at 15:39
  • 1
    @KateGregory 's suggestion, or modify the ACL on the folder so that *everyone* has full control. Problem is that no every kind of write will always be virtualized. It's a stop-gap feature, there to stop buggy programs from crashing. It really isn't something you should be relying on. In fact, virtualization can be disabled through group policy - nevermind if you want it or not. – Ian Boyd May 04 '12 at 03:30
  • 1
    @KateGregory: I don't have the source. If I had the source, I'd be using that, rather than bad workarounds that rely on stop-gap features. – DaleStan Oct 17 '12 at 15:25
  • 1
    @IanBoyd Modify the ACL to defeat the security I get by running with UAC on? I don't think so. Group Policy does not prohibit virtualization on my machine ("User Account Control: Virtualize file and registry ..." is Enabled), so that doesn't apply to me, though it may apply to others. (I eventually gave up and modified the ACL on the config file only. This does solve the original problem, and without opening any security holes, but it doesn't answer the original question.) – DaleStan Oct 17 '12 at 15:26

5 Answers5

5

File system is virtualized in certain scenarios, so is your question how to still turn it on when your application does not qualify? It is unlikely possible, MSDN:

Virtualization is not in option in the following scenarios:

  • Virtualization does not apply to applications that are elevated and run with a full administrative access token.

  • Virtualization supports only 32-bit applications. Non-elevated 64-bit applications simply receive an access denied message when they attempt to acquire a handle (a unique identifier) to a Windows object. Native Windows 64-bit applications are required to be compatible with UAC and to write data into the correct locations.

  • Virtualization is disabled for an application if the application includes an application manifest with a requested execution level attribute.

Roman R.
  • 68,205
  • 6
  • 94
  • 158
  • 1 and 2 don't apply; it's a 32-bit app that I am not running elevated, and don't want to. – DaleStan Jan 13 '12 at 18:15
  • So, I guess my question devolves to "The application manifest apparently lies. How do I fix it?" – DaleStan Jan 13 '12 at 18:21
  • So, I tried to extract the manifest with mt (mt -inputresource:tool.exe -out:tool.manifest), and was informed: "mt.exe : general error c101008c: Failed to read the manifest from the resource of file. The specified resource type cannot be found in the image file." Trying the same with an executable that does contain a manifest works. So, the answer seems to be "The manifest doesn't exist." – DaleStan Jan 13 '12 at 20:23
  • if you have a manifest, no matter what it says, you will not get virtualization. To try to get it, start by not having a manifest. – Kate Gregory Jan 27 '12 at 15:39
  • @Kate: mt tells me "Failed to read the manifest .... The specified resource type cannot be found in the image file." This makes me suspect that I don't have a manifest. If, as you seem to suspect, mt is lying, how do I remove the manifest? – DaleStan Jan 31 '12 at 19:42
4

this may come way too late now, but I am the author of the suggestion you found to activate UAC virtualization, and there was a mistake in my post. The registry keys to modify are the following:

HKLM\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers\ 
HKCU\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers\

(notice the "Layers" appended)

so a full example would be:

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers]
"C:\\Program Files (x86)\\Some Company\\someprogram.exe"="RUNASINVOKER"

note that multiple parameters must be separated with space character.

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers]
"C:\\Program Files (x86)\\Some Company\\someprogram.exe"="WINXPSP3 RUNASINVOKER"

--

I'm sincerely sorry that you lost a fair amount of time because of my mistake.

And by the way, let me express my disagreement with Ian Boyd's post. There are places where write privileges should not be granted to everyone, such as this one, since it breaks the base security rule of "System-wide writes should be authorised to privileged principals only". Program Files is a system-wide place, not a per-user one.

All rules have exceptions of course, but in the present case, one could imagine a maliciously crafted configuration file making the program exec an arbitrary command as the user running it. On a lighter side, one could imagine a "mistake delete" by another user, which would make the app fail. Back on the heavier side, application executables in Program Files are often run by the admin, sooner or later. Even if you don't want to, uninstalling programs very often run uninstall executables that are in Program Files. Maybe the uninstall procedure will use that config file which could have consequences if it's maliciously crafted.

Of course you may say, this sounds paranoid somehow, agreed. I did modify some NTFS ACLs in Program Files at the times of Win XP and was able to sleep after that, but why take the slightest risk when the tools are available ?

Ram Ghadiyaram
  • 28,239
  • 13
  • 95
  • 121
NovHak
  • 41
  • 1
2

I found one not very well cited condition where UAC Virtualization does NOT work: when the file in Program Files is maked as read-only.

That is, suppose the file C:\Program Files\<whatever>\config.ini is marked as read-only. When the application try to change it, UAC Virtualization will return an access denied error instead of reparsing it to %LOCALAPPDATA%\VirtualStore\<whatever>\config.ini.

Although I did not found this documented, this behavior is probably done by design, since it makes some sense.

The solution is simple: assure that all files that are supposed to be modified by the application are not read-only (or just unflag all files, since the user will not be able to change them anyway).

Diego Queiroz
  • 3,198
  • 1
  • 24
  • 36
1

You have an application, and you want users to be able to modify registry keys or files in locations that by default only Administrators can modify.

If you were running Windows 2000, or Windows XP, or Windows Vista, or Windows 7, or Windows 8, the solution is the same:

  • grant appropriate permissions to those locations

For example, if your program needs to modify files in:

C:\Program Files\Blizzard\World of Warcraft

Then the correct action is to change permissions on the World of Warcraft folder. This is, in fact, a shim that Microsoft applied to World of Warcraft. (On next run it granted Everyone Full Control to the folder - how else can WoW update itself no matter what user is logged in.)

If you want users to be able to modify files in a location: you have to grant them permission. If you were a standard user trying to run WoW on Windows XP you will get the same problem - and need to apply the same solution.


Your application is writing its configuration to:

C:\Program Files (x86)\Hyperion Pro\preferences.ini

then you, in fact do want to grant Users Full Control to that file:

enter image description here

So your:

  • application is not set to run as an Administrator
  • users cannot modify the executable
  • users can modify Configuration.ini

Granting permissions is not a bad thing; it's how you administer your server.


There are two solutions:

  • Install to C:\ProgramData\Contoso\Preferences.ini and ACL it at install time
  • Install to C:\Program Files\Contoso\Preferences.ini and ACL it at install time

And if you look at the guidance of the AppCompat guy at Microsoft:

Where Should I Write Program Data Instead of Program Files?

A common application code update is this: “my application used to write files to program files. It felt like as good a place to put it as any other. It had my application’s name on it already, and because my users were admins, it worked fine. But now I see that this may not be as great a place to stick things as I once thought, because with UAC even Administrators run with standard user-like privileges most of the time. So, where should I put my files instead?”

FOLDERID_ProgramData

The user would never want to browse here in Explorer, and settings changed here should affect every user on the machine. The default location is %systemdrive%ProgramData, which is a hidden folder, on an installation of Windows Vista. You’ll want to create your directory and set the ACLs you need at install time.

So you have two solutions:

  • create your file at install time, and ACL it so that all users can modify it at runtime
  • create your file at install time, and ACL it so that all users can modify it at runtime

The only difference is semantic. The Program Files folder is mean for program files. You don't want to store data here.

  • And it's not because Diego Queiroz has any insight about security.
  • It's because it's where just the programs go.

Sometimes machines are imaged with the same Program Files over and over. You don't want per-machine data in your image. That data belongs in ProgramData.

And it's not a security issue.

Some people have to learn where the security boundary is.

Ian Boyd
  • 246,734
  • 253
  • 869
  • 1,219
  • I completely disagree. Applications should not change system areas. Since Program Files is a system area, it should not be changed. The problem is that legacy apps still do that. This is why UAC virtualization exists, and you should not disable it. Disable anything related to UAC is a lazy solution. – Diego Queiroz Mar 21 '17 at 17:21
  • @DiegoQueiroz I agree; applications should put user-modifiable data into `CSIDL_ProgramData`. But the reality is that `C:\ProgramData` is also off limits to standard users by default. And the [**correct** guidance is to ACL that location at install time](https://blogs.msdn.microsoft.com/cjacks/2008/02/05/where-should-i-write-program-data-instead-of-program-files/). And if you ACL your data file correctly, and disable virtualization on your process (run **asInvoker**) then you are doing things correctly. – Ian Boyd Mar 21 '17 at 18:39
  • And, Diego, you also misunderstand what UAC is. The reason file virtualization exists is because installation programs never bothered to ACL files that they need standard users to modify. It doesn't matter if those files are in `ProgramFiles`, `ProgramData`, or `C:\`. You still need to ACL them properly. – Ian Boyd Mar 21 '17 at 18:49
  • I still disagree. Apps can modify folders ACL, but they shouldn't, specially when this is avoidable. Surely this is all about security, but this is also about system design: things should be where they are meant to be. And I don't think I misunderstood what UAC is. Changing the default ACL of any subfolder in `C:\ProgramData` (even if your app created it) is equivalent of allowing any user to write in `/etc/your_app` in Linux, what is completely crazy idea in any aspect. – Diego Queiroz Mar 24 '17 at 15:23
  • If you are designing a system independent app, great, put everything on `C:\your_app` (similar to `/opt/your_app` in Linux) and be happy with it. You can even stick to `%USERPROFILE%\...\your_app` (similar to `~/your_app` on Linux) if your app don't need to be shared between users (as Google Chrome already do with its standard installer). But don't try to convince me that changing the default ACL defined by the operating system is the "_correct_" solution in any way. – Diego Queiroz Mar 24 '17 at 15:23
  • @DiegoQueiroz It's how World of Warcraft works. It's how Steam works. It's how Occulus Store works. Fortunately i don't have to convince you. Microsoft guidelines do it for me. – Ian Boyd Mar 24 '17 at 17:03
  • Honestly, you are being rude with no reason. Actually, the reason is that you have no more arguments, so being rude is the way to go. Where are the Microsoft guidelines that you cite? In a blog post? C'mon... And seriously: you are using only games as reference to argument. Show me one updated, and well maintened software that change ACL during installation. Java? Chrome? Firefox? MS Office? No way! And I am inclined to believe that even the software you cite don't change any ACL, this is a possible hack **you** can do to make them work because they were not designed to work with UAC. – Diego Queiroz Mar 24 '17 at 21:40
0

there are quite some good points in those other answers.
actually i have upvoted all of those.
so let's all combine them together and add some more aspect ...

the OP mentions some "legacy application from the old days".
so we can assume it is x86 (32bit) and also does not include any manifest (and in particular does not specify any "requestedExecutionLevel").

--

Roman R. has good points in his answer regarding x64 and manifest file:
https://stackoverflow.com/a/8853363/1468842
but all those conditions don't seem to apply in this case.

NovHak outlines some AppCompatFlags with RUNASIVOKER in his answer:
https://stackoverflow.com/a/25903006/1468842

Diego Queiroz adds intersting aspect regarding the read-only flag in his answer:
https://stackoverflow.com/a/42934048/1468842

Ian Boyd states that probably you don't even should go for that "virtualization", but instead set according ACL on those files of interest (such as "config.ini"):
https://stackoverflow.com/a/12940213/1468842

and here comes the addtional / new aspect:
one can set a policy to disable all virtualization - system-wide:

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System]
"EnableVirtualization"=dword:00000000

actually i'm enforcing this policy on each and every system that i own.
because otherwise it will lead to confusing behaviour on multi-user environments.
where UserA applies some changes and everything goes fine.
but then UnserB does not get the changes done by UserA.

in case some old crappy software fails then it should "fail"!
and not claim that everything went "fine".
IMHO this "Virtualization" thing was the worst design decision by microsoft, ever.

so maybe the system has this policy enabled and that's why virtualization doesn't work for you?

--

so probably the ultimate checklist would be:

  • is the application x86 or x64?
  • does the exe have a manifest (including the requestedExecutionLevel)?
  • have you checked the read-only attribute (e.g. of those INI files)?
  • is there a policy to force the EnableVirtualization to 0?
  • have you tried the AppCompatFlags with RUNASIVOKER?
  • or simply go for ACL instead of virtualization

--

in the end we are discussing how to get on old legacy application to run.
by using whatever workarounds and hacks we can think of.
this should probably better discussed on either superuser or serverfault.

at stackoverflow (targeted for programmers) we all know: it's about time to get all of our own programs compatible with UAC concept and how to implement things the "right" way - the "microsoft" way :)

Opmet
  • 1,754
  • 18
  • 20