İzlenecek yol: Kısmi Güven Senaryolarında Kod Yayma

Yansıma yayma tam veya kısmi güven içinde aynı API kümesini kullanır, ancak bazı özellikler kısmen güvenilen kodda özel izinler gerektirir. Buna ek olarak, yansıma yayma özelliğine sahiptir, anonim olarak barındırılan dinamik yöntemler, kısmi güven ve güvenlik saydam derlemeler tarafından kullanılmak üzere tasarlanmıştır.

Not

.NET Framework 3.5'e geçmeden önce, bayrağıyla gerekli ReflectionPermission kodu yaymaReflectionPermissionFlag.ReflectionEmit. Bu izin varsayılan olarak FullTrust ve Intranet adlandırılmış izin kümelerine dahil edilir, ancak izin kümesine Internet eklenmez. Bu nedenle, bir kitaplık kısmi güvenden yalnızca özniteliğine sahipse SecurityCriticalAttribute ve için ReflectionEmitbir Assert yöntem yürüttüyse kullanılabilir. Kodlama hataları güvenlik açıklarına neden olabileceği için bu tür kitaplıklar dikkatli bir güvenlik incelemesi gerektirir. .NET Framework 3.5 kodun kısmi güven senaryolarında herhangi bir güvenlik talebi olmadan dağıtılmasını sağlar, çünkü kod oluşturmak doğal olarak ayrıcalıklı bir işlem değildir. Başka bir ifadeyle, oluşturulan kodun onu yayan derlemeden daha fazla izni yoktur. Bu, kod yayan kitaplıkların güvenlik saydam olmasını sağlar ve güvenli bir kitaplık yazmanın bu kadar kapsamlı bir güvenlik incelemesi gerektirmemesi için onaylama ReflectionEmitgereksinimini ortadan kaldırır.

Bu izlenecek yol aşağıdaki görevleri gösterir:

Kısmi güven senaryolarında kod yayma hakkında daha fazla bilgi için bkz. Yansıma Yaymada Güvenlik Sorunları.

Bu yordamlarda gösterilen kodun tam listesi için bu kılavuzun sonundaki Örnek bölümüne bakın.

Kısmen Güvenilen Konumları Ayarlama

Aşağıdaki iki yordamda kodu kısmi güvenle test etmek için kullanabileceğiniz konumların nasıl ayarlanacağı gösterilir.

  • İlk yordamda, koda İnternet izinleri verilen korumalı bir uygulama etki alanının nasıl oluşturulacağı gösterilmektedir.

  • İkinci yordam, eşit veya daha az güven derlemelerinde özel verilere erişimi etkinleştirmek için kısmen güvenilen bir uygulama etki alanına bayrağıyla ReflectionPermissionFlag.RestrictedMemberAccess nasıl ekleneceğini ReflectionPermission gösterir.

Korumalı Uygulama Etki Alanları Oluşturma

Derlemelerinizin kısmi güvenle çalıştığı bir uygulama etki alanı oluşturmak için, uygulama etki alanını oluşturmak için yöntem aşırı yüklemesini AppDomain.CreateDomain(String, Evidence, AppDomainSetup, PermissionSet, StrongName[]) kullanarak derlemelere verilecek izin kümesini belirtmeniz gerekir. İzin kümesini belirtmenin en kolay yolu, güvenlik ilkesinden adlandırılmış bir izin kümesi almaktır.

Aşağıdaki yordam, kodun yalnızca ortak türlerdeki genel üyelere erişebildiği senaryoları test etmek için kodunuzu kısmi güvenle çalıştıran korumalı bir uygulama etki alanı oluşturur. Sonraki yordam, yayılan kodun eşit veya daha az izin verilen derlemelerdeki abonelik dışı türlere ve üyelere erişebildiği senaryoları test etmek için öğesinin nasıl ekleneceğini RestrictedMemberAccessgösterir.

