доступ к частному методу в другой сборке С#

StackOverflow https://stackoverflow.com/questions/873150

  •  22-08-2019
  •  | 
  •  

Вопрос

Это может быть глупый вопрос, поскольку я вижу причину безопасности, по которой это происходит именно так...

У меня есть проект лицензирования С#, в нем есть класс, в котором есть метод, который генерирует мои лицензионные ключи.Я сделал этот метод приватным, так как не хочу, чтобы кто-то еще мог вызывать мой метод по понятным причинам.

Следующее, что я хочу сделать, это сделать мой пользовательский интерфейс, который находится в другом проекте С#, который ссылается на лицензионную dll, как единственную другую «вещь», которая может получить доступ к этому методу вне себя, возможно ли это или мне нужно переместить его в тот же проект, чтобы все оно скомпилировалось в одну и ту же dll, и я мог получить доступ к его членам?

ЛицензированиеПроект
-Класс лицензирования
--Частный методX (GeneratesLicenseKeys)

ЛицензированиеПроект.UI
-ЛицензированиеUiClass
--Я хочу быть единственным классом, имеющим доступ к MethodX

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

Я бы предпочел не компилировать все в dll, поскольку моим конечным пользователям не нужен код пользовательского интерфейса.

Я знаю, что по здравому смыслу частный метод - это именно так.Я в тупике.

Это было полезно?

Решение

Вы можете сделать это внутренним методом и использовать InternalsVisibleToAttribute чтобы предоставить LicensingProject.UI дополнительный доступ к LicensingProject.

Точка зрения Мерхдада о правоприменении одновременно правильна и неверна.Если у вас нет Разрешение на отражение, CLR не позволит вам вызывать вещи, которые вам не следует делать, но если вы используете отражение из полностью доверенной сборки, вы можете вызывать что угодно.Следует предположить, что потенциальный хакер способен запустить полностью доверенную сборку на своей машине :)

Ничто из этого не остановит кого-то от использования Отражатель для декомпиляции вашего кода.Другими словами, сделать это конфиденциальным — это не Действительно добавление значительного уровня безопасности к вашей схеме лицензирования.Если кто-то действительно приложит усилия, чтобы сломать его, он, вероятно, сможет это сделать.

Другие советы

Это действительно комментарий, в ответ на замечание Мехрдада о том, что среда выполнения не выполняет проверки доступа;здесь вы можете видеть JIT (как выяснилось), выполняющий проверку доступа, а не отражение и не компилятор C#.

Чтобы исправить код, сделайте Foo.Bar общественность.Интересно, что это также подтверждает Foo доступен - поэтому сделайте Foo внутренний, чтобы увидеть больше фейерверков:

using System;
using System.Reflection;
using System.Reflection.Emit;
static class Program {
    static void Main() {
        MethodInfo bar = typeof(Foo).GetMethod("Bar",
            BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
        var method = new DynamicMethod("FooBar", null, new[] {typeof(Foo)});
        var il = method.GetILGenerator();
        il.Emit(OpCodes.Ldarg_0);
        il.EmitCall(OpCodes.Callvirt, bar, null);
        il.Emit(OpCodes.Ret);

        Action<Foo> action = (Action<Foo>) method.CreateDelegate(typeof(Action<Foo>));
        Foo foo = new Foo();
        Console.WriteLine("Created method etc");
        action(foo); // MethodAccessException
    }
}

public class Foo {
    private void Bar() {
        Console.WriteLine("hi");
    }
}

public, private, ...вещи просто применяются компилятором.Вы можете использовать отражение для довольно легкого доступа к ним (при условии, что код имеет необходимые разрешения, что является разумным предположением, поскольку он имеет полный контроль над машиной).Не полагайтесь на это, предполагая, что никто не сможет этого сделать.

Foo.Bar может остаться частным...Чтобы исправить приведенный выше код, добавьте один параметр в конец конструктора DynamicMethod:

var method = new DynamicMethod("FooBar", null, new[] {typeof(Foo)}, true);

Добавьте true, чтобы пропустить JIT-проверку видимости типов и членов, к которым обращается MSIL динамического метода.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top