2つの同一のファイルの違いを検索(そして発見)したとき

プラグインをロードして使用できる.NETアプリケーションが1つあります。 プラグインは良いことです。 機能を拡張したり、サイトからそれらをすばやく更新したり、ユーザーにSDKを提供してプラグインを作成したりすることもできます。 これをすべてやった。 プラグインは通常の.NETアセンブリであり、メインアプリケーションがダウンロードして使用する特定のフォルダーにスローする必要がありました。 おそらく、 Assembly.Load()の方法を想像してから、必要なインターフェイスを実装するクラスを探し、このクラスのオブジェクトを作成するなど。 これらはすべて、長い間着実に機能し、トラブルを引き起こすものは何もありませんでした。 しかし、突然、いくつかのファイルで構成されるプラグインを作成する必要がありました。 この点で、プラグインは.NETアセンブリ(1ファイル)だけでなく、1つのアセンブリまたは複数のファイルが存在するzipアーカイブを考慮することが決定されました。 この点で、ビルドサーバーにプラグインをアーカイブにパックすることと、メインアプリケーションが適切な場所に解凍することを教える必要がありました。 一般に、タスクは10行のコードです。 病気の前兆はありません。 そして今、ビルドサーバーからプラグインを使用してアセンブルされたアーカイブをダウンロードし、目的のフォルダーに解凍し、アプリケーションを起動すると、...動作しません! やめて、どうしてうまくいかないの? これは同じプラグインです!



もっともっと。 私は同僚に彼のコンピューターで同じ手順を実行するよう依頼します。 彼は試みます-そして、すべてが彼のために働きます! しかし、どのように? アプリケーションの1つのバージョン、ビルドサーバーからの同じファイル。 環境に違いはありますか? 同僚のコンピューターに座って、もう一度試してください-うまくいきません! この時点で彼は私のものに挑戦しています-それは動作します! つまり、ファイルは解凍したファイルを「記憶」していることがわかります。 3人目の同僚にこのサーカスを見てもらいます。 一貫して、同じコンピューターで同じアクションを交互に実行します。プラグインでアーカイブをダウンロードし、目的のフォルダーに解凍し、アプリケーションを起動します。 これを行うと、プログラムはプラグインを表示せず、同僚がそれを実行すると、すべてが機能します。 これらの興味深い実験の第3ラウンドでは、アクションの違いに突然気付きました。標準のWindowsツールを使用してプラグインを解凍し、同僚は7-Zipを使用して解凍しました。 どちらもアーカイブのコンテキストメニューから呼び出されたため、最初は間違ったアイテムをクリックした場合の違いに誰も気付きませんでした。 大丈夫。 7-zipを使用してzipアーカイブから抽出されたファイルは、標準のWindowsアーカイバーを使用して抽出された同じアーカイブの同じファイルとは異なることがわかりました。



ところで、7-zipを解凍してWindowsエクスプローラーを使用して有効なzipアーカイブのファイルの内容が異なる可能性はありますか?



さて、WinMergeを使用してファイルを推測して比較しないでください。







ファイルは同じであり、等しくロードして処理する必要があることがわかりますか? どんなに! WinMergeは嘘をついています。 ファイルは異なります。 また、さまざまな方法で.NETがロードされます。



そして今、ひどい真実があるでしょう


インターネットからファイルをダウンロードする場合、Windowsはファイルに特別な「フラグ」を付けて、ダウンロード元のサイトに対応する信頼ゾーンを示します。 ダウンロードしたばかりの実行可能ファイルを実行しようとすると、多くの人がそれを実行する価値がないかもしれないと思ったと思います。 セキュリティポリシーとファイルの作成元に応じて、これらの警告の妄想のレベルは、完全な不在(管理者の下での作業、UACの無効化、ファイルの署名)から起動のブロック(企業環境、署名のないファイル)までさまざまです。 「はい、実行します」と1回または数回言わなければならない中間段階がいくつかあります。 しかし、これはすべてexeファイルでのみ機能しますか? いや! このフラグは、インターネットからダウンロードされたdllファイルまたはアーカイブにもハングアップします! 技術的な観点からは、代替NTFSファイルストリームであり、 AlternateStreamViewユーティリティまたはコマンドを使用して表示できます。



more < Plugin.dll:Zone.Identifier
      
      





そして、ここでは次の状況の組み合わせがあります。



  1. ロード時に、ブラウザはダウンロードされたアーカイブ用の代替ファイルストリーム「Zone.Identifier」を作成し、そこにファイルの送信元のゾーンのIDを書き込みます。
  2. 標準のWindowsエクスプローラアーカイバを解凍すると、メインファイルストリームだけでなく、代替ファイルストリームも読み取り、抽出された各ファイルに追加します。 (7-Zipはサポートしていません)。
  3. WinMergeユーティリティは、メインファイルストリームのみを比較し、7-ZipとExplorerによって作成されたファイルは同一であると言います。
  4. .NETでは、 Assembly.Load()メソッドも代替ファイルストリームを読み取り、信頼性が低下したゾーン識別子を見つけ、ファイルのダウンロードを拒否します。 同時に、信頼されていないアプリケーションの起動を確認するリクエストをユーザーに知っているメッセージは表示されず、バグが発生します。


この問題に対処するのは非常に簡単です-このファイルストリームをチェックして削除する必要があります。 Windowsでは、このためにファイルプロパティを呼び出し、そこでブロック解除ボタンをクリックすることができます(まあ、またはプログラムで行う)。







アーカイブからファイルを抽出する前にアーカイブに対してこれを行うと、その後抽出されるすべてのファイルのゾーン識別子が消えます。



おそらく私はここで些細で有名なことを話しましたが、異なるアーカイバが同じアーカイブから異なるファイルを抽出することができ、さらに非常に巧妙に異なるため、WinMergeはこの違いを認識しませんが、.NETは個人的にそれを認識しますそれは私にとって興味深い発見でした。



All Articles