Kısmi güvene sahip bir uygulama etki alanı oluşturmak için

  1. Korumalı uygulama etki alanındaki derlemelere vermek için bir izin kümesi oluşturun. Bu durumda, İnternet bölgesinin izin kümesi kullanılır.

    Evidence ev = new Evidence();
    ev.AddHostEvidence(new Zone(SecurityZone.Internet));
    PermissionSet pset = new NamedPermissionSet("Internet", SecurityManager.GetStandardSandbox(ev));
    
    Dim ev As New Evidence()
    ev.AddHostEvidence(new Zone(SecurityZone.Internet))
    Dim pset As New NamedPermissionSet("Internet", SecurityManager.GetStandardSandbox(ev))
    
  2. Uygulama etki alanını bir AppDomainSetup uygulama yolu ile başlatmak için bir nesne oluşturun.

    Önemli

    Kolaylık olması için bu kod örneği geçerli klasörü kullanır. İnternet'ten gelen kodu çalıştırmak için, Nasıl yapılır: Korumalı Alanda Kısmen Güvenilen Kod Çalıştırma bölümünde açıklandığı gibi güvenilmeyen kod için ayrı bir klasör kullanın.

    AppDomainSetup adSetup = new AppDomainSetup();
    adSetup.ApplicationBase = ".";
    
    Dim adSetup As New AppDomainSetup()
    adSetup.ApplicationBase = "."
    
  3. Uygulama etki alanı kurulum bilgilerini ve uygulama etki alanında yürütülen tüm derlemeler için izin kümesini belirterek uygulama etki alanını oluşturun.

    AppDomain ad = AppDomain.CreateDomain("Sandbox", ev, adSetup, pset, null);
    
    Dim ad As AppDomain = AppDomain.CreateDomain("Sandbox", ev, adSetup, pset, Nothing)
    

    Yöntem aşırı yüklemesinin AppDomain.CreateDomain(String, Evidence, AppDomainSetup, PermissionSet, StrongName[]) son parametresi, uygulama etki alanının izin kümesi yerine tam güven verilecek bir derleme kümesi belirtmenizi sağlar. Uygulamanızın kullandığı .NET Framework derlemelerini belirtmeniz gerekmez, çünkü bu derlemeler genel derleme önbelleğindedir. Genel bütünleştirilmiş kod önbelleğindeki derlemelere her zaman tam olarak güvenilir. Bu parametreyi, genel derleme önbelleğinde olmayan tanımlayıcı adlı derlemeleri belirtmek için kullanabilirsiniz.

Korumalı Etki Alanlarına RestrictedMemberAccess Ekleme

Konak uygulamaları, anonim olarak barındırılan dinamik yöntemlerin kodu yayan derlemenin güven düzeyine eşit veya ondan küçük güven düzeylerine sahip derlemelerdeki özel verilere erişmesine izin verebilir. Bu kısıtlı özelliğin tam zamanında (JIT) görünürlük denetimlerini atlamayı etkinleştirmek için, konak uygulaması verme kümesine (RMA) bayrağı olan ReflectionPermissionFlag.RestrictedMemberAccess bir ReflectionPermission nesne ekler.

Örneğin, bir ana bilgisayar İnternet uygulamalarına İnternet izinleri ve RMA verebilir, böylece bir İnternet uygulaması kendi derlemelerindeki özel verilere erişen kodu yayabilir. Erişim, eşit veya daha az güven derlemeleriyle sınırlı olduğundan, İnternet uygulaması .NET Framework derlemeleri gibi tam olarak güvenilen derlemelerin üyelerine erişemez.

Not

Ayrıcalıkların yükseltilmesini önlemek için, anonim olarak barındırılan dinamik yöntemler oluşturulduğunda yayma derlemesi için yığın bilgileri eklenir. yöntemi çağrıldığında yığın bilgileri denetlener. Bu nedenle, tam olarak güvenilen koddan çağrılan anonim olarak barındırılan dinamik yöntem yine de yayan derlemenin güven düzeyiyle sınırlıdır.

Kısmi güven artı RMA ile bir uygulama etki alanı oluşturmak için

  1. (RMA) bayrağıyla RestrictedMemberAccess yeni ReflectionPermission bir nesne oluşturun ve izni verme kümesine eklemek için yöntemini kullanınPermissionSet.SetPermission.

    pset.SetPermission(
        new ReflectionPermission(
            ReflectionPermissionFlag.RestrictedMemberAccess));
    
    pset.SetPermission( _
        New ReflectionPermission( _
            ReflectionPermissionFlag.RestrictedMemberAccess))
    

    AddPermission yöntemi, önceden dahil edilmediyse izni verme kümesine ekler. İzin, izin kümesine zaten eklenmişse, belirtilen bayraklar var olan izne eklenir.

    Not

    RMA, anonim olarak barındırılan dinamik yöntemlerin bir özelliğidir. Sıradan dinamik yöntemler JIT görünürlük denetimlerini atladığında, yayılan kod tam güven gerektirir.

  2. Uygulama etki alanı kurulum bilgilerini ve izin kümesini belirterek uygulama etki alanını oluşturun.

    ad = AppDomain.CreateDomain("Sandbox2", ev, adSetup, pset, null);
    
    ad = AppDomain.CreateDomain("Sandbox2", ev, adSetup, pset, Nothing)
    

Korumalı Uygulama Etki Alanlarında Kod Çalıştırma

Aşağıdaki yordamda, bir uygulama etki alanında yürütülebilen yöntemleri kullanarak bir sınıfın nasıl tanımlanacağı, etki alanında sınıfın bir örneğinin nasıl oluşturulacağı ve yöntemlerinin nasıl yürütülebileceği açıklanmaktadır.

