25

私は一連の C# (v2) アプリを持っており、Win7 (およびそれほどではないが Vista) でのレジストリ仮想化に苦労しています。

アプリケーションが HKLM\Software\Company にアクセスする必要がある共有レジストリ構成領域があります。

このコードは、そのレジストリ キーへの書き込みの失敗を適切に検出し、適切にフォールバックします (代わりに HKCU に書き込み、適用した設定が現在のユーザーにのみ影響することをユーザーに通知します)。

Vista では、HKLM 書き込みに使用していたアクセス チェックがサイレントに「成功」​​し、代わりに HKCR\VirtualStore\Machine... に仮想化されるため、レジストリの仮想化によってこれらすべてが壊れていました。この場合、ユーザーはマシン全体の構成を保存したと考えますが、代わりに仮想ストアに書き込んだだけです。

悲しいことに、HKLM reg キーのアクセス許可を列挙しようとしても、ユーザーがアクセスしているかどうかに関係なく、ユーザーがアクセスできることを示す結果が明示的に返されます。

Vista のサポートを追加したときに使用した回避策は、HKLM へのプローブ書き込みを実行することでした...次に、HKCR\VirtualStore\Machine... で同じ値をチェックインし、値が見つかった場合は仮想化が行われたことに注意してください。

明示的な仮想ロケーション (HKCR) に対するクエリは、書き込みが仮想化されていない場合でも、HKLM ロケーションからマージされた結果を表示するようになったため、Win7 はこれを (再び) 破ったようです。

これを回避するための提案はありますか?

制約: - 昇格を必要とせずに機能するソリューションが必要です (管理者レベルのアクセス許可がない場合、HKCU でユーザーごとの構成にフォールバックしますが、このケースを確実に検出できる必要があります)。

  • v2 C# アプリで動作する必要があります (C++ コードで見たオプションの 1 つは、.exe の仮想化を無効にするマニフェストを埋め込むことですが、C# V2 ではそれを行うことができませんでした。Windows でフォルダーの仮想化を無効にするを参照してください) .

  • 「インストーラー」なしで動作する必要があります (これにより、REG FLAGS... コマンドで必要なレジストリ キーの仮想化を無効にすることができなくなります)。

4

4 に答える 4

11

これは優れた質問です。+1 (なぜコミュニティ ウィキなのか、ポイントに値します!)

一般に、UAC [および暗黙のうちにレジストリ] の仮想化が行われているかどうかを制御する一連のルールがあります ([あなたが遭遇したように] 時間の経過とともに変化します)。

MSDN のレジストリ仮想化ルールセット ドキュメントの重要な部分は次のとおりです。

  1. [jeffamaphone が言うように] マニフェストに requestedPrivileges/requestedExecutionLevel が設定されている場合、それはオフになります。マニフェストを追加することを除外していないようですが、これがうまくいかない理由を教えてください。(「C# V2 ではそれを行うことができなかった」と言う - アプリケーション マニフェスト ファイルを追加するための [項目の追加] オプションがあり、VS2005 で利用可能です)
  2. exeが64ビットで実行されている場合、デフォルトでオフになっています
  3. インタラクティブなプロセス (サービス、または IIS でホストされているものなど) でない場合はオフです。

上記のいずれにも影響を与える立場になく、これが理想であり、UAC 仮想化が現在のコンテキストに適用されるかどうかを検出したい場合は、最初は関連していないように思われるものに対してこの回答を使用してください。質問。(明らかに、操作している特定のキーに適用するかどうかを決定する必要があります。これは、変更を追跡する必要があるコードを実装したくないことは明らかです。ほとんどの場合、比較的明確なはずです。)

于 2009-08-24T13:06:57.517 に答える
2

thisに従って、キーごとに仮想化を有効/無効にできますが、コマンドラインツールを使用するように指示されます。しかし、プログラムでそれを行う方法が必要です。

マニフェストで requestedExecutionLevel を設定して、アプリの仮想化を完全にオフにするのが最も簡単な場合があります。maximumAvailable を試すことはできますが、それはアプリが常に管理者として実行されることを意味する可能性があります。asInvoker に設定するだけで仮想化がオフになることを暗示しているようです。参照してください。

于 2009-06-16T17:07:27.377 に答える
1

私も同様の問題を抱えていましたが、マニフェストを導入することで解決しました。

私はレジストリセキュリティに依存して、(Win32)アプリケーションが標準ユーザーとして実行されているときにHKLM / Software / Wow6432Nodeでキーを作成しないようにしました。それが成功したのを見て非常に驚きましたが、キーが存在せず、代わりに、この新しいVirtualStoreエリアの下に作成されます。

PEマニフェストにセキュリティに関連する情報が含まれていることが判明すると、レジストリの仮想化はオフになります。特権の昇格を必要としないために、私のマニフェストには次のノードが含まれています。

<trustInfo xmlns:ms_asmv2="urn:schemas-microsoft-com:asm.v2">
   <security>
      <requestedPrivileges>
         <requestedExecutionLevel level="asInvoker">
         </requestedExecutionLevel>
      </requestedPrivileges>
   </security>
</trustInfo>

実行可能ファイルがVistaおよびXPと互換性を持つためには、TrustInfoセクションの各ノードに名前空間が含まれている必要があります。

<ms_asmv2:trustInfo xmlns:ms_asmv2="urn:schemas-microsoft-com:asm.v2">
   <ms_asmv2:security>
      <ms_asmv2:requestedPrivileges>
         <ms_asmv2:requestedExecutionLevel level="asInvoker">
         </ms_asmv2:requestedExecutionLevel>
      </ms_asmv2:requestedPrivileges>
   </ms_asmv2:security>
</ms_asmv2:trustInfo>

マニフェストが.exeに正しく埋め込まれると(プロジェクトの適切なプロパティを変更することで数回の試行が必要になりました)、プログラムはついに期待どおりに失敗しました。

マネージコードの場合、mt.exeツールを実行することにより、マニフェストをビルド後の手順として含めることができます。たとえば、MSDNの記事で報告されているように

mt.exe –manifest YourFile.manifest –outputresource:YourApp.exe;#1

この記事で説明されているように、reg.exeを使用してレジストリノードのフラグを変更するよりも、マニフェストアプローチを使用する方が好きです。これにより、すべてのマシンで動作が一貫するようになります。

お役に立てば幸いです(元の投稿の日付を読んだ後でも、問題はずっと前に解決されたと確信しています!!)

アルベルト

于 2011-12-21T10:59:06.503 に答える
1

HKCRは仮想化されたストア自体であり、 と の組み合わせであることにHKLM\Software\Classes注意してくださいHKCU\Software\Classes

最善の方法は、レジストリの仮想化さえ行わないことです。最初に、ユーザーが実行時に昇格されていることを確認してから、変更を開始する前に、変更が現在のユーザーにのみ適用されることをユーザーに通知できます。

最初に昇格された管理者であるかどうかを検出することで、HKLM が仮想化されるときに HKLM への書き込みを簡単に回避できます。

例:

private bool IsAdministrator
{
    get
    {
        WindowsIdentity wi = WindowsIdentity.GetCurrent();
        WindowsPrincipal wp = new WindowsPrincipal(wi);

        return wp.IsInRole(WindowsBuiltInRole.Administrator);
    }
}

注:私は C# でコーディングしていません。例は質問から削除されています。プロセスが UAC で昇格されているかどうかを検出するにはどうすればよいですか?

于 2009-06-17T03:54:32.680 に答える