2013年12月12日木曜日

アプリケーションの互換性について - ファイルが見つからない VirtualStore の波紋




アプリケーションの互換性について - ファイルが見つからない VirtualStore の波紋 (Windowsの本当の力を知っていますか?)




ファイルが見つからない。。。VirtualStore の波紋について

vExpert Advent Calendar に参加しています。
「仮想化でプリセールスしてるSEの一日」@ogawadさんに引き続き今日は私が担当します。いつもながら、@ogawadさんの投稿は参考になりますね。ネットワーク帯域制御装置が手軽に0円で、できるなんて素敵です。
装置って言葉にグッときますね。ピタゴラ装置とか。

今回の内容は、アプリケーションの互換性についての第3弾になります。
・ⅰ「アプリケーションの互換性について (Windowsの本当の力を知っていますか?)

・ⅱ「アプリケーションの互換性について - 実践編 (Windowsの本当の力を知っていますか?)

前回は、アプリケーション互換性の実践編として、環境変数 __COMPAT_LAYER を利用してアプリケーション互換性エンジンを利用する方法を投稿しました。

今回は、Windows Vista以降に搭載された VirtualStore 機能 (ファイル、レジストリの仮想化機能)について投稿します。


参考:
Windows Vista または Windows 7 のファイルおよびレジストリの仮想化に関する一般的な問題
http://support.microsoft.com/kb/927387/ja


初めに:
Windows XPから Windows 7に移行した場合に、しばしば以下のような質問を頂く事があります。

アプリから見ると
ファイルは、あるんだよ。

でも

エクスプローラーから見ると
ファイルが見つからないんだけど。。。


尊敬するポルナレフさん的に表現すると、こんな感じですw

あ…ありのまま 今 起こった事を話すぜ!

「おれは アプリからファイルを保存して
もう一度、そのファイルアプリから
開けることを確認した。

その後に、エクスプローラーから、その
ファイルを見つけよう思ったら無かった。
な… 何を言っているのか、わからねーと思うが
おれも 何をされたのか、わからなかった…
頭がどうにかなりそうだった…
催眠術だとか超スピードだとか
そんなチャチなもんじゃあ 断じてねえ
もっと恐ろしいものの片鱗を 味わったぜ…

参考:「あ…ありのまま 今 起こった事を話すぜ!

この恐ろしい現象は、「ファイルが無いけど有る。」or「 ファイルが有るけど無い」現象と呼ぶことにします。
ポルナレフは、DIO の スタンドの「ザ・ワールド」で「時を止める」能力を使っている間に
階段を降ろされていましたね。

(「時を止めた後、階段を登っている、ポルナレフをDIOもしくはザ・ワールドが階段の下まで運んでいって、すかさず元の位置に戻ってから余裕の表情を浮かべて時の流れを元に戻す」を想像するとシュールですねw)


で、今回の現象は、ジョジョ的に表現すると、Windows 7 の スタンドである 「UAC」 の 「VirtualStore ファイル・レジストリ仮想化」能力により、違うパスにファイルが迂回されていました。

ジョジョ ネタから元に戻りたいと思ったのですが、このままジョジョ ネタのまま進行しちゃいます。

まずは、Windows 7のスタンド「UAC」の特徴について。



UACが搭載された時期:
Windows Vistaに初めて搭載されました。
Windows Vista以降のOSには標準で搭載されています。
  (Windows Vista,7,8,8.1 /2008,2008R2,2012,2012R2)

NT Versionで表すと、NT6系(Longhornカーネル)から搭載されました。
 第3部のスタンド時代の始まりですw
 きっと、Longhornカーネルは、例のあの矢が刺さったんですねw

UACの役割:
・主人である、OSをを守る。
XPまでのOSは、利用者の不注意によってウイルス、マルウェアに感染しやすかった為
特に、利用者が管理者権限、Poweruser権限を持っている場合に
危ないEXEを実行すると、感染していたため。

・OSを守りつつ、OSの利用者を困らせないようにする。
権限が必要な操作時に、UACの確認画面を表示することで
利用者に問題ない操作なのか確認する。
OSを守ることを考えると、危ない操作は、無言で無視させた方が良いのですが、
無視するわけにもいかないので、確認画面をだしているんですね。Vistaはその確認画面が
頻繁に表示されて、使いにくかったですが、Win7以降はMSの署名がある、システム系の操作に関しては、表示されないような改善が加わりました。

