SORU
13 Mayıs 2011, Cuma


.NET 4.0, nasıl 'kum' ın-bellek bir montaj ve bir yöntemi uygulamak?

Bu soru soruluyor neden işte nedeni: www.devplusplus.com/Tests/CSharp/Hello_World.

Benzer sorular daha önce soruldu ise, birçok cevapları internetten birkaç sorun var:

  1. Bu yapılmalıdır ".Net 4.0" tarzı, eski moda değil.
  2. Derleme-hafıza ve sadece bellekte, o olacakolamazdosya sistemi için yazılmış.
  3. Dosya sistemi, ağ, vb tüm erişimi sınırlamak istiyorum.

Şöyle bir şey:

    var evidence = new Evidence();
    evidence.AddHostEvidence(new Zone(SecurityZone.Internet));
    var permissionSet = SecurityManager.GetStandardSandbox(evidence);

Şimdiye kadar, ben bir Uygulama oluşturmak ve bir derleme yüklemek için bir yol bulmakDOSYA SİSTEMİ ÜZERİNDE DEĞİLama RAM yerine.

Yine, diğer çözümler işe yaramadı neden yukarıda belirlenmiştir: 1. Çok önceden 4.0 ve 2 için. Birçok dayanıyordu ".Yük" yöntemi dosya sistemine işaret.

Bir derleme başvurusu CSharpCodeProvider sınıfı tarafından oluşturulmuş olması sebebiyle, eğer öyleyse açmak için bir yol biliyorsanız . cevap 2: ^em>bubayt dizisine, bu harika olurdu!

Örnek Kod Güvenlik Kusur Göstermek

var provider = new CSharpCodeProvider(new Dictionary<String, String>
    { { "CompilerVersion", "v4.0" } });

var compilerparams = new CompilerParameters
    { GenerateExecutable = false, GenerateInMemory = true, };

var compilerResults = provider.CompileAssemblyFromSource(compilerparams,
    string_Of_Code_From_A_User);

var instanceOfSomeClass = compilerResults.CompiledAssembly
    .CreateInstance(className);

// The 'DoSomething' method can write to the file system and I don't like that!
instanceOfSomeClass.GetType().GetMethod("DoSomething")
    .Invoke(instanceOfSomeClass, null);

Neden sadece bir dosya için Kurul ilk kurtarabilir mi?

İki sebepten:

  1. Bu kod sınırlı izinleri paylaşılan bir web sunucusu üzerinde dosya sistemi kendisi için.
  2. Bu kod potansiyel olarak binlerce kez çalıştırmak gerekir, ve 1000 DLL, geçici bile olsa istemiyorum.

CEVAP
13 Mayıs 2011, Cuma


TAMAM, ilk şeyler ilk: CSharpCodeProvider C dinamik derleme yapmak için kullanmak için gerçek bir yolu yoktur# tamamen bellek kaynak. Orada yöntemleri gibi destek işlevleri, ama beri C# derleyicisi bir yerli çalıştırılabilir olan çalışma süreci, kaynak dize kaydedilmiş bir geçici dosya, derleyici çağrılır bu dosya ve daha sonra ortaya çıkan montaj kayıtlı disk ve daha sonra yüklenen kullanarak Montaj.Yük.

Keşfettiğin gibi ikinci olarak, Uygulama derleme yüklenemedi içinden Derleme yöntemi ve istenilen izinleri vermek kullanmak gerekir. Bu aynı olağandışı davranış ile karşılaştım, ve çok fazla araştırma çerçevesinde bir hata olduğunu bulduktan sonra. MS Connect Bu konuda bir rapor hazırladım.

Çerçeve zaten dosya sistemine zaten yazılı olduğundan, geçici Meclis geçici bir dosyaya yazılır ve daha sonra gerektiğinde yüklenir. Ne zaman dosya sistemine erişim izni var beri ancak, geçici olarak Uygulama izinleri savunmak gerekir, yük. İşte bir örnek, bu parçacığı:

new FileIOPermission(FileIOPermissionAccess.Read | FileIOPermissionAccess.PathDiscovery, assemblyPath).Assert();
var assembly = Assembly.LoadFile(assemblyPath);
CodeAccessPermission.RevertAssert();

Oradan yöntemi çağırmak için montaj yansıma kullanabilirsiniz. Bu yöntem, benim görüşüme göre bir artı korumalı Uygulama etki alanı dışında derleme işlemi kaldırma sağlar unutmayın.

Başvuru için, burada sınırlı izinlere sahip ve gerektiğinde kolayca yüklenmemiş olabilir Sanal sınıfım güzel, temiz ayrı bir Türün script derlemeler başlatılması kolaylaştırmak için oluşturulur:

class Sandbox : MarshalByRefObject
{
    const string BaseDirectory = "Untrusted";
    const string DomainName = "Sandbox";

    public Sandbox()
    {
    }

    public static Sandbox Create()
    {
        var setup = new AppDomainSetup()
        {
            ApplicationBase = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, BaseDirectory),
            ApplicationName = DomainName,
            DisallowBindingRedirects = true,
            DisallowCodeDownload = true,
            DisallowPublisherPolicy = true
        };

        var permissions = new PermissionSet(PermissionState.None);
        permissions.AddPermission(new ReflectionPermission(ReflectionPermissionFlag.RestrictedMemberAccess));
        permissions.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));

        var domain = AppDomain.CreateDomain(DomainName, null, setup, permissions,
            typeof(Sandbox).Assembly.Evidence.GetHostEvidence<StrongName>());

        return (Sandbox)Activator.CreateInstanceFrom(domain, typeof(Sandbox).Assembly.ManifestModule.FullyQualifiedName, typeof(Sandbox).FullName).Unwrap();
    }

    public string Execute(string assemblyPath, string scriptType, string method, params object[] parameters)
    {
        new FileIOPermission(FileIOPermissionAccess.Read | FileIOPermissionAccess.PathDiscovery, assemblyPath).Assert();
        var assembly = Assembly.LoadFile(assemblyPath);
        CodeAccessPermission.RevertAssert();

        Type type = assembly.GetType(scriptType);
        if (type == null)
            return null;

        var instance = Activator.CreateInstance(type);
        return string.Format("{0}", type.GetMethod(method).Invoke(instance, parameters));
    }
}

Ufak bir not: Eğer yeni bir Uygulama için güvenlik kanıt sağlamak için bu yöntemi kullanırsanız, derleme imzalamak için gereken güçlü bir isim vermek.

Not bu işler iyi zaman çalışma süreci, ama eğer gerçekten istediğiniz bir kurşun geçirmez script çevre, gitmen gerek bir adım daha ileri ve izole senaryoda ayrı bir sürecin emin olmak için komut bunu kötü niyetli (ya da aptal) gibi şeyler yığını taşmaları, çatal bomba ve RAM de durumlar yok getir bütün uygulama süreci. Eğer ihtiyacınız varsa bunu yapma hakkında daha fazla bilgi verebilirim.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Chaoticmoogle

    Chaoticmoogl

    13 ŞUBAT 2006
  • Floortile83

    Floortile83

    16 Ocak 2010
  • Sali Kaceli

    Sali Kaceli

    24 ŞUBAT 2009