Uygulama etki alanında yöntem tanımlamak ve yürütmek için

  1. öğesinden MarshalByRefObjecttüretilen bir sınıf tanımlayın. Bu, sınıfın örneklerini diğer uygulama etki alanlarında oluşturmanıza ve uygulama etki alanı sınırları arasında yöntem çağrıları yapmanıza olanak tanır. Bu örnekteki sınıf olarak adlandırılır Worker.

    public class Worker : MarshalByRefObject
    {
    
    Public Class Worker
        Inherits MarshalByRefObject
    
  2. Yürütmek istediğiniz kodu içeren bir ortak yöntem tanımlayın. Bu örnekte kod basit bir dinamik yöntem yayar, yöntemi yürütmek için bir temsilci oluşturur ve temsilciyi çağırır.

    public void SimpleEmitDemo()
    {
        DynamicMethod meth = new DynamicMethod("", null, null);
        ILGenerator il = meth.GetILGenerator();
        il.EmitWriteLine("Hello, World!");
        il.Emit(OpCodes.Ret);
    
        Test1 t1 = (Test1) meth.CreateDelegate(typeof(Test1));
        t1();
    }
    
    Public Sub SimpleEmitDemo()
    
        Dim meth As DynamicMethod = new DynamicMethod("", Nothing, Nothing)
        Dim il As ILGenerator = meth.GetILGenerator()
        il.EmitWriteLine("Hello, World!")
        il.Emit(OpCodes.Ret)
    
        Dim t1 As Test1 = CType(meth.CreateDelegate(GetType(Test1)), Test1)
        t1()
    End Sub
    
  3. Ana programınızda derlemenizin görünen adını alın. Bu ad, korumalı uygulama etki alanında sınıfın Worker örneklerini oluştururken kullanılır.

    String asmName = typeof(Worker).Assembly.FullName;
    
    Dim asmName As String = GetType(Worker).Assembly.FullName
    
  4. Ana programınızda, bu kılavuzdaki ilk yordamda açıklandığı gibi korumalı bir uygulama etki alanı oluşturun. yöntem yalnızca genel yöntemleri kullandığından Internet , izin kümesine SimpleEmitDemo herhangi bir izin eklemeniz gerekmez.

  5. Ana programınızda korumalı uygulama etki alanında sınıfının bir örneğini Worker oluşturun.

    Worker w = (Worker) ad.CreateInstanceAndUnwrap(asmName, "Worker");
    
    Dim w As Worker = _
        CType(ad.CreateInstanceAndUnwrap(asmName, "Worker"), Worker)
    

    CreateInstanceAndUnwrap yöntemi, hedef uygulama etki alanında nesnesini oluşturur ve nesnenin özelliklerini ve yöntemlerini çağırmak için kullanılabilecek bir ara sunucu döndürür.

    Not

    Bu kodu Visual Studio'da kullanıyorsanız, sınıfın adını ad alanını içerecek şekilde değiştirmeniz gerekir. Ad alanı varsayılan olarak projenin adıdır. Örneğin, proje "PartialTrust" ise, sınıf adı "PartialTrust.Worker" olmalıdır.

  6. yöntemini çağırmak SimpleEmitDemo için kod ekleyin. Çağrı, uygulama etki alanı sınırı boyunca oluşturulur ve kod korumalı uygulama etki alanında yürütülür.

    w.SimpleEmitDemo();
    
    w.SimpleEmitDemo()
    

Anonim Olarak Barındırılan Dinamik Yöntemleri Kullanma

Anonim olarak barındırılan dinamik yöntemler, sistem tarafından sağlanan saydam bir derlemeyle ilişkilendirilir. Bu nedenle, içerdikleri kod saydamdır. Diğer yandan, normal dinamik yöntemlerin mevcut bir modülle ilişkilendirilmesi (doğrudan belirtilen veya ilişkili bir türden çıkarsanmalı) ve güvenlik düzeyini bu modülden alması gerekir.

Not

Dinamik bir yöntemi anonim barındırma sağlayan derlemeyle ilişkilendirmenin tek yolu, aşağıdaki yordamda açıklanan oluşturucuları kullanmaktır. Anonim barındırma derlemesinde açıkça bir modül belirtemezsiniz.

Sıradan dinamik yöntemler, ilişkili oldukları modülün iç üyelerine veya ilişkili oldukları türün özel üyelerine erişebilir. Anonim olarak barındırılan dinamik yöntemler diğer kodlardan yalıtıldığından, özel verilere erişimi yoktur. Ancak, özel verilere erişim elde etmek için JIT görünürlük denetimlerini atlayabilirler. Bu özellik, kodu yayan derlemenin güven düzeyine eşit veya ondan küçük güven düzeylerine sahip derlemelerle sınırlıdır.

Ayrıcalıkların yükseltilmesini önlemek için, anonim olarak barındırılan dinamik yöntemler oluşturulduğunda yayma derlemesi için yığın bilgileri eklenir. yöntemi çağrıldığında yığın bilgileri denetlener. Tam olarak güvenilen koddan çağrılan anonim olarak barındırılan dinamik yöntem, yine de onu gösteren derlemenin güven düzeyiyle sınırlıdır.

Anonim olarak barındırılan dinamik yöntemleri kullanmak için

  • İlişkili bir modül veya tür belirtmeyen bir oluşturucu kullanarak anonim olarak barındırılan bir dinamik yöntem oluşturun.

    DynamicMethod meth = new DynamicMethod("", null, null);
    ILGenerator il = meth.GetILGenerator();
    il.EmitWriteLine("Hello, World!");
    il.Emit(OpCodes.Ret);
    
    Dim meth As DynamicMethod = new DynamicMethod("", Nothing, Nothing)
    Dim il As ILGenerator = meth.GetILGenerator()
    il.EmitWriteLine("Hello, World!")
    il.Emit(OpCodes.Ret)
    

    Anonim olarak barındırılan bir dinamik yöntem yalnızca genel türleri ve yöntemleri kullanıyorsa, kısıtlı üye erişimi gerektirmez ve JIT görünürlük denetimlerini atlar.

    Dinamik bir yöntem yaymak için özel izin gerekmez, ancak yayılan kod, kullandığı türler ve yöntemler tarafından istenen izinleri gerektirir. Örneğin, yayılan kod bir dosyaya erişen bir yöntemi çağırırsa, gerektirir FileIOPermission. Güven düzeyi bu izni içermiyorsa, yayılan kod yürütürken bir güvenlik özel durumu oluşturulur. Burada gösterilen kod, yalnızca Console.WriteLine yöntemini kullanan dinamik bir yöntem yayar. Bu nedenle, kod kısmen güvenilen konumlardan yürütülebilir.

  • Alternatif olarak, oluşturucuyu kullanarak ve parametresini belirterek JIT görünürlük denetimlerini atlamayı kısıtlayan true anonim olarak barındırılan DynamicMethod(String, Type, Type[], Boolean)restrictedSkipVisibility bir dinamik yöntem oluşturun.

    DynamicMethod meth = new DynamicMethod("",
                                           typeof(char),
                                           new Type[] { typeof(String) },
                                           true);
    
    Dim meth As New DynamicMethod("", _
                                  GetType(Char), _
                                  New Type() {GetType(String)}, _
                                  True)
    

    Kısıtlama, anonim olarak barındırılan dinamik yöntemin özel verilere yalnızca yayan derlemenin güven düzeyine eşit veya ondan küçük güven düzeylerine sahip derlemelerde erişebilmesidir. Örneğin, dinamik yöntem İnternet güveni ile yürütülüyorsa, aynı zamanda İnternet güveni ile yürütülen diğer derlemelerdeki özel verilere erişebilir, ancak .NET Framework derlemelerin özel verilerine erişemez. .NET Framework derlemeler genel bütünleştirilmiş kod önbelleğine yüklenir ve her zaman tam olarak güvenilir.

    Anonim olarak barındırılan dinamik yöntemler, yalnızca ana bilgisayar uygulaması bayrağını ReflectionPermissionFlag.RestrictedMemberAccess verirse JIT görünürlük denetimlerini ReflectionPermission atlamak için bu kısıtlı özelliği kullanabilir. Yöntem çağrıldığında bu izin için talep yapılır.

    Not

    Dinamik yöntem oluşturulduğunda yayma derlemesi için çağrı yığını bilgileri eklenir. Bu nedenle talep, yöntemini çağıran derleme yerine yayan derlemenin izinlerine karşı yapılır. Bu, gösterilen kodun yükseltilmiş izinlerle yürütülmesini engeller.

    Bu kılavuzun sonundaki tam kod örneği , kısıtlı üye erişiminin kullanımını ve sınırlamalarını gösterir. sınıfı Worker , görünürlük denetimlerini atlamayı kısıtlayan veya olmayan anonim olarak barındırılan dinamik yöntemler oluşturabilen bir yöntem içerir ve örnek, bu yöntemin farklı güven düzeylerine sahip uygulama etki alanlarında yürütülmesinin sonucunu gösterir.

    Not

    Görünürlük denetimlerini atlamayı kısıtlayan özellik, anonim olarak barındırılan dinamik yöntemlerin bir özelliğidir. Sıradan dinamik yöntemler JIT görünürlük denetimlerini atladığında, bunlara tam güven verilmelidir.

Örnek

Description

Aşağıdaki kod örneği, anonim olarak barındırılan dinamik yöntemlerin RestrictedMemberAccess JIT görünürlük denetimlerini atmasına izin vermek için bayrağının kullanımını gösterir, ancak yalnızca hedef üye kodu yayan derlemeden eşit veya daha düşük bir güven düzeyinde olduğunda.

Örnek, uygulama etki alanı sınırları arasında sıralanabilir bir Worker sınıf tanımlar. sınıfı dinamik yöntemleri yayan ve yürüten iki AccessPrivateMethod yöntem aşırı yüküne sahiptir. İlk aşırı yükleme, sınıfın özel PrivateMethod yöntemini çağıran dinamik bir yöntem Worker yayar ve dinamik yöntemi JIT görünürlük denetimleriyle veya olmadan yayar. İkinci aşırı yükleme, sınıfın bir özelliğine (FriendVisual Basic'teki özellik) String erişen dinamik bir internal yöntem yayar.

Örnek, izinlerle sınırlı Internet bir izin kümesi oluşturmak için bir yardımcı yöntem kullanır ve ardından etki alanında yürütülen tüm kodların bu izin kümesini kullandığını belirtmek için yöntem aşırı yüklemesini kullanarak AppDomain.CreateDomain(String, Evidence, AppDomainSetup, PermissionSet, StrongName[]) bir uygulama etki alanı oluşturur. Örnek, uygulama etki alanında sınıfının bir örneğini Worker oluşturur ve yöntemini iki kez yürütür AccessPrivateMethod .

  • Yöntem ilk kez AccessPrivateMethod yürütülürken JIT görünürlük denetimleri zorlanır. JIT görünürlük denetimleri özel yönteme erişmesini engellediğinden, dinamik yöntem çağrıldığında başarısız olur.

  • Yöntem ikinci kez AccessPrivateMethod yürütülürken JIT görünürlük denetimleri atlanır. İzin kümesi görünürlük denetimlerini atlamak için yeterli izinleri vermediğinden dinamik yöntem derlendiğinde Internet başarısız olur.

Örnek, grant kümesine ile ekler ReflectionPermissionReflectionPermissionFlag.RestrictedMemberAccess . Örnek daha sonra ikinci bir etki alanı oluşturur ve etki alanında yürütülen tüm koda yeni izin kümesindeki izinlerin verildiğini belirtir. Örnek, yeni uygulama etki alanında sınıfının bir örneğini Worker oluşturur ve yönteminin her iki aşırı yüklemesini AccessPrivateMethod de yürütür.

  • Yöntemin AccessPrivateMethod ilk aşırı yüklemesi yürütülür ve JIT görünürlük denetimleri atlanır. Kodu yayan derleme, özel yöntemi içeren derlemeyle aynı olduğundan dinamik yöntem başarıyla derlenip yürütülür. Bu nedenle, güven düzeyleri eşittir. sınıfını Worker içeren uygulamanın birkaç derlemesi varsa, aynı işlem bu derlemelerin herhangi biri için başarılı olur çünkü hepsi aynı güven düzeyinde olur.

  • Yöntemin AccessPrivateMethod ikinci aşırı yüklemesi yürütülür ve yine JIT görünürlük denetimleri atlanır. Bu kez dinamik yöntem, sınıfının özelliğine String erişmeye çalıştığından internalFirstChar derlendiğinde başarısız olur. sınıfını String içeren derlemeye tam olarak güvenilir. Bu nedenle, kodu yayan derlemeden daha yüksek bir güven düzeyindedir.

Bu karşılaştırma, kısmen güvenilen kodun, güvenilen kodun güvenliğinden ödün vermeden diğer kısmen güvenilen kodlar için görünürlük denetimlerini atlamayı nasıl ReflectionPermissionFlag.RestrictedMemberAccess sağladığını gösterir.

Kod

using System;
using System.Reflection.Emit;
using System.Reflection;
using System.Security;
using System.Security.Permissions;
using System.Security.Policy;
using System.Collections;
using System.Diagnostics;

// This code example works properly only if it is run from a fully
// trusted location, such as your local computer.

// Delegates used to execute the dynamic methods.
//
public delegate void Test(Worker w);
public delegate void Test1();
public delegate char Test2(String instance);

// The Worker class must inherit MarshalByRefObject so that its public
// methods can be invoked across application domain boundaries.
//
public class Worker : MarshalByRefObject
{
    private void PrivateMethod()
    {
        Console.WriteLine("Worker.PrivateMethod()");
    }

    public void SimpleEmitDemo()
    {
        DynamicMethod meth = new DynamicMethod("", null, null);
        ILGenerator il = meth.GetILGenerator();
        il.EmitWriteLine("Hello, World!");
        il.Emit(OpCodes.Ret);

        Test1 t1 = (Test1) meth.CreateDelegate(typeof(Test1));
        t1();
    }

    // This overload of AccessPrivateMethod emits a dynamic method and
    // specifies whether to skip JIT visiblity checks. It creates a
    // delegate for the method and invokes the delegate. The dynamic
    // method calls a private method of the Worker class.
    public void AccessPrivateMethod(bool restrictedSkipVisibility)
    {
        // Create an unnamed dynamic method that has no return type,
        // takes one parameter of type Worker, and optionally skips JIT
        // visiblity checks.
        DynamicMethod meth = new DynamicMethod(
            "",
            null,
            new Type[] { typeof(Worker) },
            restrictedSkipVisibility);

        // Get a MethodInfo for the private method.
        MethodInfo pvtMeth = typeof(Worker).GetMethod("PrivateMethod",
            BindingFlags.NonPublic | BindingFlags.Instance);

        // Get an ILGenerator and emit a body for the dynamic method.
        ILGenerator il = meth.GetILGenerator();

        // Load the first argument, which is the target instance, onto the
        // execution stack, call the private method, and return.
        il.Emit(OpCodes.Ldarg_0);
        il.EmitCall(OpCodes.Call, pvtMeth, null);
        il.Emit(OpCodes.Ret);

        // Create a delegate that represents the dynamic method, and
        // invoke it.
        try
        {
            Test t = (Test) meth.CreateDelegate(typeof(Test));
            try
            {
                t(this);
            }
            catch (Exception ex)
            {
                Console.WriteLine("{0} was thrown when the delegate was invoked.",
                    ex.GetType().Name);
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("{0} was thrown when the delegate was compiled.",
                ex.GetType().Name);
        }
    }

    // This overload of AccessPrivateMethod emits a dynamic method that takes
    // a string and returns the first character, using a private field of the
    // String class. The dynamic method skips JIT visiblity checks.
    public void AccessPrivateMethod()
    {
        DynamicMethod meth = new DynamicMethod("",
                                               typeof(char),
                                               new Type[] { typeof(String) },
                                               true);

        // Get a MethodInfo for the 'get' accessor of the private property.
        PropertyInfo pi = typeof(System.String).GetProperty(
            "FirstChar",
            BindingFlags.NonPublic | BindingFlags.Instance);
        MethodInfo pvtMeth = pi.GetGetMethod(true);

        // Get an ILGenerator and emit a body for the dynamic method.
        ILGenerator il = meth.GetILGenerator();

        // Load the first argument, which is the target string, onto the
        // execution stack, call the 'get' accessor to put the result onto
        // the execution stack, and return.
        il.Emit(OpCodes.Ldarg_0);
        il.EmitCall(OpCodes.Call, pvtMeth, null);
        il.Emit(OpCodes.Ret);

        // Create a delegate that represents the dynamic method, and
        // invoke it.
        try
        {
            Test2 t = (Test2) meth.CreateDelegate(typeof(Test2));
            char first = t("Hello, World!");
            Console.WriteLine("{0} is the first character.", first);
        }
        catch (Exception ex)
        {
            Console.WriteLine("{0} was thrown when the delegate was compiled.",
                ex.GetType().Name);
        }
    }

    // The entry point for the code example.
    static void Main()
    {
        // Get the display name of the executing assembly, to use when
        // creating objects to run code in application domains.
        String asmName = typeof(Worker).Assembly.FullName;

        // Create the permission set to grant to other assemblies. In this
        // case they are the permissions found in the Internet zone.
        Evidence ev = new Evidence();
        ev.AddHostEvidence(new Zone(SecurityZone.Internet));
        PermissionSet pset = new NamedPermissionSet("Internet", SecurityManager.GetStandardSandbox(ev));

        // For simplicity, set up the application domain to use the
        // current path as the application folder, so the same executable
        // can be used in both trusted and untrusted scenarios. Normally
        // you would not do this with real untrusted code.
        AppDomainSetup adSetup = new AppDomainSetup();
        adSetup.ApplicationBase = ".";

        // Create an application domain in which all code that executes is
        // granted the permissions of an application run from the Internet.
        AppDomain ad = AppDomain.CreateDomain("Sandbox", ev, adSetup, pset, null);

        // Create an instance of the Worker class in the partially trusted
        // domain. Note: If you build this code example in Visual Studio,
        // you must change the name of the class to include the default
        // namespace, which is the project name. For example, if the project
        // is "AnonymouslyHosted", the class is "AnonymouslyHosted.Worker".
        Worker w = (Worker) ad.CreateInstanceAndUnwrap(asmName, "Worker");

        // Emit a simple dynamic method that prints "Hello, World!"
        w.SimpleEmitDemo();

        // Emit and invoke a dynamic method that calls a private method
        // of Worker, with JIT visibility checks enforced. The call fails
        // when the delegate is invoked.
        w.AccessPrivateMethod(false);

        // Emit and invoke a dynamic method that calls a private method
        // of Worker, skipping JIT visibility checks. The call fails when
        // the method is invoked.
        w.AccessPrivateMethod(true);

        // Unload the application domain. Add RestrictedMemberAccess to the
        // grant set, and use it to create an application domain in which
        // partially trusted code can call private members, as long as the
        // trust level of those members is equal to or lower than the trust
        // level of the partially trusted code.
        AppDomain.Unload(ad);
        pset.SetPermission(
            new ReflectionPermission(
                ReflectionPermissionFlag.RestrictedMemberAccess));
        ad = AppDomain.CreateDomain("Sandbox2", ev, adSetup, pset, null);

        // Create an instance of the Worker class in the partially trusted
        // domain.
        w = (Worker) ad.CreateInstanceAndUnwrap(asmName, "Worker");

        // Again, emit and invoke a dynamic method that calls a private method
        // of Worker, skipping JIT visibility checks. This time compilation
        // succeeds because of the grant for RestrictedMemberAccess.
        w.AccessPrivateMethod(true);

        // Finally, emit and invoke a dynamic method that calls an internal
        // method of the String class. The call fails, because the trust level
        // of the assembly that contains String is higher than the trust level
        // of the assembly that emits the dynamic method.
        w.AccessPrivateMethod();
    }
}

/* This code example produces the following output:

Hello, World!
MethodAccessException was thrown when the delegate was invoked.
MethodAccessException was thrown when the delegate was invoked.
Worker.PrivateMethod()
MethodAccessException was thrown when the delegate was compiled.
 */
Imports System.Reflection.Emit
Imports System.Reflection
Imports System.Security
Imports System.Security.Permissions
Imports System.Security.Policy
Imports System.Collections
Imports System.Diagnostics

' This code example works properly only if it is run from a fully 
' trusted location, such as your local computer.

' Delegates used to execute the dynamic methods.
'
Public Delegate Sub Test(ByVal w As Worker)
Public Delegate Sub Test1()
Public Delegate Function Test2(ByVal instance As String) As Char

' The Worker class must inherit MarshalByRefObject so that its public 
' methods can be invoked across application domain boundaries.
'
Public Class Worker
    Inherits MarshalByRefObject

    Private Sub PrivateMethod()
        Console.WriteLine("Worker.PrivateMethod()")
    End Sub

    Public Sub SimpleEmitDemo()

        Dim meth As DynamicMethod = new DynamicMethod("", Nothing, Nothing)
        Dim il As ILGenerator = meth.GetILGenerator()
        il.EmitWriteLine("Hello, World!")
        il.Emit(OpCodes.Ret)

        Dim t1 As Test1 = CType(meth.CreateDelegate(GetType(Test1)), Test1)
        t1()
    End Sub

    ' This overload of AccessPrivateMethod emits a dynamic method and
    ' specifies whether to skip JIT visiblity checks. It creates a 
    ' delegate for the method and invokes the delegate. The dynamic 
    ' method calls a private method of the Worker class.
    Overloads Public Sub AccessPrivateMethod( _
                       ByVal restrictedSkipVisibility As Boolean)

        ' Create an unnamed dynamic method that has no return type,
        ' takes one parameter of type Worker, and optionally skips JIT
        ' visiblity checks.
        Dim meth As New DynamicMethod("", _
                                      Nothing, _
                                      New Type() {GetType(Worker)}, _
                                      restrictedSkipVisibility)

        ' Get a MethodInfo for the private method.
        Dim pvtMeth As MethodInfo = GetType(Worker).GetMethod( _
            "PrivateMethod", _
            BindingFlags.NonPublic Or BindingFlags.Instance)

        ' Get an ILGenerator and emit a body for the dynamic method.
        Dim il As ILGenerator = meth.GetILGenerator()

        ' Load the first argument, which is the target instance, onto the
        ' execution stack, call the private method, and return.
        il.Emit(OpCodes.Ldarg_0)
        il.EmitCall(OpCodes.Call, pvtMeth, Nothing)
        il.Emit(OpCodes.Ret)

        ' Create a delegate that represents the dynamic method, and 
        ' invoke it. 
        Try
            Dim t As Test = CType(meth.CreateDelegate(GetType(Test)), Test)
            Try
                t(Me)
            Catch ex As Exception
                Console.WriteLine("{0} was thrown when the delegate was invoked.", _
                    ex.GetType().Name)
            End Try
        Catch ex As Exception
            Console.WriteLine("{0} was thrown when the delegate was compiled.", _
                ex.GetType().Name)
        End Try

    End Sub


    ' This overload of AccessPrivateMethod emits a dynamic method that takes
    ' a string and returns the first character, using a private field of the 
    ' String class. The dynamic method skips JIT visiblity checks.
    Overloads Public Sub AccessPrivateMethod()

        Dim meth As New DynamicMethod("", _
                                      GetType(Char), _
                                      New Type() {GetType(String)}, _
                                      True)

        ' Get a MethodInfo for the 'get' accessor of the private property.
        Dim pi As PropertyInfo = GetType(String).GetProperty( _
            "FirstChar", _
            BindingFlags.NonPublic Or BindingFlags.Instance)
        Dim pvtMeth As MethodInfo = pi.GetGetMethod(True)

        ' Get an ILGenerator and emit a body for the dynamic method.
        Dim il As ILGenerator = meth.GetILGenerator()

        ' Load the first argument, which is the target string, onto the
        ' execution stack, call the 'get' accessor to put the result onto 
        ' the execution stack, and return.
        il.Emit(OpCodes.Ldarg_0)
        il.EmitCall(OpCodes.Call, pvtMeth, Nothing)
        il.Emit(OpCodes.Ret)

        ' Create a delegate that represents the dynamic method, and 
        ' invoke it. 
        Try
            Dim t As Test2 = CType(meth.CreateDelegate(GetType(Test2)), Test2)
            Dim first As Char = t("Hello, World!")
            Console.WriteLine("{0} is the first character.", first)
        Catch ex As Exception
            Console.WriteLine("{0} was thrown when the delegate was compiled.", _
                ex.GetType().Name)
        End Try

    End Sub
End Class

Friend Class Example

    ' The entry point for the code example.
    Shared Sub Main()

        ' Get the display name of the executing assembly, to use when
        ' creating objects to run code in application domains.
        Dim asmName As String = GetType(Worker).Assembly.FullName

        ' Create the permission set to grant to other assemblies. In this
        ' case they are the permissions found in the Internet zone.
        Dim ev As New Evidence()
        ev.AddHostEvidence(new Zone(SecurityZone.Internet))
        Dim pset As New NamedPermissionSet("Internet", SecurityManager.GetStandardSandbox(ev))

        ' For simplicity, set up the application domain to use the 
        ' current path as the application folder, so the same executable
        ' can be used in both trusted and untrusted scenarios. Normally
        ' you would not do this with real untrusted code.
        Dim adSetup As New AppDomainSetup()
        adSetup.ApplicationBase = "."

        ' Create an application domain in which all code that executes is 
        ' granted the permissions of an application run from the Internet.
        Dim ad As AppDomain = AppDomain.CreateDomain("Sandbox", ev, adSetup, pset, Nothing)

        ' Create an instance of the Worker class in the partially trusted 
        ' domain. Note: If you build this code example in Visual Studio, 
        ' you must change the name of the class to include the default 
        ' namespace, which is the project name. For example, if the project
        ' is "AnonymouslyHosted", the class is "AnonymouslyHosted.Worker".
        Dim w As Worker = _
            CType(ad.CreateInstanceAndUnwrap(asmName, "Worker"), Worker)

        ' Emit a simple dynamic method that prints "Hello, World!"
        w.SimpleEmitDemo()

        ' Emit and invoke a dynamic method that calls a private method
        ' of Worker, with JIT visibility checks enforced. The call fails 
        ' when the delegate is invoked.
        w.AccessPrivateMethod(False)

        ' Emit and invoke a dynamic method that calls a private method
        ' of Worker, skipping JIT visibility checks. The call fails when
        ' the method is compiled.
        w.AccessPrivateMethod(True)


        ' Unload the application domain. Add RestrictedMemberAccess to the
        ' grant set, and use it to create an application domain in which
        ' partially trusted code can call private members, as long as the 
        ' trust level of those members is equal to or lower than the trust 
        ' level of the partially trusted code. 
        AppDomain.Unload(ad)
        pset.SetPermission( _
            New ReflectionPermission( _
                ReflectionPermissionFlag.RestrictedMemberAccess))
        ad = AppDomain.CreateDomain("Sandbox2", ev, adSetup, pset, Nothing)

        ' Create an instance of the Worker class in the partially trusted 
        ' domain. 
        w = CType(ad.CreateInstanceAndUnwrap(asmName, "Worker"), Worker)

        ' Again, emit and invoke a dynamic method that calls a private method
        ' of Worker, skipping JIT visibility checks. This time compilation 
        ' succeeds because of the grant for RestrictedMemberAccess.
        w.AccessPrivateMethod(True)

        ' Finally, emit and invoke a dynamic method that calls an internal 
        ' method of the String class. The call fails, because the trust level
        ' of the assembly that contains String is higher than the trust level
        ' of the assembly that emits the dynamic method.
        w.AccessPrivateMethod()

    End Sub
End Class

' This code example produces the following output:
'
'Hello, World!
'MethodAccessException was thrown when the delegate was invoked.
'MethodAccessException was thrown when the delegate was invoked.
'Worker.PrivateMethod()
'MethodAccessException was thrown when the delegate was compiled.
' 

Kod Derleniyor

  • Visual Studio'da bu kod örneğini oluşturursanız, yöntemine geçirirken ad alanını içerecek şekilde sınıfın CreateInstanceAndUnwrap adını değiştirmeniz gerekir. Ad alanı varsayılan olarak projenin adıdır. Örneğin, proje "PartialTrust" ise, sınıf adı "PartialTrust.Worker" olmalıdır.

Ayrıca bkz.