・OSに対応していない、レガシーアプリを動作させる
今回の VirtualStore の機能です。


「VirtualStore ファイル・レジストリ仮想化」能力について

 ・Windows Vista 以降で正常に動作しないような、レガシーアプリを救うための能力です。
 ・Windowsフォルダや、Program Filesフォルダにiniファイル等を保存するタイプのアプリが
  その恩恵を受けることができます。
  権限が足りない状態にも係わらず、書き込み・作成が成功するように振る舞う。

 ・自動的に、Virtual Storeフォルダにファイルが迂回(リダイレクト)されます。


VirtualStoreの能力に影響されるレガシーアプリの判定方法について

・タスクマネージャーの「プロセス」タブの「UACの仮想化」で確認できます。
 ※表示メニューから列の選択で「UACの仮想化」を追加できます。

下記の条件に該当すると、レガシーアプリと判定されます。
・32bitアプリであること、アプリケーションmanifestにより、
 実行権(requestedExecutionLevel)を明示化していない場合

VirtualStoreの能力により、実際に保存されている場所について

対象の場所
実際の場所
%Program Files%

既定値:
 C:\Program Files\
%LOCALAPPDATA%\VirtualStore\Program Files

既定値:
C:\Users\<USERID>\AppData\Local\VirtualStore\Program Files
%ProgramData%

既定値:
C:\ProgramData\

%LOCALAPPDATA%\VirtualStore\ProgramData

既定値:
C:\Users\<USERID>\AppData\Local\VirtualStore\ProgramData
%SystemRoot%

既定値:
C:\Windows\
%LOCALAPPDATA%\VirtualStore\ProgramData

既定値:
C:\Users\<USERID>\AppData\Local\VirtualStore\Windows
HKEY_LOCAL_MACHINE\SOFTWARE
HKCU\Software\Classes\VirtualStore\Machine\Software
※対象外のファイル:.exe .dll .sys
※対象外のレジストリ:HKLM\Software\Classes
HKLM\Software\Microsoft\Windows
HKLM\Software\Microsoft\Windows NT

Virtual Store を無効にする方法:

1.UAC自体を無効にする。
 お勧めしません。

2.Virtual Storeの機能をグループポリシーで無効化する。
「ローカルコンピュータ ポリシー」-「コンピュータの構成」-「Windowsの設定」-
「セキュリティの設定」-「ローカルポリシー」-「セキュリティ オプション」

「ユーザー アカウント制御:各ユーザーの場所へのファイルまたはレジストリの書き込みエラーを仮想化する」



3.Virtual Storeの機能をレジストリで無効化する。
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System

名前: EnableVirtualization
種類: Dio the WORLD
データ: 1 (有効) / 0 (無効)



4.対象のEXEにアプリケーションmanifestファイルを追加し実行権を明示化する。
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
        <requestedPrivileges>
            <requestedExecutionLevel level="asInvoker" uiAccess="false"/>
        </requestedPrivileges>
    </security>
</trustInfo>

具体例)NilBrowser ver1.1.0.4 http://nilbrowser.ifdef.jp/
C:\Program Files\NilBrowser\NilBrowser\NilBrowser.exe.manifest

編集前:
<?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="PicoBrain.NilBrowser"
    type="win32"
/>
<description>NilBrowser</description>
<dependency>
    <dependentAssembly>
        <assemblyIdentity
            type="win32"
            name="Microsoft.Windows.Common-Controls"
            version="6.0.0.0"
            processorArchitecture="X86"
            publicKeyToken="6595b64144ccf1df"
            language="*"
        />
    </dependentAssembly>
</dependency>
</assembly>

編集後 実行権の追加:
<?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="PicoBrain.NilBrowser"
    type="win32"
/>
<description>NilBrowser</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.v3">
    <security>
        <requestedPrivileges>
            <requestedExecutionLevel level="asInvoker" uiAccess="false"/>
        </requestedPrivileges>
    </security>
</trustInfo>
</assembly>



実行結果:



と言う訳で、今回の投稿は、ジョジョに関するものでしたw
ファイルが見つからない場合は、VirtualStoreの能力を感じて下さい。
後、ThinAppも独自のスタンドと能力があるので、その話は、いずれしたいと思います。
承太郎のスタープラチナみたいな、素敵なスタンドです。


明日は、「仮想化でプリセールスしてるSEの一日」@ogawadさんのターンです。乞うご期待!