Страницы

Поиск по вопросам

суббота, 30 ноября 2019 г.

Ограничить возможности стороннего класса C#

#c_sharp #классы #модульность #песочница


Имеется (модульное) игровое приложение - арена, в нем реализован абстрактный класс
(или интерфейс) для игрока. Игроков (игровые ИИ) наследуют от указанного класса и разрабатывают
сторонние разработчики и предоставляют в виде скомпилированного dll.
Есть ли вообще возможность ограничить возможности этой сторонней dll? Ну, например
защититься от "FORMAT C:" или от пересылки данных по сети, чтения с диска и т. д.
Пусть даже этот класс падает в этом случае - тогда игроку просто засчитывается техническое
поражение.

Какой день бьюсь, но, хоть убейте, никак не пойму, как заставить это работать.
Как сделать чтобы все сторонние игроки работали в песочнице? Сейчас есть примерно
такой код:

static class PlayersHost
{
    static public List Players;

    static public void LoadPlayers()
    {
        Players = new List();

        var files = Directory.EnumerateFiles(Path.Combine(Environment.CurrentDirectory,
"Players"), "*.dll");
        foreach (var file in files)
        {
            try
            {
                var asm = Assembly.LoadFrom(file);
                var types = asm.GetTypes();
                foreach (var type in types)
                {
                    try
                    {
                        IPlayer player = (IPlayer)Activator.CreateInstance(type);
                        players.Add(player);
                    }
                    catch { }
                }
            }
            catch { }
        }
    }
}


Потом я просто при старте приложения загружаю всех игроков:

PlayersHost.LoadPlayers();


и пользуюсь полученной коллекцией, например:

var player = PlayersHost.Players[0];
try { player.PrepareToPlay(); } catch { }


Нужно решение с использованием AppDomain
    


Ответы

Ответ 1



Для изолирования частично доверенного кода в .NET предусмотрен механизм ограничения доступа в рамках AppDomain - это называется Sandbox (запуск в песочнице). AppDomain.CreateDomain( string friendlyName, Evidence securityInfo, AppDomainSetup info, PermissionSet grantSet, params StrongName[] fullTrustAssemblies); Информация о том, как его использовать, а также ряд дополнительных соображений и нюансов подробно описаны в этой статье на MSDN: https://msdn.microsoft.com/ru-ru/library/bb763046(v=vs.110).aspx

Ответ 2



Альтернативным, более высокоуровневым решением может быть использование System.AddIn. Это фреймворк, более сложный, чем использование AppDomain, но он предоставляет больше возможностей. В частности, он позволяет автоматически находить загруженные add-in'ы, и загружать их по вашему желанию в текущий AppDomain в отдельный, специальный AppDomain для компонент, которым вы не доверяете каждую компоненту в отдельный AppDomain в отдельный внешний процесс каждую компоненту в отдельный AppDomain общего внешнего процесса. При этом протокол взаимодействия остаётся тем же самым. При этом объекты, которые переходят через границу между основным кодом и add-in'ами, должны быть сериализуемыми. К сожалению, полновесный пример не вписывается в формат ответа, но хороший пример есть в документации: Add-in overview Walkthrough: Creating an Extensible Application

Комментариев нет:

Отправить комментарий