2

1つの小さな.exeと3つの小さな.Dllで構成される.net4で実行されている小さなテストソリューションに基づいてDLLをリベースして実験しています。アセンブリ参照は正しく設定されており、プログラムは正常にコンパイルおよび実行されます。

この演習の目的は、リベースがどのように機能するかを調べて、それをngenと結び付け、作業中の大規模なプロジェクトでパフォーマンスを向上させることです。

Dllをリベースするさまざまな方法を試し、VisualStudioモジュールデバッガウィンドウおよびプロセスエクスプローラーであるvmmapを使用して結果を監視しました。これまでのところ成功したものはありません。

  1. Dll1.dll、Dll2.dll、Dll3.dllの[ビルド]->[詳細設定]->[DLLベースアドレス]設定をそれぞれ0x41000000、0x42000000、0x43000000に設定しました。これらのアドレスは、各DLLの優先ベースアドレスとして確実に保存されましたが、実行ごとに、DLLはイメージをメモリ内のさまざまな場所に不規則にリベースしました。

  2. このアプリケーションを使ってみました。それが生成するログは、DLLが実際に(私が選択した)優先ベースアドレスを組み込んでいることを示していますが、実行時の結果は依然として不安定です

  3. ngenを使ってみました。これにより、.niバージョンのDLLが元のDLLと一緒にロードされ、6つすべてのDLLのメモリ位置が、私が要求したものの近くに不規則になります。

  4. GACに画像を貼り付けてみました。DllのGACバージョンのみがロードされたのを見るのは心強いものでしたが、それらのメモリ位置は依然として不安定でした。

  5. 私は上記のすべての組み合わせのように感じるものを試しました。失敗。

VMMapを使用して実行時に調べてみると、0x10000000と0x50000000の間のアドレス空間に使用可能なメモリの大きなギャップがあることがわかります。したがって、衝突やDLLリベースの必要はありません。DLLも非常に小さく、それらの間に残している0x01000000のギャップは非常に大きいため、互いに衝突しないようにする必要があります。

私は何が欠けていますか?

この演習での私の主な参考資料は、非常に有益なこの記事ですが、2006年に.Net2用に作成されました。当時と現在の間に何か根本的な変化がありましたか?

私はそれが大きな違いを生むことを真剣に疑っていますが、念のために使用しているコードは次のとおりです。

Program.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using Dll1;
using Dll2;
using Dll3;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Thread.CurrentThread.Name = "Poodle";
            Console.ReadLine();
            //Thread.Sleep(10000);
            Blah();
        }

        static void Blah()
        {
            Console.WriteLine(Class2.shrooms(5, 'h'));
            Class3.teenAngst();
            Class1.Wait();
        }
    }
}

Class1.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Dll1
{
    public static class Class1
    {
        public static void Wait()
        {
            Console.ReadLine();
            Console.Write("   ");
        }
    }
}

Class2.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Dll2
{
    public static class Class2
    {
        public static string shrooms(int argc, char argv) 
        {
            return "Ranchdaddyx   ";
        }
    }
}

Class3.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Dll3
{
    public static class Class3
    {
        public static void teenAngst()
        {
            Console.Write("Belonging   ");
        }
    }
}
4

3 に答える 3

4

JITコンパイル済みコードをリベースする必要はありません。

JITでコンパイルされたコードには、コードがメモリ内のどこに配置されているかに基づいて実行時にアドレスが生成されるため、リベースの問題はありません。また、MSIL参照はアドレスベースではなくトークンベースであるため、MSILがベースアドレスミスの影響を受けることはめったにありません。したがって、JITコンパイラを使用すると、システムはベースアドレスの衝突に対して回復力があります。

.NETアセンブリとDLLリベース

DLLをリベースしたい場合、どうすればそれを実行できますか?

http://msdn.microsoft.com/en-us/magazine/cc163610.aspx

http://support.microsoft.com/kb/969305

于 2011-09-12T02:07:32.953 に答える
2

ASLR(アドレス空間配置のランダム化)が私の混乱の原因であることがわかりました。どうやらあなたはそれをオフにすることができます、しかしあなたは安全を犠牲にしている/あなた自身のためにたくさんの仕事をしています。私は冒険全体を失敗した実験だと考えています。

于 2011-12-08T09:04:33.927 に答える
1

.Net .dllは、管理されていない同等の獣とは大きく異なります。正直なところ、リベースが適切だとは思いませんでした。

このMSDNの記事を確認してください。これは、とりわけ、リベースしないように促します。そして、少なくとも1つの説得力のある理由を示します(強く署名されたアセンブリの署名を無効にする可能性があります)。この記事では、NGENの潜在的な利点についても説明しています(リンクも同様です)。

CLR裏返し

于 2011-09-12T01:59:41.080 に答える