2

这可能是一个愚蠢的问题,因为我可以看到它以这种方式发生的安全原因......

我有一个许可 c# 项目,它有一个类,它有一个生成我的许可证密钥的方法。我已将此方法设为私有,因为我不希望其他人能够出于明显的原因调用我的方法

我想做的下一件事是拥有我的用户界面,它位于另一个 c# 项目中,该项目引用许可 dll 是唯一可以在自身之外访问此方法的其他“事物”,这可能还是我需要将它移动到同一个项目中,以便它全部编译到同一个 dll 并且我可以访问它的成员?

LicensingProject
-LicensingClass
--Private MethodX (GeneratesLicenseKeys)

LicensingProject.UI
-LicensingUiClass
--我希望能够成为唯一能够访问 MethodX 的类

许可证密钥生成器不只是在 UI 中是有原因的,因为许可通过在自身上生成哈希并将其与许可证生成器生成的哈希进行比较来工作。

我不希望全部编译为 dll,因为我的最终用户不需要 UI 代码。

我知道根据常识,一种私有方法就是这样。我难住了。

4

4 回答 4

6

您可以将其设为内部方法,并用于InternalsVisibleToAttribute为 LicensingProject.UI 提供对 LicensingProject 的额外访问权限。

Merhdad 关于执法的观点是对的,也是错的。如果你没有ReflectionPermission,CLR 会阻止你调用你不应该调用的东西——但如果你使用来自完全受信任的程序集的反射,你可以调用任何东西。你应该假设一个潜在的黑客能够在他自己的机器上运行一个完全受信任的程序集:)

这些都不会阻止某人使用Reflector反编译您的代码。换句话说,将其设为私有并不会真正为您的许可方案增加大量安全性。如果有人真的付出任何努力来打破它,他们可能能够做到。

于 2009-05-16T19:48:24.970 回答
2

public, private, ... 东西只是由编译器强制执行的。您可以使用反射很容易地访问它们(假设代码具有所需的权限,这是一个合理的假设,因为他可以完全控制机器)。不要依赖于假设没有人可以调用它。

于 2009-05-16T19:48:15.343 回答
2

这确实是一条评论,以回应 Mehrdad 关于运行时不执行访问检查的观点;在这里,您可以看到 JIT(它发生)执行访问检查 - 不是反射,也不是 C# 编译器。

要修复代码,请Foo.Bar公开。有趣的是,它还验证了它Foo是可访问的——所以让Foointernal 看到更多的烟花:

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");
    }
}
于 2009-05-16T20:13:49.090 回答
1

Foo.Bar 可能保持私有...要修复上面的代码,请在 DynamicMethod 构造函数的末尾添加一个参数:

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

添加 true 以跳过对动态方法的 MSIL 访问的类型和成员的 JIT 可见性检查。

于 2011-01-08T07:37:02.513 回答